using System; using System.Collections.Generic; using Unity.Collections; using UnityEngine.SubsystemsImplementation; namespace UnityEngine.XR.ARSubsystems { /// /// Provides access to a device's camera. /// /// /// The XRCameraSubsystem links a Unity Camera to a device camera for video overlay (pass-thru /// rendering). It also allows developers to query for environmental light estimation if available. /// public class XRCameraSubsystem : SubsystemWithProvider { /// /// Interface for providing camera functionality for the implementation. /// public class Provider : SubsystemProvider { /// /// An instance of the used to operate on objects. /// public virtual XRCpuImage.Api cpuImageApi => null; /// /// Get the Material used by this to render the camera texture. /// /// The Material to render the camera texture. public virtual Material cameraMaterial => null; /// /// Get whether camera permission has been granted. /// /// if camera permission has been granted. Otherwise, . public virtual bool permissionGranted => false; /// /// Get whether culling should be inverted during rendering. Some front-facing camera modes might /// require this. /// /// if culling should be inverted during rendering. Otherwise, . public virtual bool invertCulling => false; /// /// Get the actual camera facing direction. /// /// The current camera facing direction. /// public virtual Feature currentCamera => Feature.None; /// /// Get or set the requested camera facing direction, that is, the bits. /// /// The requested camera facing direction. public virtual Feature requestedCamera { get => Feature.None; set { } } /// /// Get whether auto focus is enabled. /// /// if auto focus is enabled. Otherwise, . /// public virtual bool autoFocusEnabled => false; /// /// Get or set whether auto focus is requested. /// /// if auto focus is requested. Otherwise, . public virtual bool autoFocusRequested { get => false; set { } } /// /// Get whether Image Stabilization is enabled. /// /// if EIS is enabled. Otherwise, . /// public virtual bool imageStabilizationEnabled => false; /// /// Get or set whether Image Stabilization is requested. /// /// if EIS is requested. Otherwise, . public virtual bool imageStabilizationRequested { get => false; set { } } /// /// Get whether the current session configuration allows the camera torch to be turned on or off. /// /// true if supported. public virtual bool DoesCurrentCameraSupportTorch() { return false; } /// /// Gets the current camera torch mode /// /// The current . public virtual XRCameraTorchMode currentCameraTorchMode { get => XRCameraTorchMode.Off; } /// /// Get or set the requested camera torch mode. /// /// if the torch is requested to be on. Otherwise, . public virtual XRCameraTorchMode requestedCameraTorchMode { get => XRCameraTorchMode.Off; set { } } /// /// Get the current light estimation mode in use by the subsystem. /// /// The current light estimation mode. /// public virtual Feature currentLightEstimation => Feature.None; /// /// Get or set the requested light estimation mode. /// /// The requested light estimation mode. public virtual Feature requestedLightEstimation { get => Feature.None; set { } } /// /// Property to be implemented by the provider to query or set the current camera configuration. /// /// The current camera configuration, if it exists. Otherwise, . /// Thrown when setting the current configuration if the /// implementation does not support camera configurations. /// Thrown when setting the current configuration if the given /// configuration is not a valid, supported camera configuration. /// Thrown when setting the current configuration if the /// implementation is unable to set the current camera configuration. public virtual XRCameraConfiguration? currentConfiguration { get => null; set => throw new NotSupportedException("setting current camera configuration is not supported by this implementation"); } /// /// Get the current . /// /// The current . /// public virtual XRCameraBackgroundRenderingMode currentBackgroundRenderingMode => XRCameraBackgroundRenderingMode.None; /// /// Get or set the requested . /// /// The requested background rendering mode. public virtual XRSupportedCameraBackgroundRenderingMode requestedBackgroundRenderingMode { get => XRSupportedCameraBackgroundRenderingMode.Any; set { } } /// /// Get the supported s defined as s. /// /// The supported background rendering modes. public virtual XRSupportedCameraBackgroundRenderingMode supportedBackgroundRenderingMode => XRSupportedCameraBackgroundRenderingMode.None; /// /// Attempts to get the platform specific rendering parameters for rendering the camera background texture. /// /// The platform specific rendering parameters for rendering the camera background texture. /// if the platform provides specialized rendering parameters. Otherwise, . public virtual bool TryGetRenderingParameters(out XRCameraBackgroundRenderingParams cameraBackgroundRenderingParameters) { cameraBackgroundRenderingParameters = default; return false; } /// /// Start the camera for the subsystem. /// public override void Start() { } /// /// Stop the camera for the subsystem. /// public override void Stop() { } /// /// Destroy the camera for the subsystem. /// public override void Destroy() { } /// /// Get the camera frame for the subsystem. /// /// The current Unity Camera parameters. /// The current camera frame returned by the method. /// if the method successfully got a frame. Otherwise, . public virtual bool TryGetFrame( XRCameraParams cameraParams, out XRCameraFrame cameraFrame) { cameraFrame = default; return false; } /// /// Get the camera intrinsics information. /// /// The camera intrinsics information returned from the method. /// if the method successfully gets the camera intrinsics information. /// Otherwise, . public virtual bool TryGetIntrinsics( out XRCameraIntrinsics cameraIntrinsics) { cameraIntrinsics = default(XRCameraIntrinsics); return false; } /// /// Get the supported camera configurations. /// /// A default value used to fill the returned array before copying in /// real values. This ensures future additions to this are backwards compatible. /// The allocation strategy to use for the returned data. /// The supported camera configurations. public virtual NativeArray GetConfigurations( XRCameraConfiguration defaultCameraConfiguration, Allocator allocator) { return new NativeArray(0, allocator); } /// /// Get the s associated with the current . /// /// A default value used to fill the returned array before copying in real /// values. This ensures future additions to this are backwards compatible. /// The allocation strategy to use for the returned data.. /// The current texture descriptors. public virtual NativeArray GetTextureDescriptors( XRTextureDescriptor defaultDescriptor, Allocator allocator) { return new NativeArray(0, allocator); } /// /// 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 GetShaderKeywords2 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. /// /// 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 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; /// /// Get the latest native camera image. /// /// The metadata required to construct a . /// if the camera image is acquired. Otherwise, . /// Thrown if the implementation does not support camera image. public virtual bool TryAcquireLatestCpuImage(out XRCpuImage.Cinfo cameraImageCinfo) { throw new NotSupportedException("getting camera image is not supported by this implementation"); } /// /// Create the camera material from the given camera shader name. /// /// The name of the camera shader. /// The created camera material shader. /// Thrown if the shader cannot be found or if a material /// cannot be created for the shader. protected Material CreateCameraMaterial(string cameraShaderName) { var shader = Shader.Find(cameraShaderName); if (shader == null) { throw new InvalidOperationException( $"Could not find shader named '{cameraShaderName}' required " + $"for video overlay on camera subsystem."); } var material = new Material(shader); if (material == null) { throw new InvalidOperationException( $"Could not create a material for shader named '{cameraShaderName}' required for video" + " overlay on camera subsystem."); } return material; } /// /// Method to be implemented by the provider to handle any required platform-specific functionality /// immediately before rendering the camera background. This method will always be called on the render /// thread and should only be called by the code responsible for executing background rendering on /// mobile AR platforms. /// /// Platform-specific identifier. public virtual void OnBeforeBackgroundRender(int id) {} } /// /// Get the camera currently in use. /// /// The current camera. public Feature currentCamera => provider.currentCamera.Cameras(); /// /// Get or set the requested camera (that is, the bits). /// /// The requested camera. public Feature requestedCamera { get => provider.requestedCamera; set => provider.requestedCamera = value.Cameras(); } /// /// Get the current . /// /// The current camera background rendering mode. /// public XRCameraBackgroundRenderingMode currentCameraBackgroundRenderingMode => permissionGranted ? provider.currentBackgroundRenderingMode : XRCameraBackgroundRenderingMode.None; /// /// Get or set the requested . /// /// The requested camera background rendering mode. public XRSupportedCameraBackgroundRenderingMode requestedCameraBackgroundRenderingMode { get => provider.requestedBackgroundRenderingMode; set => provider.requestedBackgroundRenderingMode = value; } /// /// Get the supported s. /// Indicates which s are supported. /// /// The supported camera background rendering modes. public XRSupportedCameraBackgroundRenderingMode supportedCameraBackgroundRenderingMode => provider.supportedBackgroundRenderingMode; /// /// Indicates whether auto focus is enabled. /// /// if auto focus is enabled. Otherwise, . /// public bool autoFocusEnabled => provider.autoFocusEnabled; /// /// Get or set whether autofocus is requested. /// /// if autofocus is requested. Otherwise, . public bool autoFocusRequested { get => provider.autoFocusRequested; set => provider.autoFocusRequested = value; } /// /// Indicate whether Image Stabilization is enabled. /// /// if EIS is enabled. Otherwise, . /// public bool imageStabilizationEnabled => provider.imageStabilizationEnabled; /// /// Get or set whether Image Stabilization is requested. /// /// if EIS is requested. Otherwise, . public bool imageStabilizationRequested { get => provider.imageStabilizationRequested; set => provider.imageStabilizationRequested = value; } /// /// Get or set the requested camera torch mode. /// /// if the torch is requested to be on. Otherwise, . public XRCameraTorchMode requestedCameraTorchMode { get => provider.requestedCameraTorchMode; set => provider.requestedCameraTorchMode = value; } /// /// Gets the current camera torch mode. /// /// The camera torch mode. public XRCameraTorchMode currentCameraTorchMode { get => provider.currentCameraTorchMode; } /// /// Get whether the current session configuration allows the camera torch to be turned on or off. /// /// true if supported. public bool DoesCurrentCameraSupportTorch() { return provider.DoesCurrentCameraSupportTorch(); } /// /// Get the current light estimation mode in use by the provider. /// /// The current light estimation mode. /// public Feature currentLightEstimation => provider.currentLightEstimation.LightEstimation(); /// /// Get or set the requested light estimation mode. /// /// The requested light estimation mode. public Feature requestedLightEstimation { get => provider.requestedLightEstimation.LightEstimation(); set => provider.requestedLightEstimation = value.LightEstimation(); } /// /// Get the Material used by to render the camera texture. /// /// The Material to render the camera texture. public Material cameraMaterial => provider.cameraMaterial; /// /// Attempts to get the platform specific rendering parameters for rendering the camera background texture. /// /// /// The platform specific rendering parameters for rendering the camera background texture. /// /// /// if the platform provides specialized rendering parameters or otherwise. /// public bool TryGetRenderingParameters(out XRCameraBackgroundRenderingParams cameraBackgroundRenderingParameters) => provider.TryGetRenderingParameters(out cameraBackgroundRenderingParameters); /// /// Indicates whether camera permission has been granted. /// /// if camera permission has been granted. Otherwise, . public bool permissionGranted => provider.permissionGranted; /// /// Set this to to invert the culling mode during rendering. Some front-facing /// camera modes might require this. /// public bool invertCulling => provider.invertCulling; /// /// The current camera configuration. /// /// The current camera configuration, if it exists. Otherwise, . /// Thrown when setting the current configuration if the /// implementation does not support camera configurations. /// Thrown when setting the current configuration if the given /// configuration is . /// Thrown when setting the current configuration if the given /// configuration is not a supported camera configuration. /// Thrown when setting the current configuration if the /// implementation is unable to set the current camera configuration. /// public virtual XRCameraConfiguration? currentConfiguration { get => provider.currentConfiguration; set { if (value == null) { throw new ArgumentNullException(nameof(value), "cannot set the camera configuration to null"); } provider.currentConfiguration = value; } } /// /// Construct the . /// public XRCameraSubsystem() { } /// /// Gets the s associated with the current frame. The caller owns the returned /// NativeArray and is responsible for calling Dispose on it. /// /// An array of texture descriptors. /// The allocator to use when creating the returned NativeArray. public NativeArray GetTextureDescriptors(Allocator allocator) { return provider.GetTextureDescriptors(default, allocator); } /// /// Method to be called on the render thread to handle any required platform-specific functionality /// immediately before rendering the camera background. This method will always be called on the render /// thread and should only be called by the code responsible for executing background rendering on /// mobile AR platforms. /// /// Platform-specific identifier. public void OnBeforeBackgroundRender(int id) { provider.OnBeforeBackgroundRender(id); } /// /// Get the camera intrinsics information. /// /// The returned camera intrinsics information. /// if the method successfully gets the camera intrinsics information. /// Otherwise, . /// /// > [!NOTE] /// > The intrinsics may change each frame. You should call this each frame that you need intrinsics /// > in order to ensure you are using the intrinsics for the current frame. /// public bool TryGetIntrinsics(out XRCameraIntrinsics cameraIntrinsics) { return provider.TryGetIntrinsics(out cameraIntrinsics); } /// /// Get the supported camera configurations. /// /// The allocation strategy to use for the returned data. /// The supported camera configurations. public NativeArray GetConfigurations(Allocator allocator) { return provider.GetConfigurations(default, allocator); } /// /// Get the latest frame from the provider. /// /// The Unity Camera parameters. /// The camera frame to be populated if the subsystem is running and successfully provides /// the latest camera frame. /// if the camera frame is successfully returned. Otherwise, . public bool TryGetLatestFrame(XRCameraParams cameraParams, out XRCameraFrame frame) { if (running && provider.TryGetFrame(cameraParams, out frame)) { 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 GetShaderKeywords2 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(); /// /// Attempts to acquire the latest camera image. This provides direct access to the raw pixel data, as well as /// to utilities to convert to RGB and Grayscale formats. /// /// A valid if this method returns . /// if the image was acquired. Otherwise, . /// Thrown if the implementation does not support camera image. /// The returned must be disposed to avoid resource leaks. public bool TryAcquireLatestCpuImage(out XRCpuImage cpuImage) { if (provider.cpuImageApi != null && provider.TryAcquireLatestCpuImage(out var cinfo)) { cpuImage = new XRCpuImage(provider.cpuImageApi, cinfo); return true; } cpuImage = default; return false; } /// /// Registers a camera subsystem implementation based on the given subsystem parameters. /// /// The parameters defining the camera subsystem functionality implemented /// by the subsystem provider. /// if the subsystem implementation is registered. Otherwise, . /// Thrown when the values specified in the parameter are invalid. /// Typically, this happens when required parameters are or empty /// or types that do not derive from the required base class. /// [Obsolete("XRCameraSubsystem.Register(XRCameraSubsystemCinfo) has been deprecated in AR Foundation version 6.0. Use XRCameraSubsystemDescriptor.Register(XRCameraSubsystemDescriptor.Cinfo) instead.")] public static bool Register(XRCameraSubsystemCinfo cameraSubsystemParams) { var cameraSubsystemCinfo = new XRCameraSubsystemDescriptor.Cinfo { id = cameraSubsystemParams.id, providerType = cameraSubsystemParams.providerType, subsystemTypeOverride = cameraSubsystemParams.subsystemTypeOverride, supportsAverageBrightness = cameraSubsystemParams.supportsAverageBrightness, supportsAverageColorTemperature = cameraSubsystemParams.supportsAverageColorTemperature, supportsColorCorrection = cameraSubsystemParams.supportsColorCorrection, supportsDisplayMatrix = cameraSubsystemParams.supportsDisplayMatrix, supportsProjectionMatrix = cameraSubsystemParams.supportsProjectionMatrix, supportsTimestamp = cameraSubsystemParams.supportsTimestamp, supportsCameraConfigurations = cameraSubsystemParams.supportsCameraConfigurations, supportsCameraImage = cameraSubsystemParams.supportsCameraImage, supportsAverageIntensityInLumens = cameraSubsystemParams.supportsAverageIntensityInLumens, supportsFocusModes = cameraSubsystemParams.supportsFocusModes, supportsFaceTrackingAmbientIntensityLightEstimation = cameraSubsystemParams.supportsFaceTrackingAmbientIntensityLightEstimation, supportsFaceTrackingHDRLightEstimation = cameraSubsystemParams.supportsFaceTrackingHDRLightEstimation, supportsWorldTrackingAmbientIntensityLightEstimation = cameraSubsystemParams.supportsWorldTrackingAmbientIntensityLightEstimation, supportsWorldTrackingHDRLightEstimation = cameraSubsystemParams.supportsWorldTrackingHDRLightEstimation, supportsCameraGrain = cameraSubsystemParams.supportsCameraGrain, supportsImageStabilizationDelegate = cameraSubsystemParams.supportsImageStabilizationDelegate, supportsExifData = cameraSubsystemParams.supportsExifData, }; XRCameraSubsystemDescriptor.Register(cameraSubsystemCinfo); return true; } } }