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