//cvar_t r_subdivide_size = {CF_CLIENT | CF_ARCHIVE, "r_subdivide_size", "128", "how large water polygons should be (smaller values produce more polygons which give better warping effects)"};
-cvar_t mod_bsp_portalize = {CF_CLIENT | CF_SERVER, "mod_bsp_portalize", "0", "enables portal generation from BSP tree (may take several seconds per map), used by r_drawportals, r_useportalculling, r_shadow_realtime_world_compileportalculling, sv_cullentities_portal"};
+cvar_t mod_bsp_portalize = {CF_CLIENT | CF_SERVER, "mod_bsp_portalize", "1", "enables portal generation from BSP tree (may take several seconds per map), used by r_drawportals, r_useportalculling, r_shadow_realtime_world_compileportalculling, sv_cullentities_portal"};
cvar_t r_novis = {CF_CLIENT, "r_novis", "0", "draws whole level, see also sv_cullentities_pvs 0"};
cvar_t r_nosurftextures = {CF_CLIENT, "r_nosurftextures", "0", "pretends there was no texture lump found in the q1bsp/hlbsp loading (useful for debugging this rare case)"};
cvar_t r_subdivisions_tolerance = {CF_CLIENT, "r_subdivisions_tolerance", "4", "maximum error tolerance on curve subdivision for rendering purposes (in other words, the curves will be given as many polygons as necessary to represent curves at this quality)"};
// fixes up sky surfaces that have SKY contents behind them, so that they do not cast shadows (e1m5 logo shadow trick).
static void Mod_Q1BSP_AssignNoShadowSkySurfaces(model_t *mod)
{
- int i;
+ int surfaceindex;
msurface_t *surface;
vec3_t center;
int contents;
- for (i = 0, surface = mod->data_surfaces + mod->firstmodelsurface; i < mod->nummodelsurfaces; i++, surface++)
+ for (surfaceindex = mod->submodelsurfaces_start; surfaceindex < mod->submodelsurfaces_end;surfaceindex++)
{
+ surface = mod->data_surfaces + surfaceindex;
if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
{
// check if the point behind the surface polygon is SOLID or SKY contents
// TODO: calculate node bounding boxes during recursion and calculate a maximum plane size accordingly to improve precision (as most maps do not need 1 billion unit plane polygons)
PolygonD_QuadForPlane(nodeportal->points, nodeportal->plane.normal[0], nodeportal->plane.normal[1], nodeportal->plane.normal[2], nodeportal->plane.dist, 1024.0*1024.0*1024.0);
nodeportal->numpoints = 4;
- // side = 0; // shut up compiler warning -> should be no longer needed, Host_Error is declared noreturn now
+
for (portal = (portal_t *)node->portals;portal;portal = portal->next[side])
{
clipplane = portal->plane;
}
}
datapointer = (unsigned char *)Mem_Alloc(mod->mempool, mod->num_surfaces * sizeof(int) + totalstyles * sizeof(model_brush_lightstyleinfo_t) + totalstylesurfaces * sizeof(int *));
+ mod->modelsurfaces_sorted = (int*)datapointer;datapointer += mod->num_surfaces * sizeof(int);
for (i = 0;i < mod->brush.numsubmodels;i++)
{
// LadyHavoc: this code was originally at the end of this loop, but
mod->brushq1.hulls[j].lastclipnode = mod->brushq1.numclipnodes - 1;
}
- mod->firstmodelsurface = bm->firstface;
- mod->nummodelsurfaces = bm->numfaces;
+ mod->submodelsurfaces_start = bm->firstface;
+ mod->submodelsurfaces_end = bm->firstface + bm->numfaces;
// set node/leaf parents for this submodel
Mod_BSP_LoadNodes_RecursiveSetParent(mod->brush.data_nodes + mod->brushq1.hulls[0].firstclipnode, NULL);
// this has to occur after hull info has been set, as it uses Mod_Q1BSP_PointSuperContents
Mod_Q1BSP_AssignNoShadowSkySurfaces(mod);
- // make the model surface list (used by shadowing/lighting)
- mod->sortedmodelsurfaces = (int *)datapointer;datapointer += mod->nummodelsurfaces * sizeof(int);
- Mod_MakeSortedSurfaces(mod);
-
// copy the submodel bounds, then enlarge the yaw and rotated bounds according to radius
// (previously this code measured the radius of the vertices of surfaces in the submodel, but that broke submodels that contain only CLIP brushes, which do not produce surfaces)
VectorCopy(bm->mins, mod->normalmins);
mod->radius = modelradius;
mod->radius2 = modelradius * modelradius;
- // this gets altered below if sky or water is used
- mod->DrawSky = NULL;
- mod->DrawAddWaterPlanes = NULL;
+ Mod_SetDrawSkyAndWater(mod);
- // scan surfaces for sky and water and flag the submodel as possessing these features or not
- // build lightstyle lists for quick marking of dirty lightmaps when lightstyles flicker
- if (mod->nummodelsurfaces)
+ if (mod->submodelsurfaces_start < mod->submodelsurfaces_end)
{
- for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
- if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawSky = R_Mod_DrawSky;
-
- for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
- if (surface->texture && surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
-
// build lightstyle update chains
// (used to rapidly mark lightmapupdateflags on many surfaces
// when d_lightstylevalue changes)
memset(stylecounts, 0, sizeof(stylecounts));
- for (k = 0;k < mod->nummodelsurfaces;k++)
- {
- surface = mod->data_surfaces + mod->firstmodelsurface + k;
+ for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
for (j = 0;j < MAXLIGHTMAPS;j++)
- stylecounts[surface->lightmapinfo->styles[j]]++;
- }
+ stylecounts[mod->data_surfaces[k].lightmapinfo->styles[j]]++;
mod->brushq1.num_lightstyles = 0;
for (k = 0;k < 255;k++)
{
mod->brushq1.num_lightstyles++;
}
}
- for (k = 0;k < mod->nummodelsurfaces;k++)
+ for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
{
- surface = mod->data_surfaces + mod->firstmodelsurface + k;
+ surface = mod->data_surfaces + k;
for (j = 0;j < MAXLIGHTMAPS;j++)
{
if (surface->lightmapinfo->styles[j] != 255)
{
int r = remapstyles[surface->lightmapinfo->styles[j]];
- styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = mod->firstmodelsurface + k;
+ styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = k;
}
}
}
//Mod_Q1BSP_ProcessLightList();
}
}
+ mod = loadmodel;
+
+ // make the model surface list (used by shadowing/lighting)
+ Mod_MakeSortedSurfaces(loadmodel);
Con_DPrintf("Stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
}
}
}
datapointer = (unsigned char *)Mem_Alloc(mod->mempool, mod->num_surfaces * sizeof(int) + totalstyles * sizeof(model_brush_lightstyleinfo_t) + totalstylesurfaces * sizeof(int *));
+ mod->modelsurfaces_sorted = (int*)datapointer; datapointer += mod->num_surfaces * sizeof(int);
// set up the world model, then on each submodel copy from the world model
// and set up the submodel with the respective model info.
mod = loadmodel;
// we store the headnode (there's only one in Q2BSP) as if it were the first hull
mod->brushq1.hulls[0].firstclipnode = bm->headnode[0];
- mod->firstmodelsurface = bm->firstface;
- mod->nummodelsurfaces = bm->numfaces;
+ mod->submodelsurfaces_start = bm->firstface;
+ mod->submodelsurfaces_end = bm->firstface + bm->numfaces;
// set node/leaf parents for this submodel
// note: if the root of this submodel is a leaf (headnode[0] < 0) then there is nothing to do...
Mod_BSP_LoadNodes_RecursiveSetParent(rootnode, NULL);
// make the model surface list (used by shadowing/lighting)
- mod->sortedmodelsurfaces = (int *)datapointer;datapointer += mod->nummodelsurfaces * sizeof(int);
Mod_Q2BSP_FindSubmodelBrushRange_r(mod, rootnode, &firstbrush, &lastbrush);
if (firstbrush <= lastbrush)
{
mod->firstmodelbrush = 0;
mod->nummodelbrushes = 0;
}
- Mod_MakeSortedSurfaces(mod);
VectorCopy(bm->mins, mod->normalmins);
VectorCopy(bm->maxs, mod->normalmaxs);
mod->radius = modelradius;
mod->radius2 = modelradius * modelradius;
- // this gets altered below if sky or water is used
- mod->DrawSky = NULL;
- mod->DrawAddWaterPlanes = NULL;
+ Mod_SetDrawSkyAndWater(mod);
- // scan surfaces for sky and water and flag the submodel as possessing these features or not
// build lightstyle lists for quick marking of dirty lightmaps when lightstyles flicker
- if (mod->nummodelsurfaces)
+ if (mod->submodelsurfaces_start < mod->submodelsurfaces_end)
{
- for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
- if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawSky = R_Mod_DrawSky;
-
- for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
- if (surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
-
// build lightstyle update chains
// (used to rapidly mark lightmapupdateflags on many surfaces
// when d_lightstylevalue changes)
memset(stylecounts, 0, sizeof(stylecounts));
- for (k = 0;k < mod->nummodelsurfaces;k++)
- {
- surface = mod->data_surfaces + mod->firstmodelsurface + k;
+ for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
for (j = 0;j < MAXLIGHTMAPS;j++)
- stylecounts[surface->lightmapinfo->styles[j]]++;
- }
+ stylecounts[mod->data_surfaces[k].lightmapinfo->styles[j]]++;
mod->brushq1.num_lightstyles = 0;
for (k = 0;k < 255;k++)
{
mod->brushq1.num_lightstyles++;
}
}
- for (k = 0;k < mod->nummodelsurfaces;k++)
+ for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
{
- surface = mod->data_surfaces + mod->firstmodelsurface + k;
+ surface = mod->data_surfaces + k;
for (j = 0;j < MAXLIGHTMAPS;j++)
{
if (surface->lightmapinfo->styles[j] != 255)
{
int r = remapstyles[surface->lightmapinfo->styles[j]];
- styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = mod->firstmodelsurface + k;
+ styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = k;
}
}
}
}
mod = loadmodel;
+ // make the model surface list (used by shadowing/lighting)
+ Mod_MakeSortedSurfaces(loadmodel);
+
Con_DPrintf("Stats for q2bsp model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
}
int triangleindex;
int bihleafindex;
int nummodelbrushes = model->nummodelbrushes;
- int nummodelsurfaces = model->nummodelsurfaces;
const int *e;
const int *collisionelement3i;
const float *collisionvertex3f;
bihnumleafs = 0;
if (userendersurfaces)
{
- for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
- bihnumleafs += surface->num_triangles;
+ for (j = model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
+ bihnumleafs += model->data_surfaces[j].num_triangles;
}
else
{
for (brushindex = 0, brush = model->brush.data_brushes + brushindex+model->firstmodelbrush;brushindex < nummodelbrushes;brushindex++, brush++)
if (brush->colbrushf)
bihnumleafs++;
- for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
+ for (j = model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
{
- if (surface->texture->basematerialflags & MATERIALFLAG_MESHCOLLISIONS)
- bihnumleafs += surface->num_triangles + surface->num_collisiontriangles;
+ if (model->data_surfaces[j].texture->basematerialflags & MATERIALFLAG_MESHCOLLISIONS)
+ bihnumleafs += model->data_surfaces[j].num_triangles + model->data_surfaces[j].num_collisiontriangles;
else
- bihnumleafs += surface->num_collisiontriangles;
+ bihnumleafs += model->data_surfaces[j].num_collisiontriangles;
}
}
// add render surfaces
renderelement3i = model->surfmesh.data_element3i;
rendervertex3f = model->surfmesh.data_vertex3f;
- for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
+ for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
{
+ surface = model->data_surfaces + j;
for (triangleindex = 0, e = renderelement3i + 3*surface->num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
{
if (!userendersurfaces && !(surface->texture->basematerialflags & MATERIALFLAG_MESHCOLLISIONS))
// add collision surfaces
collisionelement3i = model->brush.data_collisionelement3i;
collisionvertex3f = model->brush.data_collisionvertex3f;
- for (j = 0, surface = model->data_surfaces + model->firstmodelsurface;j < nummodelsurfaces;j++, surface++)
+ for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
{
+ surface = model->data_surfaces + j;
for (triangleindex = 0, e = collisionelement3i + 3*surface->num_firstcollisiontriangle;triangleindex < surface->num_collisiontriangles;triangleindex++, e += 3)
{
bihleafs[bihleafindex].type = BIH_COLLISIONTRIANGLE;
loadmodel->brush.submodels = (model_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brush.numsubmodels * sizeof(model_t *));
mod = loadmodel;
+ mod->modelsurfaces_sorted = (int*)Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*mod->modelsurfaces_sorted));
for (i = 0;i < loadmodel->brush.numsubmodels;i++)
{
if (i > 0)
loadmodel->brush.submodels[i] = mod;
// make the model surface list (used by shadowing/lighting)
- mod->firstmodelsurface = mod->brushq3.data_models[i].firstface;
- mod->nummodelsurfaces = mod->brushq3.data_models[i].numfaces;
+ mod->submodelsurfaces_start = mod->brushq3.data_models[i].firstface;
+ mod->submodelsurfaces_end = mod->brushq3.data_models[i].firstface + mod->brushq3.data_models[i].numfaces;
mod->firstmodelbrush = mod->brushq3.data_models[i].firstbrush;
mod->nummodelbrushes = mod->brushq3.data_models[i].numbrushes;
- mod->sortedmodelsurfaces = (int *)Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->sortedmodelsurfaces));
- Mod_MakeSortedSurfaces(mod);
VectorCopy(mod->brushq3.data_models[i].mins, mod->normalmins);
VectorCopy(mod->brushq3.data_models[i].maxs, mod->normalmaxs);
// outside the level - an unimportant concern)
//printf("Editing model %d... BEFORE re-bounding: %f %f %f - %f %f %f\n", i, mod->normalmins[0], mod->normalmins[1], mod->normalmins[2], mod->normalmaxs[0], mod->normalmaxs[1], mod->normalmaxs[2]);
- for (j = 0;j < mod->nummodelsurfaces;j++)
+ for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
{
- const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
+ const msurface_t *surface = mod->data_surfaces + j;
const float *v = mod->surfmesh.data_vertex3f + 3 * surface->num_firstvertex;
int k;
if (!surface->num_vertices)
mod->radius = modelradius;
mod->radius2 = modelradius * modelradius;
- // this gets altered below if sky or water is used
- mod->DrawSky = NULL;
- mod->DrawAddWaterPlanes = NULL;
-
- for (j = 0;j < mod->nummodelsurfaces;j++)
- if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & MATERIALFLAG_SKY)
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawSky = R_Mod_DrawSky;
-
- for (j = 0;j < mod->nummodelsurfaces;j++)
- if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
-
+ Mod_SetDrawSkyAndWater(mod);
Mod_MakeCollisionBIH(mod, false, &mod->collision_bih);
Mod_MakeCollisionBIH(mod, true, &mod->render_bih);
if (i == 0)
Mod_BuildVBOs();
}
+ mod = loadmodel;
+
+ // make the model surface list (used by shadowing/lighting)
+ Mod_MakeSortedSurfaces(loadmodel);
if (mod_q3bsp_sRGBlightmaps.integer)
{
Host_Error("Mod_IBSP_Load: unknown/unsupported version %i", i);
}
+void Mod_VBSP_Load(model_t *mod, void *buffer, void *bufferend)
+{
+ Host_Error("Mod_VBSP_Load: not yet implemented");
+}
+
void Mod_MAP_Load(model_t *mod, void *buffer, void *bufferend)
{
Host_Error("Mod_MAP_Load: not yet implemented");
loadmodel->num_texturesperskin = numtextures;
data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + numtriangles * sizeof(int[3]) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0) + numvertices * sizeof(float[14]) + loadmodel->brush.numsubmodels * sizeof(model_t *));
loadmodel->brush.submodels = (model_t **)data;data += loadmodel->brush.numsubmodels * sizeof(model_t *);
- loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
+ loadmodel->modelsurfaces_sorted = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
loadmodel->surfmesh.num_vertices = numvertices;
loadmodel->surfmesh.num_triangles = numtriangles;
loadmodel->brush.data_pvsclusters = nobsp_pvs;
//if (loadmodel->num_nodes) loadmodel->data_nodes = (mnode_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_nodes * sizeof(mnode_t));
//loadmodel->data_leafsurfaces = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->num_leafsurfaces * sizeof(int));
- loadmodel->brush.data_leafsurfaces = loadmodel->sortedmodelsurfaces;
+ loadmodel->brush.data_leafsurfaces = loadmodel->modelsurfaces_sorted;
VectorCopy(loadmodel->normalmins, loadmodel->brush.data_leafs->mins);
VectorCopy(loadmodel->normalmaxs, loadmodel->brush.data_leafs->maxs);
loadmodel->brush.data_leafs->combinedsupercontents = 0; // FIXME?
loadmodel->brush.submodels[i] = mod;
// make the model surface list (used by shadowing/lighting)
- mod->firstmodelsurface = submodelfirstsurface[i];
- mod->nummodelsurfaces = submodelfirstsurface[i+1] - submodelfirstsurface[i];
+ mod->submodelsurfaces_start = submodelfirstsurface[i];
+ mod->submodelsurfaces_end = submodelfirstsurface[i+1];
mod->firstmodelbrush = 0;
mod->nummodelbrushes = 0;
- mod->sortedmodelsurfaces = loadmodel->sortedmodelsurfaces + mod->firstmodelsurface;
- Mod_MakeSortedSurfaces(mod);
VectorClear(mod->normalmins);
VectorClear(mod->normalmaxs);
l = false;
- for (j = 0;j < mod->nummodelsurfaces;j++)
+ for (j = mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
{
- const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
+ const msurface_t *surface = mod->data_surfaces + j;
const float *v3f = mod->surfmesh.data_vertex3f + 3 * surface->num_firstvertex;
int k;
if (!surface->num_vertices)
mod->radius = modelradius;
mod->radius2 = modelradius * modelradius;
- // this gets altered below if sky or water is used
- mod->DrawSky = NULL;
- mod->DrawAddWaterPlanes = NULL;
-
- for (j = 0;j < mod->nummodelsurfaces;j++)
- if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & MATERIALFLAG_SKY)
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawSky = R_Mod_DrawSky;
-
- for (j = 0;j < mod->nummodelsurfaces;j++)
- if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
- break;
- if (j < mod->nummodelsurfaces)
- mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
+ Mod_SetDrawSkyAndWater(mod);
Mod_MakeCollisionBIH(mod, true, &mod->collision_bih);
mod->render_bih = mod->collision_bih;
mod = loadmodel;
Mem_Free(submodelfirstsurface);
+ // make the model surface list (used by shadowing/lighting)
+ Mod_MakeSortedSurfaces(loadmodel);
+
Con_DPrintf("Stats for obj model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
}