]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
implemented sv_fixedframeratesingleplayer cvar
[xonotic/darkplaces.git] / model_brush.c
index f45949567cc4f1f0d1975f850d5c1c24cf45f58d..cd92bb8ccace9dd1058ae7b55d1e4e0a2c39e900 100644 (file)
@@ -112,7 +112,7 @@ static int Mod_Q1BSP_FindBoxClusters(model_t *model, const vec3_t mins, const ve
        node = model->brush.data_nodes;
        for (;;)
        {
-#if 0
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
@@ -175,7 +175,7 @@ static int Mod_Q1BSP_BoxTouchingPVS(model_t *model, const qbyte *pvs, const vec3
        node = model->brush.data_nodes;
        for (;;)
        {
-#if 0
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
@@ -244,7 +244,7 @@ static int Mod_Q1BSP_BoxTouchingLeafPVS(model_t *model, const qbyte *pvs, const
        node = model->brush.data_nodes;
        for (;;)
        {
-#if 0
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
@@ -313,7 +313,7 @@ static int Mod_Q1BSP_BoxTouchingVisibleLeafs(model_t *model, const qbyte *visibl
        node = model->brush.data_nodes;
        for (;;)
        {
-#if 0
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
@@ -2536,57 +2536,12 @@ static void Mod_Q1BSP_RecursiveRecalcNodeBBox(mnode_t *node)
        Mod_Q1BSP_RecursiveRecalcNodeBBox(node->children[1]);
 
        // make combined bounding box from children
-       if (node->plane)
-       {
-               node->mins[0] = min(node->children[0]->mins[0], node->children[1]->mins[0]);
-               node->mins[1] = min(node->children[0]->mins[1], node->children[1]->mins[1]);
-               node->mins[2] = min(node->children[0]->mins[2], node->children[1]->mins[2]);
-               node->maxs[0] = max(node->children[0]->maxs[0], node->children[1]->maxs[0]);
-               node->maxs[1] = max(node->children[0]->maxs[1], node->children[1]->maxs[1]);
-               node->maxs[2] = max(node->children[0]->maxs[2], node->children[1]->maxs[2]);
-       }
-       else if (((mleaf_t *)node->children[0])->clusterindex >= 0)
-       {
-               if (((mleaf_t *)node->children[1])->clusterindex >= 0)
-               {
-                       node->mins[0] = min(node->children[0]->mins[0], node->children[1]->mins[0]);
-                       node->mins[1] = min(node->children[0]->mins[1], node->children[1]->mins[1]);
-                       node->mins[2] = min(node->children[0]->mins[2], node->children[1]->mins[2]);
-                       node->maxs[0] = max(node->children[0]->maxs[0], node->children[1]->maxs[0]);
-                       node->maxs[1] = max(node->children[0]->maxs[1], node->children[1]->maxs[1]);
-                       node->maxs[2] = max(node->children[0]->maxs[2], node->children[1]->maxs[2]);
-               }
-               else
-               {
-                       node->mins[0] = node->children[0]->mins[0];
-                       node->mins[1] = node->children[0]->mins[1];
-                       node->mins[2] = node->children[0]->mins[2];
-                       node->maxs[0] = node->children[0]->maxs[0];
-                       node->maxs[1] = node->children[0]->maxs[1];
-                       node->maxs[2] = node->children[0]->maxs[2];
-               }
-       }
-       else
-       {
-               if (((mleaf_t *)node->children[1])->clusterindex >= 0)
-               {
-                       node->mins[0] = node->children[1]->mins[0];
-                       node->mins[1] = node->children[1]->mins[1];
-                       node->mins[2] = node->children[1]->mins[2];
-                       node->maxs[0] = node->children[1]->maxs[0];
-                       node->maxs[1] = node->children[1]->maxs[1];
-                       node->maxs[2] = node->children[1]->maxs[2];
-               }
-               else
-               {
-                       node->mins[0] = 2000000000;
-                       node->mins[1] = 2000000000;
-                       node->mins[2] = 2000000000;
-                       node->maxs[0] = -2000000000;
-                       node->maxs[1] = -2000000000;
-                       node->maxs[2] = -2000000000;
-               }
-       }
+       node->mins[0] = min(node->children[0]->mins[0], node->children[1]->mins[0]);
+       node->mins[1] = min(node->children[0]->mins[1], node->children[1]->mins[1]);
+       node->mins[2] = min(node->children[0]->mins[2], node->children[1]->mins[2]);
+       node->maxs[0] = max(node->children[0]->maxs[0], node->children[1]->maxs[0]);
+       node->maxs[1] = max(node->children[0]->maxs[1], node->children[1]->maxs[1]);
+       node->maxs[2] = max(node->children[0]->maxs[2], node->children[1]->maxs[2]);
 }
 
 static void Mod_Q1BSP_FinalizePortals(void)
@@ -2692,17 +2647,14 @@ static void Mod_Q1BSP_FinalizePortals(void)
                        for (i = 0;i < 2;i++)
                        {
                                leaf = (mleaf_t *)p->nodes[i];
-                               if (leaf->clusterindex >= 0)
+                               for (j = 0;j < p->numpoints;j++)
                                {
-                                       for (j = 0;j < p->numpoints;j++)
-                                       {
-                                               if (leaf->mins[0] > p->points[j*3+0]) leaf->mins[0] = p->points[j*3+0];
-                                               if (leaf->mins[1] > p->points[j*3+1]) leaf->mins[1] = p->points[j*3+1];
-                                               if (leaf->mins[2] > p->points[j*3+2]) leaf->mins[2] = p->points[j*3+2];
-                                               if (leaf->maxs[0] < p->points[j*3+0]) leaf->maxs[0] = p->points[j*3+0];
-                                               if (leaf->maxs[1] < p->points[j*3+1]) leaf->maxs[1] = p->points[j*3+1];
-                                               if (leaf->maxs[2] < p->points[j*3+2]) leaf->maxs[2] = p->points[j*3+2];
-                                       }
+                                       if (leaf->mins[0] > p->points[j*3+0]) leaf->mins[0] = p->points[j*3+0];
+                                       if (leaf->mins[1] > p->points[j*3+1]) leaf->mins[1] = p->points[j*3+1];
+                                       if (leaf->mins[2] > p->points[j*3+2]) leaf->mins[2] = p->points[j*3+2];
+                                       if (leaf->maxs[0] < p->points[j*3+0]) leaf->maxs[0] = p->points[j*3+0];
+                                       if (leaf->maxs[1] < p->points[j*3+1]) leaf->maxs[1] = p->points[j*3+1];
+                                       if (leaf->maxs[2] < p->points[j*3+2]) leaf->maxs[2] = p->points[j*3+2];
                                }
                        }
                }
@@ -5139,7 +5091,7 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model,
 static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model, mnode_t *node, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int markframe, const vec3_t segmentmins, const vec3_t segmentmaxs)
 {
        int i;
-       //int sides;
+       int sides;
        float nodesegmentmins[3], nodesegmentmaxs[3];
        mleaf_t *leaf;
        colbrushf_t *brush;
@@ -5360,6 +5312,57 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model
                }
        */
 #if 1
+       for (;;)
+       {
+               mplane_t *plane = node->plane;
+               if (!plane)
+                       break;
+               // axial planes are much more common than non-axial, so an optimized
+               // axial case pays off here
+               if (plane->type < 3)
+               {
+                       // this is an axial plane, compare bounding box directly to it and
+                       // recurse sides accordingly
+                       // recurse down node sides
+                       // use an inlined axial BoxOnPlaneSide to slightly reduce overhead
+                       //sides = BoxOnPlaneSide(nodesegmentmins, nodesegmentmaxs, plane);
+                       sides = ((segmentmaxs[plane->type] >= plane->dist) | ((segmentmins[plane->type] < plane->dist) << 1));
+                       if (sides == 3)
+                       {
+                               // segment box crosses plane
+                               Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, node->children[0], thisbrush_start, thisbrush_end, markframe, segmentmins, segmentmaxs);
+                               sides = 2;
+                       }
+               }
+               else
+               {
+                       // this is a non-axial plane, entire trace bounding box
+                       // comparisons against it are likely to be very sloppy, so in if
+                       // the whole box is split by the plane we then test the start/end
+                       // boxes against it to be sure
+                       sides = BoxOnPlaneSide(segmentmins, segmentmaxs, plane);
+                       if (sides == 3)
+                       {
+                               // segment box crosses plane
+                               // now check start and end brush boxes to handle a lot of 'diagonal' cases more efficiently...
+                               sides = BoxOnPlaneSide(thisbrush_start->mins, thisbrush_start->maxs, plane) | BoxOnPlaneSide(thisbrush_end->mins, thisbrush_end->maxs, plane);
+                               if (sides == 3)
+                               {
+                                       Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, node->children[0], thisbrush_start, thisbrush_end, markframe, segmentmins, segmentmaxs);
+                                       sides = 2;
+                               }
+                       }
+               }
+               // take whichever side the segment box is on
+               node = node->children[sides - 1];
+       }
+       nodesegmentmins[0] = max(segmentmins[0], node->mins[0]);
+       nodesegmentmins[1] = max(segmentmins[1], node->mins[1]);
+       nodesegmentmins[2] = max(segmentmins[2], node->mins[2]);
+       nodesegmentmaxs[0] = min(segmentmaxs[0], node->maxs[0]);
+       nodesegmentmaxs[1] = min(segmentmaxs[1], node->maxs[1]);
+       nodesegmentmaxs[2] = min(segmentmaxs[2], node->maxs[2]);
+#elif 1
        for (;;)
        {
                nodesegmentmins[0] = max(segmentmins[0], node->mins[0]);