public static int getLeaf(Vector3 pos) { int index = 0; bsp_tree_node node = null; Plane plane = null; double distance = 0.0; while (index >= 0) { node = BspCompiler.nodes[index]; plane = BspCompiler.planes[(int)node.plane]; distance = Vector3.Dot(plane.normal, pos) - plane.distance; if (distance >= 0) { index = (int)node.children[0]; } else { index = (int)node.children[1]; } } return(-(index + 1)); }
/// <summary> /// Read all Node structures /// </summary> private static List <bsp_tree_node> ReadNodes(bsp_header_lump_t lump, BinaryStreamReader src) { int count = (int)lump.length / 36; List <bsp_tree_node> elements = new List <bsp_tree_node>(); bsp_tree_node node; src.Seek(lump.offset); for (int i = 0; i < count; ++i) { node = new bsp_tree_node(); node.plane = src.ReadInt32(); // ReadInt64 node.children = new long[] { src.ReadInt32(), src.ReadInt32() }; node.min = new long[] { src.ReadInt32(), src.ReadInt32(), src.ReadInt32() }; node.max = new long[] { src.ReadInt32(), src.ReadInt32(), src.ReadInt32() }; elements.Add(node); } return(elements); }
public static void traceNode(long nodeIdx, float startFraction, float endFraction, Vector3 start, Vector3 end, float radius, TraceOutput output) { if (nodeIdx < 0) { // Leaf node? Leaf leaf = BspCompiler.leaves[(int)-(nodeIdx + 1)]; for (int i = 0; i < leaf.leafBrushCount; i++) { Brush brush = BspCompiler.brushes[(int)BspCompiler.leafBrushes[(int)(leaf.leafBrush) + i]]; shader_p shader = BspCompiler.shaders[(int)brush.shader]; if (brush.brushSideCount > 0 && (shader.contents == 0)) // (shader['contents'] & 1)) { traceBrush(brush, start, end, radius, ref output); } } return; } // Tree node bsp_tree_node node = BspCompiler.nodes[(int)nodeIdx]; Plane plane = BspCompiler.planes[(int)node.plane]; float startDist = Vector3.Dot(plane.normal, start) - plane.distance; float endDist = Vector3.Dot(plane.normal, end) - plane.distance; if (startDist >= radius && endDist >= radius) { traceNode(node.children[0], startFraction, endFraction, start, end, radius, output); } else if (startDist < -radius && endDist < -radius) { traceNode(node.children[1], startFraction, endFraction, start, end, radius, output); } else { int side; float fraction1, fraction2, middleFraction; Vector3 middle = Vector3.Zero; if (startDist < endDist) { side = 1; // back var iDist = 1 / (startDist - endDist); fraction1 = (startDist - radius + 0.03125f) * iDist; fraction2 = (startDist + radius + 0.03125f) * iDist; } else if (startDist > endDist) { side = 0; // front var iDist = 1 / (startDist - endDist); fraction1 = (startDist + radius + 0.03125f) * iDist; fraction2 = (startDist - radius - 0.03125f) * iDist; } else { side = 0; // front fraction1 = 1.0f; fraction2 = 0.0f; } if (fraction1 < 0) { fraction1 = 0.0f; } else if (fraction1 > 1) { fraction1 = 1.0f; } if (fraction2 < 0) { fraction2 = 0.0f; } else if (fraction2 > 1) { fraction2 = 1.0f; } middleFraction = startFraction + (endFraction - startFraction) * fraction1; middle.X = start.X + fraction1 * (end.X - start.X); middle.Y = start.Y + fraction1 * (end.Y - start.Y); middle.Z = start.Z + fraction1 * (end.Z - start.Z); //for (var i = 0; i < 3; i++) //{ // middle[i] = start[i] + fraction1 * (end[i] - start[i]); //} traceNode(node.children[side], startFraction, middleFraction, start, middle, radius, output); middleFraction = startFraction + (endFraction - startFraction) * fraction2; middle.X = start.X + fraction2 * (end.X - start.X); middle.Y = start.Y + fraction2 * (end.Y - start.Y); middle.Z = start.Z + fraction2 * (end.Z - start.Z); //for (var i = 0; i < 3; i++) //{ // middle[i] = start[i] + fraction2 * (end[i] - start[i]); //} traceNode(node.children[side == 0 ? 1 : 0], middleFraction, endFraction, middle, end, radius, output); } }
public TraceOutput traceNode(long nodeIdx, float startFraction, float endFraction, Vector3 start, Vector3 end, float radius, TraceOutput output, SceneCamera camera) { if (nodeIdx < 0) // Leaf node? { Leaf leaf = this.bsp.leaves[(int)(-(nodeIdx + 1))]; for (var i = 0; i < leaf.leafBrushCount; i++) { Brush brush = this.bsp.brushes[(int)(this.bsp.leafBrushes[(leaf.leafBrush + i)])]; shader_p surface = this.bsp.surfaces[(int)brush.shader]; if (brush.brushSideCount > 0 && surface.contents != 0) // surface['contents'] & 1 { output = this.traceBrush(brush, start, end, radius, output); } } return(output); } // Tree node bsp_tree_node node = this.bsp.nodes[(int)nodeIdx]; Plane plane = this.bsp.planes[(int)node.plane]; float startDist = Vector3.Dot(plane.normal, start) - plane.distance; float endDist = Vector3.Dot(plane.normal, end) - plane.distance; if (startDist >= radius && endDist >= radius) { output = this.traceNode(node.children[0], startFraction, endFraction, start, end, radius, output, camera); } else if (startDist < -radius && endDist < -radius) { output = this.traceNode(node.children[1], startFraction, endFraction, start, end, radius, output, camera); } else { int side; float fraction1; float fraction2; float middleFraction; Vector3 middle = Vector3.Zero; if (startDist < endDist) { side = 1; // back var iDist = 1 / (startDist - endDist); fraction1 = (startDist - radius + Config.q3bsptree_trace_offset) * iDist; fraction2 = (startDist + radius + Config.q3bsptree_trace_offset) * iDist; } else if (startDist > endDist) { side = 0; // front var iDist = 1 / (startDist - endDist); fraction1 = (startDist + radius + Config.q3bsptree_trace_offset) * iDist; fraction2 = (startDist - radius - Config.q3bsptree_trace_offset) * iDist; } else { side = 0; // front fraction1 = 1.0f; fraction2 = 0.0f; } if (fraction1 < 0) { fraction1 = 0.0f; } else if (fraction1 > 1) { fraction1 = 1.0f; } if (fraction2 < 0) { fraction2 = 0.0f; } else if (fraction2 > 1) { fraction2 = 1.0f; } middleFraction = startFraction + (endFraction - startFraction) * fraction1; middle.X = start.X + fraction1 * (end.X - start.X); middle.Y = start.Y + fraction1 * (end.Y - start.Y); middle.Z = start.Z + fraction1 * (end.Z - start.Z); //for (var i = 0; i < 3; i++) //{ // middle[i] = start[i] + fraction1 * (end[i] - start[i]); //} output = this.traceNode(node.children[side], startFraction, middleFraction, start, middle, radius, output, camera); middleFraction = startFraction + (endFraction - startFraction) * fraction2; middle.X = start.X + fraction2 * (end.X - start.X); middle.Y = start.Y + fraction2 * (end.Y - start.Y); middle.Z = start.Z + fraction2 * (end.Z - start.Z); //for (var i = 0; i < 3; i++) //{ // middle[i] = start[i] + fraction2 * (end[i] - start[i]); //} output = this.traceNode(node.children[side == 0 ? 1 : 0], middleFraction, endFraction, middle, end, radius, output, camera); } return(output); }