/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal.NRExamples { using NRKernal; using System.Collections; using System.Collections.Generic; using UnityEngine; /// A polygon plane visualizer. public class PolygonPlaneVisualizer : NRTrackableBehaviour { /// The material. public Material Material; /// The renderer. private MeshRenderer m_Renderer; /// Specifies the filter. private MeshFilter m_Filter; /// The collider. private MeshCollider m_Collider; /// List of positions. List m_PosList = new List(); /// The plane mesh. Mesh m_PlaneMesh = null; #if UNITY_EDITOR /// The vectors data editor. [SerializeField] private Vector3[] VectorsDataEditor = new Vector3[4]; /// Gets boundary polygon. /// The tran. /// List of polygons. public void GetBoundaryPolygon(Transform tran, List polygonList) { polygonList.Clear(); var unityWorldTPlane = Matrix4x4.TRS(tran.position, tran.rotation, Vector3.one); for (int i = 0; i < VectorsDataEditor.Length; i++) { polygonList.Add(unityWorldTPlane.MultiplyPoint3x4(VectorsDataEditor[i])); } } #endif void Start() { StartCoroutine(UpdateMesh()); } /// Updates this object. private IEnumerator UpdateMesh() { WaitForSeconds wait = new WaitForSeconds(1f / 5); while (true) { yield return wait; #if UNITY_EDITOR var center = new Pose(transform.position, transform.rotation); GetBoundaryPolygon(transform, m_PosList); #else var center = Trackable.GetCenterPose(); ((NRTrackablePlane)Trackable).GetBoundaryPolygon(m_PosList); #endif this.DrawFromCenter(center, m_PosList); #if !UNITY_EDITOR if (Trackable.GetTrackingState() == TrackingState.Stopped) { Destroy(gameObject); } #endif } } /// Draw from center. /// The center pose. /// The vectors. private void DrawFromCenter(Pose centerPose, List vectors) { if (vectors == null || vectors.Count < 3) { return; } var center = centerPose.position; Vector3[] vertices3D = new Vector3[vectors.Count + 1]; vertices3D[0] = transform.InverseTransformPoint(center); for (int i = 1; i < vectors.Count + 1; i++) { vertices3D[i] = transform.InverseTransformPoint(vectors[i - 1]); } int[] triangles = GenerateTriangles(vectors); if (m_PlaneMesh == null) { m_PlaneMesh = new Mesh(); } m_PlaneMesh.vertices = vertices3D; m_PlaneMesh.triangles = triangles; if (m_Renderer == null) { m_Renderer = gameObject.GetComponent(); m_Renderer.material = Material; var planeInVector_1 = vertices3D[0] - vertices3D[1]; var planeInVector_2 = vertices3D[1] - vertices3D[2]; m_Renderer.material.SetVector("_PlaneIn", planeInVector_1); m_Renderer.material.SetVector("_PlaneNormal", Vector3.Cross(planeInVector_1, planeInVector_2)); } if (m_Filter == null) { m_Filter = gameObject.GetComponent(); } m_Filter.mesh = m_PlaneMesh; if (m_Collider == null) { m_Collider = gameObject.GetComponent(); } m_Collider.sharedMesh = m_PlaneMesh; } public static int[] GenerateTriangles(List posList) { List indices = new List(); for (int i = 0; i < posList.Count; i++) { if (i != posList.Count - 1) { indices.Add(0); indices.Add(i + 1); indices.Add(i + 2); } else { indices.Add(0); indices.Add(i + 1); indices.Add(1); } } return indices.ToArray(); } } }