123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using UnityEngine;
- using UnityEngine.UI;
- using System.Collections;
- namespace UMP
- {
- public class ARVideoCanvasHelper : MonoBehaviour
- {
- // Name of properties that we will use in shader to set the left/right and top/bottom border size
- private const string SHADER_BORDER_U_WIDTH = "_BorderUWidth";
- private const string SHADER_BORDER_V_WIDTH = "_BorderVWidth";
- // Main camera property that we will use to find the size of gameobject that have "MeshRenderer " component
- [SerializeField]
- private Camera _mainCamera = null;
- // Media player property that we will use to get current video size
- [SerializeField]
- private UniversalMediaPlayer _mediaPlayer = null;
- // Default size of video canvas (used if native library can't return correct video size)
- [SerializeField]
- public int _defaultWidth = 640;
- [SerializeField]
- public int _defaultHeight = 640;
- private MeshRenderer _meshRenderer;
- private RawImage _rawImageRenderer;
- private Material _objectMaterial;
- private Vector2 _objectSize;
- private Vector2 _videoSize;
- private Vector2 _calcSize;
- private Vector2 _borderUVSize;
- private IEnumerator _updateCanvasRatioEnum;
- private void Start()
- {
- _rawImageRenderer = gameObject.GetComponent<RawImage>();
- _meshRenderer = gameObject.GetComponent<MeshRenderer>();
- if (_rawImageRenderer == null && _meshRenderer == null)
- {
- Debug.LogError("Object need have MeshRenderer or RawImage component!");
- return;
- }
- _objectMaterial = _rawImageRenderer != null ? _rawImageRenderer.material : _meshRenderer.material;
- if (_mediaPlayer != null)
- {
- _mediaPlayer.AddImageReadyEvent(OnPlayerImageReady);
- _mediaPlayer.AddStoppedEvent(OnPlayerStopped);
- }
- ShowVideoCanvasBorder(true);
- }
- private void OnDestroy()
- {
- if (_mediaPlayer != null)
- {
- _mediaPlayer.RemoveImageReadyEvent(OnPlayerImageReady);
- _mediaPlayer.RemoveStoppedEvent(OnPlayerStopped);
- }
- if (_updateCanvasRatioEnum != null)
- StopCoroutine(_updateCanvasRatioEnum);
- ShowVideoCanvasBorder(false);
- }
- /// <summary>
- /// Calculate the size of video canvas borders and send results to custom shader
- /// </summary>
- private IEnumerator UpdateVideoCanvasRatio()
- {
- while (true)
- {
- _objectSize = GetPixelSizeOfMeshRenderer(_meshRenderer, _mainCamera);
- if (_objectSize == Vector2.zero)
- _objectSize = GetPixelSizeOfRawImage(_rawImageRenderer);
- _calcSize = Vector2.zero;
- _calcSize.x = (_objectSize.y / _videoSize.y) * _videoSize.x;
- if (_calcSize.x < _objectSize.x)
- _calcSize.y = _objectSize.y;
- else
- _calcSize = new Vector2(_objectSize.x, (_objectSize.x / _videoSize.x) * _videoSize.y);
- _borderUVSize = new Vector2((1 - (_calcSize.x / _objectSize.x)) * 0.5f, (1 - (_calcSize.y / _objectSize.y)) * 0.5f);
- _objectMaterial.SetFloat(SHADER_BORDER_U_WIDTH, _borderUVSize.x);
- _objectMaterial.SetFloat(SHADER_BORDER_V_WIDTH, _borderUVSize.y);
- yield return null;
- }
- }
- /// <summary>
- /// Show/Hide special video canvas borders in output texture
- /// </summary>
- private void ShowVideoCanvasBorder(bool state)
- {
- _objectMaterial.SetFloat(SHADER_BORDER_U_WIDTH, state ? 1 : 0);
- _objectMaterial.SetFloat(SHADER_BORDER_V_WIDTH, state ? 1 : 0);
- }
- private void OnPlayerImageReady(Texture2D image)
- {
- _videoSize = new Vector2(image.width, image.height);
- if (_updateCanvasRatioEnum == null)
- {
- _updateCanvasRatioEnum = UpdateVideoCanvasRatio();
- StartCoroutine(_updateCanvasRatioEnum);
- }
- }
- private void OnPlayerStopped()
- {
- if (!_mediaPlayer.Loop)
- {
- if (_updateCanvasRatioEnum != null)
- {
- StopCoroutine(_updateCanvasRatioEnum);
- _updateCanvasRatioEnum = null;
- }
- ShowVideoCanvasBorder(true);
- }
- }
- /// <summary>
- /// Get size in pixels of gameobject that have "MeshRenderer" component
- /// </summary>
- /// <param name="meshRenderer">Gameobject "MeshRenderer" component</param>
- /// <param name="camera">Main camera of current scene</param>
- /// <returns></returns>
- public static Vector2 GetPixelSizeOfMeshRenderer(MeshRenderer meshRenderer, Camera camera)
- {
- if (meshRenderer == null)
- return Vector2.zero;
- Vector3 posStart = camera.WorldToScreenPoint(new Vector3(meshRenderer.bounds.min.x, meshRenderer.bounds.min.y, meshRenderer.bounds.min.z));
- Vector3 posEnd = camera.WorldToScreenPoint(new Vector3(meshRenderer.bounds.max.x, meshRenderer.bounds.max.y, meshRenderer.bounds.min.z));
- float widthX = Mathf.Abs((posEnd.x - posStart.x));
- float widthY = Mathf.Abs((posEnd.y - posStart.y));
- return new Vector2((int)widthX, (int)widthY);
- }
- /// <summary>
- /// Get size in pixels of gameobject that have "RawImage" component
- /// </summary>
- /// <param name="rawImage">Gameobject "RawImage" component</param>
- /// <returns></returns>
- public static Vector2 GetPixelSizeOfRawImage(RawImage rawImage)
- {
- if (rawImage == null)
- return Vector2.zero;
- return new Vector2(rawImage.rectTransform.rect.width, rawImage.rectTransform.rect.height);
- }
- }
- }
|