Esempio n. 1
0
        public int GetNodeFaceDataLength(OctreeChild n)
        {
            int l = 0;

            if (n is OctreeNode)
            {
                for (int i = 0; i < 8; i++)
                {
                    l += GetNodeFaceDataLength((n as OctreeNode).Children[i]);
                }
            }
            else
            {
                if (n is OctreeLeaf)
                {
                    l += GetLeafFaceDataLength(n as OctreeLeaf);
                }
                else
                {
                    l += 0;
                }
            }

            return(l);
        }
Esempio n. 2
0
        public OctreeNode()
        {
            Children = new OctreeChild[8];

            for (int i = 0; i < Children.Length; i++)
            {
                Children[i] = new OctreeChild();
            }
        }
Esempio n. 3
0
        public static OctreeChild Create(BoundingBox bounds, List <OctreeFace> faces, int depth = -1)
        {
            depth++;

            OctreeChild node        = new OctreeChild();
            Vector3     centre      = (bounds.Min + bounds.Max) * 0.5f;
            BoundingBox childBounds = new BoundingBox();
            SplitFlags  splitFlags  = 0;

            if (depth > Octree.MaxDepth || (depth > 0 && faces.Count < Octree.MaxFacesPerLeaf))
            {
                splitFlags = 0;

                if (faces.Count > Octree.MaxFacesPerLeaf / 8)
                {
                    if (bounds.Max.X - bounds.Min.X > 100.0f)
                    {
                        splitFlags |= SplitFlags.SplitInX;
                    }
                    if (bounds.Max.Z - bounds.Min.Z > 100.0f)
                    {
                        splitFlags |= SplitFlags.SplitInZ;
                    }
                }

                if (splitFlags == 0)
                {
                    node = OctreeLeaf.Create(depth, faces);
                    depth--;
                    return(node);
                }
            }
            else
            {
                DetermineSplittage(depth, faces, centre, ref splitFlags);
            }

            if (depth > 0 && splitFlags == 0)
            {
                node = OctreeLeaf.Create(depth, faces);
                depth--;
                return(node);
            }

            //numNodes++;

            node = new OctreeNode
            {
                ChildType = 0,
                Flags     = splitFlags
            };

            for (int i = 0; i < (node as OctreeNode).Children.Length; i++)
            {
                if (node.Flags.HasFlag(SplitFlags.SplitInX))
                {
                    if ((i & 1) == 1)
                    {
                        childBounds.Min.X = centre.X;
                        childBounds.Max.X = bounds.Max.X;
                    }
                    else
                    {
                        childBounds.Min.X = bounds.Min.X;
                        childBounds.Max.X = centre.X;
                    }
                }
                else
                {
                    if ((i & 1) == 1)
                    {
                        continue;
                    }
                    else
                    {
                        childBounds.Min.X = bounds.Min.X;
                        childBounds.Max.X = bounds.Max.X;
                    }
                }

                if (node.Flags.HasFlag(SplitFlags.SplitInY))
                {
                    if ((i & 2) == 2)
                    {
                        childBounds.Min.Y = centre.Y;
                        childBounds.Max.Y = bounds.Max.Y;
                    }
                    else
                    {
                        childBounds.Min.Y = bounds.Min.Y;
                        childBounds.Max.Y = centre.Y;
                    }
                }
                else
                {
                    if ((i & 2) == 2)
                    {
                        continue;
                    }
                    else
                    {
                        childBounds.Min.Y = bounds.Min.Y;
                        childBounds.Max.Y = bounds.Max.Y;
                    }
                }

                if (node.Flags.HasFlag(SplitFlags.SplitInZ))
                {
                    if ((i & 4) == 4)
                    {
                        childBounds.Min.Z = centre.Z;
                        childBounds.Max.Z = bounds.Max.Z;
                    }
                    else
                    {
                        childBounds.Min.Z = bounds.Min.Z;
                        childBounds.Max.Z = centre.Z;
                    }
                }
                else
                {
                    if ((i & 4) == 4)
                    {
                        continue;
                    }
                    else
                    {
                        childBounds.Min.Z = bounds.Min.Z;
                        childBounds.Max.Z = bounds.Max.Z;
                    }
                }

                //Logger.LogToFile(Logger.LogLevel.All, $"{depth}\t{i}\t{childBounds.Min}\t{childBounds.Max}");

                List <OctreeFace> childFaces = Octree.FindFacesFromList(faces, childBounds);
                (node as OctreeNode).Children[i] = Create(childBounds, childFaces, depth);
            }

            depth--;

            return(node);
        }