using System;
using System.Runtime.InteropServices;
using UnityEngine.XR.ARSubsystems;
namespace UnityEngine.XR.MagicLeap
{
internal struct ReferenceFrame
{
public struct Cinfo
{
public Pose closetCoordinateFrame;
public Native.MagicLeapNativeBindings.MLCoordinateFrameUID cfuid;
public TrackingState trackingState;
public Pose initialAnchorPose;
}
public ReferenceFrame(Cinfo cinfo)
{
trackableId = GenerateTrackableId();
coordinateFrame = cinfo.closetCoordinateFrame;
cfuid = cinfo.cfuid;
trackingState = cinfo.trackingState;
m_AnchorFromCoordinateFrame = Pose.identity;
ComputeDelta(cinfo.initialAnchorPose);
}
Pose m_AnchorFromCoordinateFrame;
public TrackableId trackableId { get; private set; }
public Pose coordinateFrame { get; set; }
public Native.MagicLeapNativeBindings.MLCoordinateFrameUID cfuid { get; private set; }
public TrackingState trackingState { get; set; }
public Pose anchorPose
{
get
{
return m_AnchorFromCoordinateFrame.GetTransformedBy(coordinateFrame);
}
}
public XRAnchor anchor
{
get
{
return new XRAnchor(
trackableId,
anchorPose,
trackingState,
IntPtr.Zero);
}
}
public void SetCoordinateFrame(Native.MagicLeapNativeBindings.MLCoordinateFrameUID cfuid, Pose coordinateFrame)
{
var pose = anchorPose;
this.cfuid = cfuid;
this.coordinateFrame = coordinateFrame;
ComputeDelta(pose);
}
public bool SetTrackingState(TrackingState trackingState)
{
var oldTrackingState = this.trackingState;
this.trackingState = trackingState;
return oldTrackingState != trackingState;
}
void ComputeDelta(Pose pose)
{
var invRotation = Quaternion.Inverse(coordinateFrame.rotation);
m_AnchorFromCoordinateFrame = new Pose(
invRotation * (pose.position - coordinateFrame.position),
invRotation * pose.rotation);
}
static unsafe TrackableId GenerateTrackableId()
{
var guid = Guid.NewGuid();
void* guidPtr = &guid;
return Marshal.PtrToStructure<TrackableId>((IntPtr)guidPtr);
}
}
}