예제 #1
0
        private static void VisitNodes(WMOBSPNode node, Ray ray, float tMax, Action<WMOBSPNode> 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;
            }

            WMOBSPNode first;
            WMOBSPNode 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);
        }
예제 #2
0
        static void ReadMOBN(BinaryReader file, WMOGroup group, uint size)
        {
            var count = size/0x10;

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

                group.BSPNodes.Add(node);
            }
        }
예제 #3
0
        private static void VisitNodes(WMOBSPNode node, Ray ray, float tMax, Action <WMOBSPNode> 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;
            }


            WMOBSPNode first;
            WMOBSPNode 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);
        }