/// <summary> /// Run before the game starts updating /// </summary> public void Start() { if (ParseOnStart) { Stopwatch lTimer = new Stopwatch(); lTimer.Start(); Mesh lMesh = ExtractMesh(); if (lMesh != null) { int lID = lMesh.GetInstanceID(); if (lMesh.isReadable) { if (!MeshExt.MeshOctrees.ContainsKey(lID)) { MeshOctree lMeshOctree = new MeshOctree(lMesh); MeshExt.MeshOctrees.Add(lID, lMeshOctree); MeshExt.MeshParseTime.Add(lID, 0f); } } } lTimer.Stop(); ParseTime = lTimer.ElapsedTicks / (float)TimeSpan.TicksPerSecond; #if UNITY_EDITOR if (ShowDebug) { UnityEngine.Debug.Log(string.Format("{0} mesh parsed in {1:f5} seconds", gameObject.name, ParseTime)); } #endif } }
/// <summary> /// Run before the game starts updating /// </summary> public void Start() { if (ParseOnStart) { Stopwatch lTimer = new Stopwatch(); lTimer.Start(); Mesh lMesh = ExtractMesh(); if (lMesh != null) { int lID = lMesh.GetInstanceID(); if (lMesh.isReadable) { if (!MeshExt.MeshOctrees.ContainsKey(lID)) { MeshOctree lMeshOctree = new MeshOctree(lMesh); MeshExt.MeshOctrees.Add(lID, lMeshOctree); MeshExt.MeshParseTime.Add(lID, 0f); } } } lTimer.Stop(); ParseTime = lTimer.ElapsedTicks / (float)TimeSpan.TicksPerSecond; } }
/// <summary> /// Given a mesh, cycle through it and look for the nearest vertex. We'll use this /// as a starting point for figuring out the closest point /// </summary> /// <param name="rPoint"></param> /// <param name="rTransform"></param> /// <param name="rMesh"></param> /// <returns></returns> public static Vector3 ClosestPoint(Vector3 rPoint, float rRadius, Transform rTransform, Mesh rMesh) { MeshOctree lMeshOctree = null; int lID = rMesh.GetInstanceID(); if (MeshOctrees.ContainsKey(lID)) { lMeshOctree = MeshOctrees[lID]; } else { Stopwatch lTimer = new Stopwatch(); lTimer.Start(); lMeshOctree = new MeshOctree(rMesh); lTimer.Stop(); MeshOctrees.Add(lID, lMeshOctree); MeshParseTime.Add(lID, lTimer.ElapsedTicks / (float)TimeSpan.TicksPerSecond); } //DebugTransform = rTransform; //DebugDraw.DrawSphereMesh(rPoint, 0.05f, Color.green, 1f); // Move the point to local space Vector3 lLocalPoint = rTransform.InverseTransformPoint(rPoint); // Now that we're in the root, find the closest point Vector3 lClosestPoint = MeshOctrees[lID].ClosestPoint(lLocalPoint, rRadius); if (lClosestPoint.x == float.MaxValue) { lClosestPoint = Vector3.zero; } // Move the point to world space if (lClosestPoint.sqrMagnitude != 0f) { lClosestPoint = rTransform.TransformPoint(lClosestPoint); //DebugDraw.DrawSphereMesh(lClosestPoint, 0.05f, Color.red, 1f); } // Return the world space point return(lClosestPoint); }
/// <summary> /// Run before the game starts updating /// </summary> public void Start() { if (ParseOnStart) { Mesh lMesh = ExtractMesh(); if (lMesh != null) { int lID = lMesh.GetInstanceID(); if (lMesh.isReadable) { if (!MeshExt.MeshOctrees.ContainsKey(lID)) { MeshOctree lMeshOctree = new MeshOctree(lMesh); MeshExt.MeshOctrees.Add(lID, lMeshOctree); } } } } }
/// <summary> /// Given a mesh, cycle through it and look for the nearest vertex. We'll use this /// as a starting point for figuring out the closest point /// </summary> /// <param name="rPoint"></param> /// <param name="rTransform"></param> /// <param name="rMesh"></param> /// <returns></returns> public static Vector3 ClosestPoint(Vector3 rPoint, float rRadius, Transform rTransform, Mesh rMesh) { MeshOctree lMeshOctree = null; int lID = rMesh.GetInstanceID(); if (MeshOctrees.ContainsKey(lID)) { lMeshOctree = MeshOctrees[lID]; } else { lMeshOctree = new MeshOctree(rMesh); MeshOctrees.Add(lID, lMeshOctree); } //DebugTransform = rTransform; //DebugDraw.DrawSphereMesh(rPoint, 0.05f, Color.green, 1f); // Move the point to local space Vector3 lLocalPoint = rTransform.InverseTransformPoint(rPoint); // Now that we're in the root, find the closest point Vector3 lClosestPoint = MeshOctrees[lID].ClosestPoint(lLocalPoint, rRadius); if (lClosestPoint.x == float.MaxValue) { lClosestPoint = Vector3.zero; } // Move the point to world space if (lClosestPoint.sqrMagnitude != 0f) { lClosestPoint = rTransform.TransformPoint(lClosestPoint); //DebugDraw.DrawSphereMesh(lClosestPoint, 0.05f, Color.red, 1f); } // Return the world space point return lClosestPoint; }
/// <summary> /// Renders the octree to the scene /// </summary> public void OnSceneGUI() { if (!RenderOctree && !RenderMesh && !RenderTestNode && !RenderTestTriangle) { return; } Color lHandlesColor = Handles.color; if (MeshOctree == null || MeshOctree.Root == null) { Stopwatch lTimer = new Stopwatch(); lTimer.Start(); Mesh lMesh = ExtractMesh(); if (lMesh != null) { MeshOctree = new MeshOctree(lMesh); } lTimer.Stop(); ParseTime = lTimer.ElapsedTicks / (float)TimeSpan.TicksPerSecond; } if (MeshOctree != null && MeshOctree.Root != null) { if (RenderOctree) { MeshOctree.OnSceneGUI(transform); } if (RenderMesh) { Handles.color = new Color(0f, 1f, 0f, 0.5f); int[] lTriangles = MeshOctree.Root.MeshTriangles; Vector3[] lVertices = MeshOctree.Root.MeshVertices; int lTriangleCount = lTriangles.Length / 3; for (int i = 0; i < lTriangleCount; i++) { int lIndex = i * 3; Vector3 lVertex1 = transform.TransformPoint(lVertices[lTriangles[lIndex]]); Vector3 lVertex2 = transform.TransformPoint(lVertices[lTriangles[lIndex + 1]]); Vector3 lVertex3 = transform.TransformPoint(lVertices[lTriangles[lIndex + 2]]); Handles.DrawLine(lVertex1, lVertex2); Handles.DrawLine(lVertex2, lVertex3); Handles.DrawLine(lVertex3, lVertex1); } } if (RenderTestTriangle) { Handles.color = Color.magenta; Vector3 lLocalPoint = transform.InverseTransformPoint(TestTransform != null ? TestTransform.position : TestPosition); // First, let's see if our point is inside the root node. If not, make it so. if (!MeshOctree.ContainsPoint(lLocalPoint)) { if (lLocalPoint.x < MeshOctree.Root.Min.x) { lLocalPoint.x = MeshOctree.Root.Min.x; } else if (lLocalPoint.x > MeshOctree.Root.Max.x) { lLocalPoint.x = MeshOctree.Root.Max.x; } if (lLocalPoint.y < MeshOctree.Root.Min.y) { lLocalPoint.y = MeshOctree.Root.Min.y; } else if (lLocalPoint.y > MeshOctree.Root.Max.y) { lLocalPoint.y = MeshOctree.Root.Max.y; } if (lLocalPoint.z < MeshOctree.Root.Min.z) { lLocalPoint.z = MeshOctree.Root.Min.z; } else if (lLocalPoint.z > MeshOctree.Root.Max.z) { lLocalPoint.z = MeshOctree.Root.Max.z; } } // Grab the closest triangle int lTriangleIndex = MeshOctree.Root.ClosestTriangle(lLocalPoint); if (lTriangleIndex >= 0) { Vector3 lVertex1 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex]]); Vector3 lVertex2 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 1]]); Vector3 lVertex3 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 2]]); Handles.DrawLine(lVertex1, lVertex2); Handles.DrawLine(lVertex2, lVertex3); Handles.DrawLine(lVertex3, lVertex1); #if UNITY_4 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 Handles.SphereCap(0, transform.TransformPoint(lLocalPoint), Quaternion.identity, 0.05f); #else Handles.SphereHandleCap(0, transform.TransformPoint(lLocalPoint), Quaternion.identity, 0.05f, EventType.Layout | EventType.Repaint); #endif } } if (RenderTestNode) { Vector3 lLocalPoint = transform.InverseTransformPoint(TestTransform != null ? TestTransform.position : TestPosition); // Grab the closest node MeshOctreeNode lNode = MeshOctree.Root.ClosestNode(lLocalPoint); if (lNode != null) { Handles.color = Color.white; lNode.OnSceneGUI(transform); if (lNode.TriangleIndexes != null) { Handles.color = Color.magenta; for (int i = 0; i < lNode.TriangleIndexes.Count; i++) { int lTriangleIndex = lNode.TriangleIndexes[i]; Vector3 lVertex1 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex]]); Vector3 lVertex2 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 1]]); Vector3 lVertex3 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 2]]); Handles.DrawLine(lVertex1, lVertex2); Handles.DrawLine(lVertex2, lVertex3); Handles.DrawLine(lVertex3, lVertex1); } } } } } Handles.color = lHandlesColor; }
/// <summary> /// Renders the octree to the scene /// </summary> public void OnSceneGUI() { Color lHandlesColor = Handles.color; if (MeshOctree == null || MeshOctree.Root == null) { Mesh lMesh = ExtractMesh(); if (lMesh != null) { MeshOctree = new MeshOctree(lMesh); } } if (MeshOctree != null && MeshOctree.Root != null) { if (RenderOctree) { MeshOctree.OnSceneGUI(transform); } if (RenderMesh) { Handles.color = new Color(0f, 1f, 0f, 0.5f); int[] lTriangles = MeshOctree.Root.MeshTriangles; Vector3[] lVertices = MeshOctree.Root.MeshVertices; int lTriangleCount = lTriangles.Length / 3; for (int i = 0; i < lTriangleCount; i++) { int lIndex = i * 3; Vector3 lVertex1 = transform.TransformPoint(lVertices[lTriangles[lIndex]]); Vector3 lVertex2 = transform.TransformPoint(lVertices[lTriangles[lIndex + 1]]); Vector3 lVertex3 = transform.TransformPoint(lVertices[lTriangles[lIndex + 2]]); Handles.DrawLine(lVertex1, lVertex2); Handles.DrawLine(lVertex2, lVertex3); Handles.DrawLine(lVertex3, lVertex1); } } if (RenderTestTriangle) { Handles.color = Color.magenta; Vector3 lLocalPoint = transform.InverseTransformPoint(TestTransform != null ? TestTransform.position : TestPosition); // First, let's see if our point is inside the root node. If not, make it so. if (!MeshOctree.ContainsPoint(lLocalPoint)) { if (lLocalPoint.x < MeshOctree.Root.Min.x) { lLocalPoint.x = MeshOctree.Root.Min.x; } else if (lLocalPoint.x > MeshOctree.Root.Max.x) { lLocalPoint.x = MeshOctree.Root.Max.x; } if (lLocalPoint.y < MeshOctree.Root.Min.y) { lLocalPoint.y = MeshOctree.Root.Min.y; } else if (lLocalPoint.y > MeshOctree.Root.Max.y) { lLocalPoint.y = MeshOctree.Root.Max.y; } if (lLocalPoint.z < MeshOctree.Root.Min.z) { lLocalPoint.z = MeshOctree.Root.Min.z; } else if (lLocalPoint.z > MeshOctree.Root.Max.z) { lLocalPoint.z = MeshOctree.Root.Max.z; } } // Grab the closest triangle int lTriangleIndex = MeshOctree.Root.ClosestTriangle(lLocalPoint); if (lTriangleIndex >= 0) { Vector3 lVertex1 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex]]); Vector3 lVertex2 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 1]]); Vector3 lVertex3 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 2]]); Handles.DrawLine(lVertex1, lVertex2); Handles.DrawLine(lVertex2, lVertex3); Handles.DrawLine(lVertex3, lVertex1); Handles.SphereCap(0, transform.TransformPoint(lLocalPoint), Quaternion.identity, 0.05f); } } if (RenderTestNode) { Vector3 lLocalPoint = transform.InverseTransformPoint(TestTransform != null ? TestTransform.position : TestPosition); // Grab the closest node MeshOctreeNode lNode = MeshOctree.Root.ClosestNode(lLocalPoint); if (lNode != null) { Handles.color = Color.white; lNode.OnSceneGUI(transform); if (lNode.TriangleIndexes != null) { Handles.color = Color.magenta; for (int i = 0; i < lNode.TriangleIndexes.Count; i++) { int lTriangleIndex = lNode.TriangleIndexes[i]; Vector3 lVertex1 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex]]); Vector3 lVertex2 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 1]]); Vector3 lVertex3 = transform.TransformPoint(MeshOctree.Root.MeshVertices[MeshOctree.Root.MeshTriangles[lTriangleIndex + 2]]); Handles.DrawLine(lVertex1, lVertex2); Handles.DrawLine(lVertex2, lVertex3); Handles.DrawLine(lVertex3, lVertex1); } } } } } Handles.color = lHandlesColor; }