using System;
using System.Runtime.InteropServices;
using System.Text;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace UnityEngine.XR.ARCore
{
///
/// Represents the context for an ARCore session.
///
///
/// This is an opaque object that represents a native
/// [ArSession](https://developers.google.com/ar/reference/c/group/ar-session).
///
///
///
///
///
public struct ArSession : IEquatable
{
IntPtr m_Self;
ArSession(IntPtr value) => m_Self = value;
///
/// Creates an from an existing native pointer. The native pointer must point
/// to an existing .
///
/// A pointer to an existing native .
/// Returns an whose underlying native pointer is
/// .
public static ArSession FromIntPtr(IntPtr value) => new ArSession(value);
///
/// Represents a null , i.e., one whose underlying native pointer is `null`.
/// This property is obsolete. Use instead.
///
[Obsolete("Use default instead.")]
public static ArSession Null => default;
///
/// (Read Only) Indicates whether this is `null`.
/// This property is deprecated. Use the equality operator (`==`) to compare with `null` instead.
///
[Obsolete("Compare to null instead.")]
public bool IsNull => m_Self == IntPtr.Zero;
///
/// Gets the underlying native pointer for this .
///
/// Returns the underlying native pointer for this .
public IntPtr AsIntPtr() => m_Self;
///
/// Casts an to its underlying native pointer.
///
/// The to cast.
/// Returns the underlying native pointer for
public static explicit operator IntPtr(ArSession session) => session.AsIntPtr();
///
/// Tests for equality.
///
///
/// Two s are considered equal if their underlying pointers are equal.
///
/// The to compare against.
/// Returns `true` if the underlying native pointers are the same. Returns `false` otherwise.
public bool Equals(ArSession other) => m_Self == other.m_Self;
///
/// Tests for equality.
///
/// An to compare against.
/// Returns `true` if is an and it compares
/// equal to this one using .
public override bool Equals(object obj) => obj is ArSession other && Equals(other);
///
/// Generates a hash code suitable for use with a `HashSet` or `Dictionary`
///
/// Returns a hash code for this .
public override int GetHashCode() => m_Self.GetHashCode();
///
/// Tests for equality. Same as .
///
/// The to compare with .
/// The to compare with .
/// Returns `true` if is equal to using
/// . Returns `false` otherwise.
public static bool operator ==(ArSession lhs, ArSession rhs) => lhs.Equals(rhs);
///
/// Tests for inequality. Same as the negation of .
///
/// The to compare with .
/// The to compare with .
/// Returns `false` if is equal to using
/// . Returns `true` otherwise.
public static bool operator !=(ArSession lhs, ArSession rhs) => !lhs.Equals(rhs);
///
/// Tests for equality.
///
///
/// This equality operator lets you to compare an with `null` to determine whether its
/// underlying pointer is null. This allows for a more natural comparison with the native ARCore object:
///
///
/// bool TestForNull(ArSession obj)
/// {
/// if (obj == null)
/// {
/// // obj.AsIntPtr() is IntPtr.Zero
/// }
/// }
///
///
///
/// The nullable to compare with .
/// The nullable to compare with .
/// Returns true if any of these conditions are met:
/// - and are both not null and their underlying pointers are equal.
/// - is null and 's underlying pointer is null.
/// - is null and 's underlying pointer is null.
/// - Both and are null.
///
/// Returns false otherwise.
///
public static bool operator ==(ArSession? lhs, ArSession? rhs) => NativeObject.ArePointersEqual(lhs?.m_Self, rhs?.m_Self);
///
/// Tests for inequality.
///
///
/// This inequality operator lets you to compare an with `null` to determine whether its
/// underlying pointer is null. This allows for a more natural comparison with the native ARCore object:
///
///
/// bool TestForNull(ArSession obj)
/// {
/// if (obj != null)
/// {
/// // obj.AsIntPtr() is not IntPtr.Zero
/// }
/// }
///
///
///
/// The native object to compare with .
/// The native object to compare with .
/// Returns false if any of these conditions are met:
/// - and are both not null and their underlying pointers are equal.
/// - is null and 's underlying pointer is null.
/// - is null and 's underlying pointer is null.
/// - Both and are null.
///
/// Returns true otherwise.
///
public static bool operator !=(ArSession? lhs, ArSession? rhs) => !(lhs == rhs);
///
/// Sets an MP4 dataset file to playback instead of live camera feed.
///
///
/// Restrictions:
/// - Can only be called while the session is paused. Playback of the MP4
/// dataset file starts once the session is resumed.
/// - The MP4 dataset file must use the same camera facing direction as is
/// configured in the session.
///
/// When an MP4 dataset file is set:
/// - All existing trackables (i.e., anchors and trackables) immediately enter tracking state [TrackingState.None](xref:UnityEngine.XR.ARSubsystems.TrackingState.None).
/// - The desired focus mode is ignored, and does not affect the previously recorded camera images.
/// - The current camera configuration is immediately set to the default for the device the MP4 dataset file was recorded on.
/// - Calls to retrieve the supported camera configurations return camera configs supported by the device the MP4 dataset file was recorded on.
/// - Setting a previously obtained camera config has no effect.
///
/// A file path to a MP4 dataset file or `null` to use the live camera feed.
///
/// - Returns if successful.
/// - Returns if called when session is not paused.
/// - Returns if playback is incompatible with selected features.
/// - Returns if an error occurred with the MP4 dataset file such as not being able to open the file or the file is unable to be decoded.
///
public ArStatus SetPlaybackDataset(string path)
{
unsafe
{
if (string.IsNullOrEmpty(path))
{
return SetPlaybackDataset(this, null);
}
using (var bytes = path.ToBytes(Encoding.UTF8, Allocator.Temp))
{
return SetPlaybackDataset(this, (byte*)bytes.GetUnsafePtr());
}
}
}
[DllImport("arcore_sdk_c", EntryPoint = "ArSession_setPlaybackDataset")]
static extern unsafe ArStatus SetPlaybackDataset(ArSession session, byte* mp4DatasetFilePath);
///
/// (Read Only) The playback status.
///
/// Whether or not the session is playing back a recording (or has stopped because of an error).
public ArPlaybackStatus playbackStatus
{
get
{
GetPlaybackStatus(this, out var value);
return value;
}
}
[DllImport("arcore_sdk_c", EntryPoint = "ArSession_getPlaybackStatus")]
static extern void GetPlaybackStatus(ArSession session, out ArPlaybackStatus outPlaybackStatus);
///
/// Starts a new MP4 dataset file recording that is written to the specific filesystem path.
///
///
/// Existing files are overwritten.
///
/// The MP4 video stream (VGA) bitrate is 5Mbps (40Mb per minute).
///
/// Recording introduces additional overhead and may affect app performance.
///
/// The configuration defined for recording.
/// Returns if successful. Returns one of the following values otherwise:
/// -
/// -
/// -
///
public ArStatus StartRecording(ArRecordingConfig recordingConfig) => StartRecording(this, recordingConfig);
[DllImport("arcore_sdk_c", EntryPoint = "ArSession_startRecording")]
static extern ArStatus StartRecording(ArSession session, ArRecordingConfig recordingConfig);
///
/// Stops recording and flushes unwritten data to disk. The MP4 dataset file is ready to read after this
/// call.
///
///
/// Recording can be stopped automatically when the session is paused,
/// if auto stop is enabled via .
/// Recording errors that would be thrown in are silently
/// ignored on session pause.
///
/// Returns if successful. Returns
/// otherwise.
public ArStatus StopRecording() => StopRecording(this);
[DllImport("arcore_sdk_c", EntryPoint = "ArSession_stopRecording")]
static extern ArStatus StopRecording(ArSession session);
///
/// (Read Only) The current recording status.
///
/// Whether or not the session is recording (or has stopped because of an error).
public ArRecordingStatus recordingStatus
{
get
{
GetRecordingStatus(this, out var value);
return value;
}
}
[DllImport("arcore_sdk_c", EntryPoint = "ArSession_getRecordingStatus")]
static extern void GetRecordingStatus(ArSession session, out ArRecordingStatus outRecordingStatus);
}
}