Exemple #1
0
        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);
        }