cvar_t mod_generatelightmaps_vertexradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexradius", "16", "sampling area around each vertex"};
cvar_t mod_generatelightmaps_gridradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridradius", "64", "sampling area around each lightgrid cell center"};
-dp_model_t *loadmodel;
+model_t *loadmodel;
// Supported model formats
static modloader_t loader[] =
{NULL, "BSP2", 4, Mod_BSP2_Load},
{NULL, "2PSB", 4, Mod_2PSB_Load},
{NULL, "IBSP", 4, Mod_IBSP_Load},
+ {NULL, "VBSP", 4, Mod_VBSP_Load},
{NULL, "ZYMOTICMODEL", 13, Mod_ZYMOTICMODEL_Load},
{NULL, "DARKPLACESMODEL", 16, Mod_DARKPLACESMODEL_Load},
{NULL, "PSKMODEL", 9, Mod_PSKMODEL_Load},
{
int i, count;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
SCR_PushLoadingScreen("Loading models", 1.0);
count = 0;
for (i = 0;i < nummodels;i++)
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
if (mod->used)
++count;
for (i = 0;i < nummodels;i++)
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
if (mod->used)
{
SCR_PushLoadingScreen(mod->name, 1.0 / count);
{
int i;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
for (i = 0;i < nummodels;i++)
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && (mod->loaded || mod->mempool))
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && (mod->loaded || mod->mempool))
Mod_UnloadModel(mod);
Mod_FreeQ3Shaders();
msurface_t *surface;
int i, j, k, l, surfacenum, ssize, tsize;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
for (i = 0;i < nummodels;i++)
{
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool)
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool)
{
for (j = 0;j < mod->num_textures && mod->data_textures;j++)
{
for (i = 0;i < nummodels;i++)
{
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_surfaces)
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_surfaces)
{
for (surfacenum = 0, surface = mod->data_surfaces;surfacenum < mod->num_surfaces;surfacenum++, surface++)
{
void Mod_Init (void)
{
mod_mempool = Mem_AllocPool("modelinfo", 0, NULL);
- Mem_ExpandableArray_NewArray(&models, mod_mempool, sizeof(dp_model_t), 16);
+ Mem_ExpandableArray_NewArray(&models, mod_mempool, sizeof(model_t), 16);
Mod_BrushInit();
Mod_AliasInit();
R_RegisterModule("Models", mod_start, mod_shutdown, mod_newmap, NULL, NULL);
}
-void Mod_UnloadModel (dp_model_t *mod)
+void Mod_UnloadModel (model_t *mod)
{
char name[MAX_QPATH];
qbool used;
- dp_model_t *parentmodel;
+ model_t *parentmodel;
if (developer_loading.integer)
Con_Printf("unloading model %s\n", mod->name);
R_FreeTexturePool(&mod->texturepool);
Mem_FreePool(&mod->mempool);
// clear the struct to make it available
- memset(mod, 0, sizeof(dp_model_t));
+ memset(mod, 0, sizeof(model_t));
// restore the fields we want to preserve
strlcpy(mod->name, name, sizeof(mod->name));
mod->brush.parentmodel = parentmodel;
static void Mod_FrameGroupify_ParseGroups_Store (unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)
{
- dp_model_t *mod = (dp_model_t *) pass;
+ model_t *mod = (model_t *) pass;
animscene_t *anim = &mod->animscenes[i];
if(name)
strlcpy(anim->name, name, sizeof(anim[i].name));
//Con_Printf("frame group %d is %d %d %f %d\n", i, start, len, fps, loop);
}
-static void Mod_FrameGroupify(dp_model_t *mod, const char *buf)
+static void Mod_FrameGroupify(model_t *mod, const char *buf)
{
unsigned int cnt;
Mod_FrameGroupify_ParseGroups(buf, Mod_FrameGroupify_ParseGroups_Store, mod);
}
-static void Mod_FindPotentialDeforms(dp_model_t *mod)
+static void Mod_FindPotentialDeforms(model_t *mod)
{
int i, j;
texture_t *texture;
Loads a model
==================
*/
-dp_model_t *Mod_LoadModel(dp_model_t *mod, qbool crash, qbool checkdisk)
+model_t *Mod_LoadModel(model_t *mod, qbool crash, qbool checkdisk)
{
unsigned int crc;
void *buf;
// all models use memory, so allocate a memory pool
mod->mempool = Mem_AllocPool(mod->name, 0, NULL);
- // call the apropriate loader
+ // We need to have a reference to the base model in case we're parsing submodels
loadmodel = mod;
- // Try matching magic bytes.
+ // Call the appropriate loader. Try matching magic bytes.
for (i = 0; loader[i].Load; i++)
{
// Headerless formats can just load based on extension. Otherwise match the magic string.
Mem_Free(buf);
}
+ Mod_SetDrawSkyAndWater(mod);
Mod_BuildVBOs();
break;
}
{
int i;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
for (i = 0;i < nummodels;i++)
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0])
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0])
mod->used = false;
}
{
int i;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
for (i = 0;i < nummodels;i++)
{
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !mod->used)
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !mod->used)
{
Mod_UnloadModel(mod);
Mem_ExpandableArray_FreeRecord(&models, mod);
==================
*/
-dp_model_t *Mod_FindName(const char *name, const char *parentname)
+model_t *Mod_FindName(const char *name, const char *parentname)
{
int i;
int nummodels;
- dp_model_t *mod;
+ model_t *mod;
if (!parentname)
parentname = "";
// search the currently loaded models
for (i = 0;i < nummodels;i++)
{
- if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !strcmp(mod->name, name) && ((!mod->brush.parentmodel && !parentname[0]) || (mod->brush.parentmodel && parentname[0] && !strcmp(mod->brush.parentmodel->name, parentname))))
+ if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !strcmp(mod->name, name) && ((!mod->brush.parentmodel && !parentname[0]) || (mod->brush.parentmodel && parentname[0] && !strcmp(mod->brush.parentmodel->name, parentname))))
{
mod->used = true;
return mod;
}
// no match found, create a new one
- mod = (dp_model_t *) Mem_ExpandableArray_AllocRecord(&models);
+ mod = (model_t *) Mem_ExpandableArray_AllocRecord(&models);
strlcpy(mod->name, name, sizeof(mod->name));
if (parentname[0])
mod->brush.parentmodel = Mod_FindName(parentname, NULL);
Loads in a model for the given name
==================
*/
-dp_model_t *Mod_ForName(const char *name, qbool crash, qbool checkdisk, const char *parentname)
+model_t *Mod_ForName(const char *name, qbool crash, qbool checkdisk, const char *parentname)
{
- dp_model_t *model;
+ model_t *model;
// FIXME: So we don't crash if a server is started early.
if(!vid_opened)
- Host_StartVideo();
+ CL_StartVideo();
model = Mod_FindName(name, parentname);
if (!model->loaded || checkdisk)
{
int i, count;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
SCR_PushLoadingScreen("Reloading models", 1.0);
count = 0;
for (i = 0;i < nummodels;i++)
- if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used)
+ if ((mod = (model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used)
++count;
for (i = 0;i < nummodels;i++)
- if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used)
+ if ((mod = (model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used)
{
SCR_PushLoadingScreen(mod->name, 1.0 / count);
Mod_LoadModel(mod, true, true);
{
int i;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
- dp_model_t *mod;
+ model_t *mod;
Con_Print("Loaded models:\n");
for (i = 0;i < nummodels;i++)
{
- if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
+ if ((mod = (model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
{
if (mod->brush.numsubmodels)
Con_Printf("%4iK %s (%i submodels)\n", mod->mempool ? (int)((mod->mempool->totalsize + 1023) / 1024) : 0, mod->name, mod->brush.numsubmodels);
Mem_Free(mesh);
}
-void Mod_CreateCollisionMesh(dp_model_t *mod)
+void Mod_CreateCollisionMesh(model_t *mod)
{
int k, numcollisionmeshtriangles;
qbool usesinglecollisionmesh = false;
// 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++)
+ for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
{
- surface = mod->data_surfaces + mod->firstmodelsurface + k;
+ surface = mod->data_surfaces + k;
if (!strcmp(surface->texture->name, "collision") || !strcmp(surface->texture->name, "collisionconvex")) // found collision mesh
{
usesinglecollisionmesh = true;
Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
else
{
- 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;
if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
continue;
Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
#endif
#if 0
-void Mod_Terrain_SurfaceRecurseChunk(dp_model_t *model, int stepsize, int x, int y)
+void Mod_Terrain_SurfaceRecurseChunk(model_t *model, int stepsize, int x, int y)
{
float mins[3];
float maxs[3];
// TODO: emit skirt vertices
}
-void Mod_Terrain_UpdateSurfacesForViewOrigin(dp_model_t *model)
+void Mod_Terrain_UpdateSurfacesForViewOrigin(model_t *model)
{
for (y = 0;y < model->terrain.size[1];y += model->terrain.
Mod_Terrain_SurfaceRecurseChunk(model, model->terrain.maxstepsize, x, y);
for (j = 0; j < Q3MAXTCMODS && layer->tcmods[j].tcmod != Q3TCMOD_NONE; j++)
shaderpass->tcmods[j] = layer->tcmods[j];
for (j = 0; j < layer->numframes; j++)
- {
- for (int i = 0; layer->texturename[j][i]; i++)
- if(layer->texturename[j][i] == '\\')
- layer->texturename[j][i] = '/';
shaderpass->skinframes[j] = R_SkinFrame_LoadExternal(layer->texturename[j], texflags, false, true);
- }
return shaderpass;
}
*lastvertexpointer = lastvertex;
}
-void Mod_MakeSortedSurfaces(dp_model_t *mod)
+void Mod_SetDrawSkyAndWater(model_t* mod)
+{
+ int j;
+ uint64_t basematerialflags = 0;
+ // by default assume there is no sky or water used in this model
+ mod->DrawSky = NULL;
+ mod->DrawAddWaterPlanes = NULL;
+ // combine all basematerialflags observed in the submodelsurfaces range, then check for special flags
+ for (j = mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
+ if (mod->data_surfaces[j].texture)
+ basematerialflags |= mod->data_surfaces[j].texture->basematerialflags;
+ if (basematerialflags & MATERIALFLAG_SKY)
+ mod->DrawSky = R_Mod_DrawSky;
+ if (basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
+}
+
+typedef struct Mod_MakeSortedSurfaces_qsortsurface_s
+{
+ int surfaceindex;
+ q3deffect_t* effect;
+ texture_t* texture;
+ rtexture_t* lightmaptexture;
+}
+Mod_MakeSortedSurfaces_qsortsurface_t;
+
+static int Mod_MakeSortedSurfaces_qsortfunc(const void *a, const void *b)
+{
+ const Mod_MakeSortedSurfaces_qsortsurface_t* l = (Mod_MakeSortedSurfaces_qsortsurface_t*)a;
+ const Mod_MakeSortedSurfaces_qsortsurface_t* r = (Mod_MakeSortedSurfaces_qsortsurface_t*)b;
+ if (l->effect < r->effect)
+ return -1;
+ if (l->effect > r->effect)
+ return 1;
+ if (l->texture < r->texture)
+ return -1;
+ if (l->texture > r->texture)
+ return 1;
+ if (l->lightmaptexture < r->lightmaptexture)
+ return -1;
+ if (l->lightmaptexture > r->lightmaptexture)
+ return 1;
+ if (l->surfaceindex < r->surfaceindex)
+ return -1;
+ if (l->surfaceindex > r->surfaceindex)
+ return 1;
+ return 0;
+}
+
+void Mod_MakeSortedSurfaces(model_t *mod)
{
// make an optimal set of texture-sorted batches to draw...
- int j, t;
- int *firstsurfacefortexture;
- int *numsurfacesfortexture;
- if (!mod->sortedmodelsurfaces)
- mod->sortedmodelsurfaces = (int *) Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->sortedmodelsurfaces));
- firstsurfacefortexture = (int *) Mem_Alloc(tempmempool, mod->num_textures * sizeof(*firstsurfacefortexture));
- numsurfacesfortexture = (int *) Mem_Alloc(tempmempool, mod->num_textures * sizeof(*numsurfacesfortexture));
- memset(numsurfacesfortexture, 0, mod->num_textures * sizeof(*numsurfacesfortexture));
- for (j = 0;j < mod->nummodelsurfaces;j++)
- {
- const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
- if(!surface->texture)
- continue;
- t = (int)(surface->texture - mod->data_textures);
- numsurfacesfortexture[t]++;
- }
- j = 0;
- for (t = 0;t < mod->num_textures;t++)
- {
- firstsurfacefortexture[t] = j;
- j += numsurfacesfortexture[t];
- }
- for (j = 0;j < mod->nummodelsurfaces;j++)
+ int j, k;
+ Mod_MakeSortedSurfaces_qsortsurface_t *info;
+
+ if(cls.state == ca_dedicated)
+ return;
+
+ info = (Mod_MakeSortedSurfaces_qsortsurface_t*)Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*info));
+ if (!mod->modelsurfaces_sorted)
+ mod->modelsurfaces_sorted = (int *) Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*mod->modelsurfaces_sorted));
+ // the goal is to sort by submodel (can't change which submodel a surface belongs to), and then by effects and textures
+ for (j = 0; j < mod->num_surfaces; j++)
{
- const msurface_t *surface = mod->data_surfaces + j + mod->firstmodelsurface;
- if (!surface->texture)
- continue;
- t = (int)(surface->texture - mod->data_textures);
- mod->sortedmodelsurfaces[firstsurfacefortexture[t]++] = j + mod->firstmodelsurface;
+ info[j].surfaceindex = j;
+ info[j].effect = mod->data_surfaces[j].effect;
+ info[j].texture = mod->data_surfaces[j].texture;
+ info[j].lightmaptexture = mod->data_surfaces[j].lightmaptexture;
}
- Mem_Free(firstsurfacefortexture);
- Mem_Free(numsurfacesfortexture);
+ for (k = 0; k < mod->brush.numsubmodels; k++)
+ if (mod->brush.submodels[k]->submodelsurfaces_end > mod->brush.submodels[k]->submodelsurfaces_start + 1)
+ qsort(info + mod->brush.submodels[k]->submodelsurfaces_start, (size_t)mod->brush.submodels[k]->submodelsurfaces_end - mod->brush.submodels[k]->submodelsurfaces_start, sizeof(*info), Mod_MakeSortedSurfaces_qsortfunc);
+ for (j = 0; j < mod->num_surfaces; j++)
+ mod->modelsurfaces_sorted[j] = info[j].surfaceindex;
+ Mem_Free(info);
}
void Mod_BuildVBOs(void)
}
extern cvar_t mod_obj_orientation;
-static void Mod_Decompile_OBJ(dp_model_t *model, const char *filename, const char *mtlfilename, const char *originalfilename)
+static void Mod_Decompile_OBJ(model_t *model, const char *filename, const char *mtlfilename, const char *originalfilename)
{
int submodelindex, vertexindex, surfaceindex, triangleindex, textureindex, countvertices = 0, countsurfaces = 0, countfaces = 0, counttextures = 0;
int a, b, c;
const msurface_t *surface;
const int maxtextures = 256;
char *texturenames = (char *) Z_Malloc(maxtextures * MAX_QPATH);
- dp_model_t *submodel;
+ model_t *submodel;
// construct the mtllib file
l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "# mtllib for %s exported by darkplaces engine\n", originalfilename);
if (l > 0)
outbufferpos += l;
submodel = model->brush.numsubmodels ? model->brush.submodels[submodelindex] : model;
- for (surfaceindex = 0;surfaceindex < submodel->nummodelsurfaces;surfaceindex++)
+ for (surfaceindex = submodel->submodelsurfaces_start;surfaceindex < submodel->submodelsurfaces_end;surfaceindex++)
{
- surface = model->data_surfaces + submodel->sortedmodelsurfaces[surfaceindex];
+ surface = model->data_surfaces + surfaceindex;
l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "usemtl %s\n", (surface->texture && surface->texture->name[0]) ? surface->texture->name : "default");
if (l > 0)
outbufferpos += l;
Con_Printf("Wrote %s (%i bytes, %i vertices, %i faces, %i surfaces with %i distinct textures)\n", filename, (int)outbufferpos, countvertices, countfaces, countsurfaces, counttextures);
}
-static void Mod_Decompile_SMD(dp_model_t *model, const char *filename, int firstpose, int numposes, qbool writetriangles)
+static void Mod_Decompile_SMD(model_t *model, const char *filename, int firstpose, int numposes, qbool writetriangles)
{
int countnodes = 0, counttriangles = 0, countframes = 0;
int surfaceindex;
// strangely the smd angles are for a transposed matrix, so we
// have to generate a transposed matrix, then convert that...
Matrix4x4_FromBonePose7s(&posematrix, model->num_posescale, model->data_poses7s + 7*(model->num_bones * poseindex + transformindex));
- Matrix4x4_ToArray12FloatGL(&posematrix, mtest[0]);
+ Matrix4x4_ToArray12FloatGL(&posematrix, mtest);
AnglesFromVectors(angles, mtest[0], mtest[2], false);
if (angles[0] >= 180) angles[0] -= 360;
if (angles[1] >= 180) angles[1] -= 360;
static void Mod_Decompile_f(cmd_state_t *cmd)
{
int i, j, k, l, first, count;
- dp_model_t *mod;
+ model_t *mod;
char inname[MAX_QPATH];
char outname[MAX_QPATH];
char mtlname[MAX_QPATH];
extern cvar_t r_shadow_lightattenuationdividebias;
extern cvar_t r_shadow_lightattenuationlinearscale;
-static void Mod_GenerateLightmaps_LightPoint(dp_model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
+static void Mod_GenerateLightmaps_LightPoint(model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
{
int i;
int index;
VectorCopy(dir, lightdir);
}
-static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const dp_model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
+static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
{
int surfaceindex;
int triangleindex;
const int *element3i = model->surfmesh.data_element3i;
const int *e;
float v2[3][3];
- for (surfaceindex = 0, surface = model->data_surfaces;surfaceindex < model->nummodelsurfaces;surfaceindex++, surface++)
+ for (surfaceindex = model->submodelsurfaces_start;surfaceindex < model->submodelsurfaces_end;surfaceindex++)
{
+ surface = model->data_surfaces + surfaceindex;
if (!BoxesOverlap(surface->mins, surface->maxs, mins, maxs))
continue;
if (surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW)
}
}
-static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP(dp_model_t *model, lightmaplight_t *lightinfo)
+static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP(model_t *model, lightmaplight_t *lightinfo)
{
int maxnodes = 1<<14;
svbsp_node_t *nodes;
Mem_Free(nodes);
}
-static void Mod_GenerateLightmaps_CreateLights(dp_model_t *model)
+static void Mod_GenerateLightmaps_CreateLights(model_t *model)
{
int index;
int result;
}
}
-static void Mod_GenerateLightmaps_DestroyLights(dp_model_t *model)
+static void Mod_GenerateLightmaps_DestroyLights(model_t *model)
{
int i;
if (mod_generatelightmaps_lightinfo)
else {s->diffusepitch = (unsigned char)(acos(dir[2]) * (127.5f/M_PI));s->diffuseyaw = (unsigned char)(atan2(dir[1], dir[0]) * (127.5f/M_PI));}
}
-static void Mod_GenerateLightmaps_InitSampleOffsets(dp_model_t *model)
+static void Mod_GenerateLightmaps_InitSampleOffsets(model_t *model)
{
float radius[3];
float temp[3];
}
}
-static void Mod_GenerateLightmaps_DestroyLightmaps(dp_model_t *model)
+static void Mod_GenerateLightmaps_DestroyLightmaps(model_t *model)
{
msurface_t *surface;
int surfaceindex;
}
}
-static void Mod_GenerateLightmaps_UnweldTriangles(dp_model_t *model)
+static void Mod_GenerateLightmaps_UnweldTriangles(model_t *model)
{
msurface_t *surface;
int surfaceindex;
model->brush.submodels[i]->surfmesh = model->surfmesh;
}
-static void Mod_GenerateLightmaps_CreateTriangleInformation(dp_model_t *model)
+static void Mod_GenerateLightmaps_CreateTriangleInformation(model_t *model)
{
msurface_t *surface;
int surfaceindex;
}
}
-static void Mod_GenerateLightmaps_DestroyTriangleInformation(dp_model_t *model)
+static void Mod_GenerateLightmaps_DestroyTriangleInformation(model_t *model)
{
if (mod_generatelightmaps_lightmaptriangles)
Mem_Free(mod_generatelightmaps_lightmaptriangles);
float lmaxis[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model)
+static void Mod_GenerateLightmaps_CreateLightmaps(model_t *model)
{
msurface_t *surface;
int surfaceindex;
}
}
-static void Mod_GenerateLightmaps_UpdateVertexColors(dp_model_t *model)
+static void Mod_GenerateLightmaps_UpdateVertexColors(model_t *model)
{
int i;
for (i = 0;i < model->surfmesh.num_vertices;i++)
Mod_GenerateLightmaps_VertexSample(model->surfmesh.data_vertex3f + 3*i, model->surfmesh.data_normal3f + 3*i, model->surfmesh.data_lightmapcolor4f + 4*i);
}
-static void Mod_GenerateLightmaps_UpdateLightGrid(dp_model_t *model)
+static void Mod_GenerateLightmaps_UpdateLightGrid(model_t *model)
{
int x;
int y;
}
extern cvar_t mod_q3bsp_nolightmaps;
-static void Mod_GenerateLightmaps(dp_model_t *model)
+static void Mod_GenerateLightmaps(model_t *model)
{
//lightmaptriangle_t *lightmaptriangles = Mem_Alloc(model->mempool, model->surfmesh.num_triangles * sizeof(lightmaptriangle_t));
- dp_model_t *oldloadmodel = loadmodel;
+ model_t *oldloadmodel = loadmodel;
loadmodel = model;
Mod_GenerateLightmaps_InitSampleOffsets(model);
Mod_GenerateLightmaps(cl.worldmodel);
}
-void Mod_Mesh_Create(dp_model_t *mod, const char *name)
+void Mod_Mesh_Create(model_t *mod, const char *name)
{
memset(mod, 0, sizeof(*mod));
strlcpy(mod->name, name, sizeof(mod->name));
mod->DrawLight = R_Mod_DrawLight;
}
-void Mod_Mesh_Destroy(dp_model_t *mod)
+void Mod_Mesh_Destroy(model_t *mod)
{
Mod_UnloadModel(mod);
}
// resets the mesh model to have no geometry to render, ready for a new frame -
// the mesh will be prepared for rendering later using Mod_Mesh_Finalize
-void Mod_Mesh_Reset(dp_model_t *mod)
+void Mod_Mesh_Reset(model_t *mod)
{
mod->num_surfaces = 0;
mod->surfmesh.num_vertices = 0;
mod->DrawAddWaterPlanes = NULL; // will be set if a texture needs it
}
-texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
+texture_t *Mod_Mesh_GetTexture(model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
{
int i;
texture_t *t;
return t;
}
-msurface_t *Mod_Mesh_AddSurface(dp_model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
+msurface_t *Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
{
msurface_t *surf;
// batch if possible; primarily useful for UI rendering where bounding boxes don't matter
{
mod->max_surfaces = 2 * max(mod->num_surfaces, 64);
mod->data_surfaces = (msurface_t *)Mem_Realloc(mod->mempool, mod->data_surfaces, mod->max_surfaces * sizeof(*mod->data_surfaces));
- mod->sortedmodelsurfaces = (int *)Mem_Realloc(mod->mempool, mod->sortedmodelsurfaces, mod->max_surfaces * sizeof(*mod->sortedmodelsurfaces));
+ mod->modelsurfaces_sorted = (int *)Mem_Realloc(mod->mempool, mod->modelsurfaces_sorted, mod->max_surfaces * sizeof(*mod->modelsurfaces_sorted));
}
surf = mod->data_surfaces + mod->num_surfaces;
mod->num_surfaces++;
return surf;
}
-int Mod_Mesh_IndexForVertex(dp_model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
+int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
{
int hashindex, h, vnum, mask;
surfmesh_t *mesh = &mod->surfmesh;
return vnum;
}
-void Mod_Mesh_AddTriangle(dp_model_t *mod, msurface_t *surf, int e0, int e1, int e2)
+void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2)
{
surfmesh_t *mesh = &mod->surfmesh;
if (mesh->max_triangles == mesh->num_triangles)
surf->num_triangles++;
}
-static void Mod_Mesh_MakeSortedSurfaces(dp_model_t *mod)
+static void Mod_Mesh_MakeSortedSurfaces(model_t *mod)
{
int i, j;
texture_t *tex;
- msurface_t *surf, *surf2;
// build the sorted surfaces list properly to reduce material setup
// this is easy because we're just sorting on texture and don't care about the order of textures
- mod->nummodelsurfaces = 0;
+ mod->submodelsurfaces_start = 0;
+ mod->submodelsurfaces_end = 0;
for (i = 0; i < mod->num_surfaces; i++)
mod->data_surfaces[i].included = false;
for (i = 0; i < mod->num_surfaces; i++)
{
- surf = mod->data_surfaces + i;
- if (surf->included)
+ if (mod->data_surfaces[i].included)
continue;
- tex = surf->texture;
+ tex = mod->data_surfaces[i].texture;
// j = i is intentional
for (j = i; j < mod->num_surfaces; j++)
{
- surf2 = mod->data_surfaces + j;
- if (surf2->included)
- continue;
- if (surf2->texture == tex)
+ if (!mod->data_surfaces[j].included && mod->data_surfaces[j].texture == tex)
{
- surf2->included = true;
- mod->sortedmodelsurfaces[mod->nummodelsurfaces++] = j;
+ mod->data_surfaces[j].included = 1;
+ mod->modelsurfaces_sorted[mod->submodelsurfaces_end++] = j;
}
}
}
}
-static void Mod_Mesh_ComputeBounds(dp_model_t *mod)
+static void Mod_Mesh_ComputeBounds(model_t *mod)
{
int i;
vec_t x2a, x2b, y2a, y2b, z2a, z2b, x2, y2, z2, yawradius, rotatedradius;
}
}
-void Mod_Mesh_Validate(dp_model_t *mod)
+void Mod_Mesh_Validate(model_t *mod)
{
int i;
qbool warned = false;
}
}
-static void Mod_Mesh_UploadDynamicBuffers(dp_model_t *mod)
+static void Mod_Mesh_UploadDynamicBuffers(model_t *mod)
{
mod->surfmesh.data_element3s_indexbuffer = mod->surfmesh.data_element3s ? R_BufferData_Store(mod->surfmesh.num_triangles * sizeof(short[3]), mod->surfmesh.data_element3s, R_BUFFERDATA_INDEX16, &mod->surfmesh.data_element3s_bufferoffset) : NULL;
mod->surfmesh.data_element3i_indexbuffer = mod->surfmesh.data_element3i ? R_BufferData_Store(mod->surfmesh.num_triangles * sizeof(int[3]), mod->surfmesh.data_element3i, R_BUFFERDATA_INDEX32, &mod->surfmesh.data_element3i_bufferoffset) : NULL;
mod->surfmesh.data_skeletalweight4ub_vertexbuffer = mod->surfmesh.data_skeletalweight4ub ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(unsigned char[4]), mod->surfmesh.data_skeletalweight4ub, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_skeletalweight4ub_bufferoffset) : NULL;
}
-void Mod_Mesh_Finalize(dp_model_t *mod)
+void Mod_Mesh_Finalize(model_t *mod)
{
if (gl_paranoid.integer)
Mod_Mesh_Validate(mod);