|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Name of the texture rotation property in the shader.
|
|
|
|
/// Name of the max distance property in the shader.
|
|
|
|
const string k_TextureRotationName = "_TextureRotation"; |
|
|
|
const string k_MaxDistanceName = "_MaxDistance"; |
|
|
|
/// Name of the max distance property in the shader.
|
|
|
|
/// Name of the display rotation matrix in the shader.
|
|
|
|
const string k_MaxDistanceName = "_MaxDistance"; |
|
|
|
const string k_DisplayRotationPerFrameName = "_DisplayRotationPerFrame"; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The default texture aspect ratio.
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// ID of the texture rotation property in the shader.
|
|
|
|
/// ID of the max distance property in the shader.
|
|
|
|
static readonly int k_TextureRotationId = Shader.PropertyToID(k_TextureRotationName); |
|
|
|
static readonly int k_MaxDistanceId = Shader.PropertyToID(k_MaxDistanceName); |
|
|
|
/// ID of the max distance property in the shader.
|
|
|
|
/// ID of the display rotation matrix in the shader.
|
|
|
|
static readonly int k_MaxDistanceId = Shader.PropertyToID(k_MaxDistanceName); |
|
|
|
static readonly int k_DisplayRotationPerFrameId = Shader.PropertyToID(k_DisplayRotationPerFrameName); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// A string builder for construction of strings.
|
|
|
|
|
|
|
DisplayMode m_DisplayMode = DisplayMode.EnvironmentDepth; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The display rotation matrix for the shader.
|
|
|
|
/// </summary.
|
|
|
|
Matrix4x4 m_DisplayRotationMatrix = Matrix4x4.identity; |
|
|
|
|
|
|
|
#if UNITY_ANDROID
|
|
|
|
/// <summary>
|
|
|
|
/// A matrix to flip the Y coordinate for the Android platform.
|
|
|
|
/// </summary>
|
|
|
|
Matrix4x4 k_AndroidFlipYMatrix = Matrix4x4.identity; |
|
|
|
#endif // UNITY_ANDROID
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Get or set the <c>AROcclusionManager</c>.
|
|
|
|
/// </summary>
|
|
|
|
public AROcclusionManager occlusionManager |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
[SerializeField] |
|
|
|
[Tooltip("The AROcclusionManager which will produce frame events.")] |
|
|
|
[Tooltip("The AROcclusionManager which will produce depth textures.")] |
|
|
|
/// Get or set the <c>ARCameraManager</c>.
|
|
|
|
/// </summary>
|
|
|
|
public ARCameraManager cameraManager |
|
|
|
{ |
|
|
|
get => m_CameraManager; |
|
|
|
set => m_CameraManager = value; |
|
|
|
} |
|
|
|
|
|
|
|
[SerializeField] |
|
|
|
[Tooltip("The ARCameraManager which will produce camera frame events.")] |
|
|
|
ARCameraManager m_CameraManager; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The UI RawImage used to display the image on screen.
|
|
|
|
/// </summary>
|
|
|
|
public RawImage rawImage |
|
|
|
|
|
|
[SerializeField] |
|
|
|
float m_MaxHumanDistance = 3.0f; |
|
|
|
|
|
|
|
void Awake() |
|
|
|
{ |
|
|
|
#if UNITY_ANDROID
|
|
|
|
k_AndroidFlipYMatrix[1,1] = -1.0f; |
|
|
|
k_AndroidFlipYMatrix[2,1] = 1.0f; |
|
|
|
#endif // UNITY_ANDROID
|
|
|
|
} |
|
|
|
|
|
|
|
// Subscribe to the camera frame received event, and initialize the display rotation matrix.
|
|
|
|
Debug.Assert(m_CameraManager != null, "no camera manager"); |
|
|
|
m_CameraManager.frameReceived += OnCameraFrameEventReceived; |
|
|
|
m_DisplayRotationMatrix = Matrix4x4.identity; |
|
|
|
|
|
|
|
void OnDisable() |
|
|
|
{ |
|
|
|
// Unsubscribe to the camera frame received event, and initialize the display rotation matrix.
|
|
|
|
Debug.Assert(m_CameraManager != null, "no camera manager"); |
|
|
|
m_CameraManager.frameReceived -= OnCameraFrameEventReceived; |
|
|
|
m_DisplayRotationMatrix = Matrix4x4.identity; |
|
|
|
} |
|
|
|
|
|
|
|
void Update() |
|
|
|
{ |
|
|
|
// If we are on a device that does supports neither human stencil, human depth, nor environment depth,
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// When the camera frame event is raised, capture the display rotation matrix.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cameraFrameEventArgs">The arguments when a camera frame event is raised.</param>
|
|
|
|
void OnCameraFrameEventReceived(ARCameraFrameEventArgs cameraFrameEventArgs) |
|
|
|
{ |
|
|
|
Debug.Assert(m_RawImage != null, "no raw image"); |
|
|
|
if (m_RawImage.material != null) |
|
|
|
{ |
|
|
|
// Copy the display rotation matrix from the camera.
|
|
|
|
Matrix4x4 cameraMatrix = cameraFrameEventArgs.displayMatrix ?? Matrix4x4.identity; |
|
|
|
|
|
|
|
Vector2 affineBasisX; |
|
|
|
Vector2 affineBasisY; |
|
|
|
Vector2 affineTranslation; |
|
|
|
#if UNITY_IOS
|
|
|
|
affineBasisX = new Vector2(cameraMatrix[0, 0], cameraMatrix[1, 0]); |
|
|
|
affineBasisY = new Vector2(cameraMatrix[0, 1], cameraMatrix[1, 1]); |
|
|
|
affineTranslation = new Vector2(cameraMatrix[2, 0], cameraMatrix[2, 1]); |
|
|
|
#endif // UNITY_IOS
|
|
|
|
#if UNITY_ANDROID
|
|
|
|
affineBasisX = new Vector2(cameraMatrix[0, 0], cameraMatrix[0, 1]); |
|
|
|
affineBasisY = new Vector2(cameraMatrix[1, 0], cameraMatrix[1, 1]); |
|
|
|
affineTranslation = new Vector2(cameraMatrix[0, 2], cameraMatrix[1, 2]); |
|
|
|
#endif // UNITY_IOS
|
|
|
|
|
|
|
|
// The camera display matrix includes scaling and offsets to fit the aspect ratio of the device. In most
|
|
|
|
// cases, the camera display matrix should be used directly without modification when applying depth to
|
|
|
|
// the scene because that will line up the depth image with the camera image. However, for this demo,
|
|
|
|
// we want to show the full depth image as a picture-in-picture, so we remove these scaling and offset
|
|
|
|
// factors while preserving the orientation.
|
|
|
|
affineBasisX = affineBasisX.normalized; |
|
|
|
affineBasisY = affineBasisY.normalized; |
|
|
|
m_DisplayRotationMatrix = Matrix4x4.identity; |
|
|
|
m_DisplayRotationMatrix[0,0] = affineBasisX.x; |
|
|
|
m_DisplayRotationMatrix[0,1] = affineBasisY.x; |
|
|
|
m_DisplayRotationMatrix[1,0] = affineBasisX.y; |
|
|
|
m_DisplayRotationMatrix[1,1] = affineBasisY.y; |
|
|
|
m_DisplayRotationMatrix[2,0] = Mathf.Round(affineTranslation.x); |
|
|
|
m_DisplayRotationMatrix[2,1] = Mathf.Round(affineTranslation.y); |
|
|
|
|
|
|
|
#if UNITY_ANDROID
|
|
|
|
m_DisplayRotationMatrix = k_AndroidFlipYMatrix * m_DisplayRotationMatrix; |
|
|
|
#endif // UNITY_IOS
|
|
|
|
|
|
|
|
// Set the matrix to the raw image material.
|
|
|
|
m_RawImage.material.SetMatrix(k_DisplayRotationPerFrameId, m_DisplayRotationMatrix); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Create log information about the given texture.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="stringBuilder">The string builder to which to append the texture information.</param>
|
|
|
|
|
|
|
float minDimension = 480.0f; |
|
|
|
float maxDimension = Mathf.Round(minDimension * m_TextureAspectRatio); |
|
|
|
Vector2 rectSize; |
|
|
|
float rotation; |
|
|
|
rotation = 180.0f; |
|
|
|
rotation = 0.0f; |
|
|
|
rotation = 90.0f; |
|
|
|
rotation = 270.0f; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update the raw image dimensions and the raw image material parameters.
|
|
|
|
m_RawImage.rectTransform.sizeDelta = rectSize; |
|
|
|
material.SetFloat(k_TextureRotationId, rotation); |
|
|
|
material.SetMatrix(k_DisplayRotationPerFrameId, m_DisplayRotationMatrix); |
|
|
|
m_RawImage.material = material; |
|
|
|
} |
|
|
|
|
|
|
|