private static void ReadBSPTree(BinaryReader br, ExtractedWMOGroup group)
        {
            var rootId = br.ReadInt16();
            var nodeCount = br.ReadInt32();
            var nodeList = new List<BSPNode>(nodeCount);
            for (var i = 0; i < nodeCount; i++)
            {
                var node = new BSPNode {
                                           flags = (BSPNodeFlags) br.ReadByte(),
                                           negChild = br.ReadInt16(),
                                           posChild = br.ReadInt16(),
                                           planeDist = br.ReadSingle(),
                                           TriIndices = br.ReadIndex3List()
                                       };

                nodeList.Add(node);
            }

            group.Tree = new BSPTree(nodeList, rootId);
        }
        private static void WriteBSPNode(BinaryWriter writer, BSPNode node)
        {
            writer.Write((byte)node.flags);
            writer.Write(node.negChild);
            writer.Write(node.posChild);
            writer.Write(node.planeDist);

            if (node.TriIndices != null)
            {
                writer.Write(node.TriIndices);
            }
            else
            {
                writer.Write(0);
            }
        }
Beispiel #3
0
        private static void VisitNodes(BSPNode node, Ray ray, float tMax, Action<BSPNode> callback)
        {
            if (node == null) return;
            if ((node.flags & BSPNodeFlags.Flag_Leaf) != 0)
            {
                // Do stuff here
                callback(node);
            }

            //Figure out which child to recurse into first
            float startVal;
            float dirVal;
            if ((node.flags & BSPNodeFlags.Flag_XAxis) != 0)
            {
                startVal = ray.Position.X;
                dirVal = ray.Direction.X;
            }
            else if((node.flags & BSPNodeFlags.Flag_YAxis) != 0)
            {
                startVal = ray.Position.Y;
                dirVal = ray.Direction.Y;
            }
            else
            {
                startVal = ray.Position.Z;
                dirVal = ray.Direction.Z;
            }

            BSPNode first;
            BSPNode last;
            if (startVal > node.planeDist)
            {
                first = node.Positive;
                last = node.Negative;
            }
            else
            {
                first = node.Negative;
                last = node.Positive;
            }

            if (dirVal == 0.0)
            {
                // Segment is parallel to the splitting plane, visit the near side only.
                VisitNodes(first, ray, tMax, callback);
                return;
            }

            // The t-value for the intersection with the boundary plane
            var tIntersection = (node.planeDist - startVal) / dirVal;

            VisitNodes(first, ray, tMax, callback);

            // Test if line segment straddles the boundary plane
            if (0.0f > tIntersection || tIntersection > tMax) return;

            // It does, visit the far side
            VisitNodes(last, ray, tMax, callback);
        }
Beispiel #4
0
        static void ReadMOBN(BinaryReader file, WMOGroup group, uint size)
        {
            var count = size/0x10;

            group.BSPNodes = new List<BSPNode>((int)count);
            for (var i=0;i<count;i++)
            {
                var node = new BSPNode
                               {
                                   flags = (BSPNodeFlags) file.ReadUInt16(),
                                   negChild = file.ReadInt16(),
                                   posChild = file.ReadInt16(),
                                   nFaces = file.ReadUInt16(),
                                   faceStart = file.ReadUInt32(),
                                   planeDist = file.ReadSingle()
                               };

                group.BSPNodes.Add(node);
            }
        }
Beispiel #5
0
        private static void VisitNodes(BSPNode node, Ray ray, float tMax, Action <BSPNode> callback)
        {
            if (node == null)
            {
                return;
            }
            if ((node.flags & BSPNodeFlags.Flag_Leaf) != 0)
            {
                // Do stuff here
                callback(node);
            }

            //Figure out which child to recurse into first
            float startVal;
            float dirVal;

            if ((node.flags & BSPNodeFlags.Flag_XAxis) != 0)
            {
                startVal = ray.Position.X;
                dirVal   = ray.Direction.X;
            }
            else if ((node.flags & BSPNodeFlags.Flag_YAxis) != 0)
            {
                startVal = ray.Position.Y;
                dirVal   = ray.Direction.Y;
            }
            else
            {
                startVal = ray.Position.Z;
                dirVal   = ray.Direction.Z;
            }


            BSPNode first;
            BSPNode last;

            if (startVal > node.planeDist)
            {
                first = node.Positive;
                last  = node.Negative;
            }
            else
            {
                first = node.Negative;
                last  = node.Positive;
            }

            if (dirVal == 0.0)
            {
                // Segment is parallel to the splitting plane, visit the near side only.
                VisitNodes(first, ray, tMax, callback);
                return;
            }

            // The t-value for the intersection with the boundary plane
            var tIntersection = (node.planeDist - startVal) / dirVal;

            VisitNodes(first, ray, tMax, callback);

            // Test if line segment straddles the boundary plane
            if (0.0f > tIntersection || tIntersection > tMax)
            {
                return;
            }

            // It does, visit the far side
            VisitNodes(last, ray, tMax, callback);
        }