123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- //======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
- using UnityEngine;
- /// <summary>
- /// Displays the point cloud of the real world in front of the camera.
- /// Can be attached to any GameObject in a scene, but requires a ZEDManager component to exist somewhere.
- /// </summary>
- ///
- namespace sl
- {
- public class ZEDFusedPointCloudRenderer : MonoBehaviour
- {
- /// <summary>
- /// Instance of the ZEDManager interface
- /// </summary>
- public ZEDManager zedManager = null;
- /// <summary>
- /// Point size of the Fused Point cloud. If > 0, then disk shader will be used to generate spheres around points
- /// </summary>
- public float _pointSize = 0.001f;
- /// <summary>
- /// Fused point cloud resolution (sent to spatial mapping parameters)
- /// </summary>
- public float resolution = 0.5f;
- /// <summary>
- /// Fused point cloud range (sent to spatial mapping parameters)
- /// </summary>
- public float range = 5.0f;
- /// <summary>
- /// zed Camera controller by zedManager.
- /// </summary>
- private sl.ZEDCamera zed = null;
- /// <summary>
- /// Point Material
- /// </summary>
- private Material _pointMaterial;
- /// <summary>
- /// Disk material (sphere around point)
- /// </summary>
- private Material _diskMaterial;
-
- /// <summary>
- /// Array of points as point buffer (compute buffer). Send to shaders
- /// </summary>
- private ComputeBuffer _pointBuffer;
-
- /// <summary>
- /// Size of Vector4
- /// </summary>
- private const int elementSize = sizeof(float) * 4;
- /// <summary>
- /// Array of vertex points
- /// </summary>
- private Vector4[] vertPoints;
-
- private bool notStarted = true;
- private bool canUpdate = false;
- private float updateTime = 0;
- void Start()
- {
- if (zedManager == null)
- {
- zedManager = FindObjectOfType<ZEDManager>();
- if (ZEDManager.GetInstances().Count > 1) //We chose a ZED arbitrarily, but there are multiple cams present. Warn the user.
- {
- Debug.Log("Warning: " + gameObject.name + "'s zedManager was not specified, so the first available ZEDManager instance was " +
- "assigned. However, there are multiple ZEDManager's in the scene. It's recommended to specify which ZEDManager you want to " +
- "use to display a point cloud.");
- }
- }
- if (zedManager != null)
- zed = zedManager.zedCamera;
- if (_pointMaterial == null)
- {
- _pointMaterial = new Material(Resources.Load("Materials/PointCloud/Mat_ZED_FusedPC_Point") as Material);
- }
- if (_diskMaterial == null)
- {
- _diskMaterial = new Material(Resources.Load("Materials/PointCloud/Mat_ZED_FusedPC_Disk") as Material);
- }
-
- _diskMaterial.hideFlags = HideFlags.DontSave;
- _pointMaterial.hideFlags = HideFlags.DontSave;
- zedManager.OnGrab += startMap;
- }
- /// <summary>
- /// Start Map linked to grab callback. Wait for one frame to start point cloud fusion
- /// </summary>
- private void startMap()
- {
- if (zed != null && notStarted)
- {
- zed.EnableSpatialMapping(sl.SPATIAL_MAP_TYPE.FUSED_POINT_CLOUD, resolution, range);
- notStarted = false;
- canUpdate = true;
- }
-
- }
- void OnDestroy()
- {
- canUpdate = false;
-
- if (zed != null)
- zed.DisableSpatialMapping();
- if (_pointBuffer != null)
- {
- _pointBuffer.Release();
- _pointBuffer = null;
- }
-
- if (_pointMaterial != null)
- {
- if (Application.isPlaying)
- {
- Destroy(_pointMaterial);
- Destroy(_diskMaterial);
- }
- else
- {
- DestroyImmediate(_pointMaterial);
- DestroyImmediate(_diskMaterial);
- }
- }
- }
- /// <summary>
- /// Update to request Map every 1 second
- /// </summary>
- void Update()
- {
- if (zed.IsCameraReady && canUpdate) //Don't do anything unless the ZED has been initialized.
- {
- updateTime += Time.deltaTime;
- if (updateTime >= 1)
- {
- zed.RequestMesh();
- updateTime = 0;
- }
- }
- }
- /// <summary>
- /// On Render Fct
- /// </summary>
- void OnRenderObject()
- {
- if (zed != null)
- {
- int nbPoints = 0;
- zed.UpdateFusedPointCloud(ref nbPoints);
- if (nbPoints > 0)
- {
- vertPoints = new Vector4[nbPoints];
- zed.RetrieveFusedPointCloud(vertPoints);
- if (_pointBuffer != null)
- {
- _pointBuffer.Release();
- _pointBuffer = null;
- }
- _pointBuffer = new ComputeBuffer(nbPoints, elementSize);
- _pointBuffer.SetData(vertPoints);
- }
- }
- if (_pointBuffer != null)
- {
- //Draw with Point shader
- if (_pointSize == 0)
- {
- _pointMaterial.SetPass(0);
- _pointMaterial.SetMatrix("_Transform", transform.localToWorldMatrix);
- _pointMaterial.SetBuffer("_PointBuffer", _pointBuffer);
- #if UNITY_2019_1_OR_NEWER
- Graphics.DrawProceduralNow(MeshTopology.Points, _pointBuffer.count, 1);
- #else
- Graphics.DrawProcedural(MeshTopology.Points, _pointBuffer.count, 1);
- #endif
- }
- //Draw with Disk shader
- else
- {
- _diskMaterial.SetPass(0);
- _diskMaterial.SetMatrix("_Transform", transform.localToWorldMatrix);
- _diskMaterial.SetBuffer("_PointBuffer", _pointBuffer);
- _diskMaterial.SetFloat("_PointSize", _pointSize);
- #if UNITY_2019_1_OR_NEWER
- Graphics.DrawProceduralNow(MeshTopology.Points, _pointBuffer.count, 1);
- #else
- Graphics.DrawProcedural(MeshTopology.Points, _pointBuffer.count, 1);
- #endif
- }
- }
- }
- }
- }
|