using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using UnityEngine.XR.ARSubsystems; namespace UnityEngine.XR.ARFoundation { /// /// A structure for camera-related information pertaining to a particular frame. /// This is used to communicate information in the event. /// public struct ARCameraFrameEventArgs : IEquatable { /// /// The associated with this frame. /// public ARLightEstimationData lightEstimation { get; set; } /// /// The time, in nanoseconds, associated with this frame. /// Use timestampNs.HasValue to determine if this data is available. /// public long? timestampNs { get; set; } /// /// Gets or sets the projection matrix for the AR Camera. Use /// projectionMatrix.HasValue to determine if this data is available. /// public Matrix4x4? projectionMatrix { get; set; } /// /// Gets or sets the display matrix for use in the shader used /// by the . /// Use displayMatrix.HasValue to determine if this data is available. /// public Matrix4x4? displayMatrix { get; set; } /// /// The textures associated with this camera frame. These are generally /// external textures, which exist only on the GPU. To use them on the /// CPU, e.g., for computer vision processing, you will need to read /// them back from the GPU. /// public List textures { get; set; } /// /// Ids of the property name associated with each texture. This is a /// parallel List to the list. /// public List propertyNameIds { get; set; } /// /// The exposure duration in seconds with sub-millisecond precision. Used in calculating motion blur. /// /// /// can be null if platform does not support exposure duration. /// public double? exposureDuration { get; set; } /// /// The offset of camera exposure. Used to scale scene lighting in post-processed lighting stage. /// /// /// can be null if platform does not support exposure offset. /// public float? exposureOffset { get; set; } /// /// The list of keywords to be enabled for the material. /// [Obsolete("enabledMaterialKeywords has been deprecated in AR Foundation version 6.0. Use shaderKeywords instead.")] public List enabledMaterialKeywords { get; internal set; } /// /// The list of keywords to be disabled for the material. /// [Obsolete("disabledMaterialKeywords has been deprecated in AR Foundation version 6.0. Use shaderKeywords instead.")] public List disabledMaterialKeywords { get; internal set; } /// /// The enabled shader keywords. /// [Obsolete("enabledShaderKeywords is deprecated as of AR Foundation 6.1. Use shaderKeywords instead.")] public ReadOnlyCollection enabledShaderKeywords => shaderKeywords.enabledKeywords != null ? new(shaderKeywords.enabledKeywords.ToArray()) : null; /// /// The disabled shader keywords. /// [Obsolete("disabledShaderKeywords is deprecated as of AR Foundation 6.1. Use shaderKeywords instead")] public ReadOnlyCollection disabledShaderKeywords => shaderKeywords.disabledKeywords != null ? new(shaderKeywords.disabledKeywords.ToArray()) : null; /// /// The enabled and disabled shader keywords. /// public XRShaderKeywords shaderKeywords { get; internal set; } /// /// The camera grain texture effect. /// public Texture cameraGrainTexture { get; internal set; } /// /// The camera grain noise intensity. /// public float noiseIntensity { get; internal set; } /// /// The frame's EXIF data. /// internal XRCameraFrameExifData exifData { get; set; } /// /// Get the EXIF data of the frame if possible. /// /// The EXIF data of the camera frame. /// if the frame contains EXIF data. Otherwise, . public bool TryGetExifData(out XRCameraFrameExifData exifData) { exifData = this.exifData; return this.exifData.hasAnyProperties; } /// /// Generates a hash suitable for use with containers like `HashSet` and `Dictionary`. /// /// A hash code generated from this object's fields. public override int GetHashCode() { unchecked { var hash = lightEstimation.GetHashCode(); hash = hash * 486187739 + timestampNs.GetHashCode(); hash = hash * 486187739 + projectionMatrix.GetHashCode(); hash = hash * 486187739 + displayMatrix.GetHashCode(); hash = hash * 486187739 + HashCodeUtil.ReferenceHash(textures); hash = hash * 486187739 + HashCodeUtil.ReferenceHash(propertyNameIds); hash = hash * 486187739 + exposureDuration.GetHashCode(); hash = hash * 486187739 + exposureOffset.GetHashCode(); hash = hash * 486187739 + cameraGrainTexture.GetHashCode(); hash = hash * 486187739 + noiseIntensity.GetHashCode(); hash = hash * 486187739 + exifData.GetHashCode(); hash = hash * 486187739 + shaderKeywords.GetHashCode(); return hash; } } /// /// Tests for equality. /// /// The `object` to compare against. /// `True` if is of type and /// also returns `true`; otherwise `false`. public override bool Equals(object obj) => (obj is ARCameraFrameEventArgs) && Equals((ARCameraFrameEventArgs)obj); /// /// Generates a string representation of this struct suitable for debug /// logging. /// /// A string representation of this struct suitable for debug /// logging. public override string ToString() { var stringBuilder = new StringBuilder(); stringBuilder.Append("lightEstimation: " + lightEstimation.ToString()); stringBuilder.Append("\ntimestamp: " + timestampNs); if (timestampNs.HasValue) stringBuilder.Append("ns"); stringBuilder.Append("\nprojectionMatrix: " + projectionMatrix); stringBuilder.Append("\ndisplayMatrix: " + displayMatrix); stringBuilder.Append("\ntexture count: " + (textures == null ? 0 : textures.Count)); stringBuilder.Append("\npropertyNameId count: " + (propertyNameIds == null ? 0 : propertyNameIds.Count)); stringBuilder.Append("\nexifData: " + (exifData.hasAnyProperties ? exifData.ToString() : "null")); return stringBuilder.ToString(); } /// /// Tests for equality. /// /// The other to compare against. /// `True` if every field in is equal to this , otherwise false. public bool Equals(ARCameraFrameEventArgs other) { return lightEstimation.Equals(other.lightEstimation) && timestampNs == other.timestampNs && projectionMatrix == other.projectionMatrix && displayMatrix == other.displayMatrix && (textures == null ? other.textures == null : textures.Equals(other.textures)) && (propertyNameIds == null ? other.propertyNameIds == null : propertyNameIds.Equals(other.propertyNameIds)) && exposureDuration == other.exposureDuration && exposureOffset == other.exposureOffset && cameraGrainTexture == other.cameraGrainTexture && noiseIntensity == other.noiseIntensity && exifData.Equals(other.exifData) && shaderKeywords.Equals(other.shaderKeywords); } /// /// Tests for equality. Same as . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// `true` if is equal to . Otherwise, `false`. public static bool operator ==(ARCameraFrameEventArgs lhs, ARCameraFrameEventArgs rhs) => lhs.Equals(rhs); /// /// Tests for inequality. Same as `!`. /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// `true` if is not equal to . Otherwise, `false`. public static bool operator !=(ARCameraFrameEventArgs lhs, ARCameraFrameEventArgs rhs) => !lhs.Equals(rhs); } }