]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
fix a display issue with warpzone decals I caused in my last change
[xonotic/darkplaces.git] / model_brush.c
index db7947b461487b885ba268ee1ac21b196c7afa96..8db8ec9d572d5eaa851cfe8801bae1170a1f2e4f 100644 (file)
@@ -1333,8 +1333,8 @@ void R_Q1BSP_LoadSplitSky (unsigned char *src, int width, int height, int bytesp
        int x, y;
        int w = width/2;
        int h = height;
-       unsigned int *solidpixels = (unsigned int *)Mem_Alloc(tempmempool, w*h*sizeof(unsigned char[4]));
-       unsigned int *alphapixels = (unsigned int *)Mem_Alloc(tempmempool, w*h*sizeof(unsigned char[4]));
+       unsigned *solidpixels = Mem_Alloc(tempmempool, w*h*sizeof(unsigned char[4]));
+       unsigned *alphapixels = Mem_Alloc(tempmempool, w*h*sizeof(unsigned char[4]));
 
        // allocate a texture pool if we need it
        if (loadmodel->texturepool == NULL && cls.state != ca_dedicated)
@@ -1576,9 +1576,9 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                        // LordHavoc: HL sky textures are entirely different than quake
                        if (!loadmodel->brush.ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == mtheight * 2)
                        {
-                               data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s/%s", mapname, tx->name), false, false, r_texture_convertsRGB_skin.integer != 0, NULL);
+                               data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s/%s", mapname, tx->name), false, false, r_texture_convertsRGB_skin.integer, NULL);
                                if (!data)
-                                       data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s", tx->name), false, false, r_texture_convertsRGB_skin.integer != 0, NULL);
+                                       data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s", tx->name), false, false, r_texture_convertsRGB_skin.integer, NULL);
                                if (data && image_width == image_height * 2)
                                {
                                        R_Q1BSP_LoadSplitSky(data, image_width, image_height, 4);
@@ -2454,8 +2454,8 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
                                        loadmodel->texturepool = R_AllocTexturePool();
                                // could not find room, make a new lightmap
                                loadmodel->brushq3.num_mergedlightmaps = lightmapnumber + 1;
-                               loadmodel->brushq3.data_lightmaps = (rtexture_t **)Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_lightmaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_lightmaps[0]));
-                               loadmodel->brushq3.data_deluxemaps = (rtexture_t **)Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_deluxemaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_deluxemaps[0]));
+                               loadmodel->brushq3.data_lightmaps = Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_lightmaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_lightmaps[0]));
+                               loadmodel->brushq3.data_deluxemaps = Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_deluxemaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_deluxemaps[0]));
                                loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, -1, NULL);
                                if (loadmodel->brushq1.nmaplightdata)
                                        loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, -1, NULL);
@@ -3182,7 +3182,7 @@ static void Mod_Q1BSP_RecursiveNodePortals(mnode_t *node)
        if (portalpointsbuffersize < portalpointsbufferoffset + 6*MAX_PORTALPOINTS)
        {
                portalpointsbuffersize = portalpointsbufferoffset * 2;
-               portalpointsbuffer = (double *)Mem_Realloc(loadmodel->mempool, portalpointsbuffer, portalpointsbuffersize * sizeof(*portalpointsbuffer));
+               portalpointsbuffer = Mem_Realloc(loadmodel->mempool, portalpointsbuffer, portalpointsbuffersize * sizeof(*portalpointsbuffer));
        }
        frontpoints = portalpointsbuffer + portalpointsbufferoffset;
        portalpointsbufferoffset += 3*MAX_PORTALPOINTS;
@@ -3315,7 +3315,7 @@ static void Mod_Q1BSP_MakePortals(void)
        Mem_ExpandableArray_NewArray(&portalarray, loadmodel->mempool, sizeof(portal_t), 1020*1024/sizeof(portal_t));
        portalpointsbufferoffset = 0;
        portalpointsbuffersize = 6*MAX_PORTALPOINTS*128;
-       portalpointsbuffer = (double *)Mem_Alloc(loadmodel->mempool, portalpointsbuffersize * sizeof(*portalpointsbuffer));
+       portalpointsbuffer = Mem_Alloc(loadmodel->mempool, portalpointsbuffersize * sizeof(*portalpointsbuffer));
        Mod_Q1BSP_RecursiveNodePortals(loadmodel->brush.data_nodes + loadmodel->brushq1.hulls[0].firstclipnode);
        Mem_Free(portalpointsbuffer);
        portalpointsbuffer = NULL;
@@ -3447,7 +3447,6 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
        dmodel_t *bm;
        float dist, modelyawradius, modelradius;
        msurface_t *surface;
-       int numshadowmeshtriangles;
        hullinfo_t hullinfo;
        int totalstylesurfaces, totalstyles, stylecounts[256], remapstyles[256];
        model_brush_lightstyleinfo_t styleinfo[256];
@@ -3575,7 +3574,7 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
        mod->numskins = 1;
 
        // make a single combined shadow mesh to allow optimized shadow volume creation
-       numshadowmeshtriangles = Mod_Q1BSP_CreateShadowMesh(loadmodel);
+       Mod_Q1BSP_CreateShadowMesh(loadmodel);
 
        if (loadmodel->brush.numsubmodels)
                loadmodel->brush.submodels = (dp_model_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brush.numsubmodels * sizeof(dp_model_t *));
@@ -3757,6 +3756,7 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
                        // point traces and contents checks still use the bsp tree
                        mod->TraceLine = Mod_CollisionBIH_TraceLine;
                        mod->TraceBox = Mod_CollisionBIH_TraceBox;
+                       mod->TraceBrush = Mod_CollisionBIH_TraceBrush;
                }
                else
                        Mod_MakeCollisionBIH(mod, true, &mod->render_bih);
@@ -4713,7 +4713,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
        // figure out what the most reasonable merge power is within limits
 
        // find the appropriate NxN dimensions to merge to, to avoid wasted space
-       realcount = count >> (int)loadmodel->brushq3.deluxemapping;
+       realcount = count >> loadmodel->brushq3.deluxemapping;
 
        // figure out how big the merged texture has to be
        mergegoal = 128<<bound(0, mod_q3bsp_lightmapmergepower.integer, 6);
@@ -4761,7 +4761,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
        for (i = 0;i < count;i++)
        {
                // figure out which merged lightmap texture this fits into
-               realindex = i >> (int)loadmodel->brushq3.deluxemapping;
+               realindex = i >> loadmodel->brushq3.deluxemapping;
                lightmapindex = i >> powerdxy;
 
                // choose the destination address
@@ -5096,8 +5096,8 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
        Mod_AllocSurfMesh(loadmodel->mempool, meshvertices, meshtriangles, false, true, false);
        if (collisiontriangles)
        {
-               loadmodel->brush.data_collisionvertex3f = (float *)Mem_Alloc(loadmodel->mempool, collisionvertices * sizeof(float[3]));
-               loadmodel->brush.data_collisionelement3i = (int *)Mem_Alloc(loadmodel->mempool, collisiontriangles * sizeof(int[3]));
+               loadmodel->brush.data_collisionvertex3f = Mem_Alloc(loadmodel->mempool, collisionvertices * sizeof(float[3]));
+               loadmodel->brush.data_collisionelement3i = Mem_Alloc(loadmodel->mempool, collisiontriangles * sizeof(int[3]));
        }
        meshvertices = 0;
        meshtriangles = 0;
@@ -6188,10 +6188,7 @@ void Mod_CollisionBIH_TraceBox(dp_model_t *model, const frameblend_t *frameblend
                if (VectorCompare(start, end))
                        Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, shiftstart, hitsupercontentsmask);
                else
-               {
                        Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask);
-                       VectorSubtract(trace->endpos, boxmins, trace->endpos);
-               }
                return;
        }
 
@@ -6215,6 +6212,33 @@ void Mod_CollisionBIH_TraceBox(dp_model_t *model, const frameblend_t *frameblend
        Mod_CollisionBIH_TraceBrush_RecursiveBIHNode(trace, model, model->collision_bih.rootnode, &thisbrush_start.brush, &thisbrush_end.brush, segmentmins, segmentmaxs);
 }
 
+void Mod_CollisionBIH_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *start, colbrushf_t *end, int hitsupercontentsmask)
+{
+       float segmentmins[3], segmentmaxs[3];
+
+       if (mod_q3bsp_optimizedtraceline.integer && VectorCompare(start->mins, start->maxs) && VectorCompare(end->mins, end->maxs))
+       {
+               if (VectorCompare(start->mins, end->mins))
+                       Mod_CollisionBIH_TracePoint(model, frameblend, skeleton, trace, start->mins, hitsupercontentsmask);
+               else
+                       Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start->mins, end->mins, hitsupercontentsmask);
+               return;
+       }
+
+       // box trace, performed as brush trace
+       memset(trace, 0, sizeof(*trace));
+       trace->fraction = 1;
+       trace->realfraction = 1;
+       trace->hitsupercontentsmask = hitsupercontentsmask;
+       segmentmins[0] = min(start->mins[0], end->mins[0]);
+       segmentmins[1] = min(start->mins[1], end->mins[1]);
+       segmentmins[2] = min(start->mins[2], end->mins[2]);
+       segmentmaxs[0] = max(start->maxs[0], end->maxs[0]);
+       segmentmaxs[1] = max(start->maxs[1], end->maxs[1]);
+       segmentmaxs[2] = max(start->maxs[2], end->maxs[2]);
+       Mod_CollisionBIH_TraceBrush_RecursiveBIHNode(trace, model, model->collision_bih.rootnode, start, end, segmentmins, segmentmaxs);
+}
+
 int Mod_CollisionBIH_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
 {
        trace_t trace;
@@ -6554,10 +6578,7 @@ static void Mod_Q3BSP_TraceBox(dp_model_t *model, const frameblend_t *frameblend
                if (VectorCompare(start, end))
                        Mod_Q3BSP_TracePoint(model, frameblend, skeleton, trace, shiftstart, hitsupercontentsmask);
                else
-               {
                        Mod_Q3BSP_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask);
-                       VectorSubtract(trace->endpos, boxmins, trace->endpos);
-               }
                return;
        }
 
@@ -6594,6 +6615,49 @@ static void Mod_Q3BSP_TraceBox(dp_model_t *model, const frameblend_t *frameblend
                Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, model->brush.data_nodes, &thisbrush_start.brush, &thisbrush_end.brush, ++markframe, segmentmins, segmentmaxs);
 }
 
+void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *start, colbrushf_t *end, int hitsupercontentsmask)
+{
+       float segmentmins[3], segmentmaxs[3];
+       int i;
+       msurface_t *surface;
+       q3mbrush_t *brush;
+
+       if (mod_q3bsp_optimizedtraceline.integer && VectorCompare(start->mins, start->maxs) && VectorCompare(end->mins, end->maxs))
+       {
+               if (VectorCompare(start->mins, end->mins))
+                       Mod_Q3BSP_TracePoint(model, frameblend, skeleton, trace, start->mins, hitsupercontentsmask);
+               else
+                       Mod_Q3BSP_TraceLine(model, frameblend, skeleton, trace, start->mins, end->mins, hitsupercontentsmask);
+               return;
+       }
+
+       // box trace, performed as brush trace
+       memset(trace, 0, sizeof(*trace));
+       trace->fraction = 1;
+       trace->realfraction = 1;
+       trace->hitsupercontentsmask = hitsupercontentsmask;
+       segmentmins[0] = min(start->mins[0], end->mins[0]);
+       segmentmins[1] = min(start->mins[1], end->mins[1]);
+       segmentmins[2] = min(start->mins[2], end->mins[2]);
+       segmentmaxs[0] = max(start->maxs[0], end->maxs[0]);
+       segmentmaxs[1] = max(start->maxs[1], end->maxs[1]);
+       segmentmaxs[2] = max(start->maxs[2], end->maxs[2]);
+       if (mod_collision_bih.integer)
+               Mod_CollisionBIH_TraceBrush_RecursiveBIHNode(trace, model, model->collision_bih.rootnode, start, end, segmentmins, segmentmaxs);
+       else if (model->brush.submodel)
+       {
+               for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
+                       if (brush->colbrushf && BoxesOverlap(segmentmins, segmentmaxs, brush->colbrushf->mins, brush->colbrushf->maxs))
+                               Collision_TraceBrushBrushFloat(trace, start, end, brush->colbrushf, brush->colbrushf);
+               if (mod_q3bsp_curves_collisions.integer)
+                       for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
+                               if (surface->num_collisiontriangles && BoxesOverlap(segmentmins, segmentmaxs, surface->mins, surface->maxs))
+                                       Collision_TraceBrushTriangleMeshFloat(trace, start, end, surface->num_collisiontriangles, surface->deprecatedq3data_collisionelement3i, surface->deprecatedq3data_collisionvertex3f, surface->deprecatedq3num_collisionbboxstride, surface->deprecatedq3data_collisionbbox6f, surface->texture->supercontents, surface->texture->surfaceflags, surface->texture, segmentmins, segmentmaxs);
+       }
+       else
+               Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, model->brush.data_nodes, start, end, ++markframe, segmentmins, segmentmaxs);
+}
+
 static int Mod_Q3BSP_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
 {
        int i;
@@ -6679,7 +6743,7 @@ bih_t *Mod_MakeCollisionBIH(dp_model_t *model, qboolean userendersurfaces, bih_t
                return NULL;
 
        // allocate the memory for the BIH leaf nodes
-       bihleafs = (bih_leaf_t *)Mem_Alloc(loadmodel->mempool, sizeof(bih_leaf_t) * bihnumleafs);
+       bihleafs = Mem_Alloc(loadmodel->mempool, sizeof(bih_leaf_t) * bihnumleafs);
 
        // now populate the BIH leaf nodes
        bihleafindex = 0;
@@ -6747,8 +6811,8 @@ bih_t *Mod_MakeCollisionBIH(dp_model_t *model, qboolean userendersurfaces, bih_t
 
        // allocate buffers for the produced and temporary data
        bihmaxnodes = bihnumleafs - 1;
-       bihnodes = (bih_node_t *)Mem_Alloc(loadmodel->mempool, sizeof(bih_node_t) * bihmaxnodes);
-       temp_leafsort = (int *)Mem_Alloc(loadmodel->mempool, sizeof(int) * bihnumleafs * 2);
+       bihnodes = Mem_Alloc(loadmodel->mempool, sizeof(bih_node_t) * bihmaxnodes);
+       temp_leafsort = Mem_Alloc(loadmodel->mempool, sizeof(int) * bihnumleafs * 2);
        temp_leafsortscratch = temp_leafsort + bihnumleafs;
 
        // now build it
@@ -6761,7 +6825,7 @@ bih_t *Mod_MakeCollisionBIH(dp_model_t *model, qboolean userendersurfaces, bih_t
        if (out->maxnodes > out->numnodes)
        {
                out->maxnodes = out->numnodes;
-               out->nodes = (bih_node_t *)Mem_Realloc(loadmodel->mempool, out->nodes, out->numnodes * sizeof(bih_node_t));
+               out->nodes = Mem_Realloc(loadmodel->mempool, out->nodes, out->numnodes * sizeof(bih_node_t));
        }
 
        return out;
@@ -6842,7 +6906,7 @@ void Mod_Q3BSP_RecursiveFindNumLeafs(mnode_t *node)
 
 void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 {
-       int i, j, numshadowmeshtriangles, lumps;
+       int i, j, lumps;
        q3dheader_t *header;
        float corner[3], yawradius, modelradius;
 
@@ -6862,6 +6926,7 @@ void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 
        mod->soundfromcenter = true;
        mod->TraceBox = Mod_Q3BSP_TraceBox;
+       mod->TraceBrush = Mod_Q3BSP_TraceBrush;
        mod->TraceLine = Mod_Q3BSP_TraceLine;
        mod->TracePoint = Mod_Q3BSP_TracePoint;
        mod->PointSuperContents = Mod_Q3BSP_PointSuperContents;
@@ -6962,7 +7027,7 @@ void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->brush.supportwateralpha = true;
 
        // make a single combined shadow mesh to allow optimized shadow volume creation
-       numshadowmeshtriangles = Mod_Q1BSP_CreateShadowMesh(loadmodel);
+       Mod_Q1BSP_CreateShadowMesh(loadmodel);
 
        loadmodel->brush.num_leafs = 0;
        Mod_Q3BSP_RecursiveFindNumLeafs(loadmodel->brush.data_nodes);
@@ -7159,6 +7224,7 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->type = mod_obj;
        loadmodel->soundfromcenter = true;
        loadmodel->TraceBox = Mod_CollisionBIH_TraceBox;
+       loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush;
        loadmodel->TraceLine = Mod_CollisionBIH_TraceLine;
        loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
        loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
@@ -7207,7 +7273,6 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
        // parse the OBJ text now
        for(;;)
        {
-               static char emptyarg[1] = "";
                if (!*text)
                        break;
                linenumber++;
@@ -7216,7 +7281,7 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
                        line[linelen] = text[linelen];
                line[linelen] = 0;
                for (argc = 0;argc < 4;argc++)
-                       argv[argc] = emptyarg;
+                       argv[argc] = "";
                argc = 0;
                s = line;
                while (*s == ' ' || *s == '\t')
@@ -7394,12 +7459,12 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->radius2 = modelradius * modelradius;
 
        // allocate storage for triangles
-       loadmodel->surfmesh.data_element3i = (int *)Mem_Alloc(loadmodel->mempool, numtriangles * sizeof(int[3]));
+       loadmodel->surfmesh.data_element3i = Mem_Alloc(loadmodel->mempool, numtriangles * sizeof(int[3]));
        // allocate vertex hash structures to build an optimal vertex subset
        vertexhashsize = numtriangles*2;
-       vertexhashtable = (int *)Mem_Alloc(loadmodel->mempool, sizeof(int) * vertexhashsize);
+       vertexhashtable = Mem_Alloc(loadmodel->mempool, sizeof(int) * vertexhashsize);
        memset(vertexhashtable, 0xFF, sizeof(int) * vertexhashsize);
-       vertexhashdata = (objvertex_t *)Mem_Alloc(loadmodel->mempool, sizeof(*vertexhashdata) * numtriangles*3);
+       vertexhashdata = Mem_Alloc(loadmodel->mempool, sizeof(*vertexhashdata) * numtriangles*3);
        vertexhashcount = 0;
 
        // gather surface stats for assigning vertex/triangle ranges