X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=model_brush.c;h=45b5340f5713c44141b28fb6e48f00d08db949e5;hb=2278c4b5c63fc875d157b5725acd01fc9b1a12e0;hp=0834ce959413943f6f8a8ff9c21315eb04bd9c67;hpb=49efc53510842f29eccbc160e1aa56c17e575468;p=xonotic%2Fdarkplaces.git diff --git a/model_brush.c b/model_brush.c index 0834ce95..45b5340f 100644 --- a/model_brush.c +++ b/model_brush.c @@ -95,7 +95,7 @@ static void Mod_Q1BSP_AmbientSoundLevelsForPoint(model_t *model, const vec3_t p, leaf = Mod_Q1BSP_PointInLeaf(model, p); if (leaf) { - i = min(outsize, (int)sizeof(leaf->ambient_sound_level));; + i = min(outsize, (int)sizeof(leaf->ambient_sound_level)); if (i) { memcpy(out, leaf->ambient_sound_level, i); @@ -1023,7 +1023,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) } else { - if (!Mod_LoadSkinFrame(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true)) + if (!Mod_LoadSkinFrame(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, true, true)) { // did not find external texture, load it from the bsp or wad3 if (loadmodel->brush.ishlbsp) @@ -1039,7 +1039,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) { tx->width = image_width; tx->height = image_height; - tx->skin.base = tx->skin.merged = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL); + tx->skin.base = tx->skin.merged = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, NULL); if (Image_CheckAlpha(pixels, image_width * image_height, true)) { fogpixels = Mem_Alloc(tempmempool, image_width * image_height * 4); @@ -1050,7 +1050,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) fogpixels[j + 2] = 255; fogpixels[j + 3] = pixels[j + 3]; } - tx->skin.fog = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL); + tx->skin.fog = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, NULL); Mem_Free(fogpixels); } } @@ -1058,7 +1058,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) Mem_Free(freepixels); } else if (mtdata) // texture included - Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_PRECACHE, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height); + Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_PRECACHE | TEXF_PICMIP, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height); } } if (tx->skin.base == NULL) @@ -2638,9 +2638,9 @@ static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *mod int i, j, stylecounts[256], totalcount, remapstyles[256]; msurface_t *surf; memset(stylecounts, 0, sizeof(stylecounts)); - for (i = 0;i < model->brushq1.nummodelsurfaces;i++) + for (i = 0;i < model->nummodelsurfaces;i++) { - surf = model->brushq1.surfaces + model->brushq1.firstmodelsurface + i; + surf = model->brushq1.surfaces + model->firstmodelsurface + i; for (j = 0;j < MAXLIGHTMAPS;j++) stylecounts[surf->styles[j]]++; } @@ -2670,9 +2670,9 @@ static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *mod model->brushq1.light_styleupdatechains[i] = model->brushq1.light_styleupdatechainsbuffer + j; j += stylecounts[model->brushq1.light_style[i]] + 1; } - for (i = 0;i < model->brushq1.nummodelsurfaces;i++) + for (i = 0;i < model->nummodelsurfaces;i++) { - surf = model->brushq1.surfaces + model->brushq1.firstmodelsurface + i; + surf = model->brushq1.surfaces + model->firstmodelsurface + i; for (j = 0;j < MAXLIGHTMAPS;j++) if (surf->styles[j] != 255) *model->brushq1.light_styleupdatechains[remapstyles[surf->styles[j]]]++ = surf; @@ -2691,7 +2691,7 @@ static void Mod_Q1BSP_BuildPVSTextureChains(model_t *model) int i, j; for (i = 0;i < model->brushq1.numtextures;i++) model->brushq1.pvstexturechainslength[i] = 0; - for (i = 0, j = model->brushq1.firstmodelsurface;i < model->brushq1.nummodelsurfaces;i++, j++) + for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++) { if (model->brushq1.surfacepvsframes[j] == model->brushq1.pvsframecount) { @@ -2709,7 +2709,7 @@ static void Mod_Q1BSP_BuildPVSTextureChains(model_t *model) else model->brushq1.pvstexturechains[i] = NULL; } - for (i = 0, j = model->brushq1.firstmodelsurface;i < model->brushq1.nummodelsurfaces;i++, j++) + for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++) if (model->brushq1.surfacepvsframes[j] == model->brushq1.pvsframecount) *model->brushq1.pvstexturechains[model->brushq1.surfaces[j].texinfo->texture->number]++ = model->brushq1.surfaces + j; for (i = 0;i < model->brushq1.numtextures;i++) @@ -2860,19 +2860,17 @@ void Mod_Q1BSP_GetVisible(model_t *model, const vec3_t point, const vec3_t mins, } */ -extern void R_Model_Brush_DrawSky(entity_render_t *ent); -extern void R_Model_Brush_Draw(entity_render_t *ent); -extern void R_Model_Brush_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer); -extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist); -extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, int numsurfaces, const int *surfacelist); +extern void R_Q1BSP_DrawSky(entity_render_t *ent); +extern void R_Q1BSP_Draw(entity_render_t *ent); +extern void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer); +extern void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist); +extern void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, int numsurfaces, const int *surfacelist); void Mod_Q1BSP_Load(model_t *mod, void *buffer) { int i, j, k; dheader_t *header; dmodel_t *bm; mempool_t *mainmempool; - char *loadname; - model_t *originalloadmodel; float dist, modelyawradius, modelradius, *vec; msurface_t *surf; int numshadowmeshtriangles; @@ -2935,6 +2933,9 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) Mod_Q1BSP_LoadNodes(&header->lumps[LUMP_NODES]); Mod_Q1BSP_LoadClipnodes(&header->lumps[LUMP_CLIPNODES]); + if (!mod->brushq1.lightdata) + mod->brush.LightPoint = NULL; + if (mod->brushq1.data_compressedpvs) Mem_Free(mod->brushq1.data_compressedpvs); mod->brushq1.data_compressedpvs = NULL; @@ -2946,10 +2947,9 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->numframes = 2; // regular and alternate animation mainmempool = mod->mempool; - loadname = mod->name; Mod_Q1BSP_LoadLightList(); - originalloadmodel = loadmodel; + loadmodel = loadmodel; // make a single combined shadow mesh to allow optimized shadow volume creation numshadowmeshtriangles = 0; @@ -2964,11 +2964,43 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) loadmodel->brush.shadowmesh = Mod_ShadowMesh_Finish(loadmodel->mempool, loadmodel->brush.shadowmesh, false, true); Mod_BuildTriangleNeighbors(loadmodel->brush.shadowmesh->neighbor3i, loadmodel->brush.shadowmesh->element3i, loadmodel->brush.shadowmesh->numtriangles); -// -// set up the submodels(FIXME: this is confusing) -// + // LordHavoc: to clear the fog around the original quake submodel code, I + // will explain: + // first of all, some background info on the submodels: + // model 0 is the map model (the world, named maps/e1m1.bsp for example) + // model 1 and higher are submodels (doors and the like, named *1, *2, etc) + // now the weird for loop itself: + // the loop functions in an odd way, on each iteration it sets up the + // current 'mod' model (which despite the confusing code IS the model of + // the number i), at the end of the loop it duplicates the model to become + // the next submodel, and loops back to set up the new submodel. + + // LordHavoc: now the explanation of my sane way (which works identically): + // set up the world model, then on each submodel copy from the world model + // and set up the submodel with the respective model info. for (i = 0;i < mod->brush.numsubmodels;i++) { + // LordHavoc: this code was originally at the end of this loop, but + // has been transformed to something more readable at the start here. + + // LordHavoc: only register submodels if it is the world + // (prevents external bsp models from replacing world submodels with + // their own) + if (loadmodel->isworldmodel && i) + { + char name[10]; + // duplicate the basic information + sprintf(name, "*%i", i); + mod = Mod_FindName(name); + // copy the base model to this one + *mod = *loadmodel; + // rename the clone back to its proper name + strcpy(mod->name, name); + // textures and memory belong to the main model + mod->texturepool = NULL; + mod->mempool = NULL; + } + bm = &mod->brushq1.submodels[i]; mod->brushq1.hulls[0].firstclipnode = bm->headnode[0]; @@ -2978,21 +3010,20 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->brushq1.hulls[j].lastclipnode = mod->brushq1.numclipnodes - 1; } - mod->brushq1.firstmodelsurface = bm->firstface; - mod->brushq1.nummodelsurfaces = bm->numfaces; + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; // make the model surface list (used by shadowing/lighting) - mod->numsurfaces = mod->brushq1.nummodelsurfaces; - mod->surfacelist = Mem_Alloc(originalloadmodel->mempool, mod->numsurfaces * sizeof(*mod->surfacelist)); - for (j = 0;j < mod->numsurfaces;j++) - mod->surfacelist[j] = mod->brushq1.firstmodelsurface + j; + mod->surfacelist = Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->surfacelist)); + for (j = 0;j < mod->nummodelsurfaces;j++) + mod->surfacelist[j] = mod->firstmodelsurface + j; // this gets altered below if sky is used mod->DrawSky = NULL; - mod->Draw = R_Model_Brush_Draw; - mod->GetLightInfo = R_Model_Brush_GetLightInfo; - mod->DrawShadowVolume = R_Model_Brush_DrawShadowVolume; - mod->DrawLight = R_Model_Brush_DrawLight; + mod->Draw = R_Q1BSP_Draw; + mod->GetLightInfo = R_Q1BSP_GetLightInfo; + mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; + mod->DrawLight = R_Q1BSP_DrawLight; if (i != 0) { mod->brush.GetPVS = NULL; @@ -3001,23 +3032,23 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->brush.LightPoint = NULL; mod->brush.AmbientSoundLevelsForPoint = NULL; } - mod->brushq1.pvstexturechains = Mem_Alloc(originalloadmodel->mempool, mod->brushq1.numtextures * sizeof(msurface_t **)); - mod->brushq1.pvstexturechainsbuffer = Mem_Alloc(originalloadmodel->mempool,(mod->brushq1.nummodelsurfaces + mod->brushq1.numtextures) * sizeof(msurface_t *)); - mod->brushq1.pvstexturechainslength = Mem_Alloc(originalloadmodel->mempool, mod->brushq1.numtextures * sizeof(int)); + mod->brushq1.pvstexturechains = Mem_Alloc(loadmodel->mempool, mod->brushq1.numtextures * sizeof(msurface_t **)); + mod->brushq1.pvstexturechainsbuffer = Mem_Alloc(loadmodel->mempool,(mod->nummodelsurfaces + mod->brushq1.numtextures) * sizeof(msurface_t *)); + mod->brushq1.pvstexturechainslength = Mem_Alloc(loadmodel->mempool, mod->brushq1.numtextures * sizeof(int)); Mod_Q1BSP_BuildPVSTextureChains(mod); - Mod_Q1BSP_BuildLightmapUpdateChains(originalloadmodel->mempool, mod); - if (mod->brushq1.nummodelsurfaces) + Mod_Q1BSP_BuildLightmapUpdateChains(loadmodel->mempool, mod); + if (mod->nummodelsurfaces) { // LordHavoc: calculate bmodel bounding box rather than trusting what it says mod->normalmins[0] = mod->normalmins[1] = mod->normalmins[2] = 1000000000.0f; mod->normalmaxs[0] = mod->normalmaxs[1] = mod->normalmaxs[2] = -1000000000.0f; modelyawradius = 0; modelradius = 0; - for (j = 0, surf = &mod->brushq1.surfaces[mod->brushq1.firstmodelsurface];j < mod->brushq1.nummodelsurfaces;j++, surf++) + for (j = 0, surf = &mod->brushq1.surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surf++) { // we only need to have a drawsky function if it is used(usually only on world model) if (surf->texinfo->texture->flags & SURF_DRAWSKY) - mod->DrawSky = R_Model_Brush_DrawSky; + mod->DrawSky = R_Q1BSP_DrawSky; // LordHavoc: submodels always clip, even if water if (mod->brush.numsubmodels - 1) surf->flags |= SURF_SOLIDCLIP; @@ -3051,30 +3082,13 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) else { // LordHavoc: empty submodel(lacrima.bsp has such a glitch) - Con_Printf("warning: empty submodel *%i in %s\n", i+1, loadname); + Con_Printf("warning: empty submodel *%i in %s\n", i+1, loadmodel->name); } - Mod_Q1BSP_BuildSurfaceNeighbors(mod->brushq1.surfaces + mod->brushq1.firstmodelsurface, mod->brushq1.nummodelsurfaces, originalloadmodel->mempool); + Mod_Q1BSP_BuildSurfaceNeighbors(mod->brushq1.surfaces + mod->firstmodelsurface, mod->nummodelsurfaces, loadmodel->mempool); mod->brushq1.num_visleafs = bm->visleafs; - - // LordHavoc: only register submodels if it is the world - // (prevents bsp models from replacing world submodels) - if (loadmodel->isworldmodel && i < (mod->brush.numsubmodels - 1)) - { - char name[10]; - // duplicate the basic information - sprintf(name, "*%i", i+1); - loadmodel = Mod_FindName(name); - *loadmodel = *mod; - strcpy(loadmodel->name, name); - // textures and memory belong to the main model - loadmodel->texturepool = NULL; - loadmodel->mempool = NULL; - mod = loadmodel; - } } - loadmodel = originalloadmodel; //Mod_Q1BSP_ProcessLightList(); if (developer.integer) @@ -3583,7 +3597,7 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) out->surfaceflags = LittleLong(in->surfaceflags); out->nativecontents = LittleLong(in->contents); out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents); - Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true); + Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, true, true); out->surfaceparms = -1; } @@ -3717,7 +3731,10 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) { out->surfaceparms = flags; if ((flags & Q3SURFACEPARM_SKY) && sky[0]) - strcpy(loadmodel->brush.skybox, sky); + { + // quake3 seems to append a _ to the skybox name, so this must do so as well + snprintf(loadmodel->brush.skybox, sizeof(loadmodel->brush.skybox), "%s_", sky); + } } } } @@ -3985,7 +4002,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l) static void Mod_Q3BSP_LoadFaces(lump_t *l) { q3dface_t *in; - q3mface_t *out; + q3msurface_t *out; int i, j, n, count, invalidelements, patchsize[2], finalwidth, finalheight, xlevel, ylevel, row0, row1, x, y, *e, finalvertices, finaltriangles; //int *originalelement3i; //int *originalneighbor3i; @@ -4456,7 +4473,7 @@ static void Mod_Q3BSP_LoadLeafBrushes(lump_t *l) static void Mod_Q3BSP_LoadLeafFaces(lump_t *l) { int *in; - q3mface_t **out; + q3msurface_t **out; int i, n, count; in = (void *)(mod_base + l->fileofs); @@ -4769,7 +4786,7 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, q3mnode_t *node int i, startside, endside; float dist1, dist2, midfrac, mid[3], nodesegmentmins[3], nodesegmentmaxs[3]; q3mleaf_t *leaf; - q3mface_t *face; + q3msurface_t *face; colbrushf_t *brush; if (startfrac > trace->realfraction) return; @@ -4853,7 +4870,7 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, q3mnode_t *nod float nodesegmentmins[3], nodesegmentmaxs[3]; q3mleaf_t *leaf; colbrushf_t *brush; - q3mface_t *face; + q3msurface_t *face; /* // find which nodes the line is in and recurse for them while (node->plane) @@ -5231,7 +5248,7 @@ static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const colbrushf_t *thisbrush_start, *thisbrush_end; matrix4x4_t startmatrix, endmatrix; static int markframe = 0; - q3mface_t *face; + q3msurface_t *face; memset(trace, 0, sizeof(*trace)); trace->fraction = 1; trace->realfraction = 1; @@ -5462,7 +5479,7 @@ void Mod_Q3BSP_RecursiveGetVisible(q3mnode_t *node, model_t *model, const vec3_t if ((pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex))) { int marksurfacenum; - q3mface_t *surf; + q3msurface_t *surf; if (maxleafs && *numleafs < maxleafs) leaflist[(*numleaf)++] = leaf; if (maxsurfaces) @@ -5518,7 +5535,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) int i, j, numshadowmeshtriangles; q3dheader_t *header; float corner[3], yawradius, modelradius; - q3mface_t *face; + q3msurface_t *face; mod->type = mod_brushq3; mod->numframes = 1; @@ -5618,9 +5635,9 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->brushq3.submodel = i; // make the model surface list (used by shadowing/lighting) - mod->numsurfaces = mod->brushq3.data_thismodel->numfaces; - mod->surfacelist = Mem_Alloc(loadmodel->mempool, mod->numsurfaces * sizeof(*mod->surfacelist)); - for (j = 0;j < mod->numsurfaces;j++) + mod->nummodelsurfaces = mod->brushq3.data_thismodel->numfaces; + mod->surfacelist = Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->surfacelist)); + for (j = 0;j < mod->nummodelsurfaces;j++) mod->surfacelist[j] = (mod->brushq3.data_thismodel->firstface - mod->brushq3.data_faces) + j; VectorCopy(mod->brushq3.data_thismodel->mins, mod->normalmins);