TextureExtractor_WarpedImage.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Events;
  5. using System.Runtime.InteropServices;
  6. using System.IO;
  7. using System.Data.Common;
  8. namespace Imagine.WebAR
  9. {
  10. public class TextureExtractor_WarpedImage : MonoBehaviour
  11. {
  12. [DllImport("__Internal")] private static extern bool WebGLIsCameraStarted();
  13. [DllImport("__Internal")] private static extern void GetWebGLWarpedTexture(string targetId, int textureId, int resolution);
  14. private ARCamera arCamera;
  15. //[SerializeField] UnityEngine.UI.RawImage testRawImage, testRawImage2;
  16. private Texture2D warpedTexture;
  17. private int warpedTextureId;
  18. private enum TextureExtractorMode {EVERY_FRAME, MANUAL};
  19. [SerializeField] private TextureExtractorMode mode = TextureExtractorMode.EVERY_FRAME;
  20. [SerializeField] private string targetId;
  21. [SerializeField] private RenderTexture outputTexture;
  22. [SerializeField] private bool checkVisibility = false;
  23. [SerializeField] private Camera isVisibleCamera;
  24. [SerializeField] private MeshRenderer isVisibleRenderer;
  25. private bool isFullyVisibleInLastFrame = false;
  26. private bool isInitializing = false;
  27. [Tooltip("Use these events to check for full visibility before extracting the texture manually")]
  28. [SerializeField] private UnityEvent DidBecomeFullyVisible, DidBecomeObscured;
  29. void Start(){
  30. StartCoroutine(Initialize());
  31. }
  32. IEnumerator Initialize(){
  33. isInitializing = true;
  34. while(!WebGLIsCameraStarted()){
  35. Debug.Log("Unity Waiting for WebGLIsCameraStarted");
  36. yield return null;
  37. }
  38. Debug.Log("Unity WebGLIsCameraStarted");
  39. warpedTexture = new Texture2D(outputTexture.width, outputTexture.height);
  40. Debug.Log("Unity Initialized warpedTexture");
  41. warpedTextureId = (int)warpedTexture.GetNativeTexturePtr();
  42. Debug.Log("Unity Initialized warpedTextureId = " + warpedTextureId);
  43. }
  44. void OnDisable(){
  45. isFullyVisibleInLastFrame = false;
  46. isInitializing = false;
  47. DidBecomeObscured?.Invoke();
  48. }
  49. void Update(){
  50. if(mode == TextureExtractorMode.EVERY_FRAME){
  51. //Debug.Log("Unity Update EVERY_FRAME()");
  52. ExtractTexture();
  53. }
  54. if(checkVisibility && isVisibleCamera && isVisibleRenderer){
  55. var isFullyVisible = false;
  56. if(!isVisibleRenderer.gameObject.activeInHierarchy){
  57. isFullyVisible = false;
  58. DidBecomeObscured?.Invoke();
  59. return;
  60. }
  61. isFullyVisible = IsFullyVisibleInCamera();
  62. if(isFullyVisible && !isFullyVisibleInLastFrame){
  63. DidBecomeFullyVisible?.Invoke();
  64. }
  65. else if(!isFullyVisible && isFullyVisibleInLastFrame){
  66. DidBecomeObscured?.Invoke();
  67. }
  68. isFullyVisibleInLastFrame = isFullyVisible;
  69. }
  70. return;
  71. }
  72. public void ExtractTexture(){
  73. if(warpedTexture == null){
  74. if(!isInitializing){
  75. StartCoroutine(Initialize());
  76. }
  77. return;
  78. }
  79. //Debug.Log("Unity Update ExtractTexture()");
  80. var resolution = outputTexture.width;
  81. GetWebGLWarpedTexture(targetId, warpedTextureId, resolution);
  82. Graphics.Blit(warpedTexture, outputTexture);
  83. }
  84. bool IsFullyVisibleInCamera()
  85. {
  86. if (isVisibleRenderer && isVisibleCamera)
  87. {
  88. Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(isVisibleCamera);
  89. // Get the bounds of the MeshRenderer in world space
  90. Bounds bounds = isVisibleRenderer.bounds;
  91. // Calculate the vertices of the bounding box
  92. Vector3[] boundsVertices = new Vector3[8];
  93. boundsVertices[0] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z);
  94. boundsVertices[1] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, bounds.extents.z);
  95. boundsVertices[2] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, bounds.extents.z);
  96. boundsVertices[3] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, bounds.extents.z);
  97. boundsVertices[4] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, -bounds.extents.z);
  98. boundsVertices[5] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, -bounds.extents.z);
  99. boundsVertices[6] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, -bounds.extents.z);
  100. boundsVertices[7] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, -bounds.extents.z);
  101. // Check if all vertices are inside the camera's frustum
  102. for (int i = 0; i < 8; i++)
  103. {
  104. if (!GeometryUtility.TestPlanesAABB(frustumPlanes, new Bounds(boundsVertices[i], Vector3.zero)))
  105. {
  106. return false; // If any vertex is outside the frustum, return false
  107. }
  108. }
  109. return true;
  110. }
  111. return false;
  112. }
  113. // public GetBase64String(){
  114. // Texture2D tex = new Texture2D(outputTexture.width, outputTexture.height, TextureFormat.RGB24, false);
  115. // RenderTexture lastActive = RenderTexture.active
  116. // RenderTexture.active = outputTexture;
  117. // tex.ReadPixels(new Rect(0, 0, outputTexture.width, outputTexture.height), 0, 0);
  118. // RenderTexture.active = lastActive;
  119. // byte[] pngBytes = tex.EncodeToPNG();
  120. // Destroy(tex)
  121. // return "data:image/jpeg;base64," + System.Convert.ToBase64String(pngBytes);
  122. // }
  123. }
  124. }