]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
fix some crashes related to particles when csqc is not active
[xonotic/darkplaces.git] / model_brush.c
index a35aefc2c84828115c1bbb4439aebd85d55fb7a3..d0c0ae6dfc1270145f438a90e2f09e2eca60e64a 100644 (file)
@@ -1268,6 +1268,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                tx->skinframerate = 1;
                tx->currentskinframe = tx->skinframes;
                tx->skinframes[0].base = r_texture_notexture;
+               tx->backgroundcurrentskinframe = tx->backgroundskinframes;
                tx->basematerialflags = 0;
                if (i == loadmodel->num_textures - 1)
                {
@@ -2259,8 +2260,33 @@ static void Mod_Q1BSP_LoadNodes_RecursiveSetParent(mnode_t *node, mnode_t *paren
        node->parent = parent;
        if (node->plane)
        {
+               // this is a node, recurse to children
                Mod_Q1BSP_LoadNodes_RecursiveSetParent(node->children[0], node);
                Mod_Q1BSP_LoadNodes_RecursiveSetParent(node->children[1], node);
+               // combine supercontents of children
+               node->combinedsupercontents = node->children[0]->combinedsupercontents | node->children[1]->combinedsupercontents;
+       }
+       else
+       {
+               int j;
+               mleaf_t *leaf = (mleaf_t *)node;
+               // if this is a leaf, calculate supercontents mask from all collidable
+               // primitives in the leaf (brushes and collision surfaces)
+               // also flag if the leaf contains any collision surfaces
+               leaf->combinedsupercontents = 0;
+               // combine the supercontents values of all brushes in this leaf
+               for (j = 0;j < leaf->numleafbrushes;j++)
+                       leaf->combinedsupercontents |= loadmodel->brush.data_brushes[leaf->firstleafbrush[j]].texture->supercontents;
+               // check if this leaf contains any collision surfaces (q3 patches)
+               for (j = 0;j < leaf->numleafsurfaces;j++)
+               {
+                       msurface_t *surface = loadmodel->data_surfaces + leaf->firstleafsurface[j];
+                       if (surface->num_collisiontriangles)
+                       {
+                               leaf->containscollisionsurfaces = true;
+                               leaf->combinedsupercontents |= surface->texture->supercontents;
+                       }
+               }
        }
 }
 
@@ -2381,7 +2407,7 @@ qboolean Mod_Q1BSP_CheckWaterAlphaSupport(void)
                {
                        pvs = loadmodel->brush.data_pvsclusters + leaf->clusterindex * loadmodel->brush.num_pvsclusterbytes;
                        for (j = 0;j < loadmodel->brush.num_leafs;j++)
-                               if (leaf->contents == CONTENTS_EMPTY && CHECKPVSBIT(pvs, loadmodel->brush.data_leafs[j].clusterindex))
+                               if (CHECKPVSBIT(pvs, loadmodel->brush.data_leafs[j].clusterindex) && loadmodel->brush.data_leafs[j].contents == CONTENTS_EMPTY)
                                        return true;
                }
        }
@@ -4145,7 +4171,7 @@ static void Mod_Q3BSP_LoadShaders(void)
                                                {
                                                        int i;
                                                        layer->numframes = min(numparameters - 2, TEXTURE_MAXFRAMES);
-                                                       layer->framerate = atoi(parameter[1]);
+                                                       layer->framerate = atof(parameter[1]);
                                                        for (i = 0;i < layer->numframes;i++)
                                                                strlcpy(layer->texturename[i], parameter[i + 2], sizeof(layer->texturename));
                                                }
@@ -4260,8 +4286,10 @@ static void Mod_Q3BSP_LoadShaders(void)
                                                shader->surfaceparms |= Q3SURFACEPARM_WATER;
                                        else if (!strcasecmp(parameter[1], "pointlight"))
                                                shader->surfaceparms |= Q3SURFACEPARM_POINTLIGHT;
+                                       else if (!strcasecmp(parameter[1], "antiportal"))
+                                               shader->surfaceparms |= Q3SURFACEPARM_ANTIPORTAL;
                                        else
-                                               Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[fileindex], parameter[1]);
+                                               Con_DPrintf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[fileindex], parameter[1]);
                                }
                                else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2)
                                {
@@ -4425,7 +4453,18 @@ Q3 shader blendfuncs actually used in the game (* = supported by DP)
                                        if (!Mod_LoadSkinFrame(&out->skinframes[j], shader->primarylayer->texturename[j], ((shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (shader->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP) | (shader->primarylayer->clampmap ? TEXF_CLAMP : 0), false, true))
                                                Con_Printf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->primarylayer->texturename[j], j, out->name);
                        }
+                       if (shader->backgroundlayer && cls.state != ca_dedicated)
+                       {
+                               int j;
+                               out->backgroundnumskinframes = shader->backgroundlayer->numframes;
+                               out->backgroundskinframerate = shader->backgroundlayer->framerate;
+                               for (j = 0;j < shader->backgroundlayer->numframes;j++)
+                                       if (!Mod_LoadSkinFrame(&out->backgroundskinframes[j], shader->backgroundlayer->texturename[j], ((shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (shader->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP) | (shader->backgroundlayer->clampmap ? TEXF_CLAMP : 0), false, true))
+                                               Con_Printf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->backgroundlayer->texturename[j], j, out->name);
+                       }
                }
+               else if (!strcmp(out->name, "noshader"))
+                       out->surfaceparms = 0;
                else
                {
                        c++;
@@ -4452,6 +4491,7 @@ Q3 shader blendfuncs actually used in the game (* = supported by DP)
                // init the animation variables
                out->currentframe = out;
                out->currentskinframe = &out->skinframes[0];
+               out->backgroundcurrentskinframe = &out->backgroundskinframes[0];
        }
        if (c)
                Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
@@ -5421,6 +5461,9 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model,
        // walk the tree until we hit a leaf, recursing for any split cases
        while (node->plane)
        {
+               // abort if this part of the bsp tree can not be hit by this trace
+//             if (!(node->combinedsupercontents & trace->hitsupercontentsmask))
+//                     return;
                plane = node->plane;
                // axial planes are much more common than non-axial, so an optimized
                // axial case pays off here
@@ -5457,6 +5500,9 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model,
                        return;
                }
        }
+       // abort if this part of the bsp tree can not be hit by this trace
+//     if (!(node->combinedsupercontents & trace->hitsupercontentsmask))
+//             return;
        // hit a leaf
        nodesegmentmins[0] = min(start[0], end[0]) - 1;
        nodesegmentmins[1] = min(start[1], end[1]) - 1;
@@ -5476,7 +5522,7 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model,
                }
        }
        // can't do point traces on curves (they have no thickness)
-       if (mod_q3bsp_curves_collisions.integer && !VectorCompare(start, end))
+       if (leaf->containscollisionsurfaces && mod_q3bsp_curves_collisions.integer && !VectorCompare(start, end))
        {
                // line trace the curves
                for (i = 0;i < leaf->numleafsurfaces;i++)
@@ -5503,6 +5549,9 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model
        // walk the tree until we hit a leaf, recursing for any split cases
        while (node->plane)
        {
+               // abort if this part of the bsp tree can not be hit by this trace
+//             if (!(node->combinedsupercontents & trace->hitsupercontentsmask))
+//                     return;
                plane = node->plane;
                // axial planes are much more common than non-axial, so an optimized
                // axial case pays off here
@@ -5535,6 +5584,9 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model
                // take whichever side the segment box is on
                node = node->children[sides - 1];
        }
+       // abort if this part of the bsp tree can not be hit by this trace
+//     if (!(node->combinedsupercontents & trace->hitsupercontentsmask))
+//             return;
        nodesegmentmins[0] = max(segmentmins[0], node->mins[0] - 1);
        nodesegmentmins[1] = max(segmentmins[1], node->mins[1] - 1);
        nodesegmentmins[2] = max(segmentmins[2], node->mins[2] - 1);
@@ -5552,7 +5604,7 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model
                        Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, brush, brush);
                }
        }
-       if (mod_q3bsp_curves_collisions.integer)
+       if (leaf->containscollisionsurfaces && mod_q3bsp_curves_collisions.integer)
        {
                for (i = 0;i < leaf->numleafsurfaces;i++)
                {