X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=model_shared.c;h=13af108b2b30129a1051c9e7092ef407f4c0b572;hb=d672c66ae0de71fc4497f49b0b3effd539294a98;hp=9389654b14823a587bdfddc24b69650f8f200d55;hpb=f68ef7b22979928fb6b8d2ba6b28e14c4caeb7c2;p=xonotic%2Fdarkplaces.git diff --git a/model_shared.c b/model_shared.c index 9389654b..13af108b 100644 --- a/model_shared.c +++ b/model_shared.c @@ -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) {