ref: 28eafdc8ebdc8f0c05196cc45cc9bb38ae4550a6
dir: /model_brush.c/
#include "quakedef.h" void BSP_MakeHull0(model_t *mod); model_t *Mod_FindName (char *name); int BSP_LoadClipnodes(model_t *mod, byte *in, int sz); int BSP_LoadEdges(model_t *mod, byte *in, int sz); int BSP_LoadEntities(model_t *mod, byte *in, int sz); int BSP_LoadFaces(model_t *mod, byte *in, int sz); int BSP_LoadLeafs(model_t *mod, byte *in, int sz); int BSP_LoadLighting(model_t *mod, byte *in, int sz); int BSP_LoadMarksurfaces(model_t *mod, byte *in, int sz); int BSP_LoadNodes(model_t *mod, byte *in, int sz); int BSP_LoadPlanes(model_t *mod, byte *in, int sz); int BSP_LoadSubmodels(model_t *mod, byte *in, int sz); int BSP_LoadSurfedges(model_t *mod, byte *in, int sz); int BSP_LoadTexinfo(model_t *mod, byte *in, int sz); int BSP_LoadTextures(model_t *mod, byte *in, int sz); int BSP_LoadVertexes(model_t *mod, byte *in, int sz); int BSP_LoadVisibility(model_t *mod, byte *in, int sz); int BSP2_LoadClipnodes(model_t *mod, byte *in, int sz); int BSP2_LoadEdges(model_t *mod, byte *in, int sz); int BSP2_LoadFaces(model_t *mod, byte *in, int sz); int BSP2_LoadLeafs(model_t *mod, byte *in, int sz); int BSP2_LoadMarksurfaces(model_t *mod, byte *in, int sz); int BSP2_LoadNodes(model_t *mod, byte *in, int sz); static float RadiusFromBounds(vec3_t mins, vec3_t maxs) { int i; vec3_t corner; float fmin, fmax; for(i=0 ; i<3 ; i++){ fmin = fabs(mins[i]); fmax = fabs(maxs[i]); corner[i] = max(fmin, fmax); } return Length(corner); } void Mod_LoadBrushModel(model_t *mod, byte *in0, int total) { int i, j, ver, off, sz; model_t *submod; byte *in; submodel_t *bm; char name[16]; int (*loadf[HEADER_LUMPS])(model_t *, byte *, int) = { [LUMP_VERTEXES] = BSP_LoadVertexes, [LUMP_EDGES] = nil, [LUMP_SURFEDGES] = BSP_LoadSurfedges, [LUMP_TEXTURES] = BSP_LoadTextures, [LUMP_LIGHTING] = BSP_LoadLighting, [LUMP_PLANES] = BSP_LoadPlanes, [LUMP_TEXINFO] = BSP_LoadTexinfo, [LUMP_FACES] = nil, [LUMP_MARKSURFACES] = nil, [LUMP_VISIBILITY] = BSP_LoadVisibility, [LUMP_LEAFS] = nil, [LUMP_NODES] = nil, [LUMP_CLIPNODES] = nil, [LUMP_ENTITIES] = BSP_LoadEntities, [LUMP_MODELS] = BSP_LoadSubmodels, }; static const int order[HEADER_LUMPS] = { LUMP_VERTEXES, LUMP_EDGES, LUMP_SURFEDGES, LUMP_TEXTURES, LUMP_LIGHTING, LUMP_PLANES, LUMP_TEXINFO, LUMP_FACES, LUMP_MARKSURFACES, LUMP_VISIBILITY, LUMP_LEAFS, LUMP_NODES, LUMP_CLIPNODES, LUMP_ENTITIES, LUMP_MODELS, }; in = in0; ver = le32(in); if(ver == BSPVERSION){ loadf[LUMP_EDGES] = BSP_LoadEdges; loadf[LUMP_FACES] = BSP_LoadFaces; loadf[LUMP_MARKSURFACES] = BSP_LoadMarksurfaces; loadf[LUMP_LEAFS] = BSP_LoadLeafs; loadf[LUMP_NODES] = BSP_LoadNodes; loadf[LUMP_CLIPNODES] = BSP_LoadClipnodes; }else if(ver == BSP2VERSION){ loadf[LUMP_EDGES] = BSP2_LoadEdges; loadf[LUMP_FACES] = BSP2_LoadFaces; loadf[LUMP_MARKSURFACES] = BSP2_LoadMarksurfaces; loadf[LUMP_LEAFS] = BSP2_LoadLeafs; loadf[LUMP_NODES] = BSP2_LoadNodes; loadf[LUMP_CLIPNODES] = BSP2_LoadClipnodes; }else{ werrstr("unsupported version: %ux", ver); goto err; } if(total < 4+nelem(loadf)*2*4){ werrstr("truncated: total=%d", total); goto err; } mod->type = mod_brush; for(i = 0; i < nelem(loadf); i++){ in = in0+4+2*4*order[i]; off = le32(in); sz = le32(in); if(off < 0 || sz < 0 || off+sz > total){ werrstr("invalid lump off=%d sz=%d total=%d", off, sz, total); goto err; } if(loadf[order[i]](mod, in0+off, sz) != 0) goto err; } BSP_MakeHull0(mod); mod->numframes = 2; // regular and alternate animation mod->flags = 0; // set up the submodels (FIXME: this is confusing) for(i = 0; i < mod->numsubmodels; i++){ bm = &mod->submodels[i]; mod->hulls[0].firstclipnode = bm->headnode[0]; for(j = 1; j < MAX_MAP_HULLS; j++){ mod->hulls[j].firstclipnode = bm->headnode[j]; mod->hulls[j].lastclipnode = mod->numclipnodes-1; } mod->firstmodelsurface = bm->firstface; mod->nummodelsurfaces = bm->numfaces; mod->blend = false; for(j = bm->firstface; j < bm->firstface+bm->numfaces; j++){ if(mod->surfaces[j].flags & SURF_TRANS){ mod->blend = true; break; } } VectorCopy(bm->maxs, mod->maxs); VectorCopy(bm->mins, mod->mins); mod->radius = RadiusFromBounds(mod->mins, mod->maxs); mod->numleafs = bm->visleafs; if(i < mod->numsubmodels-1){ snprint(name, sizeof(name), "*%d", i+1); submod = Mod_FindName(name); *submod = *mod; strcpy(submod->name, name); mod = submod; } } return; err: Host_Error("Mod_LoadBrushModel: %s: %s", mod->name, lerr()); }