// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.OpenXR.ARSubsystems;
using System;
using Unity.Collections;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
namespace Microsoft.MixedReality.OpenXR
{
///
/// Types of markers that can be tracked.
///
public enum ARMarkerType
{
///
/// A marker of QRCode type.
/// Equivalent to XR_SCENE_MARKER_TYPE_QR_CODE_MSFT.
///
QRCode = 1
}
///
/// Represents types of QRCodes that can be detected.
///
public enum QRCodeType
{
///
/// A QRCode type of QRCode.
/// Equivalent to XR_SCENE_MARKER_QR_CODE_SYMBOL_TYPE_QR_CODE_MSFT.
///
QRCode = 1,
///
/// A QRCode type of MicroQRCode.
/// Equivalent to XR_SCENE_MARKER_QR_CODE_SYMBOL_TYPE_MICRO_QR_CODE_MSFT.
///
MicroQRCode = 2
}
///
/// Types of transforms that can be applied to markers.
///
public enum TransformMode
{
///
/// Marker centered at origin.
///
MostStable = 0,
///
/// Marker centered at geometric center.
///
Center = 1,
}
///
/// Represents properties of detected QRCodes.
///
/// See https://github.com/yansikeim/QR-Code/blob/master/ISO%20IEC%2018004%202015%20Standard.pdf for more information.
public struct QRCodeProperties
{
///
/// Version of the QRCode.
///
///
/// The version is in the range of 1-40 if the type is QRCode.
/// The version is in the range or 1-4 if the type is microQRCode.
///
public uint version;
///
/// Type of the QRCode.
///
public QRCodeType type;
}
///
/// Represents a marker detected by an AR device.
///
///
/// Generated by the when an AR device detects
/// a marker in the environment.
///
[DefaultExecutionOrder(ARUpdateOrder.k_Plane)]
[DisallowMultipleComponent]
public sealed class ARMarker : ARTrackable
{
///
/// The time when the marker was last seen. Comparable to .
///
public float lastSeenTime => sessionRelativeData.lastSeenTime;
///
/// The center relative to the pose in the X, Y plane.
///
public Vector2 center => sessionRelativeData.center;
///
/// The physical size (dimensions) of the marker in meters.
///
public Vector2 size => sessionRelativeData.size;
///
/// The type of marker. Currently we only support markert os QRCode type.
///
public ARMarkerType markerType => sessionRelativeData.markerType;
///
/// The type of transform to apply on the marker.
///
public TransformMode transformMode
{
get => sessionRelativeData.transformMode;
set
{
if (ARMarkerManager.Instance != null)
{
ARMarkerManager.Instance.SetTransformMode(trackableId, value);
}
}
}
///
/// Get a native pointer associated with this marker.
///
///
/// The data pointed to by this member is implementation defined.
/// The lifetime of the pointed to object is also
/// implementation defined, but should be valid at least until the next
/// update.
///
public IntPtr nativePtr => sessionRelativeData.nativePtr;
///
/// Get the decoded string associated with this marker.
///
public string GetDecodedString()
{
if (ARMarkerManager.Instance != null)
{
return ARMarkerManager.Instance.GetDecodedString(trackableId);
}
return string.Empty;
}
///
/// Get the raw data associated with this marker.
///
public NativeArray GetRawData(Allocator allocator)
{
if (ARMarkerManager.Instance != null)
{
return ARMarkerManager.Instance.GetRawData(trackableId, allocator);
}
return new NativeArray(0, allocator);
}
///
/// Get the properties associated with this QRCode marker.
///
public QRCodeProperties GetQRCodeProperties()
{
if (markerType == ARMarkerType.QRCode)
{
if (ARMarkerManager.Instance != null)
{
return ARMarkerManager.Instance.GetQRCodeProperties(trackableId);
}
return new QRCodeProperties();
}
else
{
throw new InvalidOperationException("GetQRCodeProperties() is only valid when markerType == ARMarkerType.QRCode");
}
}
}
}