30cvar_t r_mipskins = {
CF_CLIENT |
CF_ARCHIVE,
"r_mipskins",
"0",
"mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"};
71typedef struct q3shader_hash_entry_s
74 struct q3shader_hash_entry_s*
chain;
76#define Q3SHADER_HASH_SIZE 1021
77typedef struct q3shader_data_s
93 for (
i = 0;
i < nummodels;
i++)
97 for (
i = 0;
i < nummodels;
i++)
114 for (
i = 0;
i < nummodels;
i++)
125 int i, j, k, l, surfacenum, ssize, tsize;
129 for (
i = 0;
i < nummodels;
i++)
133 for (j = 0;j <
mod->num_textures &&
mod->data_textures;j++)
137 if (
mod->data_textures[j].shaderpasses[l])
138 for (k = 0; k <
mod->data_textures[j].shaderpasses[l]->numframes; k++)
141 if (
mod->brush.solidskyskinframe)
143 if (
mod->brush.alphaskyskinframe)
151 for (
i = 0;
i < nummodels;
i++)
155 for (surfacenum = 0, surface =
mod->data_surfaces;surfacenum < mod->num_surfaces;surfacenum++, surface++)
162 mod->brushq1.lightmapupdateflags[surfacenum] =
true;
221 parentmodel =
mod->brush.parentmodel;
225 if (
mod->surfmesh.data_element3i_indexbuffer && !
mod->surfmesh.data_element3i_indexbuffer->isdynamic)
227 mod->surfmesh.data_element3i_indexbuffer =
NULL;
228 if (
mod->surfmesh.data_element3s_indexbuffer && !
mod->surfmesh.data_element3s_indexbuffer->isdynamic)
230 mod->surfmesh.data_element3s_indexbuffer =
NULL;
231 if (
mod->surfmesh.data_vertex3f_vertexbuffer && !
mod->surfmesh.data_vertex3f_vertexbuffer->isdynamic)
233 mod->surfmesh.data_vertex3f_vertexbuffer =
NULL;
234 mod->surfmesh.data_svector3f_vertexbuffer =
NULL;
235 mod->surfmesh.data_tvector3f_vertexbuffer =
NULL;
236 mod->surfmesh.data_normal3f_vertexbuffer =
NULL;
237 mod->surfmesh.data_texcoordtexture2f_vertexbuffer =
NULL;
238 mod->surfmesh.data_texcoordlightmap2f_vertexbuffer =
NULL;
239 mod->surfmesh.data_lightmapcolor4f_vertexbuffer =
NULL;
240 mod->surfmesh.data_skeletalindex4ub_vertexbuffer =
NULL;
241 mod->surfmesh.data_skeletalweight4ub_vertexbuffer =
NULL;
250 mod->brush.parentmodel = parentmodel;
290 Con_Printf(
"framegroups file: missing number of frames\n");
323 while (bufptr && strcmp(
com_token,
"\n"))
359 Con_Printf(
"no scene found in framegroups file, aborting\n");
362 mod->numframes = cnt;
376 mod->wantnormals =
false;
377 mod->wanttangents =
false;
378 for (
i = 0;
i <
mod->num_textures;
i++)
382 mod->wantnormals =
true;
384 mod->wantnormals =
true;
389 mod->wanttangents =
true;
390 mod->wantnormals =
true;
394 mod->wantnormals =
true;
415 if (
mod->name[0] ==
'*')
418 if (!strcmp(
mod->name,
"null"))
423 if (
mod->loaded ||
mod->mempool)
430 mod->crc = (
unsigned int)-1;
440 mod->modeldatatypestring =
"null";
458 if (!
mod->loaded || checkdisk)
460 if (checkdisk &&
mod->loaded)
486 if (
mod->loaded ||
mod->mempool)
496 mod->lightmapscale = 1;
517 char *bufend = (
char *)
buf + filesize;
569 for (
i = 0;
i < nummodels;
i++)
579 for (
i = 0;
i < nummodels;
i++)
610 for (
i = 0;
i < nummodels;
i++)
649 if (!
model->loaded || checkdisk)
669 for (
i = 0;
i < nummodels;
i++)
672 for (
i = 0;
i < nummodels;
i++)
699 for (
i = 0;
i < nummodels;
i++)
703 if (
mod->brush.numsubmodels)
704 Con_Printf(
"%4iK %s (%i submodels)\n",
mod->mempool ? (
int)((
mod->mempool->totalsize + 1023) / 1024) : 0,
mod->name,
mod->brush.numsubmodels);
706 Con_Printf(
"%4iK %s\n",
mod->mempool ? (
int)((
mod->mempool->totalsize + 1023) / 1024) : 0,
mod->name);
721 Con_Print(
"usage: modelprecache <filename>\n");
729 memset(used, 0, numvertices);
730 for (
i = 0;
i < numelements;
i++)
731 used[elements[
i]] = 1;
732 for (
i = 0,
count = 0;
i < numvertices;
i++)
733 remapvertices[
i] = used[
i] ?
count++ : -1;
738qbool Mod_ValidateElements(
int *element3i,
unsigned short *element3s,
int numtriangles,
int firstvertex,
int numvertices,
const char *filename,
int fileline)
740 int first = firstvertex, last =
first + numvertices - 1, numelements = numtriangles * 3;
742 int invalidintcount = 0, invalidintexample = 0;
743 int invalidshortcount = 0, invalidshortexample = 0;
744 int invalidmismatchcount = 0, invalidmismatchexample = 0;
747 for (
i = 0;
i < numelements;
i++)
749 if (element3i[
i] <
first || element3i[
i] > last)
752 invalidintexample =
i;
758 for (
i = 0;
i < numelements;
i++)
760 if (element3s[
i] <
first || element3s[
i] > last)
763 invalidintexample =
i;
767 if (element3i && element3s)
769 for (
i = 0;
i < numelements;
i++)
771 if (element3s[
i] != element3i[
i])
773 invalidmismatchcount++;
774 invalidmismatchexample =
i;
778 if (invalidintcount || invalidshortcount || invalidmismatchcount)
780 Con_Printf(
"Mod_ValidateElements(%i, %i, %i, %p, %p) called at %s:%d", numelements,
first, last, (
void *)element3i, (
void *)element3s, filename, fileline);
781 Con_Printf(
", %i elements are invalid in element3i (example: element3i[%i] == %i)", invalidintcount, invalidintexample, element3i ? element3i[invalidintexample] : 0);
782 Con_Printf(
", %i elements are invalid in element3s (example: element3s[%i] == %i)", invalidshortcount, invalidshortexample, element3s ? element3s[invalidshortexample] : 0);
783 Con_Printf(
", %i elements mismatch between element3i and element3s (example: element3s[%i] is %i and element3i[%i] is %i)", invalidmismatchcount, invalidmismatchexample, element3s ? element3s[invalidmismatchexample] : 0, invalidmismatchexample, element3i ? element3i[invalidmismatchexample] : 0);
784 Con_Print(
". Please debug the engine code - these elements have been modified to not crash, but nothing more.\n");
788 for (
i = 0;
i < numelements;
i++)
789 if (element3i[
i] <
first || element3i[
i] > last)
792 for (
i = 0;
i < numelements;
i++)
793 if (element3s[
i] <
first || element3s[
i] > last)
795 if (element3i && element3s)
796 for (
i = 0;
i < numelements;
i++)
797 if (element3s[
i] != element3i[
i])
798 element3s[
i] = element3i[
i];
806void Mod_BuildNormals(
int firstvertex,
int numvertices,
int numtriangles,
const float *vertex3f,
const int *elements,
float *normal3f,
qbool areaweighting)
813 memset(normal3f + 3 * firstvertex, 0, numvertices *
sizeof(
float[3]));
820 for (
i = 0;
i < numtriangles;
i++, element += 3)
823 vertex3f + element[0] * 3,
824 vertex3f + element[1] * 3,
825 vertex3f + element[2] * 3,
832 for (j = 0;j < 3;j++)
834 vectorNormal = normal3f + element[j] * 3;
835 vectorNormal[0] += areaNormal[0];
836 vectorNormal[1] += areaNormal[1];
837 vectorNormal[2] += areaNormal[2];
841 vectorNormal = normal3f + 3 * firstvertex;
842 for (
i = 0;
i < numvertices;
i++, vectorNormal += 3)
847static void Mod_BuildBumpVectors(
const float *
v0,
const float *
v1,
const float *
v2,
const float *tc0,
const float *tc1,
const float *tc2,
float *svector3f,
float *tvector3f,
float *normal3f)
849 float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2];
856 normal3f[0] = v20[1] * v10[2] - v20[2] * v10[1];
857 normal3f[1] = v20[2] * v10[0] - v20[0] * v10[2];
858 normal3f[2] = v20[0] * v10[1] - v20[1] * v10[0];
860 tc10[1] = tc1[1] - tc0[1];
861 tc20[1] = tc2[1] - tc0[1];
862 svector3f[0] = tc10[1] * v20[0] - tc20[1] * v10[0];
863 svector3f[1] = tc10[1] * v20[1] - tc20[1] * v10[1];
864 svector3f[2] = tc10[1] * v20[2] - tc20[1] * v10[2];
865 tc10[0] = tc1[0] - tc0[0];
866 tc20[0] = tc2[0] - tc0[0];
867 tvector3f[0] = tc10[0] * v20[0] - tc20[0] * v10[0];
868 tvector3f[1] = tc10[0] * v20[1] - tc20[0] * v10[1];
869 tvector3f[2] = tc10[0] * v20[2] - tc20[0] * v10[2];
872 svector3f[0] -=
f * normal3f[0];
873 svector3f[1] -=
f * normal3f[1];
874 svector3f[2] -=
f * normal3f[2];
876 tvector3f[0] -=
f * normal3f[0];
877 tvector3f[1] -=
f * normal3f[1];
878 tvector3f[2] -=
f * normal3f[2];
893void Mod_BuildTextureVectorsFromNormals(
int firstvertex,
int numvertices,
int numtriangles,
const float *vertex3f,
const float *texcoord2f,
const float *normal3f,
const int *elements,
float *svector3f,
float *tvector3f,
qbool areaweighting)
896 float sdir[3], tdir[3],
normal[3], *svec, *tvec;
897 const float *
v0, *
v1, *
v2, *tc0, *tc1, *tc2, *
n;
898 float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2];
901 memset(svector3f + 3 * firstvertex, 0, numvertices *
sizeof(
float[3]));
902 memset(tvector3f + 3 * firstvertex, 0, numvertices *
sizeof(
float[3]));
904 for (tnum = 0, e = elements;tnum < numtriangles;tnum++, e += 3)
906 v0 = vertex3f + e[0] * 3;
907 v1 = vertex3f + e[1] * 3;
908 v2 = vertex3f + e[2] * 3;
909 tc0 = texcoord2f + e[0] * 2;
910 tc1 = texcoord2f + e[1] * 2;
911 tc2 = texcoord2f + e[2] * 2;
920 normal[0] = v20[1] * v10[2] - v20[2] * v10[1];
921 normal[1] = v20[2] * v10[0] - v20[0] * v10[2];
922 normal[2] = v20[0] * v10[1] - v20[1] * v10[0];
926 tc10[1] = tc1[1] - tc0[1];
927 tc20[1] = tc2[1] - tc0[1];
928 sdir[0] = tc10[1] * v20[0] - tc20[1] * v10[0];
929 sdir[1] = tc10[1] * v20[1] - tc20[1] * v10[1];
930 sdir[2] = tc10[1] * v20[2] - tc20[1] * v10[2];
931 tc10[0] = tc1[0] - tc0[0];
932 tc20[0] = tc2[0] - tc0[0];
933 tdir[0] = tc10[0] * v20[0] - tc20[0] * v10[0];
934 tdir[1] = tc10[0] * v20[1] - tc20[0] * v10[1];
935 tdir[2] = tc10[0] * v20[2] - tc20[0] * v10[2];
953 for (
i = 0;
i < 3;
i++)
955 VectorAdd(svector3f + e[
i]*3, sdir, svector3f + e[
i]*3);
956 VectorAdd(tvector3f + e[
i]*3, tdir, tvector3f + e[
i]*3);
962 for (
i = 0, svec = svector3f + 3 * firstvertex, tvec = tvector3f + 3 * firstvertex,
n = normal3f + 3 * firstvertex;
i < numvertices;
i++, svec += 3, tvec += 3,
n += 3)
976 data = (
unsigned char *)
Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) *
sizeof(
float) + numvertices * (lightmapoffsets ? 1 : 0) *
sizeof(
int) + numtriangles *
sizeof(
int[3]) + (numvertices <= 65536 ? numtriangles *
sizeof(
unsigned short[3]) : 0));
1021 int hashindex, vnum;
1024 hashindex = (
unsigned int) (vertex3f[0] * 2003 + vertex3f[1] * 4001 + vertex3f[2] * 7919) %
SHADOWMESHVERTEXHASH;
1028 if (mesh->
vertex3f[vnum * 3 + 0] == vertex3f[0] && mesh->
vertex3f[vnum * 3 + 1] == vertex3f[1] && mesh->
vertex3f[vnum * 3 + 2] == vertex3f[2])
1035 mesh->
vertex3f[vnum * 3 + 0] = vertex3f[0];
1036 mesh->
vertex3f[vnum * 3 + 1] = vertex3f[1];
1037 mesh->
vertex3f[vnum * 3 + 2] = vertex3f[2];
1045 for (
i = 0;
i < numtris;
i++)
1139 vec3_t nmins, nmaxs, ncenter, temp;
1140 float nradius2, dist2, *
v;
1148 if (nmins[0] >
v[0]) { nmins[0] =
v[0]; }
if (nmaxs[0] <
v[0]) { nmaxs[0] =
v[0]; }
1149 if (nmins[1] >
v[1]) { nmins[1] =
v[1]; }
if (nmaxs[1] <
v[1]) { nmaxs[1] =
v[1]; }
1150 if (nmins[2] >
v[2]) { nmins[2] =
v[2]; }
if (nmaxs[2] <
v[2]) { nmaxs[2] =
v[2]; }
1153 ncenter[0] = (nmins[0] + nmaxs[0]) * 0.5f;
1154 ncenter[1] = (nmins[1] + nmaxs[1]) * 0.5f;
1155 ncenter[2] = (nmins[2] + nmaxs[2]) * 0.5f;
1161 if (nradius2 < dist2)
1172 *radius =
sqrt(nradius2);
1198 int k, numcollisionmeshtriangles;
1199 qbool usesinglecollisionmesh =
false;
1203 if (!mempool &&
mod->brush.parentmodel)
1204 mempool =
mod->brush.parentmodel->mempool;
1207 numcollisionmeshtriangles = 0;
1208 for (k =
mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
1210 surface =
mod->data_surfaces + k;
1213 usesinglecollisionmesh =
true;
1221 mod->brush.collisionmesh =
Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles);
1222 if (usesinglecollisionmesh)
1226 for (k =
mod->submodelsurfaces_start; k < mod->submodelsurfaces_end; k++)
1228 surface =
mod->data_surfaces + k;
1238static void Mod_GetTerrainVertex3fTexCoord2fFromBGRA(
const unsigned char *imagepixels,
int imagewidth,
int imageheight,
int ix,
int iy,
float *vertex3f,
float *texcoord2f,
matrix4x4_t *pixelstepmatrix,
matrix4x4_t *pixeltexturestepmatrix)
1243 if (ix >= 0 && iy >= 0 && ix < imagewidth && iy < imageheight)
1244 v[2] = (imagepixels[((iy*imagewidth)+ix)*4+0] + imagepixels[((iy*imagewidth)+ix)*4+1] + imagepixels[((iy*imagewidth)+ix)*4+2]) * (1.0f / 765.0f);
1249 texcoord2f[0] =
tc[0];
1250 texcoord2f[1] =
tc[1];
1253static void Mod_GetTerrainVertexFromBGRA(
const unsigned char *imagepixels,
int imagewidth,
int imageheight,
int ix,
int iy,
float *vertex3f,
float *svector3f,
float *tvector3f,
float *normal3f,
float *texcoord2f,
matrix4x4_t *pixelstepmatrix,
matrix4x4_t *pixeltexturestepmatrix)
1255 float vup[3], vdown[3], vleft[3], vright[3];
1256 float tcup[3], tcdown[3], tcleft[3], tcright[3];
1257 float sv[3], tv[3], nl[3];
1258 Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, pixelstepmatrix, pixeltexturestepmatrix);
1259 Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix, iy - 1, vup, tcup, pixelstepmatrix, pixeltexturestepmatrix);
1260 Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix, iy + 1, vdown, tcdown, pixelstepmatrix, pixeltexturestepmatrix);
1261 Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix - 1, iy, vleft, tcleft, pixelstepmatrix, pixeltexturestepmatrix);
1262 Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix + 1, iy, vright, tcright, pixelstepmatrix, pixeltexturestepmatrix);
1263 Mod_BuildBumpVectors(vertex3f, vup, vright, texcoord2f, tcup, tcright, svector3f, tvector3f, normal3f);
1264 Mod_BuildBumpVectors(vertex3f, vright, vdown, texcoord2f, tcright, tcdown,
sv, tv, nl);
1268 Mod_BuildBumpVectors(vertex3f, vdown, vleft, texcoord2f, tcdown, tcleft,
sv, tv, nl);
1272 Mod_BuildBumpVectors(vertex3f, vleft, vup, texcoord2f, tcleft, tcup,
sv, tv, nl);
1278static void Mod_ConstructTerrainPatchFromBGRA(
const unsigned char *imagepixels,
int imagewidth,
int imageheight,
int x1,
int y1,
int width,
int height,
int *element3i,
float *vertex3f,
float *svector3f,
float *tvector3f,
float *normal3f,
float *texcoord2f,
matrix4x4_t *pixelstepmatrix,
matrix4x4_t *pixeltexturestepmatrix)
1280 int x,
y, ix, iy, *e;
1286 e[0] = (
y + 1) * (
width + 1) + (
x + 0);
1287 e[1] = (
y + 0) * (
width + 1) + (
x + 0);
1288 e[2] = (
y + 1) * (
width + 1) + (
x + 1);
1289 e[3] = (
y + 0) * (
width + 1) + (
x + 0);
1290 e[4] = (
y + 0) * (
width + 1) + (
x + 1);
1291 e[5] = (
y + 1) * (
width + 1) + (
x + 1);
1295 for (
y = 0, iy = y1;
y <
height + 1;
y++, iy++)
1296 for (
x = 0, ix =
x1;
x <
width + 1;
x++, ix++, vertex3f += 3, texcoord2f += 2, svector3f += 3, tvector3f += 3, normal3f += 3)
1297 Mod_GetTerrainVertexFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, svector3f, tvector3f, normal3f, pixelstepmatrix, pixeltexturestepmatrix);
1302void Mod_Terrain_SurfaceRecurseChunk(
model_t *
model,
int stepsize,
int x,
int y)
1306 float chunkwidth =
min(stepsize,
model->terrain.width - 1 -
x);
1307 float chunkheight =
min(stepsize,
model->terrain.height - 1 -
y);
1308 float viewvector[3];
1309 unsigned int firstvertex;
1312 if (chunkwidth < 2 || chunkheight < 2)
1316 viewvector[0] =
bound(
mins[0], localvieworigin,
maxs[0]) -
model->terrain.vieworigin[0];
1317 viewvector[1] =
bound(
mins[1], localvieworigin,
maxs[1]) -
model->terrain.vieworigin[1];
1318 viewvector[2] =
bound(
mins[2], localvieworigin,
maxs[2]) -
model->terrain.vieworigin[2];
1319 if (stepsize > 1 &&
VectorLength(viewvector) < stepsize*
model->terrain.scale[0]*r_terrain_lodscale.value)
1323 Mod_Terrain_SurfaceRecurseChunk(
model, stepsize,
x,
y);
1324 Mod_Terrain_SurfaceRecurseChunk(
model, stepsize,
x+stepsize,
y);
1325 Mod_Terrain_SurfaceRecurseChunk(
model, stepsize,
x,
y+stepsize);
1326 Mod_Terrain_SurfaceRecurseChunk(
model, stepsize,
x+stepsize,
y+stepsize);
1331 outwidth = chunkwidth+2;
1332 outheight = chunkheight+2;
1333 outwidth2 = outwidth-1;
1334 outheight2 = outheight-1;
1335 outwidth3 = outwidth+1;
1336 outheight3 = outheight+1;
1337 firstvertex = numvertices;
1338 e =
model->terrain.element3i + numtriangles;
1339 numtriangles += chunkwidth*chunkheight*2+chunkwidth*2*2+chunkheight*2*2;
1340 v =
model->terrain.vertex3f + numvertices;
1341 numvertices += (chunkwidth+1)*(chunkheight+1)+(chunkwidth+1)*2+(chunkheight+1)*2;
1343 for (ty = 0;ty < outheight;ty++)
1345 for (tx = 0;tx < outwidth;tx++)
1347 *e++ = firstvertex + (ty )*outwidth3+(tx );
1348 *e++ = firstvertex + (ty )*outwidth3+(tx+1);
1349 *e++ = firstvertex + (ty+1)*outwidth3+(tx+1);
1350 *e++ = firstvertex + (ty )*outwidth3+(tx );
1351 *e++ = firstvertex + (ty+1)*outwidth3+(tx+1);
1352 *e++ = firstvertex + (ty+1)*outwidth3+(tx );
1356 for (ty = 0;ty <= outheight;ty++)
1358 skirtrow = ty == 0 || ty == outheight;
1359 ry =
y+
bound(1, ty, outheight)*stepsize;
1360 for (tx = 0;tx <= outwidth;tx++)
1362 skirt = skirtrow || tx == 0 || tx == outwidth;
1363 rx =
x+
bound(1, tx, outwidth)*stepsize;
1366 v[2] = heightmap[ry*terrainwidth+rx]*
scale[2];
1373void Mod_Terrain_UpdateSurfacesForViewOrigin(
model_t *
model)
1376 Mod_Terrain_SurfaceRecurseChunk(
model,
model->terrain.maxstepsize,
x,
y);
1377 Mod_Terrain_BuildChunk(
model,
1384 if (!strncasecmp(s,
"user", 4))
1399 Con_DPrintf(
"Mod_LoadQ3Shaders: unknown wavefunc %s\n", s);
1432 unsigned char *start, *end, *start2;
1433 start = (
unsigned char *) (&shader->Q3SHADERINFO_COMPARE_START);
1434 end = ((
unsigned char *) (&shader->Q3SHADERINFO_COMPARE_END)) +
sizeof(shader->Q3SHADERINFO_COMPARE_END);
1435 start2 = (
unsigned char *) (&entry->
shader.Q3SHADERINFO_COMPARE_START);
1436 if(memcmp(start, start2, end - start))
1437 Con_DPrintf(
"Shader '%s' already defined, ignoring mismatching redeclaration\n", shader->
name);
1444 entry = entry->
chain;
1446 while (entry !=
NULL);
1456 lastEntry->
chain = newEntry;
1458 lastEntry = newEntry;
1477 char *custsurfaceparmnames[256];
1478 unsigned long custsurfaceflags[256];
1479 int numcustsurfaceflags;
1493 numcustsurfaceflags = 0;
1497 Con_DPrintf(
"scripts/custinfoparms.txt: contentflags section parsing error - expected \"{\", found \"%s\"\n",
com_token);
1505 Con_DPrintf(
"scripts/custinfoparms.txt: surfaceflags section parsing error - expected \"{\", found \"%s\"\n",
com_token);
1513 if (numcustsurfaceflags >= 256)
1515 Con_Printf(
"scripts/custinfoparms.txt: surfaceflags section parsing error - max 256 surfaceflags exceeded\n");
1524 custsurfaceflags[numcustsurfaceflags] = strtol(
com_token,
NULL, 0);
1526 custsurfaceflags[numcustsurfaceflags] = 0;
1527 numcustsurfaceflags++;
1538 for (fileindex = 0;fileindex < search->
numfilenames;fileindex++)
1545 memset (&shader, 0,
sizeof(shader));
1603 memset(&dummy, 0,
sizeof(dummy));
1623 if(j == 0 && !strncasecmp(
com_token,
"dp_", 3))
1627 numparameters = j + 1;
1637 for (j = 0;j < numparameters;j++)
1641 if (numparameters >= 2 && !strcasecmp(parameter[0],
"blendfunc"))
1643 if (numparameters == 2)
1645 if (!strcasecmp(parameter[1],
"add"))
1650 else if (!strcasecmp(parameter[1],
"addalpha"))
1655 else if (!strcasecmp(parameter[1],
"filter"))
1660 else if (!strcasecmp(parameter[1],
"blend"))
1666 else if (numparameters == 3)
1669 for (k = 0;k < 2;k++)
1671 if (!strcasecmp(parameter[k+1],
"GL_ONE"))
1673 else if (!strcasecmp(parameter[k+1],
"GL_ZERO"))
1675 else if (!strcasecmp(parameter[k+1],
"GL_SRC_COLOR"))
1677 else if (!strcasecmp(parameter[k+1],
"GL_SRC_ALPHA"))
1679 else if (!strcasecmp(parameter[k+1],
"GL_DST_COLOR"))
1681 else if (!strcasecmp(parameter[k+1],
"GL_DST_ALPHA"))
1683 else if (!strcasecmp(parameter[k+1],
"GL_ONE_MINUS_SRC_COLOR"))
1685 else if (!strcasecmp(parameter[k+1],
"GL_ONE_MINUS_SRC_ALPHA"))
1687 else if (!strcasecmp(parameter[k+1],
"GL_ONE_MINUS_DST_COLOR"))
1689 else if (!strcasecmp(parameter[k+1],
"GL_ONE_MINUS_DST_ALPHA"))
1696 if (numparameters >= 2 && !strcasecmp(parameter[0],
"alphafunc"))
1697 layer->alphatest =
true;
1698 if (numparameters >= 2 && (!strcasecmp(parameter[0],
"map") || !strcasecmp(parameter[0],
"clampmap")))
1700 if (!strcasecmp(parameter[0],
"clampmap"))
1701 layer->clampmap =
true;
1702 layer->numframes = 1;
1703 layer->framerate = 1;
1707 if (!strcasecmp(parameter[1],
"$lightmap"))
1710 else if (numparameters >= 3 && (!strcasecmp(parameter[0],
"animmap") || !strcasecmp(parameter[0],
"animclampmap")))
1714 layer->framerate = atof(parameter[1]);
1716 for (
i = 0;
i <
layer->numframes;
i++)
1719 else if (numparameters >= 2 && !strcasecmp(parameter[0],
"rgbgen"))
1723 layer->rgbgen.parms[
i] = atof(parameter[
i+2]);
1733 else if (!strcasecmp(parameter[1],
"wave"))
1738 layer->rgbgen.waveparms[
i] = atof(parameter[
i+3]);
1740 else Con_DPrintf(
"%s parsing warning: unknown rgbgen %s\n", search->
filenames[fileindex], parameter[1]);
1742 else if (numparameters >= 2 && !strcasecmp(parameter[0],
"alphagen"))
1746 layer->alphagen.parms[
i] = atof(parameter[
i+2]);
1755 else if (!strcasecmp(parameter[1],
"wave"))
1760 layer->alphagen.waveparms[
i] = atof(parameter[
i+3]);
1762 else Con_DPrintf(
"%s parsing warning: unknown alphagen %s\n", search->
filenames[fileindex], parameter[1]);
1764 else if (numparameters >= 2 && (!strcasecmp(parameter[0],
"texgen") || !strcasecmp(parameter[0],
"tcgen")))
1770 layer->tcgen.parms[
i] = atof(parameter[
i+2]);
1776 else Con_DPrintf(
"%s parsing warning: unknown tcgen mode %s\n", search->
filenames[fileindex], parameter[1]);
1778 else if (numparameters >= 2 && !strcasecmp(parameter[0],
"tcmod"))
1791 for (tcmodindex = 0;tcmodindex <
Q3MAXTCMODS;tcmodindex++)
1792 if (!
layer->tcmods[tcmodindex].tcmod)
1797 layer->tcmods[tcmodindex].parms[
i] = atof(parameter[
i+2]);
1799 else if (!strcasecmp(parameter[1],
"rotate"))
layer->tcmods[tcmodindex].tcmod =
Q3TCMOD_ROTATE;
1800 else if (!strcasecmp(parameter[1],
"scale"))
layer->tcmods[tcmodindex].tcmod =
Q3TCMOD_SCALE;
1801 else if (!strcasecmp(parameter[1],
"scroll"))
layer->tcmods[tcmodindex].tcmod =
Q3TCMOD_SCROLL;
1802 else if (!strcasecmp(parameter[1],
"page"))
layer->tcmods[tcmodindex].tcmod =
Q3TCMOD_PAGE;
1803 else if (!strcasecmp(parameter[1],
"stretch"))
1808 layer->tcmods[tcmodindex].waveparms[
i] = atof(parameter[
i+3]);
1812 else Con_DPrintf(
"%s parsing warning: unknown tcmod mode %s\n", search->
filenames[fileindex], parameter[1]);
1815 Con_DPrintf(
"%s parsing warning: too many tcmods on one layer\n", search->
filenames[fileindex]);
1847 layer->dptexflags = 0;
1848 if (
layer->alphatest)
1850 switch(
layer->blendfunc[0])
1857 switch(
layer->blendfunc[1])
1868 if (
layer->clampmap)
1878 if(j == 0 && !strncasecmp(
com_token,
"dp_", 3))
1882 numparameters = j + 1;
1889 if (fileindex == 0 && !strcasecmp(
com_token,
"}"))
1894 for (j = 0;j < numparameters;j++)
1898 if (numparameters < 1)
1900 if (!strcasecmp(parameter[0],
"surfaceparm") && numparameters >= 2)
1902 if (!strcasecmp(parameter[1],
"alphashadow"))
1904 else if (!strcasecmp(parameter[1],
"areaportal"))
1906 else if (!strcasecmp(parameter[1],
"botclip"))
1908 else if (!strcasecmp(parameter[1],
"clusterportal"))
1910 else if (!strcasecmp(parameter[1],
"detail"))
1912 else if (!strcasecmp(parameter[1],
"donotenter"))
1914 else if (!strcasecmp(parameter[1],
"dust"))
1916 else if (!strcasecmp(parameter[1],
"hint"))
1918 else if (!strcasecmp(parameter[1],
"fog"))
1920 else if (!strcasecmp(parameter[1],
"lava"))
1922 else if (!strcasecmp(parameter[1],
"lightfilter"))
1924 else if (!strcasecmp(parameter[1],
"lightgrid"))
1926 else if (!strcasecmp(parameter[1],
"metalsteps"))
1928 else if (!strcasecmp(parameter[1],
"nodamage"))
1930 else if (!strcasecmp(parameter[1],
"nodlight"))
1932 else if (!strcasecmp(parameter[1],
"nodraw"))
1934 else if (!strcasecmp(parameter[1],
"nodrop"))
1936 else if (!strcasecmp(parameter[1],
"noimpact"))
1938 else if (!strcasecmp(parameter[1],
"nolightmap"))
1940 else if (!strcasecmp(parameter[1],
"nomarks"))
1942 else if (!strcasecmp(parameter[1],
"nomipmaps"))
1944 else if (!strcasecmp(parameter[1],
"nonsolid"))
1946 else if (!strcasecmp(parameter[1],
"origin"))
1948 else if (!strcasecmp(parameter[1],
"playerclip"))
1950 else if (!strcasecmp(parameter[1],
"sky"))
1952 else if (!strcasecmp(parameter[1],
"slick"))
1954 else if (!strcasecmp(parameter[1],
"slime"))
1956 else if (!strcasecmp(parameter[1],
"structural"))
1958 else if (!strcasecmp(parameter[1],
"trans"))
1960 else if (!strcasecmp(parameter[1],
"water"))
1962 else if (!strcasecmp(parameter[1],
"pointlight"))
1964 else if (!strcasecmp(parameter[1],
"antiportal"))
1966 else if (!strcasecmp(parameter[1],
"skip"))
1971 for (j = 0; j < numcustsurfaceflags; j++)
1973 if (!strcasecmp(custsurfaceparmnames[j], parameter[1]))
1980 if (j == numcustsurfaceflags)
1981 Con_DPrintf(
"%s parsing warning: unknown surfaceparm \"%s\"\n", search->
filenames[fileindex], parameter[1]);
1984 else if (!strcasecmp(parameter[0],
"dpshadow"))
1986 else if (!strcasecmp(parameter[0],
"dpnoshadow"))
1988 else if (!strcasecmp(parameter[0],
"dpnortlight"))
1990 else if (!strcasecmp(parameter[0],
"dpreflectcube"))
1992 else if (!strcasecmp(parameter[0],
"dpmeshcollisions"))
1995 else if (((dpshaderkill = !strcasecmp(parameter[0],
"dpshaderkillifcvarzero")) || !strcasecmp(parameter[0],
"dpnoshaderkillifcvarzero")) && numparameters >= 2)
2001 else if (((dpshaderkill = !strcasecmp(parameter[0],
"dpshaderkillifcvar")) || !strcasecmp(parameter[0],
"dpnoshaderkillifcvar")) && numparameters >= 2)
2003 const char *op =
NULL;
2004 if (numparameters >= 3)
2011 else if (numparameters >= 4 && !strcmp(op,
"=="))
2016 else if (numparameters >= 4 && !strcmp(op,
"!="))
2021 else if (numparameters >= 4 && !strcmp(op,
">"))
2026 else if (numparameters >= 4 && !strcmp(op,
"<"))
2031 else if (numparameters >= 4 && !strcmp(op,
">="))
2036 else if (numparameters >= 4 && !strcmp(op,
"<="))
2043 Con_DPrintf(
"%s parsing warning: unknown dpshaderkillifcvar op \"%s\", or not enough arguments\n", search->
filenames[fileindex], op);
2046 else if (!strcasecmp(parameter[0],
"sky") && numparameters >= 2)
2052 else if (!strcasecmp(parameter[0],
"skyparms") && numparameters >= 2)
2056 if (!atoi(parameter[1]) && strcasecmp(parameter[1],
"-"))
2059 else if (!strcasecmp(parameter[0],
"cull") && numparameters >= 2)
2061 if (!strcasecmp(parameter[1],
"disable") || !strcasecmp(parameter[1],
"none") || !strcasecmp(parameter[1],
"twosided"))
2064 else if (!strcasecmp(parameter[0],
"nomipmaps"))
2066 else if (!strcasecmp(parameter[0],
"nopicmip"))
2068 else if (!strcasecmp(parameter[0],
"polygonoffset"))
2070 else if (!strcasecmp(parameter[0],
"dppolygonoffset"))
2073 if(numparameters >= 2)
2076 if(numparameters >= 3)
2082 else if (!strcasecmp(parameter[0],
"dptransparentsort") && numparameters >= 2)
2085 if (!strcasecmp(parameter[1],
"sky"))
2087 else if (!strcasecmp(parameter[1],
"distance"))
2089 else if (!strcasecmp(parameter[1],
"hud"))
2092 Con_DPrintf(
"%s parsing warning: unknown dptransparentsort category \"%s\", or not enough arguments\n", search->
filenames[fileindex], parameter[1]);
2094 else if (!strcasecmp(parameter[0],
"dprefract") && numparameters >= 5)
2100 else if (!strcasecmp(parameter[0],
"dpreflect") && numparameters >= 6)
2106 else if (!strcasecmp(parameter[0],
"dpcamera"))
2110 else if (!strcasecmp(parameter[0],
"dpwater") && numparameters >= 12)
2121 else if (!strcasecmp(parameter[0],
"dpwaterscroll") && numparameters >= 3)
2126 else if (!strcasecmp(parameter[0],
"dpglossintensitymod") && numparameters >= 2)
2130 else if (!strcasecmp(parameter[0],
"dpglossexponentmod") && numparameters >= 2)
2134 else if (!strcasecmp(parameter[0],
"dprtlightambient") && numparameters >= 2)
2138 else if (!strcasecmp(parameter[0],
"dpoffsetmapping") && numparameters >= 2)
2140 if (!strcasecmp(parameter[1],
"disable") || !strcasecmp(parameter[1],
"none") || !strcasecmp(parameter[1],
"off"))
2142 else if (!strcasecmp(parameter[1],
"default") || !strcasecmp(parameter[1],
"normal"))
2144 else if (!strcasecmp(parameter[1],
"linear"))
2146 else if (!strcasecmp(parameter[1],
"relief"))
2148 if (numparameters >= 3)
2150 if (numparameters >= 5)
2152 if(!strcasecmp(parameter[3],
"bias"))
2154 else if(!strcasecmp(parameter[3],
"match"))
2155 shader.
offsetbias = 1.0f - atof(parameter[4]);
2156 else if(!strcasecmp(parameter[3],
"match8"))
2157 shader.
offsetbias = 1.0f - atof(parameter[4]) / 255.0f;
2158 else if(!strcasecmp(parameter[3],
"match16"))
2159 shader.
offsetbias = 1.0f - atof(parameter[4]) / 65535.0f;
2162 else if (!strcasecmp(parameter[0],
"deformvertexes") && numparameters >= 2)
2165 for (deformindex = 0;deformindex <
Q3MAXDEFORMS;deformindex++)
2185 else if (!strcasecmp(parameter[1],
"wave" ))
2192 else if (!strcasecmp(parameter[1],
"move" ))
2215 for (j = 0; j < numcustsurfaceflags; j++)
2221 unsigned short hash;
2227 while (entry !=
NULL)
2231 entry = entry->
chain;
2265 for (j = 0; j <
layer->numframes; j++)
2272 int texflagsmask, texflagsor;
2273 qbool success =
true;
2284 texflagsmask &= ~TEXF_PICMIP;
2286 texflagsmask &= ~TEXF_COMPRESS;
2296 texture->specularscalemod = 1;
2297 texture->specularpowermod = 1;
2386 int terrainbackgroundlayer = -1;
2387 int lightmaplayer = -1;
2388 int alphagenspecularlayer = -1;
2389 int rgbgenvertexlayer = -1;
2390 int rgbgendiffuselayer = -1;
2391 int materiallayer = -1;
2392 int endofprelayers = 0;
2393 int firstpostlayer = 0;
2394 int shaderpassindex = 0;
2400 rgbgenvertexlayer =
i;
2402 rgbgendiffuselayer =
i;
2404 alphagenspecularlayer =
i;
2413 terrainbackgroundlayer = 0;
2416 firstpostlayer = lightmaplayer >= 0 ? lightmaplayer + 1 : materiallayer + 1;
2418 else if (lightmaplayer == 0)
2422 firstpostlayer = lightmaplayer + 2;
2424 else if (lightmaplayer >= 1)
2427 endofprelayers = lightmaplayer - 1;
2428 materiallayer = lightmaplayer - 1;
2429 firstpostlayer = lightmaplayer + 1;
2431 else if (rgbgenvertexlayer >= 0)
2434 materiallayer = rgbgenvertexlayer;
2435 endofprelayers = rgbgenvertexlayer;
2436 firstpostlayer = rgbgenvertexlayer + 1;
2441 else if (rgbgendiffuselayer >= 0)
2444 materiallayer = rgbgendiffuselayer;
2445 endofprelayers = rgbgendiffuselayer;
2446 firstpostlayer = rgbgendiffuselayer + 1;
2448 if (alphagenspecularlayer >= 0)
2449 firstpostlayer = alphagenspecularlayer + 1;
2460 if (materiallayer >= 0)
2463 if (terrainbackgroundlayer >= 0)
2466 texture->startpreshaderpass = shaderpassindex;
2467 for (
i = 0;
i < endofprelayers;
i++)
2469 texture->endpreshaderpass = shaderpassindex;
2470 texture->startpostshaderpass = shaderpassindex;
2474 texture->startpostshaderpass = shaderpassindex;
2478 texture->basematerialflags &= ~MATERIALFLAG_NOSHADOW;
2584 Con_DPrintf(
"^1%s:^7 killing shader ^3\"%s\" because of cvar\n", modelname,
name);
2586 else if (!strcmp(
texture->name,
"noshader") || !
texture->name[0])
2589 Con_DPrintf(
"^1%s:^7 using fallback noshader material for ^3\"%s\"\n", modelname,
name);
2590 texture->basematerialflags = defaultmaterialflags;
2593 else if (!strcmp(
texture->name,
"common/nodraw") || !strcmp(
texture->name,
"textures/common/nodraw"))
2596 Con_DPrintf(
"^1%s:^7 using fallback nodraw material for ^3\"%s\"\n", modelname,
name);
2603 Con_DPrintf(
"^1%s:^7 No shader found for texture ^3\"%s\"\n", modelname,
texture->name);
2616 texture->basematerialflags = defaultmaterialflags;
2630 if (
texture->materialshaderpass->skinframes[0]->hasalpha)
2637 if (!success && warnmissing)
2638 Con_Printf(
"^1%s:^7 could not load texture ^3\"%s\"\n", modelname,
texture->name);
2644 if (!
texture->materialshaderpass)
2646 if (!
texture->materialshaderpass->skinframes[0])
2649 texture->backgroundcurrentskinframe =
texture->backgroundshaderpass ?
texture->backgroundshaderpass->skinframes[0] :
NULL;
2656 Con_DPrintf(
"^1Custom texture ^3\"%s\" does not have MATERIALFLAG_WALL set\n",
texture->name);
2660 texture->basematerialflags = materialflags;
2661 texture->supercontents = supercontents;
2666 texture->specularscalemod = 1;
2667 texture->specularpowermod = 1;
2681 texture->currentskinframe = skinframe;
2687 long unsigned int i, j;
2688 for (
i = 0;
i <
sizeof(
texture->shaderpasses) /
sizeof(
texture->shaderpasses[0]);
i++)
2694 if (
texture->shaderpasses[
i]->skinframes[j] &&
texture->shaderpasses[
i]->skinframes[j]->base)
2707 int i, words, line, wordsoverflow;
2730 memset(word, 0,
sizeof(word));
2734 if (skinfile ==
NULL)
2742 skinfile = skinfile->
next;
2746 for(line = 0;;line++)
2754 wordsoverflow =
false;
2760 wordsoverflow =
true;
2765 Con_Printf(
"Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: line with too many statements, skipping\n",
loadmodel->
name,
i, line);
2769 if (!strcmp(word[0],
"replace"))
2774 Con_Printf(
"Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[1], word[2]);
2777 skinfile->
items = skinfileitem;
2782 Con_Printf(
"Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: wrong number of parameters to command \"%s\", see documentation in DP_GFX_SKINFILES extension in dpextensions.qc\n",
loadmodel->
name,
i, line, word[0]);
2784 else if (words >= 2 && !strncmp(word[0],
"tag_", 4))
2789 else if (words >= 2 && !strcmp(word[1],
","))
2793 Con_Printf(
"Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[0], word[2]);
2796 skinfile->
items = skinfileitem;
2801 Con_Printf(
"Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: does not look like tag or mesh specification, or replace command, see documentation in DP_GFX_SKINFILES extension in dpextensions.qc\n",
loadmodel->
name,
i, line);
2814 for (;skinfile;skinfile = next)
2816 next = skinfile->
next;
2817 for (skinfileitem = skinfile->
items;skinfileitem;skinfileitem = nextitem)
2819 nextitem = skinfileitem->
next;
2829 for (
i = 0;skinfile;skinfile = skinfile->
next,
i++);
2836 double isnap = 1.0 / snap;
2837 for (
i = 0;
i < numvertices*numcomponents;
i++)
2838 vertices[
i] =
floor(vertices[
i]*isnap)*snap;
2843 int i, outtriangles;
2844 float edgedir1[3], edgedir2[3], temp[3];
2849 for (
i = 0, outtriangles = 0;
i < numtriangles;
i++, inelement3i += 3)
2852 VectorSubtract(vertex3f + inelement3i[1] * 3, vertex3f + inelement3i[0] * 3, edgedir1);
2853 VectorSubtract(vertex3f + inelement3i[2] * 3, vertex3f + inelement3i[0] * 3, edgedir2);
2862 return outtriangles;
2868 int firstvertex, lastvertex;
2869 if (numelements > 0 && elements)
2871 firstvertex = lastvertex = elements[0];
2872 for (
i = 1;
i < numelements;
i++)
2875 firstvertex =
min(firstvertex, e);
2876 lastvertex =
max(lastvertex, e);
2880 firstvertex = lastvertex = 0;
2881 if (firstvertexpointer)
2882 *firstvertexpointer = firstvertex;
2883 if (lastvertexpointer)
2884 *lastvertexpointer = lastvertex;
2890 uint64_t basematerialflags = 0;
2893 mod->DrawAddWaterPlanes =
NULL;
2895 for (j =
mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
2896 if (
mod->data_surfaces[j].texture)
2897 basematerialflags |=
mod->data_surfaces[j].texture->basematerialflags;
2904typedef struct Mod_MakeSortedSurfaces_qsortsurface_s
2946 if (!
mod->modelsurfaces_sorted)
2949 for (j = 0; j <
mod->num_surfaces; j++)
2952 info[j].
effect =
mod->data_surfaces[j].effect;
2953 info[j].
texture =
mod->data_surfaces[j].texture;
2956 for (k = 0; k <
mod->brush.numsubmodels; k++)
2957 if (
mod->brush.submodels[k]->submodelsurfaces_end >
mod->brush.submodels[k]->submodelsurfaces_start + 1)
2958 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);
2959 for (j = 0; j <
mod->num_surfaces; j++)
3035 int submodelindex, vertexindex, surfaceindex, triangleindex, textureindex, countvertices = 0, countsurfaces = 0, countfaces = 0, counttextures = 0;
3037 const char *texname;
3039 const float *
v, *vn, *vt;
3041 size_t outbufferpos = 0;
3042 size_t outbuffermax = 0x100000;
3043 char *outbuffer = (
char *)
Z_Malloc(outbuffermax), *oldbuffer;
3045 const int maxtextures = 256;
3050 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"# mtllib for %s exported by darkplaces engine\n", originalfilename);
3053 for (surfaceindex = 0, surface =
model->data_surfaces;surfaceindex < model->num_surfaces;surfaceindex++, surface++)
3059 for (textureindex = 0;textureindex < counttextures;textureindex++)
3060 if (!strcmp(texturenames + textureindex *
MAX_QPATH, texname))
3062 if (textureindex < counttextures)
3064 if (textureindex >= maxtextures)
3066 textureindex = counttextures++;
3068 if (outbufferpos >= outbuffermax >> 1)
3071 oldbuffer = outbuffer;
3072 outbuffer = (
char *)
Z_Malloc(outbuffermax);
3073 memcpy(outbuffer, oldbuffer, outbufferpos);
3076 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"newmtl %s\nNs 96.078431\nKa 0 0 0\nKd 0.64 0.64 0.64\nKs 0.5 0.5 0.5\nNi 1\nd 1\nillum 2\nmap_Kd %s%s\n\n", texname, texname, strstr(texname,
".tga") ?
"" :
".tga");
3086 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"# model exported from %s by darkplaces engine\n# %i vertices, %i faces, %i surfaces\nmtllib %s\n", originalfilename, countvertices, countfaces, countsurfaces, mtlfilename);
3090 for (vertexindex = 0,
v =
model->surfmesh.data_vertex3f, vn =
model->surfmesh.data_normal3f, vt =
model->surfmesh.data_texcoordtexture2f;vertexindex < model->surfmesh.num_vertices;vertexindex++,
v += 3, vn += 3, vt += 2)
3092 if (outbufferpos >= outbuffermax >> 1)
3095 oldbuffer = outbuffer;
3096 outbuffer = (
char *)
Z_Malloc(outbuffermax);
3097 memcpy(outbuffer, oldbuffer, outbufferpos);
3101 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"v %f %f %f\nvn %f %f %f\nvt %f %f\n",
v[0],
v[2],
v[1], vn[0], vn[2], vn[1], vt[0], 1-vt[1]);
3103 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"v %f %f %f\nvn %f %f %f\nvt %f %f\n",
v[0],
v[1],
v[2], vn[0], vn[1], vn[2], vt[0], 1-vt[1]);
3108 for (submodelindex = 0;submodelindex <
max(1,
model->brush.numsubmodels);submodelindex++)
3110 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"o %i\n", submodelindex);
3114 for (surfaceindex = submodel->
submodelsurfaces_start;surfaceindex < submodel->submodelsurfaces_end;surfaceindex++)
3116 surface =
model->data_surfaces + surfaceindex;
3120 for (triangleindex = 0, e =
model->surfmesh.data_element3i + surface->
num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
3122 if (outbufferpos >= outbuffermax >> 1)
3125 oldbuffer = outbuffer;
3126 outbuffer = (
char *)
Z_Malloc(outbuffermax);
3127 memcpy(outbuffer, oldbuffer, outbufferpos);
3134 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"f %i/%i/%i %i/%i/%i %i/%i/%i\n",
a,
a,
a,
b,
b,
b,c,c,c);
3136 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"f %i/%i/%i %i/%i/%i %i/%i/%i\n",
a,
a,
a,c,c,c,
b,
b,
b);
3151 Con_Printf(
"Wrote %s (%i bytes, %i vertices, %i faces, %i surfaces with %i distinct textures)\n", filename, (
int)outbufferpos, countvertices, countfaces, countsurfaces, counttextures);
3156 int countnodes = 0, counttriangles = 0, countframes = 0;
3164 size_t outbufferpos = 0;
3165 size_t outbuffermax = 0x100000;
3166 char *outbuffer = (
char *)
Z_Malloc(outbuffermax), *oldbuffer;
3168 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"version 1\nnodes\n");
3171 for (transformindex = 0;transformindex <
model->num_bones;transformindex++)
3173 if (outbufferpos >= outbuffermax >> 1)
3176 oldbuffer = outbuffer;
3177 outbuffer = (
char *)
Z_Malloc(outbuffermax);
3178 memcpy(outbuffer, oldbuffer, outbufferpos);
3182 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"%3i \"%s\" %3i\n", transformindex,
model->data_bones[transformindex].name,
model->data_bones[transformindex].parent);
3186 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"end\nskeleton\n");
3189 for (poseindex = 0;poseindex < numposes;poseindex++)
3192 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"time %i\n", poseindex);
3195 for (transformindex = 0;transformindex <
model->num_bones;transformindex++)
3200 if (outbufferpos >= outbuffermax >> 1)
3203 oldbuffer = outbuffer;
3204 outbuffer = (
char *)
Z_Malloc(outbuffermax);
3205 memcpy(outbuffer, oldbuffer, outbufferpos);
3223 float cy, sy, cp, sp, cr, sr;
3236 test[1][0] = sr*sp*cy+cr*-sy;
3237 test[1][1] = sr*sp*sy+cr*cy;
3239 test[2][0] = (cr*sp*cy+-sr*-sy);
3240 test[2][1] = (cr*sp*sy+-sr*cy);
3242 test[3][0] = pose[9];
3243 test[3][1] = pose[10];
3244 test[3][2] = pose[11];
3252 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"end\n");
3257 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"triangles\n");
3260 for (surfaceindex = 0, surface =
model->data_surfaces;surfaceindex < model->num_surfaces;surfaceindex++, surface++)
3262 for (triangleindex = 0, e =
model->surfmesh.data_element3i + surface->
num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
3265 if (outbufferpos >= outbuffermax >> 1)
3268 oldbuffer = outbuffer;
3269 outbuffer = (
char *)
Z_Malloc(outbuffermax);
3270 memcpy(outbuffer, oldbuffer, outbufferpos);
3276 for (cornerindex = 0;cornerindex < 3;cornerindex++)
3278 const int index = e[2-cornerindex];
3279 const float *
v =
model->surfmesh.data_vertex3f +
index * 3;
3280 const float *vn =
model->surfmesh.data_normal3f +
index * 3;
3281 const float *vt =
model->surfmesh.data_texcoordtexture2f +
index * 2;
3284 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"%3i %f %f %f %f %f %f %f %f\n" ,
b,
v[0],
v[1],
v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1]);
3288 const unsigned char *wi =
w->
index;
3289 const unsigned char *wf =
w->influence;
3290 if (wf[3]) l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"%3i %f %f %f %f %f %f %f %f 4 %i %f %i %f %i %f %i %f\n", wi[0],
v[0],
v[1],
v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1], wi[0], wf[0]/255.0f, wi[1], wf[1]/255.0f, wi[2], wf[2]/255.0f, wi[3], wf[3]/255.0f);
3291 else if (wf[2]) l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"%3i %f %f %f %f %f %f %f %f 3 %i %f %i %f %i %f\n" , wi[0],
v[0],
v[1],
v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1], wi[0], wf[0]/255.0f, wi[1], wf[1]/255.0f, wi[2], wf[2]/255.0f);
3292 else if (wf[1]) l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"%3i %f %f %f %f %f %f %f %f 2 %i %f %i %f\n" , wi[0],
v[0],
v[1],
v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1], wi[0], wf[0]/255.0f, wi[1], wf[1]/255.0f);
3293 else l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"%3i %f %f %f %f %f %f %f %f\n" , wi[0],
v[0],
v[1],
v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1]);
3300 l =
dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos,
"end\n");
3308 Con_Printf(
"Wrote %s (%i bytes, %i nodes, %i frames, %i triangles)\n", filename, (
int)outbufferpos, countnodes, countframes, counttriangles);
3328 char zymtextbuffer[16384];
3329 char dpmtextbuffer[16384];
3330 char framegroupstextbuffer[16384];
3331 int zymtextsize = 0;
3332 int dpmtextsize = 0;
3333 int framegroupstextsize = 0;
3338 Con_Print(
"usage: modeldecompile <filename>\n");
3351 if (
mod->brush.submodel)
3355 dpsnprintf(basename,
sizeof(basename),
"%s/%s", outname,
mod->name);
3358 if (!
mod->surfmesh.num_triangles)
3365 if (
mod->surfmesh.num_triangles)
3367 dpsnprintf(outname,
sizeof(outname),
"%s_decompiled.obj", basename);
3368 dpsnprintf(mtlname,
sizeof(mtlname),
"%s_decompiled.mtl", basename);
3373 if (
mod->surfmesh.num_triangles &&
mod->num_bones)
3375 dpsnprintf(outname,
sizeof(outname),
"%s_decompiled/ref1.smd", basename);
3377 l =
dpsnprintf(zymtextbuffer + zymtextsize,
sizeof(zymtextbuffer) - zymtextsize,
"output out.zym\nscale 1\norigin 0 0 0\nmesh ref1.smd\n");
3378 if (l > 0) zymtextsize += l;
3379 l =
dpsnprintf(dpmtextbuffer + dpmtextsize,
sizeof(dpmtextbuffer) - dpmtextsize,
"outputdir .\nmodel out\nscale 1\norigin 0 0 0\nscene ref1.smd\n");
3380 if (l > 0) dpmtextsize += l;
3381 for (
i = 0;
i <
mod->numframes;
i = j)
3385 if (
mod->animscenes[
i].framecount > 1)
3395 for (l = 0, k = (
int)
strlen(animname);animname[l];l++)
3396 if(animname[l] <
'0' || animname[l] >
'9')
3398 if(k > 0 && animname[k-1] ==
'_')
3402 for (j =
i + 1;j <
mod->numframes;j++)
3404 dp_strlcpy(animname2,
mod->animscenes[j].name,
sizeof(animname2));
3405 for (l = 0, k = (
int)
strlen(animname2);animname2[l];l++)
3406 if(animname2[l] <
'0' || animname2[l] >
'9')
3408 if(k > 0 && animname[k-1] ==
'_')
3411 if (strcmp(animname2, animname) ||
mod->animscenes[j].framecount > 1)
3422 dpsnprintf(outname,
sizeof(outname),
"%s_decompiled/%s.smd", basename, animname);
3424 if (zymtextsize < (
int)
sizeof(zymtextbuffer) - 100)
3426 l =
dpsnprintf(zymtextbuffer + zymtextsize,
sizeof(zymtextbuffer) - zymtextsize,
"scene %s.smd fps %g %s\n", animname,
mod->animscenes[
i].framerate,
mod->animscenes[
i].loop ?
"" :
" noloop");
3427 if (l > 0) zymtextsize += l;
3429 if (dpmtextsize < (
int)
sizeof(dpmtextbuffer) - 100)
3431 l =
dpsnprintf(dpmtextbuffer + dpmtextsize,
sizeof(dpmtextbuffer) - dpmtextsize,
"scene %s.smd fps %g %s\n", animname,
mod->animscenes[
i].framerate,
mod->animscenes[
i].loop ?
"" :
" noloop");
3432 if (l > 0) dpmtextsize += l;
3434 if (framegroupstextsize < (
int)
sizeof(framegroupstextbuffer) - 100)
3436 l =
dpsnprintf(framegroupstextbuffer + framegroupstextsize,
sizeof(framegroupstextbuffer) - framegroupstextsize,
"%d %d %f %d // %s\n",
first,
count,
mod->animscenes[
i].framerate,
mod->animscenes[
i].loop, animname);
3437 if (l > 0) framegroupstextsize += l;
3444 if (framegroupstextsize)
3445 FS_WriteFile(
va(vabuf,
sizeof(vabuf),
"%s_decompiled.framegroups", basename), framegroupstextbuffer, (
fs_offset_t)framegroupstextsize);
3452 memset(state, 0,
sizeof(*state));
3479 memset(state, 0,
sizeof(*state));
3487 row = state->
rows + blockheight;
3500 for (
y = blockheight;
y < state->
height;
y++)
3504 row = state->
rows +
y;
3519typedef struct lightmapsample_s
3529typedef struct lightmapvertex_s
3534 float texcoordbase[2];
3535 float texcoordlightmap[2];
3536 float lightcolor[4];
3540typedef struct lightmaptriangle_s
3559typedef struct lightmaplight_s
3572#define MAX_LIGHTMAPSAMPLES 64
3587 float relativepoint[3];
3594 float lightorigin[3];
3598 float lightcolor[3];
3600 for (
i = 0;
i < 5*3;
i++)
3609 lightradius2 = lightradius * lightradius;
3612 if (dist2 >= lightradius2)
3614 lightiradius = 1.0f / lightradius;
3615 dist =
sqrt(dist2) * lightiradius;
3642 diffuse[0] = (
dir[0]*sample[3] +
dir[1]*sample[6] +
dir[2]*sample[ 9] + sample[ 0]);
3643 diffuse[1] = (
dir[0]*sample[4] +
dir[1]*sample[7] +
dir[2]*sample[10] + sample[ 1]);
3644 diffuse[2] = (
dir[0]*sample[5] +
dir[1]*sample[8] +
dir[2]*sample[11] + sample[ 2]);
3646 VectorMA(sample, -0.333f, diffuse, ambient);
3656 const float *vertex3f =
model->surfmesh.data_vertex3f;
3657 const int *element3i =
model->surfmesh.data_element3i;
3660 for (surfaceindex =
model->submodelsurfaces_start;surfaceindex < model->submodelsurfaces_end;surfaceindex++)
3662 surface =
model->data_surfaces + surfaceindex;
3667 for (triangleindex = 0, e = element3i + 3*surface->
num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
3679 int maxnodes = 1<<14;
3696 if (maxnodes > 1<<22)
3710 memcpy(svbsp.
nodes, nodes, svbsp.
numnodes *
sizeof(*nodes));
3711 lightinfo->
svbsp = svbsp;
3785 float relativepoint[3];
3796 for (
i = 0;
i < 5*3;
i++)
3806 if (dist2 >= lightinfo->
radius2)
3818 for (offsetindex = 1;offsetindex < numoffsets;offsetindex++)
3867 f =
max(0,
f) * 255.0f;
3871 lm_bgr[0] = (
unsigned char)
bound(0.0f,
color[2], 255.0f);
3872 lm_bgr[1] = (
unsigned char)
bound(0.0f,
color[1], 255.0f);
3873 lm_bgr[2] = (
unsigned char)
bound(0.0f,
color[0], 255.0f);
3875 lm_dir[0] = (
unsigned char)
dir[2];
3876 lm_dir[1] = (
unsigned char)
dir[1];
3877 lm_dir[2] = (
unsigned char)
dir[0];
3900 diffuse[0] = (
dir[0]*sample[3] +
dir[1]*sample[6] +
dir[2]*sample[ 9] + sample[ 0]) * 127.5f;
3901 diffuse[1] = (
dir[0]*sample[4] +
dir[1]*sample[7] +
dir[2]*sample[10] + sample[ 1]) * 127.5f;
3902 diffuse[2] = (
dir[0]*sample[5] +
dir[1]*sample[8] +
dir[2]*sample[11] + sample[ 2]) * 127.5f;
3905 VectorMA(ambient, -0.333f, diffuse, ambient);
3930 for (
i = 0;
i < 3;
i++)
3945 for (surfaceindex = 0;surfaceindex <
model->num_surfaces;surfaceindex++)
3947 surface =
model->data_surfaces + surfaceindex;
3951 if (
model->brushq3.data_lightmaps)
3953 for (
i = 0;
i <
model->brushq3.num_mergedlightmaps;
i++)
3954 if (
model->brushq3.data_lightmaps[
i])
3959 if (
model->brushq3.data_deluxemaps)
3961 for (
i = 0;
i <
model->brushq3.num_mergedlightmaps;
i++)
3962 if (
model->brushq3.data_deluxemaps[
i])
3979 unsigned char *
data;
3980 oldsurfmesh =
model->surfmesh;
3984 size +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3985 size +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3986 size +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3987 size +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3988 size +=
model->surfmesh.num_vertices *
sizeof(
float[2]);
3989 size +=
model->surfmesh.num_vertices *
sizeof(
float[2]);
3990 size +=
model->surfmesh.num_vertices *
sizeof(
float[4]);
3992 model->surfmesh.data_vertex3f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3993 model->surfmesh.data_normal3f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3994 model->surfmesh.data_svector3f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3995 model->surfmesh.data_tvector3f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[3]);
3996 model->surfmesh.data_texcoordtexture2f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[2]);
3997 model->surfmesh.data_texcoordlightmap2f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[2]);
3998 model->surfmesh.data_lightmapcolor4f = (
float *)
data;
data +=
model->surfmesh.num_vertices *
sizeof(
float[4]);
3999 if (
model->surfmesh.num_vertices > 65536)
4002 if (
model->surfmesh.data_element3i_indexbuffer && !
model->surfmesh.data_element3i_indexbuffer->isdynamic)
4004 model->surfmesh.data_element3i_indexbuffer =
NULL;
4005 if (
model->surfmesh.data_element3s_indexbuffer && !
model->surfmesh.data_element3s_indexbuffer->isdynamic)
4007 model->surfmesh.data_element3s_indexbuffer =
NULL;
4008 if (
model->surfmesh.data_vertex3f_vertexbuffer && !
model->surfmesh.data_vertex3f_vertexbuffer->isdynamic)
4010 model->surfmesh.data_vertex3f_vertexbuffer =
NULL;
4011 model->surfmesh.data_svector3f_vertexbuffer =
NULL;
4012 model->surfmesh.data_tvector3f_vertexbuffer =
NULL;
4013 model->surfmesh.data_normal3f_vertexbuffer =
NULL;
4014 model->surfmesh.data_texcoordtexture2f_vertexbuffer =
NULL;
4015 model->surfmesh.data_texcoordlightmap2f_vertexbuffer =
NULL;
4016 model->surfmesh.data_lightmapcolor4f_vertexbuffer =
NULL;
4017 model->surfmesh.data_skeletalindex4ub_vertexbuffer =
NULL;
4018 model->surfmesh.data_skeletalweight4ub_vertexbuffer =
NULL;
4022 for (surfaceindex = 0;surfaceindex <
model->num_surfaces;surfaceindex++)
4024 surface =
model->data_surfaces + surfaceindex;
4031 model->surfmesh.data_vertex3f[outvertexindex*3+0] = oldsurfmesh.
data_vertex3f[vertexindex*3+0];
4032 model->surfmesh.data_vertex3f[outvertexindex*3+1] = oldsurfmesh.
data_vertex3f[vertexindex*3+1];
4033 model->surfmesh.data_vertex3f[outvertexindex*3+2] = oldsurfmesh.
data_vertex3f[vertexindex*3+2];
4034 model->surfmesh.data_normal3f[outvertexindex*3+0] = oldsurfmesh.
data_normal3f[vertexindex*3+0];
4035 model->surfmesh.data_normal3f[outvertexindex*3+1] = oldsurfmesh.
data_normal3f[vertexindex*3+1];
4036 model->surfmesh.data_normal3f[outvertexindex*3+2] = oldsurfmesh.
data_normal3f[vertexindex*3+2];
4037 model->surfmesh.data_svector3f[outvertexindex*3+0] = oldsurfmesh.
data_svector3f[vertexindex*3+0];
4038 model->surfmesh.data_svector3f[outvertexindex*3+1] = oldsurfmesh.
data_svector3f[vertexindex*3+1];
4039 model->surfmesh.data_svector3f[outvertexindex*3+2] = oldsurfmesh.
data_svector3f[vertexindex*3+2];
4040 model->surfmesh.data_tvector3f[outvertexindex*3+0] = oldsurfmesh.
data_tvector3f[vertexindex*3+0];
4041 model->surfmesh.data_tvector3f[outvertexindex*3+1] = oldsurfmesh.
data_tvector3f[vertexindex*3+1];
4042 model->surfmesh.data_tvector3f[outvertexindex*3+2] = oldsurfmesh.
data_tvector3f[vertexindex*3+2];
4058 Vector4Set(
model->surfmesh.data_lightmapcolor4f + 4*outvertexindex, 1, 1, 1, 1);
4063 if (
model->surfmesh.data_element3s)
4064 for (
i = 0;
i <
model->surfmesh.num_triangles*3;
i++)
4065 model->surfmesh.data_element3s[
i] =
model->surfmesh.data_element3i[
i];
4068 for (
i = 0;
i <
model->brush.numsubmodels;
i++)
4069 model->brush.submodels[
i]->surfmesh =
model->surfmesh;
4083 for (surfaceindex = 0;surfaceindex <
model->num_surfaces;surfaceindex++)
4085 surface =
model->data_surfaces + surfaceindex;
4109 triangle->
axis = axis;
4121float lmaxis[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
4139 float trianglenormal[3];
4140 float samplecenter[3];
4141 float samplenormal[3];
4147 float lmscalepixels;
4150 float lm_basescalepixels;
4151 int lm_borderpixels;
4156 unsigned char *lightmappixels;
4157 unsigned char *deluxemappixels;
4170 for (surfaceindex = 0;surfaceindex <
model->num_surfaces;surfaceindex++)
4172 surface =
model->data_surfaces + surfaceindex;
4174 lmscalepixels = lm_basescalepixels;
4175 for (retry = 0;retry < 30;retry++)
4179 lmscalepixels *= 0.5f;
4191 for (j = 0;j < 3;j++)
4193 if (j == triangle->
axis)
4195 lmmins =
floor(triangle->
mins[j]*lmscalepixels)-lm_borderpixels;
4196 lmmaxs =
floor(triangle->
maxs[j]*lmscalepixels)+lm_borderpixels;
4197 triangle->
lmsize[k] = (
int)(lmmaxs-lmmins);
4198 triangle->
lmbase[k] = lmmins/lmscalepixels;
4199 triangle->
lmscale[k] = lmscalepixels;
4212 lm_texturesize *= 2;
4224 if (surfaceindex > 0)
4235 model->brushq3.deluxemapping_modelspace =
true;
4236 model->brushq3.deluxemapping =
true;
4237 model->brushq3.num_mergedlightmaps = lightmapnumber;
4240 lightmappixels = (
unsigned char *)
Mem_Alloc(
tempmempool,
model->brushq3.num_mergedlightmaps * lm_texturesize * lm_texturesize * 4);
4241 deluxemappixels = (
unsigned char *)
Mem_Alloc(
tempmempool,
model->brushq3.num_mergedlightmaps * lm_texturesize * lm_texturesize * 4);
4242 for (surfaceindex = 0;surfaceindex <
model->num_surfaces;surfaceindex++)
4244 surface =
model->data_surfaces + surfaceindex;
4252 axis = triangle->
axis;
4253 axis1 = axis == 0 ? 1 : 0;
4254 axis2 = axis == 2 ? 1 : 2;
4255 lmiscale[0] = 1.0f / triangle->
lmscale[0];
4256 lmiscale[1] = 1.0f / triangle->
lmscale[1];
4257 if (trianglenormal[axis] < 0)
4261 slopebase = triangle->
vertex[0][axis] - triangle->
vertex[0][axis1]*slopex - triangle->
vertex[0][axis2]*slopey;
4262 for (j = 0;j < 3;j++)
4264 float *t2f =
model->surfmesh.data_texcoordlightmap2f + e[
i*3+j]*2;
4268 samplecenter[axis1] = (t2f[0]*lm_texturesize-triangle->
lmoffset[0])*lmiscale[0] + triangle->
lmbase[0];
4269 samplecenter[axis2] = (t2f[1]*lm_texturesize-triangle->
lmoffset[1])*lmiscale[1] + triangle->
lmbase[1];
4270 samplecenter[axis] = samplecenter[axis1]*slopex + samplecenter[axis2]*slopey + slopebase;
4271 Con_Printf(
"%f:%f %f:%f %f:%f = %f %f\n", triangle->
vertex[j][axis1], samplecenter[axis1], triangle->
vertex[j][axis2], samplecenter[axis2], triangle->
vertex[j][axis], samplecenter[axis], t2f[0], t2f[1]);
4285 left[2] = 1.0f / triangle->
lmscale[1];
4299 left[2] = 1.0f / triangle->
lmscale[1];
4312 left[1] = 1.0f / triangle->
lmscale[1];
4324#define LM_DIST_EPSILON (1.0f / 32.0f)
4328 for (
x = 0;
x < triangle->
lmsize[0];
x++, pixeloffset += 4)
4330 samplecenter[axis1] = (
x+0.5f)*lmiscale[0] + triangle->
lmbase[0];
4331 samplecenter[axis2] = (
y+0.5f)*lmiscale[1] + triangle->
lmbase[1];
4332 samplecenter[axis] = samplecenter[axis1]*slopex + samplecenter[axis2]*slopey + slopebase;
4333 VectorMA(samplecenter, 0.125f, samplenormal, samplecenter);
4340 for (lightmapindex = 0;lightmapindex <
model->brushq3.num_mergedlightmaps;lightmapindex++)
4342 model->brushq3.data_lightmaps[lightmapindex] =
R_LoadTexture2D(
model->texturepool,
va(vabuf,
sizeof(vabuf),
"lightmap%i", lightmapindex), lm_texturesize, lm_texturesize, lightmappixels + lightmapindex * lm_texturesize * lm_texturesize * 4,
TEXTYPE_BGRA,
TEXF_FORCELINEAR, -1,
NULL);
4343 model->brushq3.data_deluxemaps[lightmapindex] =
R_LoadTexture2D(
model->texturepool,
va(vabuf,
sizeof(vabuf),
"deluxemap%i", lightmapindex), lm_texturesize, lm_texturesize, deluxemappixels + lightmapindex * lm_texturesize * lm_texturesize * 4,
TEXTYPE_BGRA,
TEXF_FORCELINEAR, -1,
NULL);
4348 if (deluxemappixels)
4351 for (surfaceindex = 0;surfaceindex <
model->num_surfaces;surfaceindex++)
4353 surface =
model->data_surfaces + surfaceindex;
4364 model->brushq1.lightmapupdateflags =
NULL;
4365 model->brushq1.firstrender =
false;
4366 model->brushq1.num_lightstyles = 0;
4367 model->brushq1.data_lightstyleinfo =
NULL;
4368 for (
i = 0;
i <
model->brush.numsubmodels;
i++)
4370 model->brush.submodels[
i]->brushq1.lightmapupdateflags =
NULL;
4371 model->brush.submodels[
i]->brushq1.firstrender =
false;
4372 model->brush.submodels[
i]->brushq1.num_lightstyles = 0;
4373 model->brush.submodels[
i]->brushq1.data_lightstyleinfo =
NULL;
4380 for (
i = 0;
i <
model->surfmesh.num_vertices;
i++)
4391 for (
z = 0;
z <
model->brushq3.num_lightgrid_isize[2];
z++)
4393 pos[2] = (
model->brushq3.num_lightgrid_imins[2] +
z + 0.5f) *
model->brushq3.num_lightgrid_cellsize[2];
4394 for (
y = 0;
y <
model->brushq3.num_lightgrid_isize[1];
y++)
4396 pos[1] = (
model->brushq3.num_lightgrid_imins[1] +
y + 0.5f) *
model->brushq3.num_lightgrid_cellsize[1];
4397 for (
x = 0;
x <
model->brushq3.num_lightgrid_isize[0];
x++,
index++)
4399 pos[0] = (
model->brushq3.num_lightgrid_imins[0] +
x + 0.5f) *
model->brushq3.num_lightgrid_cellsize[0];
4432 Con_Printf(
"usage: mod_generatelightmaps\n");
4445 memset(
mod, 0,
sizeof(*
mod));
4467 mod->num_surfaces = 0;
4468 mod->surfmesh.num_vertices = 0;
4469 mod->surfmesh.num_triangles = 0;
4470 if (
mod->surfmesh.data_vertexhash)
4471 memset(
mod->surfmesh.data_vertexhash, -1,
mod->surfmesh.num_vertexhashsize *
sizeof(*
mod->surfmesh.data_vertexhash));
4473 mod->DrawAddWaterPlanes =
NULL;
4481 for (
i = 0, t =
mod->data_textures;
i < mod->num_textures;
i++, t++)
4484 if (
mod->max_textures <=
mod->num_textures)
4487 mod->max_textures =
max(
mod->max_textures * 2, 1024);
4490 for (
i = 0;
i <
mod->num_surfaces;
i++)
4491 mod->data_surfaces[
i].texture =
mod->data_textures + (
mod->data_surfaces[
i].texture - oldtextures);
4493 t = &
mod->data_textures[
mod->num_textures++];
4532 if (batchwithprevioussurface &&
mod->num_surfaces > 0 &&
mod->data_surfaces[
mod->num_surfaces - 1].texture == tex)
4533 return mod->data_surfaces +
mod->num_surfaces - 1;
4535 if (
mod->max_surfaces ==
mod->num_surfaces)
4537 mod->max_surfaces = 2 *
max(
mod->num_surfaces, 64);
4539 mod->modelsurfaces_sorted = (
int *)
Mem_Realloc(
mod->mempool,
mod->modelsurfaces_sorted,
mod->max_surfaces *
sizeof(*
mod->modelsurfaces_sorted));
4541 surf =
mod->data_surfaces +
mod->num_surfaces;
4542 mod->num_surfaces++;
4543 memset(surf, 0,
sizeof(*surf));
4554int 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)
4556 int hashindex, h, vnum,
mask;
4573 mask =
mod->surfmesh.num_vertexhashsize - 1;
4575 for (vnum = surf ? surf->
num_firstvertex : 0; vnum < mesh->num_vertices; vnum++)
4584 mask =
mod->surfmesh.num_vertexhashsize - 1;
4586 hashindex = (
unsigned int)(
x * 2003 +
y * 4001 +
z * 7919 + nx * 4097 + ny * 257 + nz * 17) &
mask;
4659 mod->submodelsurfaces_start = 0;
4660 mod->submodelsurfaces_end = 0;
4661 for (
i = 0;
i <
mod->num_surfaces;
i++)
4662 mod->data_surfaces[
i].included =
false;
4663 for (
i = 0;
i <
mod->num_surfaces;
i++)
4665 if (
mod->data_surfaces[
i].included)
4667 tex =
mod->data_surfaces[
i].texture;
4669 for (j =
i; j <
mod->num_surfaces; j++)
4671 if (!
mod->data_surfaces[j].included &&
mod->data_surfaces[j].texture == tex)
4673 mod->data_surfaces[j].included = 1;
4674 mod->modelsurfaces_sorted[
mod->submodelsurfaces_end++] = j;
4683 vec_t x2a, x2b, y2a, y2b, z2a, z2b,
x2,
y2, z2, yawradius, rotatedradius;
4685 if (
mod->surfmesh.num_vertices > 0)
4690 for (
i = 1;
i <
mod->surfmesh.num_vertices;
i++)
4692 float x =
mod->surfmesh.data_vertex3f[
i * 3 + 0];
4693 float y =
mod->surfmesh.data_vertex3f[
i * 3 + 1];
4694 float z =
mod->surfmesh.data_vertex3f[
i * 3 + 2];
4696 if (
mod->normalmins[0] >
x)
mod->normalmins[0] =
x;
4697 if (
mod->normalmins[1] >
y)
mod->normalmins[1] =
y;
4698 if (
mod->normalmins[2] >
z)
mod->normalmins[2] =
z;
4699 if (
mod->normalmaxs[0] <
x)
mod->normalmaxs[0] =
x;
4700 if (
mod->normalmaxs[1] <
y)
mod->normalmaxs[1] =
y;
4701 if (
mod->normalmaxs[2] <
z)
mod->normalmaxs[2] =
z;
4705 x2a =
mod->normalmins[0] *
mod->normalmins[0];
4706 x2b =
mod->normalmaxs[0] *
mod->normalmaxs[0];
4707 y2a =
mod->normalmins[1] *
mod->normalmins[1];
4708 y2b =
mod->normalmaxs[1] *
mod->normalmaxs[1];
4709 z2a =
mod->normalmins[2] *
mod->normalmins[2];
4710 z2b =
mod->normalmaxs[2] *
mod->normalmaxs[2];
4715 rotatedradius =
sqrt(
x2 +
y2 + z2);
4718 VectorSet(
mod->rotatedmins, -rotatedradius, -rotatedradius, -rotatedradius);
4719 VectorSet(
mod->rotatedmaxs, rotatedradius, rotatedradius, rotatedradius);
4720 mod->radius = rotatedradius;
4739 qbool warned =
false;
4740 for (
i = 0;
i <
mod->num_surfaces;
i++)
4749 if (e[j] <
first || e[j] >= end)
4768 mod->surfmesh.data_texcoordtexture2f_vertexbuffer =
mod->surfmesh.data_texcoordtexture2f ?
R_BufferData_Store(
mod->surfmesh.num_vertices *
sizeof(
float[2]),
mod->surfmesh.data_texcoordtexture2f,
R_BUFFERDATA_VERTEX, &
mod->surfmesh.data_texcoordtexture2f_bufferoffset) :
NULL;
4769 mod->surfmesh.data_texcoordlightmap2f_vertexbuffer =
mod->surfmesh.data_texcoordlightmap2f ?
R_BufferData_Store(
mod->surfmesh.num_vertices *
sizeof(
float[2]),
mod->surfmesh.data_texcoordlightmap2f,
R_BUFFERDATA_VERTEX, &
mod->surfmesh.data_texcoordlightmap2f_bufferoffset) :
NULL;
4771 mod->surfmesh.data_skeletalindex4ub_vertexbuffer =
mod->surfmesh.data_skeletalindex4ub ?
R_BufferData_Store(
mod->surfmesh.num_vertices *
sizeof(
unsigned char[4]),
mod->surfmesh.data_skeletalindex4ub,
R_BUFFERDATA_VERTEX, &
mod->surfmesh.data_skeletalindex4ub_bufferoffset) :
NULL;
4772 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;
4782 Mod_BuildTextureVectorsFromNormals(0,
mod->surfmesh.num_vertices,
mod->surfmesh.num_triangles,
mod->surfmesh.data_vertex3f,
mod->surfmesh.data_texcoordtexture2f,
mod->surfmesh.data_normal3f,
mod->surfmesh.data_element3i,
mod->surfmesh.data_svector3f,
mod->surfmesh.data_tvector3f,
true);
#define SUPERCONTENTS_SKY
#define SUPERCONTENTS_OPAQUE
#define SUPERCONTENTS_LAVA
#define SUPERCONTENTS_DONOTENTER
#define SUPERCONTENTS_MONSTERCLIP
#define SUPERCONTENTS_BOTCLIP
#define SUPERCONTENTS_SLIME
#define SUPERCONTENTS_SOLID
#define SUPERCONTENTS_PLAYERCLIP
#define SUPERCONTENTS_NODROP
#define SUPERCONTENTS_WATER
cvar_t cl_stainmaps_clearonload
void CL_KeepaliveMessage(qbool readmessages)
void SCR_PopLoadingScreen(qbool redraw)
void SCR_PushLoadingScreen(const char *msg, float len_in_parent)
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
static int Cmd_Argc(cmd_state_t *cmd)
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
#define CF_CLIENT
cvar/command that only the client can change/execute
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
unsigned short CRC_Block(const unsigned char *data, size_t size)
unsigned short CRC_Block_CaseInsensitive(const unsigned char *data, size_t size)
char com_token[MAX_INPUTLINE]
char * va(char *buf, size_t buflen, const char *format,...)
qbool COM_ParseToken_QuakeC(const char **datapointer, qbool returnnewline)
qbool COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
#define dp_strlcpy(dst, src, dsize)
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
void Con_DPrint(const char *msg)
A Con_Print that only shows up if the "developer" cvar is set.
const float DRAWFLAG_ADDITIVE
const float DRAWFLAG_2XMODULATE
float mod(float dividend, float divisor)
const float DRAWFLAG_SCREEN
const float DRAWFLAG_MODULATE
float Cvar_VariableValue(cvar_state_t *cvars, const char *var_name, unsigned neededflags)
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
const char * FS_FileExtension(const char *in)
qbool FS_WriteFile(const char *filename, const void *data, fs_offset_t len)
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
void FS_FreeSearch(fssearch_t *search)
fssearch_t * FS_Search(const char *pattern, int caseinsensitive, int quiet, const char *packfile)
static int(ZEXPORT *qz_inflate)(z_stream *strm
void FS_StripExtension(const char *in, char *out, size_t size_out)
r_meshbuffer_t * R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qbool isindexbuffer, qbool isuniformbuffer, qbool isdynamic, qbool isindex16)
void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
skinframe_t * R_SkinFrame_LoadExternal(const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
rtexture_t * R_GetCubemap(const char *basename)
void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
skinframe_t * R_SkinFrame_LoadMissing(void)
void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
r_meshbuffer_t * R_BufferData_Store(size_t datasize, const void *data, r_bufferdata_type_t type, int *returnbufferoffset)
request space in a vertex/index/uniform buffer for the chosen data, returns the buffer pointer and of...
void R_Mod_DrawSky(entity_render_t *ent)
void R_Mod_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, unsigned char *outleafpvs, int *outnumleafspointer, int *outsurfacelist, unsigned char *outsurfacepvs, int *outnumsurfacespointer, unsigned char *outshadowtrispvs, unsigned char *outlighttrispvs, unsigned char *visitingleafpvs, int numfrustumplanes, const mplane_t *frustumplanes, qbool noocclusion)
void R_Mod_DrawDebug(entity_render_t *ent)
void R_Mod_DrawLight(entity_render_t *ent, int numsurfaces, const int *surfacelist, const unsigned char *lighttrispvs)
void R_Mod_Draw(entity_render_t *ent)
void R_Mod_DrawShadowMap(int side, entity_render_t *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int modelnumsurfaces, const int *modelsurfacelist, const unsigned char *surfacesides, const vec3_t lightmins, const vec3_t lightmaxs)
void R_Mod_DrawAddWaterPlanes(entity_render_t *ent)
void R_Mod_DrawDepth(entity_render_t *ent)
void R_Mod_DrawPrepass(entity_render_t *ent)
void R_FreeTexturePool(rtexturepool_t **rtexturepool)
rtexturepool_t * R_AllocTexturePool(void)
void R_FreeTexture(rtexture_t *rt)
rtexture_t * R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
GLubyte GLubyte GLubyte z
GLenum GLenum GLuint texture
GLenum GLsizei GLsizei height
GLfloat GLfloat GLfloat v2
GLubyte GLubyte GLubyte GLubyte w
GLenum GLenum GLuint GLint GLint layer
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
#define GL_ONE_MINUS_DST_ALPHA
#define GL_ONE_MINUS_DST_COLOR
GLenum GLenum GLsizei count
GLint GLenum GLint GLint y
GLsizeiptr const GLvoid * data
GLuint GLuint GLintptr offset
#define GL_ONE_MINUS_SRC_ALPHA
GLenum GLuint GLenum GLsizei const GLchar * buf
#define GL_ONE_MINUS_SRC_COLOR
void Host_Error(const char *error,...)
void AnglesFromVectors(vec3_t angles, const vec3_t forward, const vec3_t up, qbool flippitch)
LadyHavoc: calculates pitch/yaw/roll angles from forward and up vectors.
#define VectorLerp(v1, lerp, v2, out)
#define Vector2Copy(in, out)
#define VectorNegate(a, b)
#define BoxesOverlap(a, b, c, d)
#define VectorNormalize(v)
#define bound(min, num, max)
#define Vector4Set(vec, r, g, b, a)
#define VectorSet(vec, x, y, z)
#define Vector4Copy(in, out)
#define VectorSubtract(a, b, out)
#define CrossProduct(a, b, out)
#define TriangleNormal(a, b, c, n)
#define VectorCopy(in, out)
#define VectorScale(in, scale, out)
#define VectorAdd(a, b, out)
#define VectorMA(a, scale, b, out)
void Matrix4x4_FromBonePose7s(matrix4x4_t *m, float originscale, const short *pose7s)
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
void Matrix4x4_ToArray12FloatGL(const matrix4x4_t *in, float out[4][3])
void Matrix4x4_FromVectors(matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_Skeletal_FreeBuffers(void)
void Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_q3shader_force_addalpha
void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_q3shader_default_polygonfactor
void Mod_HLBSP_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_noshader_default_offsetmapping
void Mod_IBSP_Load(model_t *mod, void *buffer, void *bufferend)
int Mod_Q2BSP_SuperContentsFromNativeContents(int nativecontents)
cvar_t mod_q3shader_default_offsetmapping_scale
cvar_t mod_q3shader_default_polygonoffset
cvar_t mod_q3shader_default_offsetmapping_bias
void Mod_2PSB_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_q3shader_default_offsetmapping
void Mod_VBSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_BSP2_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_q3shader_force_terrain_alphaflag
void Mod_MAP_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_q3shader_default_refractive_index
#define MATERIALFLAG_VERTEXCOLOR
#define MATERIALFLAG_FULLBRIGHT
#define MATERIALFLAG_ALPHA
#define MATERIALFLAG_REFRACTION
#define MATERIALFLAG_NODRAW
#define MATERIALFLAG_ALPHATEST
#define MATERIALFLAG_BLENDED
#define MATERIALFLAG_ALPHAGEN_VERTEX
#define MATERIALFLAG_WATERSHADER
#define MATERIALFLAG_CAMERA
#define MATERIALFLAGMASK_TRANSLUCENT
#define MATERIALFLAG_WALL
#define MATERIALFLAG_NOSHADOW
#define MATERIALFLAG_MESHCOLLISIONS
#define MATERIALFLAG_REFLECTION
#define MATERIALFLAG_NOCULLFACE
#define MATERIALFLAG_CUSTOMBLEND
#define MATERIALFLAG_NORTLIGHT
#define Q3SURFACEPARM_PLAYERCLIP
#define Q3SURFACEPARM_NOIMPACT
#define Q3SURFACEPARM_STRUCTURAL
#define Q3SURFACEPARM_NONSOLID
#define Q3SURFACEFLAG_SKY
#define Q3SURFACEPARM_TRANS
#define Q3SURFACEPARM_FOG
#define Q3SURFACEPARM_NODROP
#define Q3SURFACEPARM_NOMIPMAPS
#define Q3SURFACEFLAG_NOMARKS
#define Q3SURFACEPARM_CLUSTERPORTAL
#define Q3SURFACEFLAG_SLICK
#define Q3SURFACEPARM_NODAMAGE
#define Q3SURFACEFLAG_METALSTEPS
#define Q3SURFACEPARM_SLICK
#define Q3SURFACEFLAG_ALPHASHADOW
#define Q3SURFACEPARM_METALSTEPS
#define Q3SURFACEPARM_NODRAW
#define Q3SURFACEPARM_NOLIGHTMAP
#define Q3SURFACEFLAG_NOIMPACT
#define Q3SURFACEFLAG_LIGHTFILTER
#define Q3SURFACEPARM_LAVA
#define Q3SURFACEFLAG_NOLIGHTMAP
#define Q3SURFACEPARM_SLIME
#define Q3SURFACEFLAG_HINT
#define Q3SURFACEFLAG_DUST
#define Q3SURFACEPARM_SKY
#define Q3SURFACEPARM_LIGHTFILTER
#define Q3SURFACEPARM_ANTIPORTAL
#define Q3SURFACEPARM_NOMARKS
#define Q3SURFACEPARM_ORIGIN
#define Q3SURFACEFLAG_NODRAW
#define Q3SURFACEPARM_ALPHASHADOW
#define Q3SURFACEFLAG_POINTLIGHT
#define Q3SURFACEPARM_BOTCLIP
#define Q3SURFACEPARM_DUST
#define Q3SURFACEPARM_WATER
#define Q3SURFACEFLAG_NONSOLID
#define Q3SURFACEPARM_DETAIL
#define Q3SURFACEPARM_POINTLIGHT
#define Q3SURFACEFLAG_NODLIGHT
#define Q3SURFACEFLAG_NODAMAGE
#define Q3SURFACEPARM_DONOTENTER
#define Q3SURFACEPARM_AREAPORTAL
#define Q3SURFACEPARM_NODLIGHT
#define Q3SURFACEPARM_LIGHTGRID
#define Q3SURFACEPARM_HINT
static void Mod_Print_f(cmd_state_t *cmd)
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP(model_t *model, lightmaplight_t *lightinfo)
cvar_t r_shadow_lightattenuationdividebias
shader_t * Mod_LookupQ3Shader(const char *name)
qbool Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qbool warnmissing, qbool fallback, int defaulttexflags, int defaultmaterialflags)
void Mod_Mesh_Create(model_t *mod, const char *name)
void Mod_Mesh_Reset(model_t *mod)
void Mod_AllocLightmap_Reset(mod_alloclightmap_state_t *state)
static void Q3Shader_AddToHash(shader_t *shader)
cvar_t mod_generatelightmaps_borderpixels
static void Mod_Mesh_ComputeBounds(model_t *mod)
msurface_t * Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
void Mod_AllocLightmap_Init(mod_alloclightmap_state_t *state, mempool_t *mempool, int width, int height)
texture_shaderpass_t * Mod_CreateShaderPassFromQ3ShaderLayer(mempool_t *mempool, const char *modelname, q3shaderinfo_layer_t *layer, int layerindex, int texflags, const char *texturename)
void Mod_AllocLightmap_Free(mod_alloclightmap_state_t *state)
static void Mod_GenerateLightmaps_SamplePoint(const float *pos, const float *normal, float *sample, int numoffsets, const float *offsets)
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)
static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh)
static void Mod_GenerateLightmaps_LightPoint(model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
static void mod_newmap(void)
skinfile_t * Mod_LoadSkinFiles(void)
cvar_t mod_generatelightmaps_gridsamples
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
static void R_Model_Null_Draw(entity_render_t *ent)
void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qbool areaweighting)
void Mod_Mesh_Validate(model_t *mod)
texture_shaderpass_t * Mod_CreateShaderPass(mempool_t *mempool, skinframe_t *skinframe)
model_t * Mod_ForName(const char *name, qbool crash, qbool checkdisk, const char *parentname)
void Mod_ShadowMesh_Free(shadowmesh_t *mesh)
void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qbool lightmapoffsets, qbool vertexcolors)
texture_t * Mod_Mesh_GetTexture(model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
cvar_t mod_generatelightmaps_texturesize
static void Mod_FindPotentialDeforms(model_t *mod)
static void Mod_GenerateLightmaps_f(cmd_state_t *cmd)
#define Q3SHADER_HASH_SIZE
void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2)
void Mod_PurgeUnused(void)
static void Mod_Mesh_UploadDynamicBuffers(model_t *mod)
int Mod_CountSkinFiles(skinfile_t *skinfile)
int Mod_BuildVertexRemapTableFromElements(int numelements, const int *elements, int numvertices, int *remapvertices)
static modloader_t loader[]
static void Mod_GenerateLightmaps_UnweldTriangles(model_t *model)
static void Mod_GenerateLightmaps_VertexSample(const float *pos, const float *normal, float *vertex_color)
int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, const float *vertex3f)
#define MAX_LIGHTMAPSAMPLES
static void Mod_GenerateLightmaps_GridSample(const float *pos, q3dlightgrid_t *s)
static void Mod_GenerateLightmaps_InitSampleOffsets(model_t *model)
shadowmesh_t * Mod_ShadowMesh_Finish(shadowmesh_t *mesh, qbool createvbo)
void Mod_Mesh_Destroy(model_t *mod)
cvar_t mod_q3bsp_nolightmaps
static void Mod_GenerateLightmaps_CreateLightmaps(model_t *model)
static void Mod_FrameGroupify_ParseGroups_Store(unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)
static memexpandablearray_t models
qbool Mod_AllocLightmap_Block(mod_alloclightmap_state_t *state, int blockwidth, int blockheight, int *outx, int *outy)
static q3shader_data_t * q3shader_data
static void Mod_GenerateLightmaps_LightmapSample(const float *pos, const float *normal, unsigned char *lm_bgr, unsigned char *lm_dir)
cvar_t mod_generatelightmaps_lightmapradius
static lightmaplight_t * mod_generatelightmaps_lightinfo
static int Mod_MakeSortedSurfaces_qsortfunc(const void *a, const void *b)
void Mod_SnapVertices(int numcomponents, int numvertices, float *vertices, float snap)
int Mod_RemoveDegenerateTriangles(int numtriangles, const int *inelement3i, int *outelement3i, const float *vertex3f)
model_t * Mod_FindName(const char *name, const char *parentname)
lightmaptriangle_t * mod_generatelightmaps_lightmaptriangles
static void mod_start(void)
static void Mod_GenerateLightmaps(model_t *model)
static void mod_shutdown(void)
static void Mod_GenerateLightmaps_CreateLights(model_t *model)
void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qbool areaweighting)
void Mod_ShadowMesh_CalcBBox(shadowmesh_t *mesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius)
void Mod_FreeSkinFiles(skinfile_t *skinfile)
void Mod_MakeSortedSurfaces(model_t *mod)
static float mod_generatelightmaps_offsets[3][MAX_LIGHTMAPSAMPLES][3]
static void Mod_Decompile_f(cmd_state_t *cmd)
static int mod_generatelightmaps_numoffsets[3]
static mempool_t * q3shaders_mem
void Mod_CreateCollisionMesh(model_t *mod)
static int Mod_LoadQ3Shaders_EnumerateWaveFunc(const char *s)
static int mod_generatelightmaps_numlights
static void Mod_GenerateLightmaps_DestroyLights(model_t *model)
void Mod_UnloadModel(model_t *mod)
cvar_t mod_generatelightmaps_vertexsamples
void Mod_ShadowMesh_AddMesh(shadowmesh_t *mesh, const float *vertex3f, int numtris, const int *element3i)
static void Mod_GenerateLightmaps_CreateTriangleInformation(model_t *model)
void Mod_FreeQ3Shaders(void)
qbool Mod_ValidateElements(int *element3i, unsigned short *element3s, int numtriangles, int firstvertex, int numvertices, const char *filename, int fileline)
shadowmesh_t * Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles)
model_t * Mod_LoadModel(model_t *mod, qbool crash, qbool checkdisk)
void Mod_LoadCustomMaterial(mempool_t *mempool, texture_t *texture, const char *name, int supercontents, int materialflags, skinframe_t *skinframe)
cvar_t r_shadow_lightattenuationlinearscale
static mempool_t * mod_mempool
void Mod_RenderInit(void)
static int Mod_FrameGroupify_ParseGroups(const char *buf, mod_framegroupify_parsegroups_t cb, void *pass)
void Mod_Mesh_Finalize(model_t *mod)
void Mod_LoadQ3Shaders(void)
cvar_t mod_generatelightmaps_lightmapsamples
void Mod_UnloadCustomMaterial(texture_t *texture, qbool purgeskins)
Removes all shaderpasses from material, and optionally deletes the textures in the skinframes.
static void Mod_GenerateLightmaps_DestroyLightmaps(model_t *model)
shadowmesh_t * Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles)
static void Mod_GenerateLightmaps_DestroyTriangleInformation(model_t *model)
cvar_t mod_generatelightmaps_unitspersample
static void Mod_Mesh_MakeSortedSurfaces(model_t *mod)
static void Mod_GenerateLightmaps_UpdateVertexColors(model_t *model)
static qbool Mod_GenerateLightmaps_SamplePoint_SVBSP(const svbsp_t *svbsp, const float *pos)
static void Mod_GenerateLightmaps_UpdateLightGrid(model_t *model)
static void Mod_Precache_f(cmd_state_t *cmd)
void Mod_VertexRangeFromElements(int numelements, const int *elements, int *firstvertexpointer, int *lastvertexpointer)
static void Mod_FrameGroupify(model_t *mod, const char *buf)
static void Mod_Decompile_SMD(model_t *model, const char *filename, int firstpose, int numposes, qbool writetriangles)
void Mod_SetDrawSkyAndWater(model_t *mod)
Sets the mod->DrawSky and mod->DrawAddWaterPlanes pointers conditionally based on whether surfaces in...
static void Mod_Decompile_OBJ(model_t *model, const char *filename, const char *mtlfilename, const char *originalfilename)
void(* mod_framegroupify_parsegroups_t)(unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)
cvar_t mod_generatelightmaps_vertexradius
cvar_t mod_obj_orientation
cvar_t mod_generatelightmaps_gridradius
#define SHADOWMESHVERTEXHASH
void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_SpriteInit(void)
void Mod_IDS2_Load(model_t *mod, void *buffer, void *bufferend)
#define MAX_QPATH
max length of a quake game pathname
void R_RegisterModule(const char *name, void(*start)(void), void(*shutdown)(void), void(*newmap)(void), void(*devicelost)(void), void(*devicerestored)(void))
#define Q3TEXTUREFLAG_WATERSHADER
#define Q3TEXTUREFLAG_NOPICMIP
#define TEXTURE_MAXFRAMES
#define Q3ALPHAGEN_MAXPARMS
#define Q3RGBGEN_MAXPARMS
@ Q3RGBGEN_LIGHTINGDIFFUSE
@ Q3RGBGEN_IDENTITYLIGHTING
@ Q3RGBGEN_ONEMINUSENTITY
@ Q3RGBGEN_ONEMINUSVERTEX
#define Q3TEXTUREFLAG_POLYGONOFFSET
@ Q3DEFORM_PROJECTIONSHADOW
#define Q3SHADER_MAXLAYERS
@ TRANSPARENTSORT_DISTANCE
#define Q3WAVEFUNC_USER_SHIFT
#define Q3TEXTUREFLAG_TRANSPARENTSORT
@ Q3TCMOD_ENTITYTRANSLATE
#define Q3TEXTUREFLAG_CAMERA
@ Q3ALPHAGEN_LIGHTINGSPECULAR
@ Q3ALPHAGEN_ONEMINUSENTITY
@ Q3ALPHAGEN_ONEMINUSVERTEX
#define Q3DEFORM_MAXPARMS
#define Q3TEXTUREFLAG_REFLECTION
#define Q3TEXTUREFLAG_TWOSIDED
#define Q3TEXTUREFLAG_REFRACTION
@ Q3WAVEFUNC_INVERSESAWTOOTH
int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color)
@ R_BUFFERDATA_INDEX32
index buffer - 16bit (because D3D cares)
@ R_BUFFERDATA_INDEX16
vertex buffer
rtexture_t * lightmaptexture
struct model_s * worldmodel
char model_name[MAX_MODELS][MAX_QPATH]
command interpreter state - the tokenizing and execution of commands, as well as pointers to which cv...
mod_alloclightmap_row_t * rows
int submodelsurfaces_start
struct mempool_s * mempool
void(* Load)(model_t *, void *, void *)
unsigned char * stainsamples
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
msurface_lightmapinfo_t * lightmapinfo
lightmaptexture rebuild information not used in q3bsp
int num_triangles
range of triangles and vertices in model->surfmesh
texture_t * texture
the texture to use on the surface
vec3_t mins
bounding box for onscreen checks
struct rtexture_s * deluxemaptexture
the lighting direction texture fragment to use on the rendering mesh
struct rtexture_s * lightmaptexture
the lightmap texture fragment to use on the rendering mesh
unsigned char diffusergb[3]
unsigned char ambientrgb[3]
unsigned char diffusepitch
q3shader_hash_entry_t hash[Q3SHADER_HASH_SIZE]
memexpandablearray_t char_ptrs
memexpandablearray_t hash_entries
struct q3shader_hash_entry_s * chain
q3shaderinfo_layer_alphagen_t alphagen
q3shaderinfo_layer_rgbgen_t rgbgen
float r_water_waterscroll[2]
q3shaderinfo_layer_t layers[Q3SHADER_MAXLAYERS]
dptransparentsortcategory_t transparentsort
q3shaderinfo_deform_t deforms[Q3MAXDEFORMS]
char skyboxname[Q3PATHLENGTH]
dpoffsetmapping_technique_t offsetmapping
char dpreflectcube[Q3PATHLENGTH]
shadowmeshvertexhash_t ** vertexhashtable
r_meshbuffer_t * element3s_indexbuffer
struct mempool_s * mempool
r_meshbuffer_t * vbo_vertexbuffer
r_meshbuffer_t * element3i_indexbuffer
unsigned short * element3s
shadowmeshvertexhash_t * vertexhashentries
struct shadowmeshvertexhash_s * next
char replacement[MAX_QPATH]
struct skinfileitem_s * next
r_meshbuffer_t * data_svector3f_vertexbuffer
int data_normal3f_bufferoffset
int data_skeletalweight4ub_bufferoffset
r_meshbuffer_t * data_lightmapcolor4f_vertexbuffer
r_meshbuffer_t * data_normal3f_vertexbuffer
int data_texcoordlightmap2f_bufferoffset
int data_skeletalindex4ub_bufferoffset
int data_svector3f_bufferoffset
float * data_lightmapcolor4f
unsigned char * data_skeletalweight4ub
unsigned char * data_skeletalindex4ub
unsigned short * data_element3s
r_meshbuffer_t * data_texcoordtexture2f_vertexbuffer
r_meshbuffer_t * data_skeletalindex4ub_vertexbuffer
r_meshbuffer_t * data_tvector3f_vertexbuffer
r_meshbuffer_t * data_element3i_indexbuffer
int * data_lightmapoffsets
int data_texcoordtexture2f_bufferoffset
int data_tvector3f_bufferoffset
r_meshbuffer_t * data_texcoordlightmap2f_vertexbuffer
r_meshbuffer_t * data_skeletalweight4ub_vertexbuffer
int data_vertex3f_bufferoffset
int data_lightmapcolor4f_bufferoffset
float * data_texcoordtexture2f
r_meshbuffer_t * data_element3s_indexbuffer
float * data_texcoordlightmap2f
r_meshbuffer_t * data_vertex3f_vertexbuffer
q3shaderinfo_layer_tcmod_t tcmods[Q3MAXTCMODS]
q3shaderinfo_layer_rgbgen_t rgbgen
q3shaderinfo_layer_alphagen_t alphagen
struct skinframe_s * skinframes[TEXTURE_MAXFRAMES]
q3shaderinfo_layer_tcgen_t tcgen
int mesh_defaultmaterialflags
unsigned int maxtexturesize_2d
void SVBSP_Init(svbsp_t *b, const float *origin, int maxnodes, svbsp_node_t *nodes)
int SVBSP_AddPolygon(svbsp_t *b, int numpoints, const float *points, int insertoccluder, void(*fragmentcallback)(void *fragmentcallback_pointer1, int fragmentcallback_number1, svbsp_t *b, int numpoints, const float *points), void *fragmentcallback_pointer1, int fragmentcallback_number1)
viddef_t vid
global video state
size_t Mem_ExpandableArray_IndexRange(const memexpandablearray_t *l)
void Mem_ExpandableArray_NewArray(memexpandablearray_t *l, mempool_t *mempool, size_t recordsize, int numrecordsperarray)
void Mem_ExpandableArray_FreeRecord(memexpandablearray_t *l, void *record)
void * Mem_ExpandableArray_AllocRecord(memexpandablearray_t *l)
void * Mem_ExpandableArray_RecordAtIndex(const memexpandablearray_t *l, size_t index)
#define Mem_FreePool(pool)
#define Mem_Alloc(pool, size)
static size_t Mem_Size(void *data)
Returns the current size of an allocation.
#define Mem_strdup(pool, s)
#define Mem_AllocPool(name, flags, parent)
#define Mem_Realloc(pool, data, size)