Exemple #1
0
        /// <summary>
        /// Returns the node that the point belongs to
        /// </summary>
        /// <param name="rPoint"></param>
        /// <returns></returns>
        public MeshOctreeNode ClosestNode(Vector3 rPoint)
        {
            MeshOctreeNode lClosestNode = null;

            if (rPoint.x + EPSILON < Min.x)
            {
                return(lClosestNode);
            }
            if (rPoint.x - EPSILON > Max.x)
            {
                return(lClosestNode);
            }
            if (rPoint.y + EPSILON < Min.y)
            {
                return(lClosestNode);
            }
            if (rPoint.y - EPSILON > Max.y)
            {
                return(lClosestNode);
            }
            if (rPoint.z + EPSILON < Min.z)
            {
                return(lClosestNode);
            }
            if (rPoint.z - EPSILON > Max.z)
            {
                return(lClosestNode);
            }

            if (Children == null)
            {
                lClosestNode = this;
            }
            else
            {
                for (int i = 0; i < 8; i++)
                {
                    MeshOctreeNode lTestClosestNode = Children[i].ClosestNode(rPoint);
                    if (lTestClosestNode != null)
                    {
                        if (lClosestNode == null || lTestClosestNode.Size.sqrMagnitude < lClosestNode.Size.sqrMagnitude)
                        {
                            lClosestNode = lTestClosestNode;
                        }
                    }
                }
            }

            return(lClosestNode);
        }
        /// <summary>
        /// Initializes the octree with the specific mesh
        /// </summary>
        /// <param name="rMesh"></param>
        public void Initialize(Mesh rMesh)
        {
            if (rMesh == null) { return; }

            Name = rMesh.name;

            float lSize = Mathf.Max(rMesh.bounds.size.x, Mathf.Max(rMesh.bounds.size.y, rMesh.bounds.size.z));

            Root = new MeshOctreeNode(rMesh.bounds.center, new Vector3(lSize, lSize, lSize));
            Root.MeshVertices = rMesh.vertices;
            Root.MeshTriangles = rMesh.triangles;

            // Build the octree with the triangles
            int lTriangleCount = Root.MeshTriangles.Length / 3;
            for (int i = 0; i < lTriangleCount; i++)
            {
                Root.Insert(i * 3);
            }
        }
Exemple #3
0
        /// <summary>
        /// Split the octree and distribute it's values
        /// </summary>
        public virtual void Split()
        {
            Vector3 lHalfSize    = Size * 0.5f;
            Vector3 lQuarterSize = lHalfSize * 0.5f;

            // Split into eight children
            Children    = new MeshOctreeNode[8];
            Children[0] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y - lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom left back
            Children[1] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y - lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom right back
            Children[2] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y + lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top left back
            Children[3] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y + lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top right back
            Children[4] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y - lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom left forward
            Children[5] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y - lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom right forward
            Children[6] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y + lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top left forward
            Children[7] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y + lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top right forward

            // Distribute values to the children
            for (int lIndex = 0; lIndex < TriangleIndexes.Count; lIndex++)
            {
                //float lTriangleRadius;
                Vector3 lTriangleCenter;
                Vector3 lTriangleMin;
                Vector3 lTriangleMax;
                int     lTriangleIndex = TriangleIndexes[lIndex];

                //GetTriangleBounds(lTriangleIndex, out lTriangleCenter, out lTriangleRadius);
                GetTriangleBounds(lTriangleIndex, out lTriangleCenter, out lTriangleMin, out lTriangleMax);

                for (int i = 0; i < 8; i++)
                {
                    //Children[i].Insert(lTriangleIndex, lTriangleCenter, lTriangleRadius);
                    Children[i].Insert(lTriangleIndex, lTriangleCenter, lTriangleMin, lTriangleMax);
                }
            }

            // Since we have children, clear out values
            TriangleIndexes.Clear();
            TriangleIndexes = null;
        }
Exemple #4
0
        /// <summary>
        /// Initializes the octree with the specific mesh
        /// </summary>
        /// <param name="rMesh"></param>
        public void Initialize(Mesh rMesh)
        {
            if (rMesh == null)
            {
                return;
            }

            Name = rMesh.name;

            float lSize = Mathf.Max(rMesh.bounds.size.x, Mathf.Max(rMesh.bounds.size.y, rMesh.bounds.size.z));

            Root = new MeshOctreeNode(rMesh.bounds.center, new Vector3(lSize, lSize, lSize));
            Root.MeshVertices  = rMesh.vertices;
            Root.MeshTriangles = rMesh.triangles;

            // Build the octree with the triangles
            int lTriangleCount = Root.MeshTriangles.Length / 3;

            for (int i = 0; i < lTriangleCount; i++)
            {
                Root.Insert(i * 3);
            }
        }
        /// <summary>
        /// Split the octree and distribute it's values
        /// </summary>
        public virtual void Split()
        {
            Vector3 lHalfSize = Size * 0.5f;
            Vector3 lQuarterSize = lHalfSize * 0.5f;

            // Split into eight children
            Children = new MeshOctreeNode[8];
            Children[0] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y - lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom left back
            Children[1] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y - lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom right back
            Children[2] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y + lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top left back
            Children[3] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y + lQuarterSize.y, Center.z - lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top right back
            Children[4] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y - lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom left forward
            Children[5] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y - lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // bottom right forward
            Children[6] = new MeshOctreeNode(Center.x - lQuarterSize.x, Center.y + lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top left forward
            Children[7] = new MeshOctreeNode(Center.x + lQuarterSize.x, Center.y + lQuarterSize.y, Center.z + lQuarterSize.z, lHalfSize, MeshVertices, MeshTriangles); // top right forward

            // Distribute values to the children
            for (int lIndex = 0; lIndex < TriangleIndexes.Count; lIndex++)
            {
                //float lTriangleRadius;
                Vector3 lTriangleCenter;
                Vector3 lTriangleMin;
                Vector3 lTriangleMax;
                int lTriangleIndex = TriangleIndexes[lIndex];               
                
                //GetTriangleBounds(lTriangleIndex, out lTriangleCenter, out lTriangleRadius);
                GetTriangleBounds(lTriangleIndex, out lTriangleCenter, out lTriangleMin, out lTriangleMax);

                for (int i = 0; i < 8; i++)
                {
                    //Children[i].Insert(lTriangleIndex, lTriangleCenter, lTriangleRadius);
                    Children[i].Insert(lTriangleIndex, lTriangleCenter, lTriangleMin, lTriangleMax);
                }
            }

            // Since we have children, clear out values
            TriangleIndexes.Clear();
            TriangleIndexes = null;
        }
Exemple #6
0
        /// <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;
        }