//======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
using UnityEngine;
///
/// Renders the mesh generated by ZEDSpatialMappingManager in a second, hidden camera created at runtume.
/// This gets the wireframe style with no performance loss.
/// This script is very similar to how ZEDPlaneRenderer works for Plane Detection.
///
public class ZEDMeshRenderer : MonoBehaviour
{
private ZEDManager zedManager = null;
///
/// Reference to the hidden camera we create at runtime.
///
private Camera cam;
///
/// Target texture of the rendering done by the new camera.
///
private RenderTexture meshTex;
///
/// Checks if the spatial mapping has started.
///
private bool hasStarted = false;
///
/// Checks if the mesh requested is textured. If so, deativate the wireframe.
///
public bool isTextured = false;
///
/// Shader used to render the wireframe. Normally Mat_ZED_Wireframe_Video_Overlay.
///
private Shader shaderWireframe;
///
/// Reference to the ZEDRenderingPlane component of the camera we copy.
///
private ZEDRenderingPlane renderingPlane;
///
/// Create the Mesh Rendering pipe
///
public void Create()
{
Transform ObjParent = gameObject.transform;
int tries = 0;
while (zedManager == null && tries<5) {
if (ObjParent!=null)
zedManager= ObjParent.GetComponent ();
if (zedManager == null && ObjParent!=null)
ObjParent = ObjParent.parent;
tries++;
}
if (zedManager == null) {
return;
}
//Create the new GameObject and camera as a child of the corresponding ZED rig camera.
GameObject go = new GameObject("MeshCamera");
go.transform.parent = transform;
go.transform.localPosition = Vector3.zero;
go.transform.localRotation = Quaternion.identity;
go.transform.localScale = Vector3.one;
cam = go.AddComponent();
//go.hideFlags = HideFlags.HideInHierarchy;//This hides the new camera from scene view. Comment this out to see it in the hierarchy.
//Set the target texture to a new RenderTexture that will be passed to ZEDRenderingPlane for blending.
if (zedManager.zedCamera.IsCameraReady)
{
meshTex = new RenderTexture(zedManager.zedCamera.ImageWidth, zedManager.zedCamera.ImageHeight, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
meshTex.Create();
}
//Set the camera's parameters.
cam.enabled = false;
cam.cullingMask = (1 << zedManager.zedCamera.TagInvisibleToZED); //Layer set aside for planes and spatial mapping meshes.
cam.targetTexture = meshTex;
cam.nearClipPlane = 0.1f;
cam.farClipPlane = 500.0f;
cam.fieldOfView = zedManager.zedCamera.GetFOV() * Mathf.Rad2Deg;
cam.projectionMatrix = zedManager.zedCamera.Projection;
cam.backgroundColor = new Color(0, 0, 0, 0);
cam.clearFlags = CameraClearFlags.Color;
cam.renderingPath = RenderingPath.VertexLit;
cam.depth = 0;
cam.depthTextureMode = DepthTextureMode.None;
#if UNITY_5_6_OR_NEWER
cam.allowMSAA = false;
cam.allowHDR = false;
#endif
cam.useOcclusionCulling = false;
shaderWireframe = (Resources.Load("Materials/SpatialMapping/Mat_ZED_Wireframe_Video_Overlay") as Material).shader;
//Set the ZEDRenderingPlane blend texture to the one the new camera renders to.
renderingPlane = GetComponent();
renderingPlane.SetTextureOverlayMapping(meshTex);
renderingPlane.SetMeshRenderAvailable(false);
hasStarted = true;
}
///
/// Set the rendering available. Used when loading mesh
///
///
public void UpdateRenderingPlane(bool drawMesh)
{
renderingPlane.SetMeshRenderAvailable(drawMesh);
}
///
/// Unsubscribes from relevant events.
///
private void OnDisable()
{
hasStarted = false;
}
///
/// Renders the plane each frame, before cameras normally update, so the RenderTexture is ready to be blended.
///
void OnPreRender()
{
if (zedManager.IsStereoRig)
{
if (zedManager != null)
{
if (zedManager.IsSpatialMappingDisplay && hasStarted)
{
cam.enabled = true;
if (!isTextured)
{
GL.wireframe = true;
cam.RenderWithShader(shaderWireframe, "RenderType");
GL.wireframe = false;
}
else
{
cam.Render();
}
cam.enabled = false;
if (zedManager.SpatialMappingHasChunks)
renderingPlane.SetMeshRenderAvailable(true);
}
}
}
}
private void Update()
{
if (!zedManager.IsStereoRig)
{
if (zedManager != null)
{
if (zedManager.IsSpatialMappingDisplay && hasStarted)
{
cam.enabled = true;
if (!isTextured)
{
GL.wireframe = true;
cam.RenderWithShader(shaderWireframe, "RenderType");
GL.wireframe = false;
}
else
{
cam.Render();
}
cam.enabled = false;
if (zedManager.SpatialMappingHasChunks)
renderingPlane.SetMeshRenderAvailable(true);
}
}
}
}
///
/// Releases the target RenderTexture when the application quits.
///
private void OnApplicationQuit()
{
if (meshTex != null && meshTex.IsCreated())
{
meshTex.Release();
}
}
}