Example #1
0
        private void ReadLeaves()
        {
            //Length of the Lump
            int LeavesLength = Header.DirEntries[4].Length;
            //Number of textures to load
            int nbLeaves = LeavesLength / (sizeof(int) * 12);

            Leaves = new leaf[nbLeaves];
            for (int i = 0; i < nbLeaves; i++)
            {
                //Cluster
                int cluster = ReadInt();

                //Area
                int area = ReadInt();

                //Mins
                int[] mins = new int[3] {
                    ReadInt(), ReadInt(), ReadInt()
                };

                // Maxs
                int[] maxs = new int[3] {
                    ReadInt(), ReadInt(), ReadInt()
                };

                //leafface
                int leafface = ReadInt();

                //n_leaffaces
                int n_leaffaces = ReadInt();

                //leafbrush
                int leafbrush = ReadInt();

                //n_leafbrush
                int n_leafbrush = ReadInt();


                Leaves[i] = new leaf(cluster, area, mins, maxs, leafface, n_leaffaces, leafbrush, n_leafbrush);
            }
        }
Example #2
0
        public void CheckNode(int nodeIndex, float startFraction, float endFraction, Vector3 start, Vector3 end)
        {
            if (nodeIndex < 0)
            {
                // this is a leaf

                leaf leaf = file.Leaves[-(nodeIndex + 1)];

                for (int i = 0; i < leaf.N_LeafBrushes; i++)
                {
                    brush brush = file.Brushes[file.LeafBrushes[leaf.LeafBrush + i].Brush];

                    if (brush.N_BrushSides > 0 && (file.Textures[brush.Texture].Contents & 1) != 0)
                    {
                        CheckBrush(brush);
                    }
                }
                return;
            }



            node  node  = file.Nodes[nodeIndex];
            plane plane = file.Planes[node.Plane];

            Vector3 planeNormal   = BspRenderer.V3FromFloatArray(plane.Normal);
            float   startDistance = Vector3.Dot(start, planeNormal) - plane.Dist;
            float   endDistance   = Vector3.Dot(end, planeNormal) - plane.Dist;


            float offset = 0;

            if (traceType == TT_RAY)
            {
                offset = 0;
            }
            else if (traceType == TT_SPHERE)
            {
                offset = traceRadius;
            }
            else if (traceType == TT_BOX)
            {
                offset = (float)(Math.Abs(traceExtents.X * planeNormal.X) + Math.Abs(traceExtents.Y * planeNormal.Y) + Math.Abs(traceExtents.Z * planeNormal.Z));
            }


            // A
            if (startDistance >= offset && endDistance >= offset)
            {
                // in front of the plane
                // checking front child
                CheckNode(node.Children[0], startFraction, endFraction, start, end);
            }// B
            else if (startDistance < -offset && endDistance < -offset)
            {
                // behind the plane
                // checking back child
                CheckNode(node.Children[1], startFraction, endFraction, start, end);
            }// C
            else
            {
                // splitting between planes
                int     side;
                float   fraction1, fraction2, middleFraction;
                Vector3 middle;

                // split the segment in 2
                if (startDistance < endDistance)
                {
                    side = 1; // back
                    float inverseDistance = 1.0f / (startDistance - endDistance);
                    fraction1 = (startDistance - offset + float.Epsilon) * inverseDistance;
                    fraction2 = (startDistance - offset + float.Epsilon) * inverseDistance;
                }
                else if (endDistance < startDistance)
                {
                    side = 0; // front
                    float inverseDistance = 1.0f / (startDistance - endDistance);
                    fraction1 = (startDistance + offset + float.Epsilon) * inverseDistance;
                    fraction2 = (startDistance - offset - float.Epsilon) * inverseDistance;
                }
                else
                {
                    side      = 0; //front
                    fraction1 = 1.0f;
                    fraction2 = 0.0f;
                }

                // make sure numbers are valid

                if (fraction1 < 0.0f)
                {
                    fraction1 = 0.0f;
                }
                else if (fraction1 > 1.0f)
                {
                    fraction1 = 1.0f;
                }
                if (fraction2 < 0.0f)
                {
                    fraction2 = 0.0f;
                }
                else if (fraction2 > 1.0f)
                {
                    fraction2 = 1.0f;
                }

                // calculate middle point for the first side

                middleFraction = startFraction + (endFraction - startFraction) * fraction1;
                middle         = start + fraction1 * (end - start);

                // check first side

                CheckNode(node.Children[side], startFraction, middleFraction, start, middle);


                // calculate middle point for the second side

                middleFraction = startFraction + (endFraction - startFraction) * fraction2;
                middle         = start * fraction2 * (end - start);


                // check second side
                CheckNode(node.Children[inverseSide(side)], startFraction, middleFraction, start, middle);
            }
        }