dheader_t *header;
dmodel_t *bm;
mempool_t *mainmempool;
- float dist, modelyawradius, modelradius, *vec;
+ float dist, modelyawradius, modelradius;
msurface_t *surface;
int numshadowmeshtriangles;
hullinfo_t hullinfo;
mod->brush.LightPoint = NULL;
mod->brush.AmbientSoundLevelsForPoint = NULL;
}
+
// 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);
VectorCopy(bm->maxs, mod->normalmaxs);
- VectorCopy(bm->mins, mod->yawmins);
- VectorCopy(bm->maxs, mod->yawmaxs);
- VectorCopy(bm->mins, mod->rotatedmins);
- VectorCopy(bm->maxs, mod->rotatedmaxs);
+ dist = max(fabs(mod->normalmins[0]), fabs(mod->normalmaxs[0]));
+ modelyawradius = max(fabs(mod->normalmins[1]), fabs(mod->normalmaxs[1]));
+ modelyawradius = dist*dist+modelyawradius*modelyawradius;
+ modelradius = max(fabs(mod->normalmins[2]), fabs(mod->normalmaxs[2]));
+ modelradius = modelyawradius + modelradius * modelradius;
+ modelyawradius = sqrt(modelyawradius);
+ modelradius = sqrt(modelradius);
+ mod->yawmins[0] = mod->yawmins[1] = -modelyawradius;
+ mod->yawmins[2] = mod->normalmins[2];
+ mod->yawmaxs[0] = mod->yawmaxs[1] = modelyawradius;
+ mod->yawmaxs[2] = mod->normalmaxs[2];
+ mod->rotatedmins[0] = mod->rotatedmins[1] = mod->rotatedmins[2] = -modelradius;
+ mod->rotatedmaxs[0] = mod->rotatedmaxs[1] = mod->rotatedmaxs[2] = modelradius;
+ mod->radius = modelradius;
+ mod->radius2 = modelradius * modelradius;
+
+ // 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)
{
- modelyawradius = 0;
- modelradius = 0;
for (j = 0, surface = &mod->data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++)
{
// we only need to have a drawsky function if it is used(usually only on world model)
mod->DrawSky = R_Q1BSP_DrawSky;
if (surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))
mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
- // calculate bounding shapes
- for (k = 0, vec = (loadmodel->surfmesh.data_vertex3f + 3 * surface->num_firstvertex);k < surface->num_vertices;k++, vec += 3)
- {
- dist = vec[0]*vec[0]+vec[1]*vec[1];
- if (modelyawradius < dist)
- modelyawradius = dist;
- dist += vec[2]*vec[2];
- if (modelradius < dist)
- modelradius = dist;
- }
}
- modelyawradius = sqrt(modelyawradius);
- modelradius = sqrt(modelradius);
- mod->yawmins[0] = min(mod->yawmins[0], -modelyawradius);
- mod->yawmaxs[0] = min(mod->yawmaxs[0], -modelyawradius);
- mod->yawmins[1] = min(mod->yawmins[1], modelyawradius);
- mod->yawmaxs[1] = min(mod->yawmaxs[1], modelyawradius);
- mod->rotatedmins[0] = min(mod->rotatedmins[0], -modelradius);
- mod->rotatedmaxs[0] = min(mod->rotatedmaxs[0], modelradius);
- mod->rotatedmins[1] = min(mod->rotatedmins[1], -modelradius);
- mod->rotatedmaxs[1] = min(mod->rotatedmaxs[1], modelradius);
- mod->rotatedmins[2] = min(mod->rotatedmins[2], -modelradius);
- mod->rotatedmaxs[2] = min(mod->rotatedmaxs[2], modelradius);
- mod->radius = modelradius;
- mod->radius2 = modelradius * modelradius;
// build lightstyle update chains
// (used to rapidly mark lightmapupdateflags on many surfaces
}
}
- convertedpixels = Mem_Alloc(tempmempool, size*size*4);
+ convertedpixels = (unsigned char *) Mem_Alloc(tempmempool, size*size*4);
loadmodel->brushq3.lightmapsize = size;
loadmodel->brushq3.num_originallightmaps = count;
loadmodel->num_surfaces = count;
if(count > 0)
- patchtess = Mem_Alloc(tempmempool, count * sizeof(*patchtess));
+ patchtess = (patchtess_t*) Mem_Alloc(tempmempool, count * sizeof(*patchtess));
i = 0;
oldi = i;
cxtess = Q3PatchTesselationOnX(patchsize[0], patchsize[1], 3, originalvertex3f, r_subdivisions_collision_tolerance.value);
cytess = Q3PatchTesselationOnY(patchsize[0], patchsize[1], 3, originalvertex3f, r_subdivisions_collision_tolerance.value);
// bound to user settings
- cxtess = bound(r_subdivisions_mintess.integer, xtess, r_subdivisions_collision_maxtess.integer);
- cytess = bound(r_subdivisions_mintess.integer, ytess, r_subdivisions_collision_maxtess.integer);
+ cxtess = bound(r_subdivisions_collision_mintess.integer, cxtess, r_subdivisions_collision_maxtess.integer);
+ cytess = bound(r_subdivisions_collision_mintess.integer, cytess, r_subdivisions_collision_maxtess.integer);
// bound to sanity settings
- cxtess = bound(1, xtess, 1024);
- cytess = bound(1, ytess, 1024);
+ cxtess = bound(1, cxtess, 1024);
+ cytess = bound(1, cytess, 1024);
// store it for the LOD grouping step
patchtess[patchtesscount].surface_id = i;
patchtess[patchtesscount].lodgroup[4] = in->specific.patch.maxs[1];
patchtess[patchtesscount].lodgroup[5] = in->specific.patch.maxs[2];
- patchtess[patchtesscount].cxtess = xtess;
- patchtess[patchtesscount].cytess = ytess;
+ patchtess[patchtesscount].cxtess = cxtess;
+ patchtess[patchtesscount].cytess = cytess;
++patchtesscount;
break;
case Q3FACETYPE_FLARE:
//out->lightmapinfo->styles[3] = 255;
}
+ i = oldi;
+ out = oldout;
+ for (;i < count;i++, out++)
+ {
+ if(out->num_vertices && out->num_triangles)
+ continue;
+ if(out->num_vertices == 0)
+ Con_Printf("Mod_Q3BSP_LoadFaces: surface %d has no vertices, ignoring\n", i);
+ if(out->num_triangles == 0)
+ Con_Printf("Mod_Q3BSP_LoadFaces: surface %d has no triangles, ignoring\n", i);
+ }
+
// for per pixel lighting
Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true);