using System; using System.Collections.Generic; using Unity.Collections; using UnityEngine.SubsystemsImplementation; namespace UnityEngine.XR.ARSubsystems { /// /// Defines an interface for interacting with occlusion functionality. /// public class XROcclusionSubsystem : SubsystemWithProvider { /// /// Specifies the human segmentation stencil mode. /// /// The human segmentation stencil mode. /// Thrown when setting the human segmentation stencil mode to /// `enabled` if the implementation does not support human segmentation. public HumanSegmentationStencilMode requestedHumanStencilMode { get => provider.requestedHumanStencilMode; set => provider.requestedHumanStencilMode = value; } /// /// Get the current segmentation stencil mode in use by the subsystem. /// public HumanSegmentationStencilMode currentHumanStencilMode => provider.currentHumanStencilMode; /// /// Specifies the human segmentation depth mode. /// /// The human segmentation depth mode. /// Thrown when setting the human segmentation depth mode to /// `enabled` if the implementation does not support human segmentation. public HumanSegmentationDepthMode requestedHumanDepthMode { get => provider.requestedHumanDepthMode; set => provider.requestedHumanDepthMode = value; } /// /// Get the human segmentation depth mode currently in use by the provider. /// public HumanSegmentationDepthMode currentHumanDepthMode => provider.currentHumanDepthMode; /// /// Specifies the environment depth mode. /// /// The environment depth mode. public EnvironmentDepthMode requestedEnvironmentDepthMode { get => provider.requestedEnvironmentDepthMode; set => provider.requestedEnvironmentDepthMode = value; } /// /// Get the environment depth mode currently in use by the provider. /// public EnvironmentDepthMode currentEnvironmentDepthMode => provider.currentEnvironmentDepthMode; /// /// Get or set whether temporal smoothing should be applied to the environment depth image. Query for support with /// . /// /// if temporal smoothing is requested for the environment depth image. /// Otherwise, . public bool environmentDepthTemporalSmoothingRequested { get => provider.environmentDepthTemporalSmoothingRequested; set => provider.environmentDepthTemporalSmoothingRequested = value; } /// /// Get whether temporal smoothing is applied to the environment depth image. Query for support with /// . /// /// if temporal smoothing is enabled for the environment depth image. /// Otherwise, . public bool environmentDepthTemporalSmoothingEnabled => provider.environmentDepthTemporalSmoothingEnabled; /// /// Specifies the requested occlusion preference mode. /// /// The requested occlusion preference mode. public OcclusionPreferenceMode requestedOcclusionPreferenceMode { get => provider.requestedOcclusionPreferenceMode; set => provider.requestedOcclusionPreferenceMode = value; } /// /// Get the occlusion preference mode currently in use by the provider. /// /// The current occlusion preference mode. public OcclusionPreferenceMode currentOcclusionPreferenceMode => provider.currentOcclusionPreferenceMode; /// /// Construct the subsystem by creating the functionality provider. /// public XROcclusionSubsystem() { } /// /// Get all the texture descriptors in the provider's swapchain, if possible. /// Must return if the provider does not use a fixed-length swapchain. /// /// All texture descriptors in the provider's swapchain, /// if this method returns . Each texture descriptor represents a possible value used by /// call to on a later frame. Allocator is `Allocator.Temp`. /// /// Texture descriptors are grouped per frame. All texture descriptors that are used within one frame must /// be grouped together in the same inner array. /// /// if the provider uses a fixed-length swapchain and all texture /// descriptors were successfully output. Otherwise, . /// /// This method is used by the [AR Occlusion Manager component](xref:arfoundation-occlusion-manager) during /// `OnBeforeStart` to determine whether the provider uses a fixed-length swapchain of fixed-size textures. /// If so, `AROcclusionManager` is able to create Unity `Texture` objects for the entire swapchain at once and /// re-use them throughout the life cycle of your app. /// /// public bool TryGetSwapchainTextureDescriptors( out NativeArray> swapchainDescriptors) => provider.TryGetAllTextureDescriptorsInSwapchain(out swapchainDescriptors); /// /// Gets the human stencil texture descriptor. /// /// The human stencil texture descriptor to be populated, if available /// from the provider. /// if the human stencil texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support human stencil /// texture. public bool TryGetHumanStencil(out XRTextureDescriptor humanStencilDescriptor) => provider.TryGetHumanStencil(out humanStencilDescriptor); /// /// Tries to acquire the latest human stencil CPU image. /// /// An acquired `XRCpuImage`, if this method returns . The CPU image /// must be disposed by the caller. /// if an image was successfully acquired. Otherwise, . public bool TryAcquireHumanStencilCpuImage(out XRCpuImage cpuImage) { if (provider.humanStencilCpuImageApi != null && provider.TryAcquireHumanStencilCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.humanStencilCpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Gets the human depth texture descriptor. /// /// The human depth texture descriptor to be populated, if available from /// the provider. /// if the human depth texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support human depth /// texture. public bool TryGetHumanDepth(out XRTextureDescriptor humanDepthDescriptor) => provider.TryGetHumanDepth(out humanDepthDescriptor); /// /// Tries to acquire the latest human depth CPU image. /// /// An acquired `XRCpuImage`, if this method returns . The CPU image /// must be disposed by the caller. /// if an image was successfully acquired. Otherwise, . public bool TryAcquireHumanDepthCpuImage(out XRCpuImage cpuImage) { if (provider.humanDepthCpuImageApi != null && provider.TryAcquireHumanDepthCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.humanDepthCpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Gets the environment depth texture descriptor. /// /// /// Whether the depth image is smoothed or raw depends on the value of . /// /// The environment depth texture descriptor to be populated, if /// available from the provider. /// if the environment depth texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support environment depth /// texture. public bool TryGetEnvironmentDepth(out XRTextureDescriptor environmentDepthDescriptor) => provider.TryGetEnvironmentDepth(out environmentDepthDescriptor); /// /// Tries to acquire the latest environment depth CPU image. /// /// /// Whether the depth image is smoothed or raw depends on the value of . /// /// An acquired `XRCpuImage`, if this method returns . The CPU image /// must be disposed by the caller. /// if an image was successfully acquired. Otherwise, . /// /// public bool TryAcquireEnvironmentDepthCpuImage(out XRCpuImage cpuImage) { if (provider.environmentDepthCpuImageApi != null && provider.TryAcquireEnvironmentDepthCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.environmentDepthCpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Tries to acquire the latest raw environment depth CPU image. /// /// /// This method differs from in that it always tries to /// acquire the raw depth image, whereas the image provided by /// depends on the value of . /// /// An acquired `XRCpuImage`, if this method returns . The CPU image /// must be disposed by the caller. /// if the raw environment depth CPU image was acquired. /// Otherwise, . public bool TryAcquireRawEnvironmentDepthCpuImage(out XRCpuImage cpuImage) { if (provider.TryAcquireRawEnvironmentDepthCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.environmentDepthCpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Tries to acquire the latest smoothed environment depth CPU image. /// /// /// This method differs from in that it always tries to /// acquire the temporally smoothed depth image, whereas the image provided by /// depends on the value of /// . /// /// The type of smoothing applied is implementation dependent; refer to the documentation for the specific /// provider in use. /// /// An acquired `XRCpuImage`, if this method returns . The CPU image /// must be disposed by the caller. /// if the smoothed environment depth CPU image was acquired. /// Otherwise, . public bool TryAcquireSmoothedEnvironmentDepthCpuImage(out XRCpuImage cpuImage) { if (provider.TryAcquireSmoothedEnvironmentDepthCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.environmentDepthCpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Gets the environment depth confidence texture descriptor. /// /// The environment depth confidence texture descriptor to /// be populated, if available from the provider. /// if the environment depth confidence texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support environment depth /// confidence texture. public bool TryGetEnvironmentDepthConfidence(out XRTextureDescriptor environmentDepthConfidenceDescriptor) => provider.TryGetEnvironmentDepthConfidence(out environmentDepthConfidenceDescriptor); /// /// Tries to acquire the latest environment depth confidence CPU image. /// /// An acquired `XRCpuImage`, if this method returns . The CPU image /// must be disposed by the caller. /// if the image was successfully acquired. Otherwise, . public bool TryAcquireEnvironmentDepthConfidenceCpuImage(out XRCpuImage cpuImage) { if (provider.environmentDepthConfidenceCpuImageApi != null && provider.TryAcquireEnvironmentDepthConfidenceCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.environmentDepthConfidenceCpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Gets the occlusion texture descriptors associated with the current AR frame. /// /// The allocator to use when creating the returned NativeArray. /// An array of texture descriptors. /// /// The caller owns the returned NativeArray and is responsible for calling Dispose on it. /// public NativeArray GetTextureDescriptors(Allocator allocator) => provider.GetTextureDescriptors(default, allocator); /// /// Get the current occlusion frame. /// /// The allocator to use for any s contained in the frame. /// The output occlusion frame, if this method returned . /// if the method successfully got a frame. Otherwise, . public bool TryGetFrame(Allocator allocator, out XROcclusionFrame frame) { if (running && provider.TryGetFrame(allocator, out frame).IsSuccess()) return true; frame = default; return false; } /// /// Get the enabled and disabled shader keywords for the material. /// /// The keywords to enable for the material. /// The keywords to disable for the material. [Obsolete("GetMaterialKeywords(out List, out List) has been deprecated in AR Foundation version 6.0. Use GetShaderKeywords() instead.")] public void GetMaterialKeywords(out List enabledKeywords, out List disabledKeywords) => provider.GetMaterialKeywords(out enabledKeywords, out disabledKeywords); /// /// Get the enabled and disabled shader keywords for the material. /// /// Returns an with the enabled and disabled shader keywords for the Material. [Obsolete("GetShaderKeywords is deprecated as of AR Foundation 6.1. Use GetShaderKeywords2 instead.")] public ShaderKeywords GetShaderKeywords() => provider.GetShaderKeywords(); /// /// Get the shader keywords that are enabled or disabled by the provider. /// /// The enabled and disabled shader keywords. public XRShaderKeywords GetShaderKeywords2() => provider.GetShaderKeywords2(); /// /// Register the descriptor for the occlusion subsystem implementation. /// /// The occlusion subsystem implementation construction information. /// /// true if the descriptor was registered. Otherwise, false. [Obsolete("XROcclusionSubsystem.Register(XROcclusionSubsystemCinfo) has been deprecated in AR Foundation version 6.0. Use XROcclusionSubsystemDescriptor.Register(XROcclusionSubsystemDescriptor.Cinfo) instead.")] public static bool Register(XROcclusionSubsystemCinfo occlusionSubsystemCinfo) { var occlusionSubsystemInfo = new XROcclusionSubsystemDescriptor.Cinfo { id = occlusionSubsystemCinfo.id, providerType = occlusionSubsystemCinfo.providerType, subsystemTypeOverride = occlusionSubsystemCinfo.subsystemTypeOverride, humanSegmentationStencilImageSupportedDelegate = occlusionSubsystemCinfo.humanSegmentationStencilImageSupportedDelegate, humanSegmentationDepthImageSupportedDelegate = occlusionSubsystemCinfo.humanSegmentationDepthImageSupportedDelegate, environmentDepthImageSupportedDelegate = occlusionSubsystemCinfo.environmentDepthImageSupportedDelegate, environmentDepthConfidenceImageSupportedDelegate = occlusionSubsystemCinfo.environmentDepthConfidenceImageSupportedDelegate, environmentDepthTemporalSmoothingSupportedDelegate = occlusionSubsystemCinfo.environmentDepthTemporalSmoothingSupportedDelegate }; XROcclusionSubsystemDescriptor.Register(occlusionSubsystemInfo); return true; } /// /// The provider which will service the . /// public abstract class Provider : SubsystemProvider { /// /// Property to be implemented by the provider to get or set the requested human segmentation stencil mode. /// /// /// The requested human segmentation stencil mode. /// /// Thrown when setting the human segmentation stencil mode /// to `enabled` if the implementation does not support human segmentation. public virtual HumanSegmentationStencilMode requestedHumanStencilMode { get => HumanSegmentationStencilMode.Disabled; set { if (value.Enabled()) { throw new NotSupportedException( "Setting human segmentation stencil to enabled is not supported by this implementation"); } } } /// /// Property to be implemented by the provider to get the segmentation stencil mode currently in use. /// public virtual HumanSegmentationStencilMode currentHumanStencilMode => HumanSegmentationStencilMode.Disabled; /// /// Property to be implemented by the provider to get or set the requested human segmentation depth mode. /// /// /// The requested human segmentation depth mode. /// /// Thrown when setting the human segmentation depth mode /// to `enabled` if the implementation does not support human segmentation. public virtual HumanSegmentationDepthMode requestedHumanDepthMode { get => HumanSegmentationDepthMode.Disabled; set { if (value.Enabled()) { throw new NotSupportedException( "Setting human segmentation depth to enabled is not supported by this implementation"); } } } /// /// Property to be implemented by the provider to get the human segmentation depth mode currently in use. /// /// The current human segmentation depth mode. public virtual HumanSegmentationDepthMode currentHumanDepthMode => HumanSegmentationDepthMode.Disabled; /// /// Property to be implemented by the provider to get or set the environment depth mode. /// /// The requested environment depth mode. public virtual EnvironmentDepthMode requestedEnvironmentDepthMode { get => EnvironmentDepthMode.Disabled; set {} } /// /// Property to be implemented by the provider to get the environment depth mode currently in use. /// /// The current environment depth mode. public virtual EnvironmentDepthMode currentEnvironmentDepthMode => EnvironmentDepthMode.Disabled; /// /// Property to be implemented by the provider to get whether temporal smoothing has been requested for the /// environment depth image. /// /// if environment depth temporal smoothing is requested. /// Otherwise, . public virtual bool environmentDepthTemporalSmoothingRequested { get => false; set {} } /// /// Property to be implemented by the provider to get whether temporal smoothing is currently applied to the /// environment depth image. /// /// if environment depth temporal smoothing is enabled. /// Otherwise, . public virtual bool environmentDepthTemporalSmoothingEnabled => false; /// /// Specifies the requested occlusion preference mode. /// /// The requested occlusion preference mode. public virtual OcclusionPreferenceMode requestedOcclusionPreferenceMode { get => default; set {} } /// /// Get the occlusion preference mode currently in use by the provider. /// /// The current occlusion preference mode. public virtual OcclusionPreferenceMode currentOcclusionPreferenceMode => default; /// /// Get all the texture descriptors in the provider's swapchain, if possible. /// Must return if the provider does not use a fixed-length swapchain. /// /// All texture descriptors in the provider's swapchain, /// if this method returns . Each texture descriptor represents a possible value used by /// call to on a later frame. Allocator is `Allocator.Temp`. /// /// Texture descriptors are grouped per frame. All texture descriptors that are used within one frame must /// be grouped together in the same inner array. /// if the provider uses a fixed-length swapchain and all texture /// descriptors were successfully output. Otherwise, . /// /// This method is used by the [AR Occlusion Manager component](xref:arfoundation-occlusion-manager) during /// `OnBeforeStart` to determine whether the provider uses a fixed-length swapchain of fixed-size textures. /// If so, `AROcclusionManager` is able to create Unity `Texture` objects for the entire swapchain at once /// and re-use them throughout the life cycle of your app. /// public virtual bool TryGetAllTextureDescriptorsInSwapchain( out NativeArray> swapchainDescriptors) { swapchainDescriptors = default; return false; } /// /// Get the current occlusion frame. /// /// The allocator to use for any s contained in the frame. /// The output occlusion frame, if this method returned . /// if the method successfully got a frame. Otherwise, . public virtual XRResultStatus TryGetFrame(Allocator allocator, out XROcclusionFrame frame) { // This API was added in AR Foundation 6.1. In order for this to not be a breaking change for providers // that don't implement this method, the default implementation must return `true`. frame = default; return true; } /// /// Method to be implemented by the provider to get the human stencil texture descriptor. /// /// The human stencil texture descriptor to be populated, if /// available. /// if the human stencil texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support human /// stencil texture. public virtual bool TryGetHumanStencil(out XRTextureDescriptor humanStencilDescriptor) => throw new NotSupportedException("Human stencil texture is not supported by this implementation"); /// /// Tries to acquire the latest human stencil CPU image. /// /// If this method returns `true`, this should be populated with construction /// information for an . /// if the human stencil CPU image was acquired. Otherwise, . /// Thrown if the implementation does not support human /// stencil CPU images. public virtual bool TryAcquireHumanStencilCpuImage(out XRCpuImage.Cinfo cinfo) => throw new NotSupportedException("Human stencil CPU images are not supported by this implementation."); /// /// The API for interacting with an acquired with . /// /// The human stencil CPU image API. public virtual XRCpuImage.Api humanStencilCpuImageApi => null; /// /// Method to be implemented by the provider to get the human depth texture descriptor. /// /// The human depth texture descriptor to be populated, if available. /// if the human depth texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support human /// depth texture. public virtual bool TryGetHumanDepth(out XRTextureDescriptor humanDepthDescriptor) => throw new NotSupportedException("Human depth texture is not supported by this implementation"); /// /// Tries to acquire the latest human depth CPU image. /// /// The construction information for an , if this method /// returns . /// if the human depth CPU image was acquired. /// Otherwise, . /// Thrown if the implementation does not support human /// depth CPU images. public virtual bool TryAcquireHumanDepthCpuImage(out XRCpuImage.Cinfo cinfo) => throw new NotSupportedException("Human depth CPU images are not supported by this implementation."); /// /// The API for interacting with an acquired with . /// /// The human depth CPU image API. public virtual XRCpuImage.Api humanDepthCpuImageApi => null; /// /// Method to be implemented by the provider to get the environment depth texture descriptor. /// /// The environment depth texture descriptor to be populated, if /// available. /// if the environment depth texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support environment /// depth texture. public virtual bool TryGetEnvironmentDepth(out XRTextureDescriptor environmentDepthDescriptor) => throw new NotSupportedException("Environment depth texture is not supported by this implementation"); /// /// Tries to acquire the latest environment depth CPU image. /// /// Construction information for an , if this method returns /// . /// if the environment depth CPU image was acquired. /// Otherwise, . /// Thrown if the implementation does not support environment /// CPU images. public virtual bool TryAcquireEnvironmentDepthCpuImage(out XRCpuImage.Cinfo cinfo) => throw new NotSupportedException("Environment depth CPU images are not supported by this implementation."); /// /// Tries to acquire the latest environment depth CPU image. /// /// /// This method differs from in that it always tries to /// acquire the raw depth image, whereas the image provided by /// depends on the value of . /// /// Construction information for an , if this method returns /// . /// if the raw environment depth CPU image was acquired. /// Otherwise, . public virtual bool TryAcquireRawEnvironmentDepthCpuImage(out XRCpuImage.Cinfo cinfo) { cinfo = default; return false; } /// /// Tries to acquire the latest smoothed environment depth CPU image. /// /// /// This method differs from in that it always tries to /// acquire the smoothed depth image, whereas the image provided by /// depends on the value of /// . /// /// Construction information for an `XRCpuImage`, if this method returns /// . /// if the smoothed environment depth CPU image was acquired. /// Otherwise, . public virtual bool TryAcquireSmoothedEnvironmentDepthCpuImage(out XRCpuImage.Cinfo cinfo) { cinfo = default; return false; } /// /// The API for interacting with an acquired with . /// /// The environment depth CPU image API. public virtual XRCpuImage.Api environmentDepthCpuImageApi => null; /// /// Method to be implemented by the provider to get the environment depth confidence texture descriptor. /// /// The environment depth texture descriptor to be /// populated, if available. /// if the environment depth confidence texture descriptor is available and returned. /// Otherwise, . /// Thrown if the implementation does not support environment /// depth confidence texture. public virtual bool TryGetEnvironmentDepthConfidence(out XRTextureDescriptor environmentDepthConfidenceDescriptor) => throw new NotSupportedException("Environment depth confidence texture is not supported by this implementation"); /// /// Tries to acquire the latest environment depth confidence CPU image. /// /// Construction information for an , if this method returns /// . /// if the environment depth confidence CPU image was acquired. /// Otherwise, . /// Thrown if the implementation does not support environment /// depth confidence CPU images. public virtual bool TryAcquireEnvironmentDepthConfidenceCpuImage(out XRCpuImage.Cinfo cinfo) => throw new NotSupportedException("Environment depth CPU images are not supported by this implementation."); /// /// The API for interacting with an acquired with . /// /// The environment depth confidence CPU image API. public virtual XRCpuImage.Api environmentDepthConfidenceCpuImageApi => null; /// /// Method to be implemented by the provider to get the occlusion texture descriptors associated with the /// current AR frame. /// /// The default descriptor value. /// The allocator to use when creating the returned NativeArray. /// An array of the occlusion texture descriptors. public virtual NativeArray GetTextureDescriptors( XRTextureDescriptor defaultDescriptor, Allocator allocator) => new(0, allocator); /// /// Method to be implemented by the provider to get the enabled and disabled shader keywords for the material. /// /// The keywords to enable for the material. /// The keywords to disable for the material. [Obsolete("GetMaterialKeywords(out List, out List) has been deprecated in AR Foundation version 6.0. Use GetShaderKeywords() instead.")] public virtual void GetMaterialKeywords(out List enabledKeywords, out List disabledKeywords) { enabledKeywords = null; disabledKeywords = null; } /// /// Get the enabled and disabled shader keywords for the material. /// /// The enabled and disabled shader keywords for the Material. [Obsolete("GetShaderKeywords is deprecated as of AR Foundation 6.1. Use GetShaderKeywords2 instead.")] public virtual ShaderKeywords GetShaderKeywords() => default; /// /// Get the shader keywords that are enabled or disabled by the provider. /// /// The enabled and disabled shader keywords. public virtual XRShaderKeywords GetShaderKeywords2() => default; } } }