163 lines
6.1 KiB
C#
163 lines
6.1 KiB
C#
// Copyright 2022-2024 Niantic.
|
|
using System.Text;
|
|
using UnityEngine.XR.ARFoundation;
|
|
using UnityEngine.UI;
|
|
using UnityEngine;
|
|
|
|
namespace Niantic.Lightship.AR.Samples
|
|
{
|
|
public abstract class DisplayImage : MonoBehaviour
|
|
{
|
|
// Name of the display rotation matrix in the shader.
|
|
const string k_DisplayMatrixName = "_DisplayMatrix";
|
|
|
|
private readonly int k_DisplayMatrix = Shader.PropertyToID(k_DisplayMatrixName);
|
|
|
|
protected readonly StringBuilder m_StringBuilder = new();
|
|
|
|
protected ScreenOrientation m_CurrentScreenOrientation;
|
|
|
|
[SerializeField]
|
|
[Tooltip("The ARCameraManager which will produce camera frame events.")]
|
|
ARCameraManager m_CameraManager;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Raw Image UI element for display.")]
|
|
protected RawImage m_RawImage;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Material using the shader.")]
|
|
Material m_Material;
|
|
|
|
[SerializeField]
|
|
[Tooltip("UI Text field for image info")]
|
|
Text m_ImageInfo;
|
|
|
|
private Camera m_camera;
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
// Acquire a reference to the rendering camera
|
|
m_camera = m_CameraManager.GetComponent<Camera>();
|
|
|
|
// Get the current screen orientation, and update the raw image UI
|
|
m_CurrentScreenOrientation = Screen.orientation;
|
|
}
|
|
|
|
protected virtual void OnEnable()
|
|
{
|
|
UpdateRawImage();
|
|
}
|
|
|
|
protected virtual void Update()
|
|
{
|
|
Debug.Assert(m_RawImage != null, "no raw image");
|
|
|
|
// If the raw image needs to be updated because of a device orientation change or because of a texture
|
|
// aspect ratio difference, then update the raw image with the new values.
|
|
if (m_CurrentScreenOrientation != Screen.orientation)
|
|
{
|
|
m_CurrentScreenOrientation = Screen.orientation;
|
|
UpdateRawImage();
|
|
}
|
|
|
|
// Update the image
|
|
var sizeDelta = m_RawImage.rectTransform.sizeDelta;
|
|
OnUpdatePresentation(
|
|
viewportWidth: (int)sizeDelta.x,
|
|
viewportHeight: (int)sizeDelta.y,
|
|
orientation: m_CurrentScreenOrientation,
|
|
renderingMaterial: m_RawImage.material,
|
|
image: out var texture,
|
|
displayMatrix: out var displayMatrix);
|
|
|
|
m_RawImage.texture = texture;
|
|
m_RawImage.material.SetMatrix(k_DisplayMatrix, displayMatrix);
|
|
|
|
if (m_RawImage.texture != null)
|
|
{
|
|
// Display some text information about each of the textures.
|
|
var displayTexture = m_RawImage.texture as Texture2D;
|
|
if (displayTexture != null)
|
|
{
|
|
m_StringBuilder.Clear();
|
|
BuildTextureInfo(m_StringBuilder, "env", displayTexture);
|
|
LogText(m_StringBuilder.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invoked when it is time to update the presentation.
|
|
/// </summary>
|
|
/// <param name="viewportWidth">The width of the portion of the screen the image will be rendered onto.</param>
|
|
/// <param name="viewportHeight">The height of the portion of the screen the image will be rendered onto.</param>
|
|
/// <param name="orientation">The orientation of the screen.</param>
|
|
/// <param name="renderingMaterial">The material used to render the image.</param>
|
|
/// <param name="image">The image to render.</param>
|
|
/// <param name="displayMatrix">A transformation matrix to fit the image onto the viewport.</param>
|
|
protected abstract void OnUpdatePresentation( int viewportWidth, int viewportHeight, ScreenOrientation orientation,
|
|
Material renderingMaterial, out Texture image, out Matrix4x4 displayMatrix);
|
|
|
|
|
|
private static void BuildTextureInfo(StringBuilder stringBuilder, string textureName, Texture2D texture)
|
|
{
|
|
stringBuilder.AppendLine($"texture : {textureName}");
|
|
if (texture == null)
|
|
{
|
|
stringBuilder.AppendLine(" <null>");
|
|
}
|
|
else
|
|
{
|
|
stringBuilder.AppendLine($" format : {texture.format}");
|
|
stringBuilder.AppendLine($" width : {texture.width}");
|
|
stringBuilder.AppendLine($" height : {texture.height}");
|
|
stringBuilder.AppendLine($" mipmap : {texture.mipmapCount}");
|
|
}
|
|
}
|
|
|
|
private void LogText(string text)
|
|
{
|
|
if (m_ImageInfo != null)
|
|
{
|
|
m_ImageInfo.text = text;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log(text);
|
|
}
|
|
}
|
|
|
|
private void UpdateRawImage()
|
|
{
|
|
Debug.Assert(m_RawImage != null, "no raw image");
|
|
|
|
// The aspect ratio of the presentation in landscape orientation
|
|
var aspect = Mathf.Max(m_camera.pixelWidth, m_camera.pixelHeight) /
|
|
(float)Mathf.Min(m_camera.pixelWidth, m_camera.pixelHeight);
|
|
|
|
// Determine the raw image rectSize preserving the texture aspect ratio, matching the screen orientation,
|
|
// and keeping a minimum dimension size.
|
|
float minDimension = 480.0f;
|
|
float maxDimension = Mathf.Round(minDimension * aspect);
|
|
Vector2 rectSize;
|
|
switch (m_CurrentScreenOrientation)
|
|
{
|
|
case ScreenOrientation.LandscapeRight:
|
|
case ScreenOrientation.LandscapeLeft:
|
|
rectSize = new Vector2(maxDimension, minDimension);
|
|
break;
|
|
case ScreenOrientation.PortraitUpsideDown:
|
|
case ScreenOrientation.Portrait:
|
|
default:
|
|
rectSize = new Vector2(minDimension, maxDimension);
|
|
break;
|
|
}
|
|
|
|
// Update the raw image dimensions and the raw image material parameters.
|
|
m_RawImage.rectTransform.sizeDelta = rectSize;
|
|
m_RawImage.material = m_Material;
|
|
}
|
|
}
|
|
}
|