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