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