Initialer Upload neues Unity-Projekt
This commit is contained in:
349
Assets/Oculus/VR/Scripts/OVRAnchor/OVRAnchor.cs
Normal file
349
Assets/Oculus/VR/Scripts/OVRAnchor/OVRAnchor.cs
Normal 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);
|
||||
}
|
||||
3
Assets/Oculus/VR/Scripts/OVRAnchor/OVRAnchor.cs.meta
Normal file
3
Assets/Oculus/VR/Scripts/OVRAnchor/OVRAnchor.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f2967bab93d4b57ab8d2b9799ca6de9
|
||||
timeCreated: 1669366542
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49d8ce21824e4f38a4ce11967992e63c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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);
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4858e79b20d841adb5e0d5236a35dd1f
|
||||
timeCreated: 1669391737
|
||||
@ -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;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3d7c9331dd825041bbd89858f165463
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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);
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 808c13beb83f4e819eb369c205ccd05c
|
||||
timeCreated: 1669392046
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 955209a5d89b4116b1fe76931b971c18
|
||||
timeCreated: 1669713526
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e084c5263424e6aaa12b7c6536407ad
|
||||
timeCreated: 1669714557
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2896867f1aef412690defa16271f3dcc
|
||||
timeCreated: 1669392029
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d22c4dde2fa64be99f6c39b1c57ff87b
|
||||
timeCreated: 1669715079
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efe24f81961b460eb43781a3f72460ed
|
||||
timeCreated: 1669712605
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e2d445935c74f9484188ad82fbfd067
|
||||
timeCreated: 1674000939
|
||||
Reference in New Issue
Block a user