Пример #1
0
        public static OctreeLeaf Create(int depth, List <OctreeFace> faces)
        {
            OctreeLeaf leaf = new OctreeLeaf();

            if (faces.Count > 0)
            {
                List <ushort> faceData = new List <ushort>();
                int           stackSize = faces.Count * 6 + 2;
                bool          notYetFoundAFace = true;
                ushort        modelIndex = 0, lastModelIndex = 0xffff, firstFaceIndex = 0xffff, lastFaceIndex = 0xffff;

                leaf.NumFaces = 0;

                for (int i = 0; i < faces.Count; i++)
                {
                    OctreeFace face = faces[i];

                    if (face.HitNumber == depth || face.HitNumber < depth)
                    {
                        if (notYetFoundAFace)
                        {
                            faceData.Add(modelIndex);
                            faceData.Add(face.FaceNum);

                            lastModelIndex   = 0;
                            firstFaceIndex   = face.FaceNum;
                            notYetFoundAFace = false;
                        }
                        else
                        {
                            if (face.FaceNum != lastFaceIndex + 1 || modelIndex != lastModelIndex)
                            {
                                faceData = EncodeRun(faceData, (ushort)(lastFaceIndex - firstFaceIndex));

                                if (modelIndex != lastModelIndex)
                                {
                                    faceData.Add(0xfffe);
                                    faceData.Add(modelIndex);
                                    lastModelIndex = modelIndex;
                                }

                                faceData.Add(face.FaceNum);
                                firstFaceIndex = face.FaceNum;
                            }
                        }

                        lastFaceIndex = face.FaceNum;
                        leaf.NumFaces++;
                    }
                }

                faceData = EncodeRun(faceData, (ushort)(lastFaceIndex - firstFaceIndex));
                faceData.Add(0xffff);
                leaf.FaceData = faceData.ToArray();
            }
            else
            {
                leaf.FaceData = new ushort[0];
            }

            //OctreeFace poop = faces.FirstOrDefault(f => f.FaceNum == 8090);

            //if (poop != null)
            //{
            //    Logger.LogToFile(Logger.LogLevel.All, $"{poop.Vertices[0]}\t{poop.Vertices[1]}\t{poop.Vertices[2]}");
            //    Logger.LogToFile(Logger.LogLevel.All, string.Join(" ", Array.ConvertAll(leaf.FaceData, x => $"0x{x.ToString("X4")}")));
            //}

            return(leaf);
        }
Пример #2
0
        public static void DetermineSplittage(int depth, List <OctreeFace> faces, Vector3 centre, ref SplitFlags splitFlags)
        {
            int nFacesXMin = 0, nFacesXMax = 0;
            int nFacesYMin = 0, nFacesYMax = 0;
            int nFacesZMin = 0, nFacesZMax = 0;

            for (int i = 0; i < faces.Count; i++)
            {
                OctreeFace face = faces[i];

                if (face.HitNumber == depth || face.HitNumber < 0)
                {
                    if (face.Vertices[0].X < centre.X &&
                        face.Vertices[1].X < centre.X &&
                        face.Vertices[2].X < centre.X)
                    {
                        nFacesXMin++;
                    }

                    if (face.Vertices[0].X > centre.X &&
                        face.Vertices[1].X > centre.X &&
                        face.Vertices[2].X > centre.X)
                    {
                        nFacesXMax++;
                    }

                    if (face.Vertices[0].Y < centre.Y &&
                        face.Vertices[1].Y < centre.Y &&
                        face.Vertices[2].Y < centre.Y)
                    {
                        nFacesYMin++;
                    }

                    if (face.Vertices[0].Y > centre.Y &&
                        face.Vertices[1].Y > centre.Y &&
                        face.Vertices[2].Y > centre.Y)
                    {
                        nFacesYMax++;
                    }

                    if (face.Vertices[0].Z < centre.Z &&
                        face.Vertices[1].Z < centre.Z &&
                        face.Vertices[2].Z < centre.Z)
                    {
                        nFacesZMin++;
                    }

                    if (face.Vertices[0].Z > centre.Z &&
                        face.Vertices[1].Z > centre.Z &&
                        face.Vertices[2].Z > centre.Z)
                    {
                        nFacesZMax++;
                    }
                }
            }

            splitFlags = 0;

            if (nFacesXMin + nFacesXMax > Octree.NodeSplitParameter * faces.Count)
            {
                splitFlags |= SplitFlags.SplitInX;
            }
            if (nFacesYMin + nFacesYMax > Octree.NodeSplitParameter * faces.Count)
            {
                splitFlags |= SplitFlags.SplitInY;
            }
            if (nFacesZMin + nFacesZMax > Octree.NodeSplitParameter * faces.Count)
            {
                splitFlags |= SplitFlags.SplitInZ;
            }
        }