Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,212 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using UnityEngine;
/// <summary>
/// Represents the Pose of the anchor. Enabling it will localize the anchor.
/// </summary>
/// <remarks>
/// This component can be accessed from an <see cref="OVRAnchor"/> that supports it by calling
/// <see cref="OVRAnchor.GetComponent{T}"/> from the anchor.
/// This component needs to be enabled before requesting its Pose. See <see cref="IsEnabled"/> and
/// <see cref="SetEnabledAsync"/>
/// </remarks>
/// <seealso cref="TrackingSpacePose"/>
/// <seealso cref="TryGetSceneAnchorPose"/>
/// <seealso cref="TryGetSpatialAnchorPose"/>
public readonly partial struct OVRLocatable : IOVRAnchorComponent<OVRLocatable>, IEquatable<OVRLocatable>
{
/// <summary>
/// Tracking space position and rotation of the anchor
/// </summary>
/// <remarks>
/// Position and rotation are both nullable <see cref="Vector3"/> and <see cref="Quaternion"/>
/// and might be null independently if one of them or both are invalid.
/// </remarks>
/// <seealso cref="Position"/>
/// <seealso cref="IsPositionTracked"/>
/// <seealso cref="ComputeWorldPosition"/>
/// <seealso cref="Rotation"/>
/// <seealso cref="IsRotationTracked"/>
/// <seealso cref="ComputeWorldRotation"/>
public readonly struct TrackingSpacePose
{
/// <summary>
/// Position in tracking space of the anchor
/// </summary>
/// <remarks>
/// Null if and when the position is invalid
/// </remarks>
/// <seealso cref="Rotation"/>
/// <seealso cref="ComputeWorldPosition"/>
/// <seealso cref="ComputeWorldRotation"/>
public Vector3? Position { get; }
/// <summary>
/// Rotation in tracking space of the Anchor
/// </summary>
/// <remarks>
/// Null if and when the rotation is invalid
/// </remarks>
/// <seealso cref="Position"/>
/// <seealso cref="ComputeWorldPosition"/>
/// <seealso cref="ComputeWorldRotation"/>
public Quaternion? Rotation { get; }
/// <summary>
/// Indicates whether or not the position is currently tracked
/// </summary>
public bool IsPositionTracked => _flags.IsPositionTracked();
/// <summary>
/// Indicates whether or not the rotation is currently tracked
/// </summary>
public bool IsRotationTracked => _flags.IsOrientationTracked();
private readonly OVRPlugin.SpaceLocationFlags _flags;
internal TrackingSpacePose(Vector3 position, Quaternion rotation, OVRPlugin.SpaceLocationFlags flags)
{
_flags = flags;
Position = _flags.IsPositionValid() ? position : default(Vector3?);
Rotation = _flags.IsOrientationValid() ? rotation : default(Quaternion?);
}
/// <summary>
/// Computes the world space position of the anchor
/// </summary>
/// <param name="camera">A <see cref="Camera"/> component that will be use to compute the transform to world space</param>
/// <returns>
/// The nullable <see cref="Vector3"/> position in world space which may be
/// null if and when <see cref="Position"/> is invalid or head pose is invalid.
/// </returns>
/// <seealso cref="Position"/>
/// <seealso cref="Rotation"/>
/// <seealso cref="ComputeWorldRotation"/>
/// <exception cref="ArgumentNullException">If <paramref name="camera"/> is null</exception>
public Vector3? ComputeWorldPosition(Camera camera)
{
if (camera == null) throw new ArgumentNullException(nameof(camera));
if (!Position.HasValue) return null;
var headPose = OVRPose.identity;
if (!OVRNodeStateProperties.GetNodeStatePropertyVector3(UnityEngine.XR.XRNode.Head,
NodeStatePropertyType.Position, OVRPlugin.Node.Head, OVRPlugin.Step.Render, out headPose.position))
return null;
if (!OVRNodeStateProperties.GetNodeStatePropertyQuaternion(UnityEngine.XR.XRNode.Head,
NodeStatePropertyType.Orientation, OVRPlugin.Node.Head, OVRPlugin.Step.Render,
out headPose.orientation))
return null;
headPose = headPose.Inverse();
var headTrackingPosition = headPose.position + headPose.orientation * Position.Value;
return camera.transform.localToWorldMatrix.MultiplyPoint(headTrackingPosition);
}
/// <summary>
/// Computes the world space rotation of the anchor
/// </summary>
/// <param name="camera">A <see cref="Camera"/> component that will be use to compute the transform to world space</param>
/// <returns>
/// The nullable <see cref="Quaternion"/> rotation in world space which may be
/// null if and when <see cref="Rotation"/> is invalid or if head rotation is invalid.
/// </returns>
/// <seealso cref="Position"/>
/// <seealso cref="Rotation"/>
/// <seealso cref="ComputeWorldPosition"/>
/// <exception cref="ArgumentNullException">If <paramref name="camera"/> is null</exception>
public Quaternion? ComputeWorldRotation(Camera camera)
{
if (camera == null) throw new ArgumentNullException(nameof(camera));
if (!Rotation.HasValue) return null;
if (!OVRNodeStateProperties.GetNodeStatePropertyQuaternion(UnityEngine.XR.XRNode.Head,
NodeStatePropertyType.Orientation, OVRPlugin.Node.Head, OVRPlugin.Step.Render,
out var headPoseRotation))
return null;
headPoseRotation = Quaternion.Inverse(headPoseRotation);
var headTrackingOrientation = headPoseRotation * Rotation.Value;
return camera.transform.rotation * headTrackingOrientation;
}
}
/// <summary>
/// Tries to get the <see cref="TrackingSpacePose"/> representing the position and rotation of this anchor, treated as a scene anchor, in tracking space.
/// </summary>
/// <param name="pose">The out <see cref="TrackingSpacePose"/> which will get filled in.</param>
/// <returns>
/// True if the request was successful, False otherwise.
/// </returns>
/// <remarks>
/// <para>Although the request may succeed and provide a valid <see cref="TrackingSpacePose"/>, actual Position and Rotation provided
/// may not be valid and/or tracked, see <see cref="TrackingSpacePose"/> for more information on how to use its data.</para>
/// <para>Scene anchors follow a different transform from the raw OpenXR data than spatial anchors'.</para>
/// </remarks>
public bool TryGetSceneAnchorPose(out TrackingSpacePose pose)
{
if (!OVRPlugin.TryLocateSpace(Handle, OVRPlugin.GetTrackingOriginType(), out var posef, out var locationFlags))
{
pose = default;
return false;
}
// Transform from OpenXR Right-handed coordinate system
// to Unity Left-handed coordinate system with additional 180 rotation around +y
var position = posef.Position.FromFlippedZVector3f();
var rotation = new Quaternion(-posef.Orientation.z, posef.Orientation.w, -posef.Orientation.x,
posef.Orientation.y);
pose = new TrackingSpacePose(position, rotation, locationFlags);
return true;
}
/// <summary>
/// Tries to get the <see cref="TrackingSpacePose"/> representing the position and rotation of this anchor, treated as a spatial anchor, in tracking space.
/// </summary>
/// <param name="pose">The out <see cref="TrackingSpacePose"/> which will get filled in.</param>
/// <returns>
/// True if the request was successful, False otherwise.
/// </returns>
/// <remarks>
/// <para>Although the request may succeed and provide a valid <see cref="TrackingSpacePose"/>, actual position and rotation provided
/// may not be valid and/or tracked, see <see cref="TrackingSpacePose"/> for more information on how to use its data.</para>
/// <para>Spatial anchors follow a different transform from the raw OpenXR data than scene anchors'.</para>
/// </remarks>
public bool TryGetSpatialAnchorPose(out TrackingSpacePose pose)
{
if (!OVRPlugin.TryLocateSpace(Handle, OVRPlugin.GetTrackingOriginType(), out var posef, out var locationFlags))
{
pose = default;
return false;
}
// Transform from OpenXR Right-handed coordinate system
// to Unity Left-handed coordinate system
var position = posef.Position.FromFlippedZVector3f();
var rotation = posef.Orientation.FromFlippedZQuatf();
pose = new TrackingSpacePose(position, rotation, locationFlags);
return true;
}
}