예제 #1
0
파일: Octree.cs 프로젝트: q4a/ToxicRagers
        public static OctreeLeaf Read(BinaryReader br, Octree octree)
        {
            OctreeLeaf leaf = new OctreeLeaf
            {
                FaceData = octree.ReadFaceData((int)br.ReadUInt32())
            };

            //if ((leaf.FaceData.Length == 12 && leaf.FaceData[1] == 0x0536) || (leaf.FaceData.Length == 8 && leaf.FaceData[1] == 0x054C))
            //{
            //    Logger.LogToFile(Logger.LogLevel.All, string.Join(" ", Array.ConvertAll(leaf.FaceData, x => $"0x{x.ToString("X4")}")));
            //}


            return(leaf);
        }
예제 #2
0
파일: Octree.cs 프로젝트: q4a/ToxicRagers
        public int GetLeafFaceDataLength(OctreeLeaf leaf)
        {
            int l = 0;

            if (leaf.FaceData.Length > 0)
            {
                for (l = 0; leaf.FaceData[l] != 0xffff; l++)
                {
                }

                return(l + 1);
            }
            else
            {
                return(0);
            }
        }
예제 #3
0
파일: Octree.cs 프로젝트: q4a/ToxicRagers
        public static OctreeNode Read(BinaryReader br, Octree octree)
        {
            OctreeNode node = new OctreeNode();

            int childMask;
            int nodeMask;
            int iNode;

            childMask      = br.ReadByte();
            node.ChildType = br.ReadByte();
            node.Flags     = (SplitFlags)br.ReadByte();

            for (iNode = 0, nodeMask = 1; iNode < 8; iNode++, nodeMask <<= 1)
            {
                if ((childMask & nodeMask) > 0)
                {
                    if ((node.ChildType & nodeMask) > 0)
                    {
                        node.Children[iNode] = OctreeLeaf.Read(br, octree);
                    }
                    else
                    {
                        node.Children[iNode] = Read(br, octree);
                    }
                }
                else
                {
                    if ((((iNode & 1) == 0) || node.Flags.HasFlag(SplitFlags.SplitInX)) &&
                        (((iNode & 2) == 0) || node.Flags.HasFlag(SplitFlags.SplitInY)) &&
                        (((iNode & 4) == 0) || node.Flags.HasFlag(SplitFlags.SplitInZ)))
                    {
                        node.Children[iNode] = new OctreeLeaf(0, 0);
                        node.ChildType      |= nodeMask;
                    }
                }
            }

            return(node);
        }
예제 #4
0
파일: Octree.cs 프로젝트: q4a/ToxicRagers
        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);
        }
예제 #5
0
파일: Octree.cs 프로젝트: q4a/ToxicRagers
        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);
        }