ZEDPointCloudManager.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. //======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
  2. using UnityEngine;
  3. /// <summary>
  4. /// Displays the point cloud of the real world in front of the camera.
  5. /// Can be attached to any GameObject in a scene, but requires a ZEDManager component to exist somewhere.
  6. /// </summary>
  7. public class ZEDPointCloudManager : MonoBehaviour
  8. {
  9. /// <summary>
  10. /// Set to a camera if you do not want that camera to see the point cloud.
  11. /// </summary>
  12. [Tooltip("Set to a camera if you do not want that camera to see the point cloud. ")]
  13. public Camera hiddenObjectFromCamera;
  14. /// <summary>
  15. /// Number of points displayed. Usually equal to the width * height of the ZED's resolution (eg. 1280 * 720).
  16. /// </summary>
  17. private int numberPoints = 0;
  18. /// <summary>
  19. /// Instance of the ZEDManager interface
  20. /// </summary>
  21. public ZEDManager zedManager = null;
  22. /// <summary>
  23. /// zed Camera controller by zedManager
  24. /// </summary>
  25. private sl.ZEDCamera zed = null;
  26. /// <summary>
  27. /// Texture that holds the 3D position of the points.
  28. /// </summary>
  29. private Texture2D XYZTexture;
  30. /// <summary>
  31. /// Texture that holds the colors of each point.
  32. /// </summary>
  33. private Texture2D colorTexture;
  34. /// <summary>
  35. /// Temporary copy/buffer of the XYZTexture to stop the point cloud in a defined moment.
  36. /// </summary>
  37. private RenderTexture XYZTextureCopy = null;
  38. /// <summary>
  39. /// Temporary copy/buffer of the ColorTexture to stop the point cloud in a defined moment.
  40. /// </summary>
  41. private RenderTexture ColorTextureCopy = null;
  42. /// <summary>
  43. /// Material used to display the point cloud. Usually Mat_ZED_PointCloud.
  44. /// </summary>
  45. public Material mat;
  46. /// <summary>
  47. /// Cached property index of _Position shader property, so we only look it up once. Do not use.
  48. /// </summary>
  49. private static int? _positionid;
  50. /// <summary>
  51. /// Returns the property index of the _Position property, and looks it up if it hasn't been looked up yet.
  52. /// </summary>
  53. private static int positionID
  54. {
  55. get
  56. {
  57. if (_positionid == null)
  58. {
  59. _positionid = Shader.PropertyToID("_Position");
  60. }
  61. return (int)_positionid;
  62. }
  63. }
  64. /// <summary>
  65. /// Cached property index of the _ColorTex shader property, so we only look it up once. Use colorTexID instead.
  66. /// </summary>
  67. private static int? _colortexid;
  68. /// <summary>
  69. /// Returns the property index of the _ColorTex property, which is the RGB color texture from the ZED.
  70. /// </summary>
  71. private static int colorTexID
  72. {
  73. get
  74. {
  75. if (_colortexid == null)
  76. {
  77. _colortexid = Shader.PropertyToID("_ColorTex");
  78. }
  79. return (int)_colortexid;
  80. }
  81. }
  82. /// <summary>
  83. /// Cached property index of _XYZTex shader property, so we only look it up once. Use xyzTexID instead.
  84. /// </summary>
  85. private static int? _xyztexid;
  86. /// <summary>
  87. /// Returns the property index of the _XYZTex property, which is the XYZ position of each pixel relative to the ZED.
  88. /// </summary>
  89. private static int xyzTexID
  90. {
  91. get
  92. {
  93. if (_xyztexid == null)
  94. {
  95. _xyztexid = Shader.PropertyToID("_XYZTex");
  96. }
  97. return (int)_xyztexid;
  98. }
  99. }
  100. /// <summary>
  101. /// Whether the point cloud should be visible or not.
  102. /// </summary>
  103. [Tooltip("Whether the point cloud should be visible or not. ")]
  104. public bool display = true;
  105. /// <summary>
  106. /// Whether to update the point cloud.
  107. /// If false, the point cloud will display the content of the temp textures from the last update.
  108. /// </summary>
  109. [Tooltip("Whether to update the point cloud. If false, the point cloud will display the content of the temp textures from the last update. ")]
  110. public bool update = true;
  111. /// <summary>
  112. /// Flag to check if the update has changed state.
  113. /// </summary>
  114. private bool previousUpdate = true;
  115. void Start()
  116. {
  117. if(zedManager == null)
  118. {
  119. zedManager = FindObjectOfType<ZEDManager>();
  120. if(ZEDManager.GetInstances().Count > 1) //We chose a ZED arbitrarily, but there are multiple cams present. Warn the user.
  121. {
  122. Debug.Log("Warning: " + gameObject.name + "'s zedManager was not specified, so the first available ZEDManager instance was " +
  123. "assigned. However, there are multiple ZEDManager's in the scene. It's recommended to specify which ZEDManager you want to " +
  124. "use to display a point cloud.");
  125. }
  126. }
  127. if (zedManager != null)
  128. zed = zedManager.zedCamera;
  129. }
  130. // Update is called once per frame
  131. void Update()
  132. {
  133. if (zed.IsCameraReady) //Don't do anything unless the ZED has been initialized.
  134. {
  135. if (numberPoints == 0)
  136. {
  137. //Create the textures. These will be updated automatically by the ZED.
  138. //We'll copy them each frame into XYZTextureCopy and ColorTextureCopy, which will be the ones actually displayed.
  139. XYZTexture = zed.CreateTextureMeasureType(sl.MEASURE.XYZ);
  140. colorTexture = zed.CreateTextureImageType(sl.VIEW.LEFT);
  141. numberPoints = zed.ImageWidth * zed.ImageHeight;
  142. //Load and set the material properties.
  143. if (mat == null)
  144. {
  145. mat = new Material(Resources.Load("Materials/PointCloud/Mat_ZED_PointCloud") as Material);
  146. }
  147. if (mat != null)
  148. {
  149. //mat.SetTexture("_XYZTex", XYZTexture);
  150. mat.SetTexture(xyzTexID, XYZTexture);
  151. //mat.SetTexture("_ColorTex", colorTexture);
  152. mat.SetTexture(colorTexID, colorTexture);
  153. }
  154. }
  155. //If stop updated, create new render texture and fill them with the textures from the ZED.
  156. // These textures will be displayed as they are not updated
  157. if (!update && previousUpdate != update)
  158. {
  159. if (XYZTextureCopy == null)
  160. {
  161. XYZTextureCopy = new RenderTexture(XYZTexture.width, XYZTexture.height, 0, RenderTextureFormat.ARGBFloat);
  162. }
  163. if (ColorTextureCopy == null)
  164. {
  165. ColorTextureCopy = new RenderTexture(colorTexture.width, colorTexture.height, 0, RenderTextureFormat.ARGB32);
  166. }
  167. //Copy the new textures into the buffers.
  168. Graphics.Blit(XYZTexture, XYZTextureCopy);
  169. Graphics.Blit(colorTexture, ColorTextureCopy);
  170. if (mat != null)
  171. {
  172. //mat.SetTexture("_XYZTex", XYZTextureCopy);
  173. mat.SetTexture(xyzTexID, XYZTextureCopy);
  174. //mat.SetTexture("_ColorTex", ColorTextureCopy);
  175. mat.SetTexture(colorTexID, ColorTextureCopy);
  176. }
  177. }
  178. //Send the textures to the material/shader.
  179. if (update && previousUpdate != update && mat != null)
  180. {
  181. //mat.SetTexture("_XYZTex", XYZTexture);
  182. mat.SetTexture(xyzTexID, XYZTexture);
  183. //mat.SetTexture("_ColorTex", colorTexture);
  184. mat.SetTexture(colorTexID, colorTexture);
  185. }
  186. previousUpdate = update;
  187. }
  188. }
  189. void OnApplicationQuit()
  190. {
  191. //Free up memory.
  192. mat = null;
  193. if (XYZTextureCopy != null)
  194. {
  195. XYZTextureCopy.Release();
  196. }
  197. if (ColorTextureCopy != null)
  198. {
  199. ColorTextureCopy.Release();
  200. }
  201. }
  202. void OnRenderObject()
  203. {
  204. if (mat != null)
  205. {
  206. if (hiddenObjectFromCamera == Camera.current) return;
  207. if (!display) return; //Don't draw anything if the user doesn't want to.
  208. //mat.SetMatrix("_Position", transform.localToWorldMatrix);
  209. mat.SetMatrix(positionID, transform.localToWorldMatrix);
  210. mat.SetPass(0);
  211. #if UNITY_2019_1_OR_NEWER
  212. Graphics.DrawProceduralNow(MeshTopology.Points, 1, numberPoints);
  213. #else
  214. Graphics.DrawProcedural(MeshTopology.Points, 1, numberPoints);
  215. #endif
  216. }
  217. }
  218. }