Пример #1
0
        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));
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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);
            }
        }
Пример #4
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);
        }