]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_shared.c
set the isaabb/hasaabbplanes fields on box brushes
[xonotic/darkplaces.git] / model_shared.c
index 9389654b14823a587bdfddc24b69650f8f200d55..13af108b2b30129a1051c9e7092ef407f4c0b572 100644 (file)
@@ -91,21 +91,23 @@ static void mod_newmap(void)
        int nummodels = Mem_ExpandableArray_IndexRange(&models);
        dp_model_t *mod;
 
-       R_SkinFrame_PrepareForPurge();
        for (i = 0;i < nummodels;i++)
        {
-               if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_textures)
+               if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool)
                {
-                       for (j = 0;j < mod->num_textures;j++)
+                       for (j = 0;j < mod->num_textures && mod->data_textures;j++)
                        {
                                for (k = 0;k < mod->data_textures[j].numskinframes;k++)
                                        R_SkinFrame_MarkUsed(mod->data_textures[j].skinframes[k]);
                                for (k = 0;k < mod->data_textures[j].backgroundnumskinframes;k++)
                                        R_SkinFrame_MarkUsed(mod->data_textures[j].backgroundskinframes[k]);
                        }
+                       if (mod->brush.solidskyskinframe)
+                               R_SkinFrame_MarkUsed(mod->brush.solidskyskinframe);
+                       if (mod->brush.alphaskyskinframe)
+                               R_SkinFrame_MarkUsed(mod->brush.alphaskyskinframe);
                }
        }
-       R_SkinFrame_Purge();
 
        if (!cl_stainmaps_clearonload.integer)
                return;
@@ -1263,6 +1265,7 @@ void Mod_CreateCollisionMesh(dp_model_t *mod)
        if (!mempool && mod->brush.parentmodel)
                mempool = mod->brush.parentmodel->mempool;
        // make a single combined collision mesh for physics engine use
+       // TODO rewrite this to use the collision brushes as source, to fix issues with e.g. common/caulk which creates no drawsurface
        numcollisionmeshtriangles = 0;
        for (k = 0;k < mod->nummodelsurfaces;k++)
        {
@@ -1345,6 +1348,86 @@ void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int ima
                        Mod_GetTerrainVertexFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, svector3f, tvector3f, normal3f, pixelstepmatrix, pixeltexturestepmatrix);
 }
 
+#if 0
+void Mod_Terrain_SurfaceRecurseChunk(dp_model_t *model, int stepsize, int x, int y)
+{
+       float mins[3];
+       float maxs[3];
+       float chunkwidth = min(stepsize, model->terrain.width - 1 - x);
+       float chunkheight = min(stepsize, model->terrain.height - 1 - y);
+       float viewvector[3];
+       unsigned int firstvertex;
+       unsigned int *e;
+       float *v;
+       if (chunkwidth < 2 || chunkheight < 2)
+               return;
+       VectorSet(mins, model->terrain.mins[0] +  x    * stepsize * model->terrain.scale[0], model->terrain.mins[1] +  y    * stepsize * model->terrain.scale[1], model->terrain.mins[2]);
+       VectorSet(maxs, model->terrain.mins[0] + (x+1) * stepsize * model->terrain.scale[0], model->terrain.mins[1] + (y+1) * stepsize * model->terrain.scale[1], model->terrain.maxs[2]);
+       viewvector[0] = bound(mins[0], localvieworigin, maxs[0]) - model->terrain.vieworigin[0];
+       viewvector[1] = bound(mins[1], localvieworigin, maxs[1]) - model->terrain.vieworigin[1];
+       viewvector[2] = bound(mins[2], localvieworigin, maxs[2]) - model->terrain.vieworigin[2];
+       if (stepsize > 1 && VectorLength(viewvector) < stepsize*model->terrain.scale[0]*r_terrain_lodscale.value)
+       {
+               // too close for this stepsize, emit as 4 chunks instead
+               stepsize /= 2;
+               Mod_Terrain_SurfaceRecurseChunk(model, stepsize, x, y);
+               Mod_Terrain_SurfaceRecurseChunk(model, stepsize, x+stepsize, y);
+               Mod_Terrain_SurfaceRecurseChunk(model, stepsize, x, y+stepsize);
+               Mod_Terrain_SurfaceRecurseChunk(model, stepsize, x+stepsize, y+stepsize);
+               return;
+       }
+       // emit the geometry at stepsize into our vertex buffer / index buffer
+       // we add two columns and two rows for skirt
+       outwidth = chunkwidth+2;
+       outheight = chunkheight+2;
+       outwidth2 = outwidth-1;
+       outheight2 = outheight-1;
+       outwidth3 = outwidth+1;
+       outheight3 = outheight+1;
+       firstvertex = numvertices;
+       e = model->terrain.element3i + numtriangles;
+       numtriangles += chunkwidth*chunkheight*2+chunkwidth*2*2+chunkheight*2*2;
+       v = model->terrain.vertex3f + numvertices;
+       numvertices += (chunkwidth+1)*(chunkheight+1)+(chunkwidth+1)*2+(chunkheight+1)*2;
+       // emit the triangles (note: the skirt is treated as two extra rows and two extra columns)
+       for (ty = 0;ty < outheight;ty++)
+       {
+               for (tx = 0;tx < outwidth;tx++)
+               {
+                       *e++ = firstvertex + (ty  )*outwidth3+(tx  );
+                       *e++ = firstvertex + (ty  )*outwidth3+(tx+1);
+                       *e++ = firstvertex + (ty+1)*outwidth3+(tx+1);
+                       *e++ = firstvertex + (ty  )*outwidth3+(tx  );
+                       *e++ = firstvertex + (ty+1)*outwidth3+(tx+1);
+                       *e++ = firstvertex + (ty+1)*outwidth3+(tx  );
+               }
+       }
+       // TODO: emit surface vertices (x+tx*stepsize, y+ty*stepsize)
+       for (ty = 0;ty <= outheight;ty++)
+       {
+               skirtrow = ty == 0 || ty == outheight;
+               ry = y+bound(1, ty, outheight)*stepsize;
+               for (tx = 0;tx <= outwidth;tx++)
+               {
+                       skirt = skirtrow || tx == 0 || tx == outwidth;
+                       rx = x+bound(1, tx, outwidth)*stepsize;
+                       v[0] = rx*scale[0];
+                       v[1] = ry*scale[1];
+                       v[2] = heightmap[ry*terrainwidth+rx]*scale[2];
+                       v += 3;
+               }
+       }
+       // TODO: emit skirt vertices
+}
+
+void Mod_Terrain_UpdateSurfacesForViewOrigin(dp_model_t *model)
+{
+       for (y = 0;y < model->terrain.size[1];y += model->terrain.
+       Mod_Terrain_SurfaceRecurseChunk(model, model->terrain.maxstepsize, x, y);
+       Mod_Terrain_BuildChunk(model, 
+}
+#endif
+
 q3wavefunc_t Mod_LoadQ3Shaders_EnumerateWaveFunc(const char *s)
 {
        if (!strcasecmp(s, "sin"))             return Q3WAVEFUNC_SIN;
@@ -2183,7 +2266,7 @@ tag_weapon,
 tag_torso,
 */
        memset(word, 0, sizeof(word));
-       for (i = 0;i < MAX_SKINS && (data = text = (char *)FS_LoadFile(va("%s_%i.skin", loadmodel->name, i), tempmempool, true, NULL));i++)
+       for (i = 0;i < 256 && (data = text = (char *)FS_LoadFile(va("%s_%i.skin", loadmodel->name, i), tempmempool, true, NULL));i++)
        {
                // If it's the first file we parse
                if (skinfile == NULL)
@@ -2454,13 +2537,14 @@ static void Mod_Decompile_OBJ(dp_model_t *model, const char *filename, const cha
                countvertices += surface->num_vertices;
                countfaces += surface->num_triangles;
                texname = (surface->texture && surface->texture->name[0]) ? surface->texture->name : "default";
-               for (textureindex = 0;textureindex < maxtextures && texturenames[textureindex*MAX_QPATH];textureindex++)
+               for (textureindex = 0;textureindex < counttextures;textureindex++)
                        if (!strcmp(texturenames + textureindex * MAX_QPATH, texname))
                                break;
+               if (textureindex < counttextures)
+                       continue; // already wrote this material entry
                if (textureindex >= maxtextures)
                        continue; // just a precaution
-               if (counttextures < textureindex + 1)
-                       counttextures = textureindex + 1;
+               textureindex = counttextures++;
                strlcpy(texturenames + textureindex * MAX_QPATH, texname, MAX_QPATH);
                if (outbufferpos >= outbuffermax >> 1)
                {