Initialer Upload neues Unity-Projekt

This commit is contained in:
Daniel Ocks
2025-07-21 09:11:14 +02:00
commit eeca72985b
14558 changed files with 1508140 additions and 0 deletions

View File

@ -0,0 +1,349 @@
/*
* 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 System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
using static OVRPlugin;
/// <summary>
/// Represents an anchor.
/// </summary>
/// <remarks>
/// Scenes anchors are uniquely identified with their <see cref="Uuid"/>.
/// <para>You may dispose of an anchor by calling their <see cref="Dispose"/> method.</para>
/// </remarks>
public readonly struct OVRAnchor : IEquatable<OVRAnchor>, IDisposable
{
#region Static
public static readonly OVRAnchor Null = new OVRAnchor(0, Guid.Empty);
internal static OVRPlugin.SpaceQueryInfo GetQueryInfo(SpaceComponentType type,
OVRSpace.StorageLocation location, int maxResults, double timeout) => new OVRSpaceQuery.Options
{
QueryType = OVRPlugin.SpaceQueryType.Action,
ActionType = OVRPlugin.SpaceQueryActionType.Load,
ComponentFilter = type,
Location = location,
Timeout = timeout,
MaxResults = maxResults,
}.ToQueryInfo();
internal static OVRPlugin.SpaceQueryInfo GetQueryInfo(IEnumerable<Guid> uuids,
OVRSpace.StorageLocation location, double timeout) => new OVRSpaceQuery.Options
{
QueryType = OVRPlugin.SpaceQueryType.Action,
ActionType = OVRPlugin.SpaceQueryActionType.Load,
UuidFilter = uuids,
Location = location,
Timeout = timeout,
MaxResults = OVRSpaceQuery.Options.MaxUuidCount,
}.ToQueryInfo();
internal static OVRTask<bool> FetchAnchorsAsync(SpaceComponentType type, IList<OVRAnchor> anchors,
OVRSpace.StorageLocation location = OVRSpace.StorageLocation.Local,
int maxResults = OVRSpaceQuery.Options.MaxUuidCount, double timeout = 0.0)
=> FetchAnchors(anchors, GetQueryInfo(type, location, maxResults, timeout));
/// <summary>
/// Asynchronous method that fetches anchors with a specific component.
/// </summary>
/// <typeparam name="T">The type of component the fetched anchor must have.</typeparam>
/// <param name="anchors">IList that will get cleared and populated with the requested anchors.</param>s
/// <param name="location">Storage location to query</param>
/// <param name="maxResults">The maximum number of results the query can return</param>
/// <param name="timeout">Timeout in seconds for the query. Zero indicates the query does not timeout.</param>
/// <remarks>Dispose of the returned <see cref="OVRTask{T}"/> if you don't use the results</remarks>
/// <returns>An <see cref="OVRTask{T}"/> that will eventually let you test if the fetch was successful or not.
/// If the result is true, then the <see cref="anchors"/> parameter has been populated with the requested anchors.</returns>
/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="anchors"/> is `null`.</exception>
public static OVRTask<bool> FetchAnchorsAsync<T>(IList<OVRAnchor> anchors,
OVRSpace.StorageLocation location = OVRSpace.StorageLocation.Local,
int maxResults = OVRSpaceQuery.Options.MaxUuidCount, double timeout = 0.0)
where T : struct, IOVRAnchorComponent<T>
{
if (anchors == null)
{
throw new ArgumentNullException(nameof(anchors));
}
return FetchAnchorsAsync(default(T).Type, anchors, location, maxResults, timeout);
}
/// <summary>
/// Asynchronous method that fetches anchors with specifics uuids.
/// </summary>
/// <param name="uuids">Enumerable of uuids that anchors fetched must verify</param>
/// <param name="anchors">IList that will get cleared and populated with the requested anchors.</param>s
/// <param name="location">Storage location to query</param>
/// <param name="timeout">Timeout in seconds for the query. Zero indicates the query does not timeout.</param>
/// <remarks>Dispose of the returned <see cref="OVRTask{T}"/> if you don't use the results</remarks>
/// <returns>An <see cref="OVRTask{T}"/> that will eventually let you test if the fetch was successful or not.
/// If the result is true, then the <see cref="anchors"/> parameter has been populated with the requested anchors.</returns>
/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="uuids"/> is `null`.</exception>
/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="anchors"/> is `null`.</exception>
public static OVRTask<bool> FetchAnchorsAsync(IEnumerable<Guid> uuids, IList<OVRAnchor> anchors,
OVRSpace.StorageLocation location = OVRSpace.StorageLocation.Local, double timeout = 0.0)
{
if (uuids == null)
{
throw new ArgumentNullException(nameof(uuids));
}
if (anchors == null)
{
throw new ArgumentNullException(nameof(anchors));
}
return FetchAnchors(anchors, GetQueryInfo(uuids, location, timeout));
}
private static OVRTask<bool> FetchAnchors(IList<OVRAnchor> anchors, OVRPlugin.SpaceQueryInfo queryInfo)
{
if (anchors == null)
{
throw new ArgumentNullException(nameof(anchors));
}
anchors.Clear();
if (!OVRPlugin.QuerySpaces(queryInfo, out var requestId))
{
return OVRTask.FromResult(false);
}
var task = OVRTask.FromRequest<bool>(requestId);
task.SetInternalData(anchors);
return task;
}
internal static void OnSpaceQueryCompleteData(OVRDeserialize.SpaceQueryCompleteData data)
{
var requestId = data.RequestId;
var task = OVRTask.GetExisting<bool>(requestId);
if (!task.IsPending)
{
return;
}
if (!task.TryGetInternalData<IList<OVRAnchor>>(out var anchors) || anchors == null)
{
task.SetResult(false);
return;
}
if (!OVRPlugin.RetrieveSpaceQueryResults(requestId, out var rawResults, Allocator.Temp))
{
task.SetResult(false);
return;
}
foreach (var result in rawResults)
{
var anchor = new OVRAnchor(result.space, result.uuid);
anchors.Add(anchor);
}
rawResults.Dispose();
task.SetResult(true);
}
/// <summary>
/// Creates a new spatial anchor.
/// </summary>
/// <remarks>
/// Spatial anchor creation is asynchronous. This method initiates a request to create a spatial anchor at
/// <paramref name="trackingSpacePose"/>. The returned <see cref="OVRTask{TResult}"/> can be awaited or used to
/// track the completion of the request.
///
/// If spatial anchor creation fails, the resulting <see cref="OVRAnchor"/> will be <see cref="OVRAnchor.Null"/>.
/// </remarks>
/// <param name="trackingSpacePose">The pose, in tracking space, at which you wish to create the spatial anchor.</param>
/// <returns>A task which can be used to track completion of the request.</returns>
public static OVRTask<OVRAnchor> CreateSpatialAnchorAsync(Pose trackingSpacePose)
=> CreateSpatialAnchor(new SpatialAnchorCreateInfo
{
BaseTracking = GetTrackingOriginType(),
PoseInSpace = new Posef
{
Orientation = trackingSpacePose.rotation.ToFlippedZQuatf(),
Position = trackingSpacePose.position.ToFlippedZVector3f(),
},
Time = GetTimeInSeconds(),
}, out var requestId)
? OVRTask.FromRequest<OVRAnchor>(requestId)
: OVRTask.FromResult(Null);
/// <summary>
/// Creates a new spatial anchor.
/// </summary>
/// <remarks>
/// Spatial anchor creation is asynchronous. This method initiates a request to create a spatial anchor at
/// <paramref name="transform"/>. The returned <see cref="OVRTask{TResult}"/> can be awaited or used to
/// track the completion of the request.
///
/// If spatial anchor creation fails, the resulting <see cref="OVRAnchor"/> will be <see cref="OVRAnchor.Null"/>.
/// </remarks>
/// <param name="transform">The transform at which you wish to create the spatial anchor.</param>
/// <param name="centerEyeCamera">The `Camera` associated with the Meta Quest's center eye.</param>
/// <returns>A task which can be used to track completion of the request.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="transform"/> is `null`.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="centerEyeCamera"/> is `null`.</exception>
public static OVRTask<OVRAnchor> CreateSpatialAnchorAsync(Transform transform, Camera centerEyeCamera)
{
if (transform == null)
throw new ArgumentNullException(nameof(transform));
if (centerEyeCamera == null)
throw new ArgumentNullException(nameof(centerEyeCamera));
var pose = transform.ToTrackingSpacePose(centerEyeCamera);
return CreateSpatialAnchorAsync(new Pose
{
position = pose.position,
rotation = pose.orientation,
});
}
#endregion
internal ulong Handle { get; }
/// <summary>
/// Unique Identifier representing the anchor.
/// </summary>
public Guid Uuid { get; }
internal OVRAnchor(ulong handle, Guid uuid)
{
Handle = handle;
Uuid = uuid;
}
/// <summary>
/// Gets the anchor's component of a specific type.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <returns>The requested component.</returns>
/// <remarks>Make sure the anchor supports the specified type of component using <see cref="SupportsComponent{T}"/></remarks>
/// <exception cref="InvalidOperationException">Thrown if the anchor doesn't support the specified type of component.</exception>
/// <seealso cref="TryGetComponent{T}"/>
/// <seealso cref="SupportsComponent{T}"/>
public T GetComponent<T>() where T : struct, IOVRAnchorComponent<T>
{
if (!TryGetComponent<T>(out var component))
{
throw new InvalidOperationException($"Anchor {Uuid} does not have component {typeof(T).Name}");
}
return component;
}
/// <summary>
/// Tries to get the anchor's component of a specific type.
/// </summary>
/// <param name="component">The requested component, as an <c>out</c> parameter.</param>
/// <typeparam name="T">The type of the component.</typeparam>
/// <returns>Whether or not the request succeeded. It may fail if the anchor doesn't support this type of component.</returns>
/// <seealso cref="GetComponent{T}"/>
public bool TryGetComponent<T>(out T component) where T : struct, IOVRAnchorComponent<T>
{
component = default(T);
var result = OVRPlugin.GetSpaceComponentStatusInternal(Handle, component.Type, out _, out _);
if (!result.IsSuccess())
{
return false;
}
component = component.FromAnchor(this);
return true;
}
/// <summary>
/// Tests whether or not the anchor supports a specific type of component.
/// </summary>
/// <remarks>
/// For performance reasons, we use xrGetSpaceComponentStatusFB, which can
/// result in an error in the logs when the component is not available.
///
/// This error does not have impact on the control flow. The alternative method,
/// <seealso cref="GetSupportedComponents(List{SpaceComponentType})"/> avoids
/// this error reporting, but does have performance constraints.
/// </remarks>
/// <typeparam name="T">The type of the component.</typeparam>
/// <returns>Whether or not the specified type of component is supported.</returns>
public bool SupportsComponent<T>() where T : struct, IOVRAnchorComponent<T>
{
var component = default(T);
var result = OVRPlugin.GetSpaceComponentStatusInternal(Handle, component.Type, out _, out _);
return result.IsSuccess();
}
/// <summary>
/// Get all the supported components of an anchor.
/// </summary>
/// <remarks>
/// For performance reasons, this method reuses data structures to
/// avoid allocations, and is therefore not considered thread safe.
///
/// Do not use in background threads, including async functions
/// started with <seealso cref="System.Threading.Tasks.Task.Run(Action)"/>
/// </remarks>
/// <param name="components">The list that will be cleared, then populated with
/// the supported components.</param>
/// <returns>Whether or not the request succeeded.</returns>
public bool GetSupportedComponents(List<SpaceComponentType> components)
{
components.Clear();
if (OVRPlugin.EnumerateSpaceSupportedComponents(Handle,
out var componentCount, SupportedComponentsArray))
{
for (var i = 0; i < componentCount; i++)
components.Add(SupportedComponentsArray[i]);
return true;
}
return false;
}
private static readonly SpaceComponentType[] SupportedComponentsArray = new SpaceComponentType[64];
public bool Equals(OVRAnchor other) => Handle.Equals(other.Handle) && Uuid.Equals(other.Uuid);
public override bool Equals(object obj) => obj is OVRAnchor other && Equals(other);
public static bool operator ==(OVRAnchor lhs, OVRAnchor rhs) => lhs.Equals(rhs);
public static bool operator !=(OVRAnchor lhs, OVRAnchor rhs) => !lhs.Equals(rhs);
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + Uuid.GetHashCode());
public override string ToString() => Uuid.ToString();
/// <summary>
/// Disposes of an anchor.
/// </summary>
/// <remarks>
/// Calling this method will destroy the anchor so that it won't be managed by internal systems until
/// the next time it is fetched again.
/// </remarks>
public void Dispose() => OVRPlugin.DestroySpace(Handle);
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5f2967bab93d4b57ab8d2b9799ca6de9
timeCreated: 1669366542

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 49d8ce21824e4f38a4ce11967992e63c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
/*
* 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.
*/
/// <summary>
/// Interface shared by all components from an <see cref="OVRAnchor"/>.
/// </summary>
/// <typeparam name="T">The actual implementation Type of the interface.</typeparam>
/// <seealso cref="OVRAnchor.FetchAnchorsAsync{T}"/>
/// <seealso cref="OVRAnchor.TryGetComponent{T}"/>
/// <seealso cref="OVRAnchor.SupportsComponent{T}"/>
public interface IOVRAnchorComponent<T>
{
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull { get; }
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled { get; }
/// <summary>
/// Sets the enabled status of this component.
/// </summary>
/// <remarks>
/// A component must be enabled to access its data.
/// </remarks>
/// <param name="enabled">The desired state of the component.</param>
/// <param name="timeout">The timeout, in seconds, for the operation. Use zero to indicate an infinite timeout.</param>
/// <returns>Returns an <see cref="OVRTask{T}" /> whose result indicates the result of the operation.</returns>
public OVRTask<bool> SetEnabledAsync(bool enable, double timeout = 0);
internal OVRPlugin.SpaceComponentType Type { get; }
internal ulong Handle { get; }
internal T FromAnchor(OVRAnchor anchor);
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4858e79b20d841adb5e0d5236a35dd1f
timeCreated: 1669391737

View File

@ -0,0 +1,755 @@
/*
* 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 static OVRPlugin;
public readonly partial struct OVRLocatable : IOVRAnchorComponent<OVRLocatable>, IEquatable<OVRLocatable>
{
SpaceComponentType IOVRAnchorComponent<OVRLocatable>.Type => Type;
ulong IOVRAnchorComponent<OVRLocatable>.Handle => Handle;
OVRLocatable IOVRAnchorComponent<OVRLocatable>.FromAnchor(OVRAnchor anchor) => new OVRLocatable(anchor);
/// <summary>
/// A null representation of an OVRLocatable.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRLocatable Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
/// <summary>
/// Sets the enabled status of this component.
/// </summary>
/// <remarks>
/// A component must be enabled to access its data.
/// </remarks>
/// <param name="enabled">The desired state of the component.</param>
/// <param name="timeout">The timeout, in seconds, for the operation. Use zero to indicate an infinite timeout.</param>
/// <returns>Returns an <see cref="OVRTask{T}" /> whose result indicates the result of the operation.</returns>
public OVRTask<bool> SetEnabledAsync(bool enabled, double timeout = 0) => SetSpaceComponentStatus(Handle, Type, enabled, timeout, out var requestId)
? OVRTask.FromRequest<bool>(requestId)
: OVRTask.FromResult(false);
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRLocatable other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRLocatable lhs, OVRLocatable rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRLocatable lhs, OVRLocatable rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRLocatable and <see cref="Equals(OVRLocatable)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRLocatable other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.Locatable";
internal SpaceComponentType Type => SpaceComponentType.Locatable;
internal ulong Handle { get; }
private OVRLocatable(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRStorable : IOVRAnchorComponent<OVRStorable>, IEquatable<OVRStorable>
{
SpaceComponentType IOVRAnchorComponent<OVRStorable>.Type => Type;
ulong IOVRAnchorComponent<OVRStorable>.Handle => Handle;
OVRStorable IOVRAnchorComponent<OVRStorable>.FromAnchor(OVRAnchor anchor) => new OVRStorable(anchor);
/// <summary>
/// A null representation of an OVRStorable.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRStorable Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
/// <summary>
/// Sets the enabled status of this component.
/// </summary>
/// <remarks>
/// A component must be enabled to access its data.
/// </remarks>
/// <param name="enabled">The desired state of the component.</param>
/// <param name="timeout">The timeout, in seconds, for the operation. Use zero to indicate an infinite timeout.</param>
/// <returns>Returns an <see cref="OVRTask{T}" /> whose result indicates the result of the operation.</returns>
public OVRTask<bool> SetEnabledAsync(bool enabled, double timeout = 0) => SetSpaceComponentStatus(Handle, Type, enabled, timeout, out var requestId)
? OVRTask.FromRequest<bool>(requestId)
: OVRTask.FromResult(false);
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRStorable other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRStorable lhs, OVRStorable rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRStorable lhs, OVRStorable rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRStorable and <see cref="Equals(OVRStorable)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRStorable other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.Storable";
internal SpaceComponentType Type => SpaceComponentType.Storable;
internal ulong Handle { get; }
private OVRStorable(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRSharable : IOVRAnchorComponent<OVRSharable>, IEquatable<OVRSharable>
{
SpaceComponentType IOVRAnchorComponent<OVRSharable>.Type => Type;
ulong IOVRAnchorComponent<OVRSharable>.Handle => Handle;
OVRSharable IOVRAnchorComponent<OVRSharable>.FromAnchor(OVRAnchor anchor) => new OVRSharable(anchor);
/// <summary>
/// A null representation of an OVRSharable.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRSharable Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
/// <summary>
/// Sets the enabled status of this component.
/// </summary>
/// <remarks>
/// A component must be enabled to access its data.
/// </remarks>
/// <param name="enabled">The desired state of the component.</param>
/// <param name="timeout">The timeout, in seconds, for the operation. Use zero to indicate an infinite timeout.</param>
/// <returns>Returns an <see cref="OVRTask{T}" /> whose result indicates the result of the operation.</returns>
public OVRTask<bool> SetEnabledAsync(bool enabled, double timeout = 0) => SetSpaceComponentStatus(Handle, Type, enabled, timeout, out var requestId)
? OVRTask.FromRequest<bool>(requestId)
: OVRTask.FromResult(false);
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRSharable other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRSharable lhs, OVRSharable rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRSharable lhs, OVRSharable rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRSharable and <see cref="Equals(OVRSharable)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRSharable other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.Sharable";
internal SpaceComponentType Type => SpaceComponentType.Sharable;
internal ulong Handle { get; }
private OVRSharable(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRBounded2D : IOVRAnchorComponent<OVRBounded2D>, IEquatable<OVRBounded2D>
{
SpaceComponentType IOVRAnchorComponent<OVRBounded2D>.Type => Type;
ulong IOVRAnchorComponent<OVRBounded2D>.Handle => Handle;
OVRBounded2D IOVRAnchorComponent<OVRBounded2D>.FromAnchor(OVRAnchor anchor) => new OVRBounded2D(anchor);
/// <summary>
/// A null representation of an OVRBounded2D.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRBounded2D Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
OVRTask<bool> IOVRAnchorComponent<OVRBounded2D>.SetEnabledAsync(bool enabled, double timeout)
=> throw new NotSupportedException("The Bounded2D component cannot be enabled or disabled.");
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRBounded2D other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRBounded2D lhs, OVRBounded2D rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRBounded2D lhs, OVRBounded2D rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRBounded2D and <see cref="Equals(OVRBounded2D)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRBounded2D other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.Bounded2D";
internal SpaceComponentType Type => SpaceComponentType.Bounded2D;
internal ulong Handle { get; }
private OVRBounded2D(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRBounded3D : IOVRAnchorComponent<OVRBounded3D>, IEquatable<OVRBounded3D>
{
SpaceComponentType IOVRAnchorComponent<OVRBounded3D>.Type => Type;
ulong IOVRAnchorComponent<OVRBounded3D>.Handle => Handle;
OVRBounded3D IOVRAnchorComponent<OVRBounded3D>.FromAnchor(OVRAnchor anchor) => new OVRBounded3D(anchor);
/// <summary>
/// A null representation of an OVRBounded3D.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRBounded3D Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
OVRTask<bool> IOVRAnchorComponent<OVRBounded3D>.SetEnabledAsync(bool enabled, double timeout)
=> throw new NotSupportedException("The Bounded3D component cannot be enabled or disabled.");
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRBounded3D other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRBounded3D lhs, OVRBounded3D rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRBounded3D lhs, OVRBounded3D rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRBounded3D and <see cref="Equals(OVRBounded3D)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRBounded3D other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.Bounded3D";
internal SpaceComponentType Type => SpaceComponentType.Bounded3D;
internal ulong Handle { get; }
private OVRBounded3D(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRSemanticLabels : IOVRAnchorComponent<OVRSemanticLabels>, IEquatable<OVRSemanticLabels>
{
SpaceComponentType IOVRAnchorComponent<OVRSemanticLabels>.Type => Type;
ulong IOVRAnchorComponent<OVRSemanticLabels>.Handle => Handle;
OVRSemanticLabels IOVRAnchorComponent<OVRSemanticLabels>.FromAnchor(OVRAnchor anchor) => new OVRSemanticLabels(anchor);
/// <summary>
/// A null representation of an OVRSemanticLabels.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRSemanticLabels Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
OVRTask<bool> IOVRAnchorComponent<OVRSemanticLabels>.SetEnabledAsync(bool enabled, double timeout)
=> throw new NotSupportedException("The SemanticLabels component cannot be enabled or disabled.");
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRSemanticLabels other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRSemanticLabels lhs, OVRSemanticLabels rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRSemanticLabels lhs, OVRSemanticLabels rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRSemanticLabels and <see cref="Equals(OVRSemanticLabels)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRSemanticLabels other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.SemanticLabels";
internal SpaceComponentType Type => SpaceComponentType.SemanticLabels;
internal ulong Handle { get; }
private OVRSemanticLabels(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRRoomLayout : IOVRAnchorComponent<OVRRoomLayout>, IEquatable<OVRRoomLayout>
{
SpaceComponentType IOVRAnchorComponent<OVRRoomLayout>.Type => Type;
ulong IOVRAnchorComponent<OVRRoomLayout>.Handle => Handle;
OVRRoomLayout IOVRAnchorComponent<OVRRoomLayout>.FromAnchor(OVRAnchor anchor) => new OVRRoomLayout(anchor);
/// <summary>
/// A null representation of an OVRRoomLayout.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRRoomLayout Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
OVRTask<bool> IOVRAnchorComponent<OVRRoomLayout>.SetEnabledAsync(bool enabled, double timeout)
=> throw new NotSupportedException("The RoomLayout component cannot be enabled or disabled.");
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRRoomLayout other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRRoomLayout lhs, OVRRoomLayout rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRRoomLayout lhs, OVRRoomLayout rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRRoomLayout and <see cref="Equals(OVRRoomLayout)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRRoomLayout other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.RoomLayout";
internal SpaceComponentType Type => SpaceComponentType.RoomLayout;
internal ulong Handle { get; }
private OVRRoomLayout(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRAnchorContainer : IOVRAnchorComponent<OVRAnchorContainer>, IEquatable<OVRAnchorContainer>
{
SpaceComponentType IOVRAnchorComponent<OVRAnchorContainer>.Type => Type;
ulong IOVRAnchorComponent<OVRAnchorContainer>.Handle => Handle;
OVRAnchorContainer IOVRAnchorComponent<OVRAnchorContainer>.FromAnchor(OVRAnchor anchor) => new OVRAnchorContainer(anchor);
/// <summary>
/// A null representation of an OVRAnchorContainer.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRAnchorContainer Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
OVRTask<bool> IOVRAnchorComponent<OVRAnchorContainer>.SetEnabledAsync(bool enabled, double timeout)
=> throw new NotSupportedException("The AnchorContainer component cannot be enabled or disabled.");
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRAnchorContainer other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRAnchorContainer lhs, OVRAnchorContainer rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRAnchorContainer lhs, OVRAnchorContainer rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRAnchorContainer and <see cref="Equals(OVRAnchorContainer)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRAnchorContainer other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.AnchorContainer";
internal SpaceComponentType Type => SpaceComponentType.SpaceContainer;
internal ulong Handle { get; }
private OVRAnchorContainer(OVRAnchor anchor) => Handle = anchor.Handle;
}
public readonly partial struct OVRTriangleMesh : IOVRAnchorComponent<OVRTriangleMesh>, IEquatable<OVRTriangleMesh>
{
SpaceComponentType IOVRAnchorComponent<OVRTriangleMesh>.Type => Type;
ulong IOVRAnchorComponent<OVRTriangleMesh>.Handle => Handle;
OVRTriangleMesh IOVRAnchorComponent<OVRTriangleMesh>.FromAnchor(OVRAnchor anchor) => new OVRTriangleMesh(anchor);
/// <summary>
/// A null representation of an OVRTriangleMesh.
/// </summary>
/// <remarks>
/// Use this to compare with another component to determine whether it is null.
/// </remarks>
public static readonly OVRTriangleMesh Null = default;
/// <summary>
/// Whether this object represents a valid anchor component.
/// </summary>
public bool IsNull => Handle == 0;
/// <summary>
/// True if this component is enabled and no change to its enabled status is pending.
/// </summary>
public bool IsEnabled => !IsNull && GetSpaceComponentStatus(Handle, Type, out var enabled, out var pending) && enabled && !pending;
OVRTask<bool> IOVRAnchorComponent<OVRTriangleMesh>.SetEnabledAsync(bool enabled, double timeout)
=> throw new NotSupportedException("The TriangleMesh component cannot be enabled or disabled.");
/// <summary>
/// Compares this component for equality with <paramref name="other" />.
/// </summary>
/// <param name="other">The other component to compare with.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public bool Equals(OVRTriangleMesh other) => Handle == other.Handle;
/// <summary>
/// Compares two components for equality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if both components belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator ==(OVRTriangleMesh lhs, OVRTriangleMesh rhs) => lhs.Equals(rhs);
/// <summary>
/// Compares two components for inequality.
/// </summary>
/// <param name="lhs">The component to compare with <paramref name="rhs" />.</param>
/// <param name="rhs">The component to compare with <paramref name="lhs" />.</param>
/// <returns>True if the components do not belong to the same <see cref="OVRAnchor" />, otherwise false.</returns>
public static bool operator !=(OVRTriangleMesh lhs, OVRTriangleMesh rhs) => !lhs.Equals(rhs);
/// <summary>
/// Compares this component for equality with <paramref name="obj" />.
/// </summary>
/// <param name="obj">The `object` to compare with.</param>
/// <returns>True if <paramref name="obj" /> is an OVRTriangleMesh and <see cref="Equals(OVRTriangleMesh)" /> is true, otherwise false.</returns>
public override bool Equals(object obj) => obj is OVRTriangleMesh other && Equals(other);
/// <summary>
/// Gets a hashcode suitable for use in a Dictionary or HashSet.
/// </summary>
/// <returns>A hashcode for this component.</returns>
public override int GetHashCode() => unchecked(Handle.GetHashCode() * 486187739 + ((int)Type).GetHashCode());
/// <summary>
/// Gets a string representation of this component.
/// </summary>
/// <returns>A string representation of this component.</returns>
public override string ToString() => $"{Handle}.TriangleMesh";
internal SpaceComponentType Type => SpaceComponentType.TriangleMesh;
internal ulong Handle { get; }
private OVRTriangleMesh(OVRAnchor anchor) => Handle = anchor.Handle;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3d7c9331dd825041bbd89858f165463
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,55 @@
/*
* 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 System.Collections.Generic;
/// <summary>
/// Represents a container for other <see cref="OVRAnchor"/>s.
/// </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.s
/// </remarks>
/// <seealso cref="Uuids"/>
/// <seealso cref="FetchChildrenAsync"/>
public readonly partial struct OVRAnchorContainer : IOVRAnchorComponent<OVRAnchorContainer>,
IEquatable<OVRAnchorContainer>
{
/// <summary>
/// Uuids of the anchors contained by this Anchor Container.
/// </summary>
/// <seealso cref="OVRAnchor.FetchAnchorsAsync"/>
/// <exception cref="InvalidOperationException">If it fails to retrieve the Uuids, which could happen if the component is not supported or enabled.</exception>
public Guid[] Uuids => OVRPlugin.GetSpaceContainer(Handle, out var containerUuids)
? containerUuids
: throw new InvalidOperationException("Could not get Uuids");
/// <summary>
/// Asynchronous method that fetches anchors contained by this Anchor Container.
/// </summary>
/// <param name="anchors">IList that will get cleared and populated with the requested anchors.</param>
/// <remarks>Dispose of the returned <see cref="OVRTask{bool}"/> if you don't use the results</remarks>
/// <returns>An <see cref="OVRTask{bool}"/> that will eventually let you test if the fetch was successful or not.
/// If the result is true, then the <see cref="anchors"/> parameter has been populated with the requested anchors.</returns>
/// <exception cref="InvalidOperationException">If it fails to retrieve the Uuids</exception>
/// <exception cref="ArgumentNullException">If parameter anchors is null</exception>
public OVRTask<bool> FetchChildrenAsync(List<OVRAnchor> anchors) => OVRAnchor.FetchAnchorsAsync(Uuids, anchors);
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 808c13beb83f4e819eb369c205ccd05c
timeCreated: 1669392046

View File

@ -0,0 +1,104 @@
/*
* 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 Unity.Collections;
using UnityEngine;
/// <summary>
/// Represents a plane described by its <see cref="Rect"/> and boundary points.
/// </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.
/// </remarks>
/// <seealso cref="BoundingBox"/>
/// <seealso cref="TryGetBoundaryPointsCount"/>
/// <seealso cref="TryGetBoundaryPoints"/>
public readonly partial struct OVRBounded2D : IOVRAnchorComponent<OVRBounded2D>, IEquatable<OVRBounded2D>
{
/// <summary>
/// Bounding Box
/// </summary>
/// <returns>
/// <see cref="Rect"/> representing the 2D Bounding Box of the Anchor this component is attached to.
/// </returns>
/// <exception cref="InvalidOperationException">If it fails to retrieve the Bounding Box.</exception>
public Rect BoundingBox => OVRPlugin.GetSpaceBoundingBox2D(Handle, out var rectf)
? ConvertRect(rectf)
: throw new InvalidOperationException("Could not get BoundingBox");
private Rect ConvertRect(OVRPlugin.Rectf openXrRect)
{
// OpenXR Rects describe a rectangle by its position (or offset) and its size (or extents)
// https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrRect2Df.html
// Unity Rects describe a rectangle by its position and its size (or extents)
// https://docs.unity3d.com/ScriptReference/Rect.html
var extents = openXrRect.Size.FromSizef();
// OpenXR uses a right-handed coordinate system
// Unity uses left-handed coordinate system
// There is a design assumption that plane's normal should coincide with +z
// We therefore need to rotate the plane 180° around +y axis
// We therefore need to flip the x axis.
var offset = openXrRect.Pos.FromFlippedXVector2f();
// When flipping one axis, position doesn't point to a min corner any more
offset.x -= extents.x;
return new Rect(offset, extents);
}
/// <summary>
/// Retrieves the number of boundary points contained in an Anchor with an enabled Bounded2D component.
/// </summary>
/// <param name="count">The number of boundary points contained in the Bounded2D component of the Anchor, as an <c>out</c> parameter.</param>
/// <returns><c>true</c> if it successfully retrieves the count, <c>false</c> otherwise.</returns>
/// <remarks>This is the first part of the two-calls idiom for retrieving boundary points. <see cref="TryGetBoundaryPoints"/> to actually get those points.</remarks>
/// <seealso cref="TryGetBoundaryPoints"/>
public bool TryGetBoundaryPointsCount(out int count) =>
OVRPlugin.GetSpaceBoundary2DCount(Handle, out count);
/// <summary>
/// Retrieves the boundary points contained in an Anchor with an enabled Bounded2D component.
/// </summary>
/// <param name="positions">The array that will get populated with the boundary points contained in the Bounded2D component of the Anchor.</param>
/// <returns><c>true</c> if it successfully populates the <paramref name="positions"/> array with the boundary points.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="positions"/> has not been created.</exception>
/// <remarks>This is the second part of the two-calls idiom for retrieving boundary points.
/// It is expected for the <paramref name="positions"/> to be created and with enough capacity to contain the boundary points.</remarks>
/// <seealso cref="TryGetBoundaryPointsCount"/>
public bool TryGetBoundaryPoints(NativeArray<Vector2> positions)
{
if (!positions.IsCreated) throw new ArgumentException("NativeArray is not created", nameof(positions));
if (!OVRPlugin.GetSpaceBoundary2D(Handle, positions, out var count)) return false;
var low = 0;
var high = count - 1;
for (; low <= high; low++, high--)
{
var swapTemporaryPositionHigh = positions[high];
var swapTemporaryPositionLow = positions[low];
positions[low] = new Vector2(-swapTemporaryPositionHigh.x, swapTemporaryPositionHigh.y);
positions[high] = new Vector2(-swapTemporaryPositionLow.x, swapTemporaryPositionLow.y);
}
return true;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 955209a5d89b4116b1fe76931b971c18
timeCreated: 1669713526

View File

@ -0,0 +1,68 @@
/*
* 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 a volume described by its <see cref="Bounds"/>.
/// </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.
/// </remarks>
/// <seealso cref="BoundingBox"/>
public readonly partial struct OVRBounded3D : IOVRAnchorComponent<OVRBounded3D>, IEquatable<OVRBounded3D>
{
/// <summary>
/// Bounding Box
/// </summary>
/// <returns>
/// <see cref="Bounds"/> representing the 3D Bounding Box of the Anchor this component is attached to.
/// </returns>
/// <exception cref="InvalidOperationException">If it fails to retrieve the Bounding Box.</exception>
public Bounds BoundingBox => OVRPlugin.GetSpaceBoundingBox3D(Handle, out var boundsf)
? ConvertBounds(boundsf)
: throw new InvalidOperationException("Could not get BoundingBox");
private Bounds ConvertBounds(OVRPlugin.Boundsf openXrBounds)
{
// OpenXR Bounds describe a volume by its position (or offset) and its size (or extents)
// https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrRect3DfFB.html
// Unity Bounds describe a volume by its center and its size (or extents)
// https://docs.unity3d.com/ScriptReference/Bounds.html
var extents = openXrBounds.Size.FromSize3f();
// OpenXR uses a right-handed coordinate system
// Unity uses left-handed coordinate system
// We therefore need to flip the z axis to convert from OpenXR to Unity
// And then, because of the z-axis positive normal, rotate 180 around +y
// This ends up being equivalent to flipping x axis
var offset = openXrBounds.Pos.FromFlippedXVector3f();
// When flipping one axis, position doesn't point to a min corner any more
offset.x -= extents.x;
// And add half of the extents to find the center
var halfExtents = extents * 0.5f;
var center = offset + halfExtents;
// Bounds constructor takes the center and the full size (not half extents)
return new Bounds(center, extents);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4e084c5263424e6aaa12b7c6536407ad
timeCreated: 1669714557

View File

@ -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;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2896867f1aef412690defa16271f3dcc
timeCreated: 1669392029

View File

@ -0,0 +1,84 @@
/*
* 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 System.Collections.Generic;
/// <summary>
/// Represents a room described by its floor, ceiling and walls <see cref="OVRAnchor"/>s.
/// </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.
/// </remarks>
/// <seealso cref="FetchLayoutAnchorsAsync"/>
/// <seealso cref="TryGetRoomLayout"/>
public readonly partial struct OVRRoomLayout : IOVRAnchorComponent<OVRRoomLayout>, IEquatable<OVRRoomLayout>
{
/// <summary>
/// Asynchronous method that fetches anchors contained in the Room Layout.
/// </summary>
/// <param name="anchors">List that will get cleared and populated with the requested anchors.</param>
/// <remarks>Dispose of the returned task if you don't use the results</remarks>
/// <returns>A task that will eventually let you test if the fetch was successful or not.
/// If the result is true, then the <see cref="anchors"/> parameter has been populated with the requested anchors.</returns>
/// <exception cref="InvalidOperationException">If it fails to retrieve the Room Layout</exception>
/// <exception cref="ArgumentNullException">If parameter anchors is null</exception>
public OVRTask<bool> FetchLayoutAnchorsAsync(List<OVRAnchor> anchors)
{
if (!OVRPlugin.GetSpaceRoomLayout(Handle, out var roomLayout))
{
throw new InvalidOperationException("Could not get Room Layout");
}
using (new OVRObjectPool.ListScope<Guid>(out var list))
{
list.Add(roomLayout.floorUuid);
list.Add(roomLayout.ceilingUuid);
list.AddRange(roomLayout.wallUuids);
return OVRAnchor.FetchAnchorsAsync(list, anchors);
}
}
/// <summary>
/// Tries to get the Ceiling, Floor and Walls unique identifiers. These can then be used to Fetch their anchors.
/// </summary>
/// <param name="ceiling">Out <see cref="Guid"/> representing the ceiling of the room.</param>
/// <param name="floor">Out <see cref="Guid"/> representing the floor of the room.</param>
/// <param name="walls">Out array of <see cref="Guid"/>s representing the walls of the room.</param>
/// <returns>
/// <see cref="bool"/> true if the request succeeds and false if it fails.
/// </returns>
public bool TryGetRoomLayout(out Guid ceiling, out Guid floor, out Guid[] walls)
{
ceiling = Guid.Empty;
floor = Guid.Empty;
walls = null;
if (!OVRPlugin.GetSpaceRoomLayout(Handle, out var roomLayout))
{
return false;
}
ceiling = roomLayout.ceilingUuid;
floor = roomLayout.floorUuid;
walls = roomLayout.wallUuids;
return true;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d22c4dde2fa64be99f6c39b1c57ff87b
timeCreated: 1669715079

View File

@ -0,0 +1,53 @@
/*
* 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;
/// <summary>
/// Descriptive labels of the <see cref="OVRAnchor"/>, as comma separated strings.
/// </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.
/// </remarks>
/// <seealso cref="Labels"/>
public readonly partial struct OVRSemanticLabels : IOVRAnchorComponent<OVRSemanticLabels>, IEquatable<OVRSemanticLabels>
{
// Features
/// <summary>
/// Semantic Labels
/// </summary>
/// <returns>
/// <para>Comma-separated values in one <see cref="string"/></para>
/// </returns>
/// <exception cref="Exception">If it fails to get the semantic labels</exception>
public string Labels
{
get
{
if (!OVRPlugin.GetSpaceSemanticLabels(Handle, out var labels))
{
throw new Exception("Could not Get Semantic Labels");
}
return OVRSemanticClassification.ValidateAndUpgradeLabels(labels);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: efe24f81961b460eb43781a3f72460ed
timeCreated: 1669712605

View File

@ -0,0 +1,222 @@
/*
* 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 Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using UnityEngine;
using static OVRPlugin;
/// <summary>
/// Represents the Triangle Mesh component of an <see cref="OVRAnchor"/>.
/// </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.
/// </remarks>
/// <seealso cref="TryGetCounts"/>
/// <seealso cref="TryGetMeshRawUntransformed"/>
/// <seealso cref="TryGetMesh"/>
public readonly partial struct OVRTriangleMesh
{
/// <summary>
/// Gets the number of vertices and triangles in the mesh.
/// </summary>
/// <remarks>
/// Use this method to get the required sizes of the vertex and triangle index buffers. The length of the `indices`
/// array passed to <see cref="TryGetMesh"/> and <seealso cref="TryGetMeshRawUntransformed"/> should be three times
/// <paramref name="triangleCount"/>.
///
/// This method is thread-safe.
/// </remarks>
/// <param name="vertexCount">The number of vertices in the mesh.</param>
/// <param name="triangleCount">The number of triangles in the mesh. There are three times as many indices.</param>
/// <returns>True if the counts were retrieved; otherwise, false.</returns>
public bool TryGetCounts(out int vertexCount, out int triangleCount)
=> GetSpaceTriangleMeshCounts(Handle, out vertexCount, out triangleCount);
/// <summary>
/// Gets the raw, untransformed triangle mesh.
/// </summary>
/// <remarks>
/// ## Thread safety
/// This method is thread-safe.
///
/// ## Memory ownership
/// The caller owns the memory of the input arrays and is responsible for allocating them to the appropriate size
/// before passing them to this method. Use <see cref="TryGetCounts"/> to determine the required size of each array.
/// Note that <paramref name="indices"/> should be three times the number of triangles (`triangleCount`) indicated
/// by <see cref="TryGetCounts"/>.
///
/// ## Coordinate space
/// The mesh data provided by this method must be transformed into the appropriate coordinate space before being
/// used with a `UnityEngine.Mesh`. Use <see cref="TryGetMesh"/> or <see cref="ScheduleGetMeshJob"/> to get mesh
/// data in the correct coordinate space. This method is typically for advanced use cases where you want to perform
/// the conversion at a later time, or combine it with your own jobs.
///
/// The <paramref name="positions"/> are provided in the right-handed coordinate
/// space defined by OpenXR, with X to the right, Y up, and Z backward. <paramref name="indices"/> is an array of
/// index triplets which define the triangles in counter-clockwise order.
///
/// To convert to the coordinate space used by a Scene anchor in Unity's coordinate system, you must
/// - Negate each vertex's X coordinate
/// - Reverse the triangle winding by swapping each index triplet (a, b, c) => (a, c, b)
/// </remarks>
/// <param name="positions">The vertex positions of the mesh.</param>
/// <param name="indices">The triangle indices of the mesh.</param>
/// <returns>True if the mesh data was retrieved; otherwise, false.</returns>
public bool TryGetMeshRawUntransformed(NativeArray<Vector3> positions, NativeArray<int> indices)
=> GetSpaceTriangleMesh(Handle, positions, indices);
/// <summary>
/// Gets the triangle mesh.
/// </summary>
/// <remarks>
/// The caller owns the memory of the input arrays and is responsible for allocating them to the appropriate size
/// before passing them to this method. Use <see cref="TryGetCounts"/> to determine the required size of each array.
/// Note that <paramref name="indices"/> should be three times the number of triangles (`triangleCount`) indicated
/// by <see cref="TryGetCounts"/>.
///
/// This method is thread-safe.
/// </remarks>
/// <param name="positions">The vertex positions of the mesh.</param>
/// <param name="indices">The triangle indices of the mesh.</param>
/// <returns>True if the mesh data was retrieved; otherwise, false.</returns>
public bool TryGetMesh(NativeArray<Vector3> positions, NativeArray<int> indices)
{
if (!TryGetMeshRawUntransformed(positions, indices)) return false;
for (var i = 0; i < positions.Length; i++)
{
var p = positions[i];
// Necessary due to the coordinate space difference between OpenXR (right-handed) and Unity (left-handed)
positions[i] = new Vector3(-p.x, p.y, p.z);
}
var triangles = indices.Reinterpret<Triangle>(
expectedTypeSize: sizeof(int));
for (var i = 0; i < triangles.Length; i++)
{
var triangle = triangles[i];
triangles[i] = new Triangle
{
A = triangle.A,
B = triangle.C,
C = triangle.B
};
}
return true;
}
/// <summary>
/// Schedules a job to get an anchor's triangle mesh.
/// </summary>
/// <remarks>
/// This schedules jobs with the Unity Job system to retrieve the mesh data and then perform the necessary
/// conversion to Unity's coordinate space (see <see cref="TryGetMeshRawUntransformed"/>).
///
/// The caller owns the memory of the input arrays and is responsible for allocating them to the appropriate size
/// before passing them to this method. Use <see cref="TryGetCounts"/> to determine the required size of each array.
/// Note that <paramref name="indices"/> should be three times the number of triangles (`triangleCount`) indicated
/// by <see cref="TryGetCounts"/>.
///
/// If the triangle mesh cannot be retrieved, all <paramref name="indices"/> will be set to zero. Use this to check
/// for success after the job completes. For example, if the first three indices are zero, then the mesh is not
/// valid.
/// </remarks>
/// <param name="positions">The vertex positions of the triangle mesh.</param>
/// <param name="indices">The triangle indices of the triangle mesh.</param>
/// <param name="dependencies">(Optional) A job on which the new jobs will depend.</param>
/// <returns>Returns the handle associated with the new job.</returns>
public JobHandle ScheduleGetMeshJob(NativeArray<Vector3> positions, NativeArray<int> indices,
JobHandle dependencies = default)
{
var getMeshJob = new GetMeshJob
{
Positions = positions,
Indices = indices,
Space = Handle
}.Schedule(dependencies);
var triangles =
indices.Reinterpret<Triangle>(expectedTypeSize: sizeof(int));
return JobHandle.CombineDependencies(
new NegateXJob
{
Positions = positions
}.Schedule(positions.Length, 32, getMeshJob),
new FlipTriangleWindingJob
{
Triangles = triangles
}.Schedule(triangles.Length, 32, getMeshJob));
}
private struct GetMeshJob : IJob
{
public ulong Space;
public NativeArray<Vector3> Positions;
public NativeArray<int> Indices;
public unsafe void Execute()
{
if (!GetSpaceTriangleMesh(Space, Positions, Indices))
{
UnsafeUtility.MemSet(Indices.GetUnsafePtr(), 0, Indices.Length * sizeof(int));
}
}
}
private struct Triangle
{
public int A, B, C;
}
private struct FlipTriangleWindingJob : IJobParallelFor
{
public NativeArray<Triangle> Triangles;
public void Execute(int index)
{
var triangle = Triangles[index];
Triangles[index] = new Triangle
{
A = triangle.A,
B = triangle.C,
C = triangle.B
};
}
}
// Necessary due to the coordinate space difference between OpenXR (right-handed) and Unity (left-handed)
private struct NegateXJob : IJobParallelFor
{
public NativeArray<Vector3> Positions;
public void Execute(int index)
{
var p = Positions[index];
Positions[index] = new Vector3(-p.x, p.y, p.z);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0e2d445935c74f9484188ad82fbfd067
timeCreated: 1674000939