32cvar_t r_nosurftextures = {
CF_CLIENT,
"r_nosurftextures",
"0",
"pretends there was no texture lump found in the q1bsp/hlbsp loading (useful for debugging this rare case)"};
34cvar_t r_subdivisions_tolerance = {
CF_CLIENT,
"r_subdivisions_tolerance",
"4",
"maximum error tolerance on curve subdivision for rendering purposes (in other words, the curves will be given as many polygons as necessary to represent curves at this quality)"};
44cvar_t mod_q3bsp_lightmapmergepower = {
CF_CLIENT |
CF_ARCHIVE,
"mod_q3bsp_lightmapmergepower",
"4",
"merges the quake3 128x128 lightmap textures into larger lightmap group textures to speed up rendering, 1 = 256x256, 2 = 512x512, 3 = 1024x1024, 4 = 2048x2048, 5 = 4096x4096, ..."};
57cvar_t mod_q3shader_default_refractive_index = {
CF_CLIENT,
"mod_q3shader_default_refractive_index",
"1.33",
"angle of refraction specified as n to apply when a photon is refracted, example values are: 1.0003 = air, water = 1.333, crown glass = 1.517, flint glass = 1.655, diamond = 2.417"};
64cvar_t mod_q1bsp_traceoutofsolid = {
CF_SHARED,
"mod_q1bsp_traceoutofsolid",
"1",
"enables tracebox to move an entity that's stuck in solid brushwork out to empty space, 1 matches FTEQW and QSS and is required by many community maps (items/monsters will be missing otherwise), 0 matches old versions of DP and the original Quake engine (if your map or QC needs 0 it's buggy)"};
65cvar_t mod_q1bsp_zero_hullsize_cutoff = {
CF_CLIENT |
CF_SERVER,
"mod_q1bsp_zero_hullsize_cutoff",
"3",
"bboxes with an X dimension smaller than this will use the smallest cliphull (0x0x0) instead of being rounded up to the player cliphull (32x32x56) in Q1BSP, or crouching player (32x32x36) in HLBSP"};
67cvar_t mod_bsp_portalize = {
CF_CLIENT,
"mod_bsp_portalize",
"0",
"enables portal generation from BSP tree (takes a minute or more and GBs of memory when loading a complex map), used by r_drawportals, r_useportalculling, r_shadow_realtime_dlight_portalculling, r_shadow_realtime_world_compileportalculling"};
160 node =
model->brush.data_nodes +
model->brushq1.hulls[0].firstclipnode;
183 memset(out, 0, outsize);
189 int nodestackindex = 0;
190 mnode_t *node, *nodestack[1024];
191 if (!
model->brush.num_pvsclusters)
193 node =
model->brush.data_nodes +
model->brushq1.hulls[0].firstclipnode;
211 if (nodestackindex < 1024)
212 nodestack[nodestackindex++] = node->
children[0];
220 if (numclusters < maxclusters)
221 clusterlist[numclusters] = ((
mleaf_t *)node)->clusterindex;
229 if (nodestackindex < 1024)
230 nodestack[nodestackindex++] = node->
children[0];
237 if (numclusters < maxclusters)
238 clusterlist[numclusters] = ((
mleaf_t *)node)->clusterindex;
244 if (nodestackindex == 0)
246 node = nodestack[--nodestackindex];
254 int nodestackindex = 0;
255 mnode_t *node, *nodestack[1024];
256 if (!
model->brush.num_pvsclusters)
258 node =
model->brush.data_nodes +
model->brushq1.hulls[0].firstclipnode;
276 if (nodestackindex < 1024)
277 nodestack[nodestackindex++] = node->
children[0];
285 int clusterindex = ((
mleaf_t *)node)->clusterindex;
297 if (nodestackindex < 1024)
298 nodestack[nodestackindex++] = node->
children[0];
305 int clusterindex = ((
mleaf_t *)node)->clusterindex;
315 if (nodestackindex == 0)
317 node = nodestack[--nodestackindex];
325 int nodestackindex = 0;
326 mnode_t *node, *nodestack[1024];
327 if (!
model->brush.num_leafs)
329 node =
model->brush.data_nodes +
model->brushq1.hulls[0].firstclipnode;
347 if (nodestackindex < 1024)
348 nodestack[nodestackindex++] = node->
children[0];
356 int clusterindex = ((
mleaf_t *)node) -
model->brush.data_leafs;
368 if (nodestackindex < 1024)
369 nodestack[nodestackindex++] = node->
children[0];
376 int clusterindex = ((
mleaf_t *)node) -
model->brush.data_leafs;
386 if (nodestackindex == 0)
388 node = nodestack[--nodestackindex];
396 int nodestackindex = 0;
397 mnode_t *node, *nodestack[1024];
398 if (!
model->brush.num_leafs)
400 node =
model->brush.data_nodes +
model->brushq1.hulls[0].firstclipnode;
418 if (nodestackindex < 1024)
419 nodestack[nodestackindex++] = node->
children[0];
427 if (visibleleafs[(
mleaf_t *)node -
model->brush.data_leafs])
438 if (nodestackindex < 1024)
439 nodestack[nodestackindex++] = node->
children[0];
446 if (visibleleafs[(
mleaf_t *)node -
model->brush.data_leafs])
455 if (nodestackindex == 0)
457 node = nodestack[--nodestackindex];
463typedef struct findnonsolidlocationinfo_s
477 float dist,
f, vert[3][3], edge[3][3], facenormal[3], edgenormal[3][3], point[3];
486 if (facenormal[0] || facenormal[1] || facenormal[2])
527 for (i = 0;i < 3;i++)
564 int surfacenum, k, *mark;
566 for (surfacenum = 0, mark = leaf->
firstleafsurface;surfacenum < leaf->numleafsurfaces;surfacenum++, mark++)
593 if (((
mleaf_t *)node)->numleafsurfaces)
626 while (info.
bestdist < radius && ++i < 10);
632 switch(nativecontents)
665typedef struct RecursiveHullCheckTraceInfo_s
681#define DIST_EPSILON (0.03125)
683#define HULLCHECKSTATE_EMPTY 0
684#define HULLCHECKSTATE_SOLID 1
685#define HULLCHECKSTATE_DONE 2
726 if (p1side == p2side)
728#if COLLISIONPARANOID >= 3
741#if COLLISIONPARANOID >= 3
754 midf = t1 / (t1 - t2);
755 midf =
bound(p1f, midf, p2f);
793#if COLLISIONPARANOID >= 3
830#if COLLISIONPARANOID >= 3
838#if COLLISIONPARANOID >= 3
855 plane = planes + nodes[num].
planenum;
881 memset(&rhc, 0,
sizeof(rhc));
882 memset(trace, 0,
sizeof(
trace_t));
900 Mod_Q1BSP_TracePoint(
model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
911 memset(&rhc, 0,
sizeof(rhc));
912 memset(trace, 0,
sizeof(
trace_t));
923#if COLLISIONPARANOID >= 2
931 memset(&testtrace, 0,
sizeof(
trace_t));
932 rhc.
trace = &testtrace;
955static void Mod_Q1BSP_TraceBox(
struct model_s *
model,
const frameblend_t *frameblend,
const skeleton_t *skeleton,
trace_t *trace,
const vec3_t start,
const vec3_t boxmins,
const vec3_t boxmaxs,
const vec3_t end,
int hitsupercontentsmask,
int skipsupercontentsmask,
int skipmaterialflagsmask)
964 Mod_Q1BSP_TracePoint(
model, frameblend, skeleton, trace, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
966 Mod_Q1BSP_TraceLine(
model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
970 memset(&rhc, 0,
sizeof(rhc));
971 memset(trace, 0,
sizeof(
trace_t));
981 else if (
model->brush.ishlbsp)
985 if (boxsize[0] < 32.1)
999 if (boxsize[0] < 32.1)
1007#if COLLISIONPARANOID >= 2
1008 Con_Printf(
"t(%f %f %f,%f %f %f,%li %f %f %f)", rhc.
start[0], rhc.
start[1], rhc.
start[2], rhc.
end[0], rhc.
end[1], rhc.
end[2], rhc.
hull -
model->brushq1.hulls, rhc.
hull->
clip_mins[0], rhc.
hull->
clip_mins[1], rhc.
hull->
clip_mins[2]);
1015 memset(&testtrace, 0,
sizeof(
trace_t));
1016 rhc.
trace = &testtrace;
1041 int num =
model->brushq1.hulls[0].firstclipnode;
1047 plane = planes + nodes[num].
planenum;
1053void Collision_ClipTrace_Box(
trace_t *trace,
const vec3_t cmins,
const vec3_t cmaxs,
const vec3_t start,
const vec3_t mins,
const vec3_t maxs,
const vec3_t end,
int hitsupercontentsmask,
int skipsupercontentsmask,
int skipmaterialflagsmask,
int boxsupercontents,
int boxq3surfaceflags,
const texture_t *boxtexture)
1064 cbox.
planes = cbox_planes;
1074 cbox_planes[0].
normal[0] = 1;cbox_planes[0].
normal[1] = 0;cbox_planes[0].
normal[2] = 0;cbox_planes[0].
dist = cmaxs[0] -
mins[0];
1075 cbox_planes[1].
normal[0] = -1;cbox_planes[1].
normal[1] = 0;cbox_planes[1].
normal[2] = 0;cbox_planes[1].
dist =
maxs[0] - cmins[0];
1076 cbox_planes[2].
normal[0] = 0;cbox_planes[2].
normal[1] = 1;cbox_planes[2].
normal[2] = 0;cbox_planes[2].
dist = cmaxs[1] -
mins[1];
1077 cbox_planes[3].
normal[0] = 0;cbox_planes[3].
normal[1] = -1;cbox_planes[3].
normal[2] = 0;cbox_planes[3].
dist =
maxs[1] - cmins[1];
1078 cbox_planes[4].
normal[0] = 0;cbox_planes[4].
normal[1] = 0;cbox_planes[4].
normal[2] = 1;cbox_planes[4].
dist = cmaxs[2] -
mins[2];
1079 cbox_planes[5].
normal[0] = 0;cbox_planes[5].
normal[1] = 0;cbox_planes[5].
normal[2] = -1;cbox_planes[5].
dist =
maxs[2] - cmins[2];
1086 memset(trace, 0,
sizeof(
trace_t));
1098 memset(&rhc, 0,
sizeof(rhc));
1099 memset(trace, 0,
sizeof(
trace_t));
1103 box_planes[0].
dist = cmaxs[0] -
mins[0];
1104 box_planes[1].
dist = cmins[0] -
maxs[0];
1105 box_planes[2].
dist = cmaxs[1] -
mins[1];
1106 box_planes[3].
dist = cmins[1] -
maxs[1];
1107 box_planes[4].
dist = cmaxs[2] -
mins[2];
1108 box_planes[5].
dist = cmins[2] -
maxs[2];
1109#if COLLISIONPARANOID >= 3
1110 Con_Printf(
"box_planes %f:%f %f:%f %f:%f\ncbox %f %f %f:%f %f %f\nbox %f %f %f:%f %f %f\n", box_planes[0].dist, box_planes[1].dist, box_planes[2].dist, box_planes[3].dist, box_planes[4].dist, box_planes[5].dist, cmins[0], cmins[1], cmins[2], cmaxs[0], cmaxs[1], cmaxs[2],
mins[0],
mins[1],
mins[2],
maxs[0],
maxs[1],
maxs[2]);
1121 box_hull.
planes = box_planes;
1125 for (i = 0;i < 6;i++)
1133 box_clipnodes[i].
children[side^1] = i + 1;
1137 box_planes[i].
type = i>>1;
1138 box_planes[i].
normal[i>>1] = 1;
1144 rhc.
hull = &box_hull;
1163 memset(trace, 0,
sizeof(
trace_t));
1171 if ((hitsupercontentsmask & boxsupercontents) && !(skipsupercontentsmask & boxsupercontents))
1190 float mid, distz = endz - startz;
1204 if ((endz < node->plane->dist) == side)
1217 if ((back < node->plane->dist) == side)
1223 mid = startz + distz * (front - node->
plane->
dist) / (front - back);
1235 int dsi, dti, lmwidth, lmheight;
1238 unsigned char *lightmap;
1239 int maps, line3, size3;
1242 float scale,
w, w00, w01, w10, w11;
1268 if (dsi >= 0 && dsi < lmwidth && dti >= 0 && dti < lmheight)
1277 if (dsi > lmwidth-2)
1279 if (dti > lmheight-2)
1291 w00 = (1 - dsfrac) * (1 - dtfrac) * (1.0f / 128.0f);
1292 w01 = ( dsfrac) * (1 - dtfrac) * (1.0f / 128.0f);
1293 w10 = (1 - dsfrac) * ( dtfrac) * (1.0f / 128.0f);
1294 w11 = ( dsfrac) * ( dtfrac) * (1.0f / 128.0f);
1297 line3 = lmwidth * 3;
1298 size3 = lmwidth * lmheight * 3;
1308 w = w01 *
scale;
VectorMA(ambientcolor,
w, lightmap + 3 , ambientcolor);
1309 w = w10 *
scale;
VectorMA(ambientcolor,
w, lightmap + line3 , ambientcolor);
1310 w = w11 *
scale;
VectorMA(ambientcolor,
w, lightmap + line3 + 3, ambientcolor);
1322 distz = endz - startz;
1335 if (!
model->brushq1.lightdata)
1355 float edgenormal[3];
1385 for (j = 0, k = surface->
num_vertices - 1;j < surface->num_vertices;k = j, j++)
1395 if (j < surface->num_vertices)
1421 double midf, mid[3];
1426 plane = node->
plane;
1427 if (plane->
type < 3)
1429 t1 = p1[plane->
type] - plane->
dist;
1430 t2 = p2[plane->
type] - plane->
dist;
1458 if (plane->
type < 3)
1469 midf = t1 / (t1 - t2);
1513 memset(&rhc, 0,
sizeof(rhc));
1514 memset(trace, 0,
sizeof(
trace_t));
1529static void Mod_BSP_DecompressVis(
const unsigned char *in,
const unsigned char *inend,
unsigned char *out,
unsigned char *outend)
1532 unsigned char *outstart = out;
1533 while (out < outend)
1537 Con_Printf(
"Mod_BSP_DecompressVis: input underrun on model \"%s\" (decompressed %i of %i output bytes)\n",
loadmodel->name, (
int)(out - outstart), (
int)(outend - outstart));
1547 Con_Printf(
"Mod_BSP_DecompressVis: input underrun (during zero-run) on model \"%s\" (decompressed %i of %i output bytes)\n",
loadmodel->name, (
int)(out - outstart), (
int)(outend - outstart));
1550 for (c = *in++;c > 0;c--)
1554 Con_Printf(
"Mod_BSP_DecompressVis: output overrun on model \"%s\" (decompressed %i of %i output bytes)\n",
loadmodel->name, (
int)(out - outstart), (
int)(outend - outstart));
1582 if (bytesperpixel == 4)
1584 for (
y = 0;
y < h;
y++)
1586 for (
x = 0;
x <
w;
x++)
1605 for (
y = 0;
y < h;
y++)
1607 for (
x = 0;
x <
w;
x++)
1615 bgra.b[2] =
r/(
w*h);
1616 bgra.b[1] =
g/(
w*h);
1617 bgra.b[0] =
b/(
w*h);
1619 for (
y = 0;
y < h;
y++)
1621 for (
x = 0;
x <
w;
x++)
1634 (
unsigned char *) solidpixels,
1636 CRC_Block((
unsigned char *) solidpixels,
w*h*4),
1641 (
unsigned char *) alphapixels,
1643 CRC_Block((
unsigned char *) alphapixels,
w*h*4),
1651 int i, j, k, num,
max, altmax, mtwidth, mtheight, doffset, incomplete, nummiptex = 0, firstskynoshadowtexture = 0;
1653 texture_t *tx, *tx2, *anims[10], *altanims[10], *currentskynoshadowtexture;
1655 unsigned char *
data, *mtdata;
1658 unsigned char zeroopaque[4], zerotrans[4];
1676 loadmodel->num_textures = nummiptex + 2;
1679 for (i = 0; i < nummiptex; i++)
1695 for (j = 0; j < 16; j++)
1702 for (j = 0;
name[j];j++)
1703 if (
name[j] >=
'A' &&
name[j] <=
'Z')
1704 name[j] +=
'a' -
'A';
1706 if (!strncmp(
name,
"sky", 3))
1713 firstskynoshadowtexture =
loadmodel->num_textures;
1719 firstskynoshadowtexture =
loadmodel->num_textures;
1726 currentskynoshadowtexture =
loadmodel->data_textures + firstskynoshadowtexture;
1730 for (i = 0, tx =
loadmodel->data_textures;i < loadmodel->num_textures;i++, tx++)
1779 if (!strncasecmp(s,
"maps/", 5))
1784 for (i = 0;i < nummiptex;i++)
1800 for (j = 0;j < 16;j++)
1820 if (j < 40 || j + mtwidth * mtheight > miptexsb.
cursize)
1825 mtdata = miptexsb.
data + j;
1828 if ((mtwidth & 15) || (mtheight & 15))
1832 for (j = 0;
name[j];j++)
1833 if (
name[j] >=
'A' &&
name[j] <=
'Z')
1834 name[j] +=
'a' -
'A';
1838 backuptex =
loadmodel->data_textures[i];
1839 if (
name[0] && strncmp(
name,
"sky", 3) && (
Mod_LoadTextureFromQ3Shader(
loadmodel->mempool,
loadmodel->name,
loadmodel->data_textures + i,
va(vabuf,
sizeof(vabuf),
"%s/%s",
mapname,
name),
false,
false,
TEXF_ALPHA |
TEXF_MIPMAP |
TEXF_ISWORLD |
TEXF_PICMIP |
TEXF_COMPRESS,
MATERIALFLAG_WALL) ||
1840 Mod_LoadTextureFromQ3Shader(
loadmodel->mempool,
loadmodel->name,
loadmodel->data_textures + i,
va(vabuf,
sizeof(vabuf),
"%s" ,
name),
false,
false,
TEXF_ALPHA |
TEXF_MIPMAP |
TEXF_ISWORLD |
TEXF_PICMIP |
TEXF_COMPRESS,
MATERIALFLAG_WALL)))
1843 tx->
width = mtwidth;
1848 loadmodel->data_textures[i] = backuptex;
1851 tx->
width = mtwidth;
1859 if (tx->
name[0] ==
'*')
1861 if (!strncmp(tx->
name,
"*lava", 5))
1866 else if (!strncmp(tx->
name,
"*slime", 6))
1877 else if (!strncmp(tx->
name,
"sky", 3))
1896 || !strncmp(tx->
name,
"sky", 3))
1902 unsigned char*
pixels, * freepixels;
1917 else if (!strncmp(tx->
name,
"sky", 3) && mtwidth == mtheight * 2)
1927 else if (mtdata !=
NULL)
1934 if (!strncmp(tx->
name,
"*glassmirror", 12))
1936 else if (!strncmp(tx->
name,
"mirror", 6))
1945 if (tx->
name[0] ==
'*')
1948 if (!strncmp(tx->
name,
"*glassmirror", 12))
1950 else if (!strncmp(tx->
name,
"*lava",5)
1951 || !strncmp(tx->
name,
"*teleport",9)
1952 || !strncmp(tx->
name,
"*rift",5))
1959 else if (tx->
name[0] ==
'{')
1963 else if (!strncmp(tx->
name,
"mirror", 6))
1968 else if (!strncmp(tx->
name,
"sky", 3))
1970 else if (!strcmp(tx->
name,
"caulk"))
1979 *currentskynoshadowtexture = *tx;
1982 currentskynoshadowtexture++;
1987 for (i = 0;i < nummiptex;i++)
1990 if (!tx || tx->
name[0] !=
'+' || tx->
name[1] == 0 || tx->
name[2] == 0)
1993 if ((num <
'0' || num >
'9') && (num <
'a' || num >
'j'))
2002 memset(anims, 0,
sizeof(anims));
2003 memset(altanims, 0,
sizeof(altanims));
2005 for (j = i;j < nummiptex;j++)
2008 if (!tx2 || tx2->
name[0] !=
'+' || strcmp(tx2->
name+2, tx->
name+2))
2012 if (num >=
'0' && num <=
'9')
2013 anims[num -
'0'] = tx2;
2014 else if (num >=
'a' && num <=
'j')
2015 altanims[num -
'a'] = tx2;
2020 for (j = 0;j < 10;j++)
2030 for (j = 0;j <
max;j++)
2038 for (j = 0;j < altmax;j++)
2050 if (
max + altmax <= 1)
2052 Con_Printf(
"Texture %s is animated (leading +) but has only one frame\n", tx->
name);
2060 for (k = 0;k < 10;k++)
2061 altanims[k] = anims[k];
2071 for (k = 0;k < 10;k++)
2072 anims[k] = altanims[k];
2077 for (j = 0;j <
max;j++)
2083 for (k = 0;k < 10;k++)
2091 if (anims[0] != altanims[0])
2094 for (j = 0;j < altmax;j++)
2101 for (k = 0;k < 10;k++)
2114 unsigned char *in, *out, *
data, d;
2121 for (i = 0;i < sb->
cursize;i++)
2129 dp_strlcpy (dlitfilename, litfilename,
sizeof (dlitfilename));
2130 dp_strlcat (litfilename,
".lit",
sizeof (litfilename));
2131 dp_strlcat (dlitfilename,
".dlit",
sizeof (dlitfilename));
2143 memcpy(
loadmodel->brushq1.lightdata,
data + 8, filesize - 8);
2156 memcpy(
loadmodel->brushq1.nmaplightdata,
data + 8, filesize - 8);
2157 loadmodel->brushq3.deluxemapping_modelspace =
false;
2158 loadmodel->brushq3.deluxemapping =
true;
2167 Con_Printf(
"Unknown .lit file version (%d)\n", i);
2169 else if (filesize == 8)
2170 Con_Print(
"Empty .lit file, ignoring\n");
2172 Con_Printf(
"Corrupt .lit file (file size %i bytes, should be %i bytes), ignoring\n", (
int) filesize, (
int) (8 + sb->
cursize * 3));
2185 for (i = 0;i < sb->
cursize;i++)
2197 loadmodel->brushq1.num_compressedpvs = 0;
2209 char key[128],
value[4096];
2227 while (key[
strlen(key)-1] ==
' ')
2232 if (!strcmp(
"wad", key))
2237 for (i = 0;i < (
int)
sizeof(
value);i++)
2280 int structsize = 12;
2290 for ( i=0 ; i<
count ; i++, out++)
2302 int structsize = hullinfo ? (48+4*hullinfo->
filehulls) : 48;
2313 for (i = 0; i <
count; i++, out++)
2327 for (j = 0; j < hullinfo->
filehulls; j++)
2343 int structsize =
loadmodel->brush.isbsp2 ? 8 : 4;
2353 for ( i=0 ; i<
count ; i++, out++)
2365 if ((
int)out->
v[0] >=
loadmodel->brushq1.numvertexes || (
int)out->
v[1] >=
loadmodel->brushq1.numvertexes)
2367 Con_Printf(
"Mod_Q1BSP_LoadEdges: %s has invalid vertex indices in edge %i (vertices %i %i >= numvertices %i)\n",
loadmodel->name, i, out->
v[0], out->
v[1],
loadmodel->brushq1.numvertexes);
2369 Host_Error(
"Mod_Q1BSP_LoadEdges: %s has edges but no vertexes, cannot fix\n",
loadmodel->name);
2380 int i, j, k,
count, miptex;
2381 int structsize = 40;
2391 for (i = 0;i <
count;i++, out++)
2393 for (k = 0;k < 2;k++)
2394 for (j = 0;j < 4;j++)
2414 if ((
unsigned int) miptex >= (
unsigned int)
loadmodel->num_textures)
2431 for (i = 0;i < numverts;i++)
2433 for (j = 0;j < 3;j++,
v++)
2443#define MAX_SUBDIVPOLYTRIANGLES 4096
2444#define MAX_SUBDIVPOLYVERTS(MAX_SUBDIVPOLYTRIANGLES * 3)
2446static int subdivpolyverts, subdivpolytriangles;
2447static int subdivpolyindex[MAX_SUBDIVPOLYTRIANGLES][3];
2448static float subdivpolyvert[MAX_SUBDIVPOLYVERTS][3];
2450static int subdivpolylookupvert(
vec3_t v)
2453 for (i = 0;i < subdivpolyverts;i++)
2454 if (subdivpolyvert[i][0] ==
v[0]
2455 && subdivpolyvert[i][1] ==
v[1]
2456 && subdivpolyvert[i][2] ==
v[2])
2458 if (subdivpolyverts >= MAX_SUBDIVPOLYVERTS)
2459 Host_Error(
"SubDividePolygon: ran out of vertices in buffer, please increase your r_subdivide_size");
2461 return subdivpolyverts++;
2464static void SubdividePolygon(
int numverts,
float *verts)
2466 int i, i1, i2, i3,
f,
b, c, p;
2468 float m, *pv, *cv, dist[256], frac;
2471 Host_Error(
"SubdividePolygon: ran out of verts in buffer");
2473 BoundPoly(numverts, verts,
mins,
maxs);
2475 for (i = 0;i < 3;i++)
2478 m = r_subdivide_size.value *
floor(m/r_subdivide_size.value + 0.5);
2479 if (
maxs[i] - m < 8)
2481 if (m -
mins[i] < 8)
2485 for (cv = verts, c = 0;c < numverts;c++, cv += 3)
2486 dist[c] = cv[i] - m;
2489 for (p = numverts - 1, c = 0, pv = verts + p * 3, cv = verts;c < numverts;p = c, c++, pv = cv, cv += 3)
2501 if (dist[p] == 0 || dist[c] == 0)
2503 if ((dist[p] > 0) != (dist[c] > 0) )
2506 frac = dist[p] / (dist[p] - dist[c]);
2507 front[
f][0] = back[
b][0] = pv[0] + frac * (cv[0] - pv[0]);
2508 front[
f][1] = back[
b][1] = pv[1] + frac * (cv[1] - pv[1]);
2509 front[
f][2] = back[
b][2] = pv[2] + frac * (cv[2] - pv[2]);
2515 SubdividePolygon(
f, front[0]);
2516 SubdividePolygon(
b, back[0]);
2520 i1 = subdivpolylookupvert(verts);
2521 i2 = subdivpolylookupvert(verts + 3);
2522 for (i = 2;i < numverts;i++)
2524 if (subdivpolytriangles >= MAX_SUBDIVPOLYTRIANGLES)
2526 Con_Print(
"SubdividePolygon: ran out of triangles in buffer, please increase your r_subdivide_size\n");
2530 i3 = subdivpolylookupvert(verts + i * 3);
2531 subdivpolyindex[subdivpolytriangles][0] = i1;
2532 subdivpolyindex[subdivpolytriangles][1] = i2;
2533 subdivpolyindex[subdivpolytriangles][2] = i3;
2535 subdivpolytriangles++;
2542static void Mod_Q1BSP_GenerateWarpMesh(
msurface_t *surface)
2548 subdivpolytriangles = 0;
2549 subdivpolyverts = 0;
2551 if (subdivpolytriangles < 1)
2552 Host_Error(
"Mod_Q1BSP_GenerateWarpMesh: no triangles?");
2554 surface->mesh = mesh =
Mem_Alloc(
loadmodel->mempool,
sizeof(
surfmesh_t) + subdivpolytriangles *
sizeof(
int[3]) + subdivpolyverts *
sizeof(surfvertex_t));
2557 mesh->vertex = (surfvertex_t *)(mesh + 1);
2558 mesh->index = (
int *)(mesh->vertex + mesh->
num_vertices);
2559 memset(mesh->vertex, 0, mesh->
num_vertices *
sizeof(surfvertex_t));
2562 for (j = 0;j < 3;j++)
2563 mesh->index[i*3+j] = subdivpolyindex[i][j];
2565 for (i = 0,
v = mesh->vertex;i < subdivpolyverts;i++,
v++)
2578 int i, j,
count, surfacenum, planenum, smax, tmax, ssize, tsize, firstedge, numedges, totalverts, totaltris, lightmapnumber, lightmapsize, totallightmapsamples, lightmapoffset, texinfoindex;
2579 float texmins[2], texmaxs[2], val;
2580 rtexture_t *lightmaptexture, *deluxemaptexture;
2582 int structsize =
loadmodel->brush.isbsp2 ? 28 : 20;
2597 for (surfacenum = 0;surfacenum <
count;surfacenum++)
2603 totalverts += numedges;
2604 totaltris += numedges - 2;
2609 lightmaptexture =
NULL;
2613 totallightmapsamples = 0;
2617 for (surfacenum = 0, surface =
loadmodel->data_surfaces;surfacenum <
count;surfacenum++, surface++)
2631 if ((
unsigned int) firstedge > (
unsigned int)
loadmodel->brushq1.numsurfedges || (
unsigned int) numedges > (
unsigned int)
loadmodel->brushq1.numsurfedges || (
unsigned int) firstedge + (
unsigned int) numedges > (
unsigned int)
loadmodel->brushq1.numsurfedges)
2632 Host_Error(
"Mod_Q1BSP_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)", firstedge, numedges,
loadmodel->brushq1.numsurfedges);
2633 if ((
unsigned int) texinfoindex >= (
unsigned int)
loadmodel->brushq1.numtexinfo)
2634 Host_Error(
"Mod_Q1BSP_LoadFaces: invalid texinfo index %i(model has %i texinfos)", texinfoindex,
loadmodel->brushq1.numtexinfo);
2635 if ((
unsigned int) planenum >= (
unsigned int)
loadmodel->brush.num_planes)
2636 Host_Error(
"Mod_Q1BSP_LoadFaces: invalid plane index %i (model has %i planes)", planenum,
loadmodel->brush.num_planes);
2643 lightmapoffset = -1;
2654 totalverts += numedges;
2655 totaltris += numedges - 2;
2660 int lindex =
loadmodel->brushq1.surfedges[firstedge + i];
2693 for (j = 0;j < 2;j++)
2696 texmins[j] =
min(texmins[j], val);
2697 texmaxs[j] =
max(texmaxs[j], val);
2700 for (i = 0;i < 2;i++)
2714 if (lightmapoffset == -1)
2739 if (ssize > 256 || tsize > 256)
2742 if (lightmapsize < ssize)
2743 lightmapsize = ssize;
2744 if (lightmapsize < tsize)
2745 lightmapsize = tsize;
2747 totallightmapsamples += ssize*tsize;
2754 loadmodel->brushq1.lightmapupdateflags[surfacenum] =
true;
2766 for (lightmapsize = 64; (lightmapsize < i) && (lightmapsize <
bound(128,
gl_max_lightmapsize.integer, (
int)
vid.maxtexturesize_2d)) && (totallightmapsamples > lightmapsize*lightmapsize); lightmapsize*=2)
2772 int stainmapsize = 0;
2776 for (surfacenum = 0, surface =
loadmodel->data_surfaces;surfacenum <
count;surfacenum++, surface++)
2778 int iu, iv, lightmapx = 0, lightmapy = 0;
2779 float u,
v, ubase, vbase, uscale, vscale;
2781 if (!
loadmodel->brushq1.lightmapupdateflags[surfacenum])
2788 stainmapsize += ssize * tsize * 3;
2796 loadmodel->brushq3.num_mergedlightmaps = lightmapnumber + 1;
2799 loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"lightmap%i", lightmapnumber), lightmapsize, lightmapsize,
NULL,
TEXTYPE_BGRA,
TEXF_FORCELINEAR |
TEXF_ALLOWUPDATES, -1,
NULL);
2801 loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"deluxemap%i", lightmapnumber), lightmapsize, lightmapsize,
NULL,
TEXTYPE_BGRA,
TEXF_FORCELINEAR |
TEXF_ALLOWUPDATES, -1,
NULL);
2811 uscale = 1.0f / (
float)lightmapsize;
2812 vscale = 1.0f / (
float)lightmapsize;
2813 ubase = lightmapx * uscale;
2814 vbase = lightmapy * vscale;
2832 unsigned char *stainsamples =
NULL;
2834 memset(stainsamples, 255, stainmapsize);
2836 for (surfacenum = 0, surface =
loadmodel->data_surfaces;surfacenum <
count;surfacenum++, surface++)
2838 if (!
loadmodel->brushq1.lightmapupdateflags[surfacenum])
2843 stainsamples += ssize * tsize * 3;
2850 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
2893 int i, j,
count, p, child[2];
2895 int structsize =
loadmodel->brush.isbsp2rmqe ? 32 : (
loadmodel->brush.isbsp2 ? 44 : 24);
2907 for ( i=0 ; i<
count ; i++, out++)
2942 if (child[0] >=
count)
2944 if (child[1] >=
count)
2958 for (j=0 ; j<2 ; j++)
2967 if (p < loadmodel->brush.num_nodes)
2971 Con_Printf(
"Mod_Q1BSP_LoadNodes: invalid node index %i (file has only %i nodes)\n", p,
loadmodel->brush.num_nodes);
2980 if (p < loadmodel->brush.num_leafs)
2984 Con_Printf(
"Mod_Q1BSP_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p,
loadmodel->brush.num_leafs);
2998 int i, j,
count, p, firstmarksurface, nummarksurfaces;
2999 int structsize =
loadmodel->brush.isbsp2rmqe ? 32 : (
loadmodel->brush.isbsp2 ? 44 : 28);
3015 for ( i=0 ; i<
count ; i++, out++)
3027 if (p >=
loadmodel->brushq1.num_compressedpvs)
3028 Con_Print(
"Mod_Q1BSP_LoadLeafs: invalid visofs\n");
3070 if (firstmarksurface >= 0 && firstmarksurface + nummarksurfaces <= loadmodel->brush.num_leafsurfaces)
3077 Con_Printf(
"Mod_Q1BSP_LoadLeafs: invalid leafsurface range %i:%i outside range %i:%i\n", firstmarksurface, firstmarksurface+nummarksurfaces, 0,
loadmodel->brush.num_leafsurfaces);
3082 for (j = 0;j < 4;j++)
3091 const unsigned char *pvs;
3097 for (i = 0, leaf =
loadmodel->brush.data_leafs;i < loadmodel->brush.num_leafs;i++, leaf++)
3102 for (j = 0;j <
loadmodel->brush.num_leafs;j++)
3115 int structsize =
loadmodel->brush.isbsp2 ? 12 : 8;
3141 for (i=0 ; i<
count ; i++, out++)
3186 for (i = 0;i <
loadmodel->brush.num_nodes;i++, out++, in++)
3197 int structsize =
loadmodel->brush.isbsp2 ? 4 : 2;
3206 for (i = 0;i <
loadmodel->brush.num_leafsurfaces;i++)
3209 if (j < 0 || j >=
loadmodel->num_surfaces)
3210 Host_Error(
"Mod_Q1BSP_LoadLeaffaces: bad surface number");
3211 loadmodel->brush.data_leafsurfaces[i] = j;
3216 for (i = 0;i <
loadmodel->brush.num_leafsurfaces;i++)
3220 Host_Error(
"Mod_Q1BSP_LoadLeaffaces: bad surface number");
3221 loadmodel->brush.data_leafsurfaces[i] = j;
3236 for (i = 0;i <
loadmodel->brushq1.numsurfedges;i++)
3245 int structsize = 20;
3252 for (i = 0;i <
loadmodel->brush.num_planes;i++, out++)
3270 for (surfaceindex =
mod->submodelsurfaces_start; surfaceindex < mod->submodelsurfaces_end;surfaceindex++)
3272 surface =
mod->data_surfaces + surfaceindex;
3288 int submodel, numbrushes;
3290 char *text, *maptext;
3293 strlcat (mapfilename,
".map",
sizeof (mapfilename));
3325 if (submodel >
loadmodel->brush.numsubmodels)
3327 Con_Printf(
"Mod_Q1BSP_LoadMapBrushes: .map has more submodels than .bsp!\n");
3345 for (pointnum = 0;pointnum < 3;pointnum++)
3348 for (componentnum = 0;componentnum < 3;componentnum++)
3351 point[pointnum][componentnum] = atof(
com_token);
3369 planedist =
DotProduct(point[0], planenormal);
3380#define MAX_PORTALPOINTS 64
3382typedef struct portal_s
3425 endleaf = leaf +
loadmodel->brush.num_leafs;
3428 for (;leaf < endleaf;leaf++)
3431 VectorSet(leaf->
maxs, -2000000000, -2000000000, -2000000000);
3436 for (portalindex = 0;portalindex < portalrange;portalindex++)
3450 loadmodel->brush.num_portals = numportals;
3452 loadmodel->brush.num_portalpoints = numpoints;
3454 for (i = 0;i <
loadmodel->brush.num_leafs;i++)
3458 point =
loadmodel->brush.data_portalpoints;
3459 for (portalindex = 0;portalindex < portalrange;portalindex++)
3501 for (j = portal->
numpoints - 1;j >= 0;j--)
3519 for (i = 0;i < 2;i++)
3548 Host_Error(
"AddPortalToNodes: NULL front node");
3550 Host_Error(
"AddPortalToNodes: NULL back node");
3552 Host_Error(
"AddPortalToNodes: already included");
3555 p->
nodes[0] = front;
3573 void **portalpointer;
3575 for (i = 0;i < 2;i++)
3577 node = portal->
nodes[i];
3579 portalpointer = (
void **) &node->
portals;
3584 Host_Error(
"RemovePortalFromNodes: portal not in leaf");
3588 if (portal->
nodes[0] == node)
3590 *portalpointer = portal->
next[0];
3593 else if (portal->
nodes[1] == node)
3595 *portalpointer = portal->
next[1];
3599 Host_Error(
"RemovePortalFromNodes: portal not bounding leaf");
3603 if (t->
nodes[0] == node)
3604 portalpointer = (
void **) &t->
next[0];
3605 else if (t->
nodes[1] == node)
3606 portalpointer = (
void **) &t->
next[1];
3608 Host_Error(
"RemovePortalFromNodes: portal not bounding leaf");
3613#define PORTAL_DIST_EPSILON (1.0 / 32.0)
3620 mnode_t *front, *back, *other_node;
3622 portal_t *portal, *nextportal, *nodeportal, *splitportal, *temp;
3623 int numfrontpoints, numbackpoints;
3624 double *frontpoints, *backpoints;
3641 plane = node->
plane;
3646 Host_Error(
"Mod_BSP_RecursiveNodePortals: corrupt node hierarchy");
3651 nodeportal->
plane = *plane;
3659 clipplane = portal->
plane;
3661 Host_Error(
"Mod_BSP_RecursiveNodePortals: portal has same node on both sides(1)");
3662 if (portal->
nodes[0] == node)
3664 else if (portal->
nodes[1] == node)
3672 Host_Error(
"Mod_BSP_RecursiveNodePortals: mislinked portal");
3676 for (i = 0;i < nodeportal->
numpoints*3;i++)
3677 frontpoints[i] = nodeportal->
points[i];
3678 PolygonD_Divide(nodeportal->
numpoints, frontpoints, clipplane.
normal[0], clipplane.
normal[1], clipplane.
normal[2], clipplane.
dist,
PORTAL_DIST_EPSILON,
MAX_PORTALPOINTS, nodeportal->
points, &nodeportal->
numpoints, 0,
NULL,
NULL,
NULL);
3685 Con_Print(
CON_WARN "Mod_BSP_RecursiveNodePortals: WARNING: new portal was clipped away\n");
3690 Con_Print(
CON_WARN "Mod_BSP_RecursiveNodePortals: WARNING: new portal has too many points\n");
3701 Host_Error(
"Mod_BSP_RecursiveNodePortals: portal has same node on both sides(2)");
3702 if (portal->
nodes[0] == node)
3704 else if (portal->
nodes[1] == node)
3708 Host_Error(
"Mod_BSP_RecursiveNodePortals: mislinked portal");
3711 nextportal = portal->
next[side];
3715 other_node = portal->
nodes[!side];
3719 PolygonD_Divide(portal->
numpoints, portal->
points, plane->
normal[0], plane->
normal[1], plane->
normal[2], plane->
dist,
PORTAL_DIST_EPSILON,
MAX_PORTALPOINTS, frontpoints, &numfrontpoints,
MAX_PORTALPOINTS, backpoints, &numbackpoints,
NULL);
3721 if (!numfrontpoints)
3740 temp = splitportal->
chain;
3741 *splitportal = *portal;
3742 splitportal->
chain = temp;
3743 for (i = 0;i < numbackpoints*3;i++)
3744 splitportal->
points[i] = backpoints[i];
3746 for (i = 0;i < numfrontpoints*3;i++)
3747 portal->
points[i] = frontpoints[i];
3788 node =
model->brush.data_nodes +
model->brushq1.hulls[0].firstclipnode;
3791 if (((
mleaf_t *)node)->clusterindex >= 0)
3792 return model->brush.data_pvsclusters + ((
mleaf_t *)node)->clusterindex *
model->brush.num_pvsclusterbytes;
3804 else if (d < -radius)
3814 if (((
mleaf_t *)node)->clusterindex >= 0)
3817 unsigned char *pvs =
model->brush.data_pvsclusters + ((
mleaf_t *)node)->clusterindex *
model->brush.num_pvsclusterbytes;
3818 for (i = 0;i < pvsbytes;i++)
3819 pvsbuffer[i] |= pvs[i];
3827 size_t bytes =
model->brush.num_pvsclusterbytes;
3829 if (!*pvsbuffer || bytes !=
Mem_Size(*pvsbuffer))
3839 memset(*pvsbuffer, 0xFF, bytes);
3843 memset(*pvsbuffer, 0, bytes);
3883 mod->brush.isbsp2 =
true;
3884 mod->brush.isbsp2rmqe =
true;
3885 mod->modeldatatypestring =
"Q1BSP2rmqe";
3891 mod->brush.isbsp2 =
true;
3892 mod->modeldatatypestring =
"Q1BSP2";
3898 mod->brush.ishlbsp =
true;
3899 mod->modeldatatypestring =
"HLBSP";
3908 float dist, modelyawradius, modelradius;
3911 int totalstylesurfaces, totalstyles, stylecounts[256], remapstyles[256];
3921 mod->brush.skymasking =
true;
3924 if(!
mod->modeldatatypestring)
3925 mod->modeldatatypestring =
"Q1BSP";
3930 if (
mod->brush.ishlbsp)
3959 mod->soundfromcenter =
true;
3990 mod->brush.qw_md4sum = 0;
3991 mod->brush.qw_md4sum2 = 0;
4023 Host_Error(
"Lump %i incorrectly loaded (readcount %i, size %i)\n", i, lumpsb[i].readcount, lumpsb[i].cursize);
4029 if (
mod->brushq1.data_compressedpvs)
4031 mod->brushq1.data_compressedpvs =
NULL;
4032 mod->brushq1.num_compressedpvs = 0;
4058 totalstylesurfaces = 0;
4060 for (i = 0;i <
mod->brush.numsubmodels;i++)
4062 memset(stylecounts, 0,
sizeof(stylecounts));
4063 for (k = 0;k <
mod->brushq1.submodels[i].numfaces;k++)
4065 surface =
mod->data_surfaces +
mod->brushq1.submodels[i].firstface + k;
4069 for (k = 0;k < 255;k++)
4073 totalstylesurfaces += stylecounts[k];
4079 datapointer =
Mem_AllocType(
mod->mempool,
int,
mod->num_surfaces *
sizeof(
int) + totalstylesurfaces *
sizeof(
int));
4080 mod->modelsurfaces_sorted = datapointer;datapointer +=
mod->num_surfaces;
4081 for (i = 0;i <
mod->brush.numsubmodels;i++)
4102 mod->brush.BoxTouchingPVS =
NULL;
4103 mod->brush.BoxTouchingLeafPVS =
NULL;
4104 mod->brush.BoxTouchingVisibleLeafs =
NULL;
4105 mod->brush.FindBoxClusters =
NULL;
4107 mod->brush.AmbientSoundLevelsForPoint =
NULL;
4110 mod->brush.submodel = i;
4115 bm = &
mod->brushq1.submodels[i];
4117 mod->brushq1.hulls[0].firstclipnode = bm->
headnode[0];
4120 mod->brushq1.hulls[j].firstclipnode = bm->
headnode[j];
4121 mod->brushq1.hulls[j].lastclipnode =
mod->brushq1.numclipnodes - 1;
4139 modelyawradius = dist*dist+modelyawradius*modelyawradius;
4141 modelradius = modelyawradius + modelradius * modelradius;
4142 modelyawradius =
sqrt(modelyawradius);
4143 modelradius =
sqrt(modelradius);
4144 mod->yawmins[0] =
mod->yawmins[1] = -modelyawradius;
4145 mod->yawmins[2] =
mod->normalmins[2];
4146 mod->yawmaxs[0] =
mod->yawmaxs[1] = modelyawradius;
4147 mod->yawmaxs[2] =
mod->normalmaxs[2];
4148 mod->rotatedmins[0] =
mod->rotatedmins[1] =
mod->rotatedmins[2] = -modelradius;
4149 mod->rotatedmaxs[0] =
mod->rotatedmaxs[1] =
mod->rotatedmaxs[2] = modelradius;
4150 mod->radius = modelradius;
4151 mod->radius2 = modelradius * modelradius;
4155 if (
mod->submodelsurfaces_start <
mod->submodelsurfaces_end)
4160 memset(stylecounts, 0,
sizeof(stylecounts));
4161 for (k =
mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
4163 stylecounts[
mod->data_surfaces[k].lightmapinfo->styles[j]]++;
4164 mod->brushq1.num_lightstyles = 0;
4165 for (k = 0;k < 255;k++)
4169 styleinfo[
mod->brushq1.num_lightstyles].
style = k;
4170 styleinfo[
mod->brushq1.num_lightstyles].
value = 0;
4172 styleinfo[
mod->brushq1.num_lightstyles].
surfacelist = datapointer;datapointer += stylecounts[k];
4173 remapstyles[k] =
mod->brushq1.num_lightstyles;
4174 mod->brushq1.num_lightstyles++;
4177 for (k =
mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
4179 surface =
mod->data_surfaces + k;
4189 mod->brushq1.data_lightstyleinfo = lsidatapointer;lsidatapointer +=
mod->brushq1.num_lightstyles;
4204 mod->collision_bih =
mod->render_bih;
4225 Con_DPrintf(
"Stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals, mesh: %i vertices, %i triangles, %i surfaces\n",
loadmodel->name,
loadmodel->num_surfaces,
loadmodel->brush.num_nodes,
loadmodel->brush.num_leafs,
mod->brush.num_pvsclusters,
loadmodel->brush.num_portals,
loadmodel->surfmesh.num_vertices,
loadmodel->surfmesh.num_triangles,
loadmodel->num_surfaces);
4230 int supercontents = 0;
4249 return supercontents;
4254 int nativecontents = 0;
4273 return nativecontents;
4279 loadmodel->brushq1.num_compressedpvs = 0;
4282 loadmodel->brush.num_pvsclusterbytes = 0;
4292 for (i = 0;i <
count;i++)
4306 int i, j,
count, p, child[2];
4308 int structsize = 28;
4320 for ( i=0 ; i<
count ; i++, out++)
4340 for (j=0 ; j<2 ; j++)
4345 if (p < loadmodel->brush.num_nodes)
4349 Con_Printf(
"Mod_Q2BSP_LoadNodes: invalid node index %i (file has only %i nodes)\n", p,
loadmodel->brush.num_nodes);
4358 if (p < loadmodel->brush.num_leafs)
4362 Con_Printf(
"Mod_Q2BSP_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p,
loadmodel->brush.num_leafs);
4377 int structsize = 76;
4378 int maxtextures = 1024;
4390 for (i = 0;i <
count;i++, out++)
4393 for (k = 0;k < 2;k++)
4394 for (j = 0;j < 4;j++)
4405 for (j = 0;j <
loadmodel->num_texturesperskin;j++)
4406 if (!strcmp(filename,
loadmodel->data_textures[j].name)
4411 if (j ==
loadmodel->num_texturesperskin)
4413 if (
loadmodel->num_texturesperskin < maxtextures)
4417 unsigned char *walfile =
NULL;
4521 Con_Printf(
"Mod_Q2BSP_LoadTexinfo: max textures reached (%i)\n", maxtextures);
4534 for (i = 0, out =
loadmodel->brushq1.texinfo;i <
count;i++, out++)
4588 int i, j,
count, firstmarksurface, nummarksurfaces, firstmarkbrush, nummarkbrushes;
4589 int structsize = 28;
4600 for ( i=0 ; i<
count ; i++, out++)
4617 for (j = 0;j < 4;j++)
4622 Con_Print(
"Mod_Q2BSP_LoadLeafs: invalid clusterindex\n");
4626 if (firstmarksurface >= 0 && firstmarksurface + nummarksurfaces <= loadmodel->brush.num_leafsurfaces)
4633 Con_Printf(
"Mod_Q2BSP_LoadLeafs: invalid leafsurface range %i:%i outside range %i:%i\n", firstmarksurface, firstmarksurface+nummarksurfaces, 0,
loadmodel->brush.num_leafsurfaces);
4638 if (firstmarkbrush >= 0 && firstmarkbrush + nummarkbrushes <= loadmodel->brush.num_leafbrushes)
4645 Con_Printf(
"Mod_Q2BSP_LoadLeafs: invalid leafbrush range %i:%i outside range %i:%i\n", firstmarkbrush, firstmarkbrush+nummarkbrushes, 0,
loadmodel->brush.num_leafbrushes);
4662 for (i = 0;i <
loadmodel->brush.num_leafbrushes;i++)
4666 Host_Error(
"Mod_Q1BSP_LoadLeafBrushes: bad brush number");
4667 loadmodel->brush.data_leafbrushes[i] = j;
4685 for (i = 0;i <
count;i++, out++)
4689 Host_Error(
"Mod_Q2BSP_LoadBrushSides: invalid planeindex %i (%i planes)",
n,
loadmodel->brush.num_planes);
4695 Host_Error(
"Mod_Q2BSP_LoadBrushSides: invalid texinfo index %i (%i texinfos)",
n,
loadmodel->brushq1.numtexinfo);
4709 int i, j, firstside, numsides, contents,
count, maxplanes, q3surfaceflags, supercontents;
4711 int structsize = 12;
4712 qbool brushmissingtextures;
4713 int numbrushesmissingtextures = 0;
4714 int numcreatedtextures = 0;
4727 for (i = 0; i <
count; i++, out++)
4732 if (firstside < 0 || firstside + numsides >
loadmodel->brush.num_brushsides)
4733 Host_Error(
"Mod_Q3BSP_LoadBrushes: invalid brushside range %i : %i (%i brushsides)", firstside, firstside + numsides,
loadmodel->brush.num_brushsides);
4744 brushmissingtextures =
false;
4749 brushmissingtextures =
true;
4753 if (out->
firstbrushside[j].texture->supercontents == supercontents)
4759 numbrushesmissingtextures++;
4766 dpsnprintf(validtexture->
name,
sizeof(validtexture->
name),
"brushcollision%i", numcreatedtextures);
4769 numcreatedtextures++;
4781 if (maxplanes < out->numbrushsides)
4803 if (numcreatedtextures)
4804 Con_DPrintf(
"Mod_Q2BSP_LoadBrushes: %i brushes own sides that lack textures or have differing contents from the brush, %i textures have been created to describe these contents.\n", numbrushesmissingtextures, numcreatedtextures);
4838 if (*
first > brushnum)
4840 if (*last < brushnum)
4850 float dist, modelyawradius, modelradius;
4852 int totalstylesurfaces, totalstyles, stylecounts[256], remapstyles[256];
4862 mod->brush.ishlbsp =
false;
4863 mod->brush.isbsp2rmqe =
false;
4864 mod->brush.isbsp2 =
false;
4865 mod->brush.isq2bsp =
true;
4866 mod->brush.isq3bsp =
false;
4867 mod->brush.skymasking =
true;
4868 mod->modeldatatypestring =
"Q2BSP";
4888 mod->soundfromcenter =
true;
4906 mod->brush.AmbientSoundLevelsForPoint =
NULL;
4907 mod->brush.RoundUpToHullSize =
NULL;
4920 mod->brush.qw_md4sum = 0;
4921 mod->brush.qw_md4sum2 = 0;
4956 if (lumpsb[i].readcount != lumpsb[i].cursize)
4957 Host_Error(
"Lump %i incorrectly loaded (readcount %i, size %i)\n", i, lumpsb[i].readcount, lumpsb[i].cursize);
4961 loadmodel->brush.supportwateralpha =
true;
4964 if (
mod->brushq1.data_compressedpvs)
4966 mod->brushq1.data_compressedpvs =
NULL;
4967 mod->brushq1.num_compressedpvs = 0;
4979 totalstylesurfaces = 0;
4981 for (i = 0;i <
mod->brush.numsubmodels;i++)
4983 memset(stylecounts, 0,
sizeof(stylecounts));
4984 for (k = 0;k <
mod->brushq1.submodels[i].numfaces;k++)
4986 surface =
mod->data_surfaces +
mod->brushq1.submodels[i].firstface + k;
4990 for (k = 0;k < 255;k++)
4994 totalstylesurfaces += stylecounts[k];
5000 datapointer =
Mem_AllocType(
mod->mempool,
int,
mod->num_surfaces *
sizeof(
int) + totalstylesurfaces *
sizeof(
int));
5001 mod->modelsurfaces_sorted = datapointer; datapointer +=
mod->num_surfaces;
5005 for (i = 0;i <
loadmodel->brush.numsubmodels;i++)
5008 int firstbrush =
loadmodel->brush.num_brushes, lastbrush = 0;
5025 mod->brush.BoxTouchingPVS =
NULL;
5026 mod->brush.BoxTouchingLeafPVS =
NULL;
5027 mod->brush.BoxTouchingVisibleLeafs =
NULL;
5028 mod->brush.FindBoxClusters =
NULL;
5030 mod->brush.AmbientSoundLevelsForPoint =
NULL;
5032 mod->brush.submodel = i;
5036 bm = &
mod->brushq1.submodels[i];
5039 mod->brushq1.hulls[0].firstclipnode = bm->
headnode[0];
5048 rootnode =
mod->brush.data_nodes + bm->
headnode[0];
5055 if (firstbrush <= lastbrush)
5057 mod->firstmodelbrush = firstbrush;
5058 mod->nummodelbrushes = lastbrush + 1 - firstbrush;
5062 mod->firstmodelbrush = 0;
5063 mod->nummodelbrushes = 0;
5070 modelyawradius = dist*dist+modelyawradius*modelyawradius;
5072 modelradius = modelyawradius + modelradius * modelradius;
5073 modelyawradius =
sqrt(modelyawradius);
5074 modelradius =
sqrt(modelradius);
5075 mod->yawmins[0] =
mod->yawmins[1] = -modelyawradius;
5076 mod->yawmins[2] =
mod->normalmins[2];
5077 mod->yawmaxs[0] =
mod->yawmaxs[1] = modelyawradius;
5078 mod->yawmaxs[2] =
mod->normalmaxs[2];
5079 mod->rotatedmins[0] =
mod->rotatedmins[1] =
mod->rotatedmins[2] = -modelradius;
5080 mod->rotatedmaxs[0] =
mod->rotatedmaxs[1] =
mod->rotatedmaxs[2] = modelradius;
5081 mod->radius = modelradius;
5082 mod->radius2 = modelradius * modelradius;
5087 if (
mod->submodelsurfaces_start <
mod->submodelsurfaces_end)
5092 memset(stylecounts, 0,
sizeof(stylecounts));
5093 for (k =
mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
5095 stylecounts[
mod->data_surfaces[k].lightmapinfo->styles[j]]++;
5096 mod->brushq1.num_lightstyles = 0;
5097 for (k = 0;k < 255;k++)
5101 styleinfo[
mod->brushq1.num_lightstyles].
style = k;
5102 styleinfo[
mod->brushq1.num_lightstyles].
value = 0;
5104 styleinfo[
mod->brushq1.num_lightstyles].
surfacelist = datapointer;datapointer += stylecounts[k];
5105 remapstyles[k] =
mod->brushq1.num_lightstyles;
5106 mod->brushq1.num_lightstyles++;
5109 for (k =
mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
5111 surface =
mod->data_surfaces + k;
5121 mod->brushq1.data_lightstyleinfo = lsidatapointer;lsidatapointer +=
mod->brushq1.num_lightstyles;
5145 Con_DPrintf(
"Stats for q2bsp model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n",
loadmodel->name,
loadmodel->num_surfaces,
loadmodel->brush.num_nodes,
loadmodel->brush.num_leafs,
mod->brush.num_pvsclusters,
loadmodel->brush.num_portals,
loadmodel->surfmesh.num_vertices,
loadmodel->surfmesh.num_triangles,
loadmodel->num_surfaces);
5156 loadmodel->brushq3.num_lightgrid_cellsize[0] = 64;
5157 loadmodel->brushq3.num_lightgrid_cellsize[1] = 64;
5158 loadmodel->brushq3.num_lightgrid_cellsize[2] = 128;
5167 loadmodel->brushq3.deluxemapping =
false;
5180 while (key[
strlen(key)-1] ==
' ')
5185 if (!strcasecmp(
"gridsize", key))
5188#define sscanf sscanf_s
5191 if (sscanf(
value,
"%f %f %f", &
v[0], &
v[1], &
v[2]) == 3 &&
v[0] != 0 &&
v[1] != 0 &&
v[2] != 0)
5195 if(sscanf(
value,
"%f %f %f", &
v[0], &
v[1], &
v[2]) != 3)
5196 Con_Printf(
"Mod_Q3BSP_LoadEntities: funny gridsize \"%s\" in %s, interpreting as \"%f %f %f\" to match q3map2's parsing\n",
value,
loadmodel->name,
v[0],
v[1],
v[2]);
5197 if (
v[0] != 0 &&
v[1] != 0 &&
v[2] != 0)
5201 else if (!strcmp(
"deluxeMaps", key))
5205 loadmodel->brushq3.deluxemapping =
true;
5206 loadmodel->brushq3.deluxemapping_modelspace =
true;
5210 loadmodel->brushq3.deluxemapping =
true;
5211 loadmodel->brushq3.deluxemapping_modelspace =
false;
5234 for (i = 0;i <
count;i++)
5260 for (i = 0;i <
count;i++, in++, out++)
5285 for (i = 0;i <
count;i++, in++, out++)
5289 Host_Error(
"Mod_Q3BSP_LoadBrushSides: invalid planeindex %i (%i planes)",
n,
loadmodel->brush.num_planes);
5293 Host_Error(
"Mod_Q3BSP_LoadBrushSides: invalid textureindex %i (%i textures)",
n,
loadmodel->num_textures);
5313 for (i = 0;i <
count;i++, in++, out++)
5317 Host_Error(
"Mod_Q3BSP_LoadBrushSides: invalid planeindex %i (%i planes)",
n,
loadmodel->brush.num_planes);
5321 Host_Error(
"Mod_Q3BSP_LoadBrushSides: invalid textureindex %i (%i textures)",
n,
loadmodel->num_textures);
5330 int i, j,
n, c,
count, maxplanes, q3surfaceflags;
5345 for (i = 0;i <
count;i++, in++, out++)
5350 Host_Error(
"Mod_Q3BSP_LoadBrushes: invalid brushside range %i : %i (%i brushsides)",
n,
n + c,
loadmodel->brush.num_brushsides);
5355 Host_Error(
"Mod_Q3BSP_LoadBrushes: invalid textureindex %i (%i textures)",
n,
loadmodel->num_textures);
5359 if (maxplanes < out->numbrushsides)
5400 for (i = 0;i <
count;i++, in++, out++)
5406 Con_Printf(
"Mod_Q3BSP_LoadEffects: invalid brushindex %i (%i brushes), setting to -1\n",
n,
loadmodel->brush.num_brushes);
5429 for (i = 0;i <
count;i++, in++)
5489 if (l->
filelen %
sizeof(
int[3]))
5496 Con_Printf(
"Mod_Q3BSP_LoadTriangles: %s has triangles but no vertexes, broken compiler, ignoring problem\n",
loadmodel->name);
5503 loadmodel->brushq3.data_element3i = out;
5505 for (i = 0;i <
count;i++, in++, out++)
5508 if (*out < 0 || *out >=
loadmodel->brushq3.num_vertices)
5510 Con_Printf(
"Mod_Q3BSP_LoadTriangles: invalid vertexindex %i (%i vertices), setting to 0\n", *out,
loadmodel->brushq3.num_vertices);
5536 int mergedrowsxcolumns;
5541 unsigned char *mergedpixels;
5542 unsigned char *mergeddeluxepixels;
5543 unsigned char *mergebuf;
5546 unsigned char *inpixels[10000];
5571 if (l->
filelen %
sizeof(*input_pointer))
5574 for(i = 0; i <
count; ++i)
5575 inpixels[i] = input_pointer[i].
rgb;
5590 Con_Printf(
"Mod_Q3BSP_LoadLightmaps: irregularly sized external lightmap in %s",
loadmodel->name);
5602 if(!inpixels[
count])
5608 Con_Printf(
"Mod_Q3BSP_LoadLightmaps: mismatched lightmap size in %s - external lightmap %s/lm_%04d does not match earlier ones\n",
loadmodel->name,
mapname,
count);
5631 loadmodel->brushq3.deluxemapping_modelspace =
true;
5637 for (i = 0;i < facecount;i++)
5642 endlightmap =
max(endlightmap, j + 1);
5643 if ((j & 1) || j + 1 >=
count)
5645 loadmodel->brushq3.deluxemapping =
false;
5659 if (endlightmap == 1 &&
count > 1)
5664 if (c[bytesperpixel*i + rgbmap[0]])
5666 if (c[bytesperpixel*i + rgbmap[1]])
5668 if (c[bytesperpixel*i + rgbmap[2]])
5674 loadmodel->brushq3.deluxemapping =
false;
5688 mergegoal =
bound(
size, mergegoal, (
int)
vid.maxtexturesize_2d);
5689 while (mergegoal >
size && mergegoal * mergegoal / 4 >=
size *
size * realcount)
5691 mergedwidth = mergegoal;
5692 mergedheight = mergegoal;
5698 if (mergedwidth * mergedheight / 2 >=
size*
size*realcount)
5701 loadmodel->brushq3.num_lightmapmergedwidthpower = 0;
5702 loadmodel->brushq3.num_lightmapmergedheightpower = 0;
5703 while (mergedwidth >
size<<
loadmodel->brushq3.num_lightmapmergedwidthpower)
5704 loadmodel->brushq3.num_lightmapmergedwidthpower++;
5705 while (mergedheight >
size<<
loadmodel->brushq3.num_lightmapmergedheightpower)
5706 loadmodel->brushq3.num_lightmapmergedheightpower++;
5707 loadmodel->brushq3.num_lightmapmergedwidthheightdeluxepower =
loadmodel->brushq3.num_lightmapmergedwidthpower +
loadmodel->brushq3.num_lightmapmergedheightpower + (
loadmodel->brushq3.deluxemapping ? 1 : 0);
5709 powerx =
loadmodel->brushq3.num_lightmapmergedwidthpower;
5710 powery =
loadmodel->brushq3.num_lightmapmergedheightpower;
5711 powerxy = powerx+powery;
5712 powerdxy =
loadmodel->brushq3.deluxemapping + powerxy;
5714 mergedcolumns = 1 << powerx;
5715 mergedrows = 1 << powery;
5716 mergedrowsxcolumns = 1 << powerxy;
5718 loadmodel->brushq3.num_mergedlightmaps = (realcount + (1 << powerxy) - 1) >> powerxy;
5725 for (i = 0;i <
count;i++)
5728 realindex = i >> (
int)
loadmodel->brushq3.deluxemapping;
5729 lightmapindex = i >> powerdxy;
5732 mergebuf = (
loadmodel->brushq3.deluxemapping && (i & 1)) ? mergeddeluxepixels : mergedpixels;
5733 mergebuf += 4 * (realindex & (mergedcolumns-1))*
size + 4 * ((realindex >> powerx) & (mergedrows-1))*mergedwidth*
size;
5734 if ((i & 1) == 0 || !
loadmodel->brushq3.deluxemapping)
5735 Con_DPrintf(
"copying original lightmap %i (%ix%i) to %i (at %i,%i)\n", i,
size,
size, lightmapindex, (realindex & (mergedcolumns-1))*
size, ((realindex >> powerx) & (mergedrows-1))*
size);
5738 for (j = 0;j <
size;j++)
5739 for (k = 0;k <
size;k++)
5741 mergebuf[(j*mergedwidth+k)*4+0] = inpixels[i][(j*
size+k)*bytesperpixel+rgbmap[0]];
5742 mergebuf[(j*mergedwidth+k)*4+1] = inpixels[i][(j*
size+k)*bytesperpixel+rgbmap[1]];
5743 mergebuf[(j*mergedwidth+k)*4+2] = inpixels[i][(j*
size+k)*bytesperpixel+rgbmap[2]];
5744 mergebuf[(j*mergedwidth+k)*4+3] = 255;
5748 if (((realindex + 1) & (mergedrowsxcolumns - 1)) == 0 || (realindex + 1) == realcount)
5750 if (
loadmodel->brushq3.deluxemapping && (i & 1))
5751 loadmodel->brushq3.data_deluxemaps[lightmapindex] =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"deluxemap%04i", lightmapindex), mergedwidth, mergedheight, mergeddeluxepixels,
TEXTYPE_BGRA,
TEXF_FORCELINEAR | (
gl_texturecompression_q3bspdeluxemaps.integer ?
TEXF_COMPRESS : 0), -1,
NULL);
5764 loadmodel->brushq3.data_lightmaps [lightmapindex] =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels, t,
TEXF_FORCELINEAR | (
gl_texturecompression_q3bsplightmaps.integer ?
TEXF_COMPRESS : 0), -1,
NULL);
5770 loadmodel->brushq3.data_lightmaps [lightmapindex] =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels,
TEXTYPE_BGRA,
TEXF_FORCELINEAR | (
gl_texturecompression_q3bsplightmaps.integer ?
TEXF_COMPRESS : 0), -1,
NULL);
5776 if (mergeddeluxepixels)
5781 for(i = 0; i <
count; ++i)
5786typedef struct patchtess_s
5796#define PATCHTESS_SAME_LODGROUP(a,b) \
5798 (a).lodgroup[0] == (b).lodgroup[0] && \
5799 (a).lodgroup[1] == (b).lodgroup[1] && \
5800 (a).lodgroup[2] == (b).lodgroup[2] && \
5801 (a).lodgroup[3] == (b).lodgroup[3] && \
5802 (a).lodgroup[4] == (b).lodgroup[4] && \
5803 (a).lodgroup[5] == (b).lodgroup[5] \
5810 int i, oldi, j,
n,
count, invalidelements, patchsize[2], finalwidth, finalheight, xtess, ytess, finalvertices, finaltriangles, firstvertex, firstelement,
type, oldnumtriangles, oldnumtriangles2, meshvertices, meshtriangles, collisionvertices, collisiontriangles, numvertices, numtriangles, cxtess, cytess;
5811 float lightmaptcbase[2], lightmaptcscale[2];
5813 float *originalvertex3f;
5816 float *originalnormal3f;
5817 float *originalcolor4f;
5818 float *originaltexcoordtexture2f;
5819 float *originaltexcoordlightmap2f;
5820 float *surfacecollisionvertex3f;
5821 int *surfacecollisionelement3i;
5824 int patchtesscount = 0;
5845 for (;i <
count;i++, in++, out++)
5854 Con_DPrintf(
"Mod_Q3BSP_LoadFaces: face #%i: unknown face type %i\n", i,
type);
5861 Con_DPrintf(
"Mod_Q3BSP_LoadFaces: face #%i: invalid textureindex %i (%i textures)\n", i,
n,
loadmodel->num_textures);
5869 Con_DPrintf(
"Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid effectindex %i (%i effects)\n", i, out->
texture->
name,
n,
loadmodel->brushq3.num_effects);
5884 else if (
n >=
loadmodel->brushq3.num_originallightmaps)
5886 if(
loadmodel->brushq3.num_originallightmaps != 0)
5887 Con_Printf(
"Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid lightmapindex %i (%i lightmaps)\n", i, out->
texture->
name,
n,
loadmodel->brushq3.num_originallightmaps);
5908 if (firstvertex < 0 || firstvertex + numvertices >
loadmodel->brushq3.num_vertices)
5910 Con_Printf(
"Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid vertex range %i : %i (%i vertices)\n", i, out->
texture->
name, firstvertex, firstvertex + numvertices,
loadmodel->brushq3.num_vertices);
5913 if (firstelement < 0 || firstelement + numtriangles * 3 >
loadmodel->brushq3.num_triangles * 3)
5915 Con_Printf(
"Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid element range %i : %i (%i elements)\n", i, out->
texture->
name, firstelement, firstelement + numtriangles * 3,
loadmodel->brushq3.num_triangles * 3);
5929 Con_Printf(
"Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid patchsize %ix%i\n", i, out->
texture->
name, patchsize[0], patchsize[1]);
5932 originalvertex3f =
loadmodel->brushq3.data_vertex3f + firstvertex * 3;
5941 xtess =
bound(0, xtess, 1024);
5942 ytess =
bound(0, ytess, 1024);
5952 cxtess =
bound(0, cxtess, 1024);
5953 cytess =
bound(0, cytess, 1024);
5956 patchtess[patchtesscount].
info.
xsize = patchsize[0];
5957 patchtess[patchtesscount].
info.
ysize = patchsize[1];
5975 Con_DPrintf(
"Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): Q3FACETYPE_FLARE not supported (yet)\n", i, out->
texture->
name);
5989 for(i = 0; i < patchtesscount; ++i)
5991 for(j = i+1; j < patchtesscount; ++j)
5996 if (
Q3PatchAdjustTesselation(3, &patchtess[i].info, patchtess[i].originalvertex3f, &patchtess[j].info, patchtess[j].originalvertex3f) )
6004 collisionvertices = 0;
6005 collisiontriangles = 0;
6006 for(i = 0; i < patchtesscount; ++i)
6010 numvertices = finalwidth * finalheight;
6011 numtriangles = (finalwidth - 1) * (finalheight - 1) * 2;
6020 numvertices = finalwidth * finalheight;
6021 numtriangles = (finalwidth - 1) * (finalheight - 1) * 2;
6033 if (collisiontriangles)
6040 collisionvertices = 0;
6041 collisiontriangles = 0;
6081 originalvertex3f =
loadmodel->brushq3.data_vertex3f + firstvertex * 3;
6082 originalnormal3f =
loadmodel->brushq3.data_normal3f + firstvertex * 3;
6083 originaltexcoordtexture2f =
loadmodel->brushq3.data_texcoordtexture2f + firstvertex * 2;
6084 originaltexcoordlightmap2f =
loadmodel->brushq3.data_texcoordlightmap2f + firstvertex * 2;
6085 originalcolor4f =
loadmodel->brushq3.data_color4f + firstvertex * 4;
6087 xtess = ytess = cxtess = cytess = -1;
6088 for(j = 0; j < patchtesscount; ++j)
6089 if(patchtess[j].surface_id == i)
6100 xtess = ytess = cxtess = cytess = 0;
6105 finalvertices = finalwidth * finalheight;
6106 oldnumtriangles = finaltriangles = (finalwidth - 1) * (finalheight - 1) * 2;
6122 Con_DPrintf(
"Mod_Q3BSP_LoadFaces: %ix%i curve subdivided to %i vertices / %i triangles, %i degenerate triangles removed (leaving %i)\n", patchsize[0], patchsize[1], out->
num_vertices, finaltriangles, finaltriangles - out->
num_triangles, out->
num_triangles);
6130 finalvertices = finalwidth * finalheight;
6131 oldnumtriangles2 = finaltriangles = (finalwidth - 1) * (finalheight - 1) * 2;
6136 surfacecollisionvertex3f =
loadmodel->brush.data_collisionvertex3f + collisionvertices * 3;
6137 surfacecollisionelement3i =
loadmodel->brush.data_collisionelement3i + collisiontriangles * 3;
6138 Q3PatchTesselateFloat(3,
sizeof(
float[3]), surfacecollisionvertex3f, patchsize[0], patchsize[1],
sizeof(
float[3]), originalvertex3f, cxtess, cytess);
6146 collisionvertices += finalvertices;
6154 for (j = 0, invalidelements = 0;j < out->
num_triangles * 3;j++)
6157 if (invalidelements)
6159 Con_Printf(
CON_WARN "Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements,
type, out->
texture->
name, out->
texture->
surfaceflags, firstvertex, out->
num_vertices, firstelement, out->
num_triangles * 3);
6179 lightmapindex &= mergewidth * mergeheight - 1;
6180 lightmaptcscale[0] = 1.0f / mergewidth;
6181 lightmaptcscale[1] = 1.0f / mergeheight;
6182 lightmaptcbase[0] = (lightmapindex % mergewidth) * lightmaptcscale[0];
6183 lightmaptcbase[1] = (lightmapindex / mergewidth) * lightmaptcscale[1];
6187 v[0] =
v[0] * lightmaptcscale[0] + lightmaptcbase[0];
6188 v[1] =
v[1] * lightmaptcscale[1] + lightmaptcbase[1];
6202 out->
mins[0] -= 1.0f;
6203 out->
mins[1] -= 1.0f;
6204 out->
mins[2] -= 1.0f;
6205 out->
maxs[0] += 1.0f;
6206 out->
maxs[1] += 1.0f;
6207 out->
maxs[2] += 1.0f;
6218 for (;i <
count;i++, out++)
6224 Con_Printf(
"Mod_Q3BSP_LoadFaces: surface %d (texture %s) has no vertices, ignoring\n", i, out->
texture ? out->
texture->
name :
"(none)");
6226 Con_Printf(
"Mod_Q3BSP_LoadFaces: surface %d (texture %s) has no triangles, ignoring\n", i, out->
texture ? out->
texture->
name :
"(none)");
6229 Con_Printf(
"Mod_Q3BSP_LoadFaces: surface %d (texture %s, near %f %f %f) has no triangles, ignoring\n", i, out->
texture ? out->
texture->
name :
"(none)",
6240 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
6277 for (i = 0;i <
count;i++, in++, out++)
6279 for (j = 0;j < 3;j++)
6287 Host_Error(
"Mod_Q3BSP_LoadModels: invalid face range %i : %i (%i faces)",
n,
n + c,
loadmodel->num_surfaces);
6293 Host_Error(
"Mod_Q3BSP_LoadModels: invalid brush range %i : %i (%i brushes)",
n,
n + c,
loadmodel->brush.num_brushes);
6311 loadmodel->brush.data_leafbrushes = out;
6314 for (i = 0;i <
count;i++, in++, out++)
6318 Host_Error(
"Mod_Q3BSP_LoadLeafBrushes: invalid brush index %i (%i brushes)",
n,
loadmodel->brush.num_brushes);
6335 loadmodel->brush.data_leafsurfaces = out;
6338 for (i = 0;i <
count;i++, in++, out++)
6342 Host_Error(
"Mod_Q3BSP_LoadLeafFaces: invalid face index %i (%i faces)",
n,
loadmodel->num_surfaces);
6362 for (i = 0;i <
count;i++, in++, out++)
6368 for (j = 0;j < 3;j++)
6378 Host_Error(
"Mod_Q3BSP_LoadLeafs: invalid leafsurface range %i : %i (%i leafsurfaces)",
n,
n + c,
loadmodel->brush.num_leafsurfaces);
6384 Host_Error(
"Mod_Q3BSP_LoadLeafs: invalid leafbrush range %i : %i (%i leafbrushes)",
n,
n + c,
loadmodel->brush.num_leafbrushes);
6407 for (i = 0;i <
count;i++, in++, out++)
6412 Host_Error(
"Mod_Q3BSP_LoadNodes: invalid planeindex %i (%i planes)",
n,
loadmodel->brush.num_planes);
6414 for (j = 0;j < 2;j++)
6420 Host_Error(
"Mod_Q3BSP_LoadNodes: invalid child node index %i (%i nodes)",
n,
loadmodel->brush.num_nodes);
6427 Host_Error(
"Mod_Q3BSP_LoadNodes: invalid child leaf index %i (%i leafs)",
n,
loadmodel->brush.num_leafs);
6431 for (j = 0;j < 3;j++)
6450 unsigned char *texturergba, *texturelayer[3], *texturepadding[2];
6451 double lightgridmatrix[4][4];
6456 loadmodel->brushq3.num_lightgrid_scale[0] = 1.0f /
loadmodel->brushq3.num_lightgrid_cellsize[0];
6457 loadmodel->brushq3.num_lightgrid_scale[1] = 1.0f /
loadmodel->brushq3.num_lightgrid_cellsize[1];
6458 loadmodel->brushq3.num_lightgrid_scale[2] = 1.0f /
loadmodel->brushq3.num_lightgrid_cellsize[2];
6465 loadmodel->brushq3.num_lightgrid_isize[0] =
loadmodel->brushq3.num_lightgrid_imaxs[0] -
loadmodel->brushq3.num_lightgrid_imins[0] + 1;
6466 loadmodel->brushq3.num_lightgrid_isize[1] =
loadmodel->brushq3.num_lightgrid_imaxs[1] -
loadmodel->brushq3.num_lightgrid_imins[1] + 1;
6467 loadmodel->brushq3.num_lightgrid_isize[2] =
loadmodel->brushq3.num_lightgrid_imaxs[2] -
loadmodel->brushq3.num_lightgrid_imins[2] + 1;
6477 Con_Printf(
CON_ERROR "Mod_Q3BSP_LoadLightGrid: invalid lightgrid lump size %i bytes, should be %i bytes (%ix%ix%i)", l->
filelen, (
int)(
count *
sizeof(*in)),
loadmodel->brushq3.num_lightgrid_isize[0],
loadmodel->brushq3.num_lightgrid_isize[1],
loadmodel->brushq3.num_lightgrid_isize[2]);
6481 Con_Printf(
CON_WARN "Mod_Q3BSP_LoadLightGrid: Warning: calculated lightgrid size %i bytes does not match lump size %i\n", (
int)(
count *
sizeof(*in)), l->
filelen);
6483 loadmodel->brushq3.data_lightgrid = out;
6486 memcpy(out, in,
count * (
int)
sizeof(*out));
6496 for(i = 0; i <
count; ++i)
6511 for(i = 0; i <
count; ++i)
6535 texturesize[0] =
loadmodel->brushq3.num_lightgrid_isize[0];
6536 texturesize[1] =
loadmodel->brushq3.num_lightgrid_isize[1];
6537 texturesize[2] = (
loadmodel->brushq3.num_lightgrid_isize[2] + 2) * 3;
6538 texturergba = (
unsigned char*)
Mem_Alloc(
loadmodel->mempool, texturesize[0] * texturesize[1] * texturesize[2] *
sizeof(
char[4]));
6539 texturelayer[0] = texturergba +
loadmodel->brushq3.num_lightgrid_isize[0] *
loadmodel->brushq3.num_lightgrid_isize[1] * 4;
6540 texturelayer[1] = texturelayer[0] + (
loadmodel->brushq3.num_lightgrid_isize[0] *
loadmodel->brushq3.num_lightgrid_isize[1] * (
loadmodel->brushq3.num_lightgrid_isize[2] + 2)) * 4;
6541 texturelayer[2] = texturelayer[1] + (
loadmodel->brushq3.num_lightgrid_isize[0] *
loadmodel->brushq3.num_lightgrid_isize[1] * (
loadmodel->brushq3.num_lightgrid_isize[2] + 2)) * 4;
6543 texturepadding[0] = texturelayer[2] -
loadmodel->brushq3.num_lightgrid_isize[0] *
loadmodel->brushq3.num_lightgrid_isize[1] * 4;
6544 texturepadding[1] = texturelayer[2] +
loadmodel->brushq3.num_lightgrid_isize[0] *
loadmodel->brushq3.num_lightgrid_isize[1] *
loadmodel->brushq3.num_lightgrid_isize[2] * 4;
6545 for (i = 0; i < texturesize[0] * texturesize[1]; i++)
6547 texturepadding[0][i * 4] = texturepadding[1][i * 4] = 127;
6548 texturepadding[0][i * 4 + 1] = texturepadding[1][i * 4 + 1] = 127;
6549 texturepadding[0][i * 4 + 2] = texturepadding[1][i * 4 + 2] = 127;
6550 texturepadding[0][i * 4 + 3] = texturepadding[1][i * 4 + 3] = 255;
6552 for (i = 0; i <
count; i++)
6554 texturelayer[0][i * 4 + 0] = out[i].
ambientrgb[0];
6555 texturelayer[0][i * 4 + 1] = out[i].
ambientrgb[1];
6556 texturelayer[0][i * 4 + 2] = out[i].
ambientrgb[2];
6557 texturelayer[0][i * 4 + 3] = 255;
6558 texturelayer[1][i * 4 + 0] = out[i].
diffusergb[0];
6559 texturelayer[1][i * 4 + 1] = out[i].
diffusergb[1];
6560 texturelayer[1][i * 4 + 2] = out[i].
diffusergb[2];
6561 texturelayer[1][i * 4 + 3] = 255;
6565 texturelayer[2][i * 4 + 0] = (char)((
mod_md3_sin[64 + out[i].diffuseyaw] *
mod_md3_sin[out[i].diffusepitch]) * 127 + 127);
6566 texturelayer[2][i * 4 + 1] = (char)((
mod_md3_sin[out[i].diffuseyaw] *
mod_md3_sin[out[i].diffusepitch]) * 127 + 127);
6567 texturelayer[2][i * 4 + 2] = (char)((
mod_md3_sin[64 + out[i].diffusepitch]) * 127 + 127);
6568 texturelayer[2][i * 4 + 3] = 255;
6573 for (
z = 0;
z <
loadmodel->brushq3.num_lightgrid_isize[2];
z++)
6575 for (
y = 0;
y <
loadmodel->brushq3.num_lightgrid_isize[1];
y++)
6577 for (
x = 0;
x <
loadmodel->brushq3.num_lightgrid_isize[0];
x++)
6579 i = (
z * texturesize[1] +
y) * texturesize[0] +
x;
6580 texturelayer[0][i * 4 + 0] =
x * 256 /
loadmodel->brushq3.num_lightgrid_isize[0];
6581 texturelayer[0][i * 4 + 1] =
y * 256 /
loadmodel->brushq3.num_lightgrid_isize[1];
6582 texturelayer[0][i * 4 + 2] =
z * 256 /
loadmodel->brushq3.num_lightgrid_isize[2];
6587 loadmodel->brushq3.lightgridtexturesize[0] = texturesize[0];
6588 loadmodel->brushq3.lightgridtexturesize[1] = texturesize[1];
6589 loadmodel->brushq3.lightgridtexturesize[2] = texturesize[2];
6590 memset(lightgridmatrix[0], 0,
sizeof(lightgridmatrix));
6591 lightgridmatrix[0][0] =
loadmodel->brushq3.num_lightgrid_scale[0] / texturesize[0];
6592 lightgridmatrix[1][1] =
loadmodel->brushq3.num_lightgrid_scale[1] / texturesize[1];
6593 lightgridmatrix[2][2] =
loadmodel->brushq3.num_lightgrid_scale[2] / texturesize[2];
6594 lightgridmatrix[0][3] = -(
loadmodel->brushq3.num_lightgrid_imins[0] - 0.5f) / texturesize[0];
6595 lightgridmatrix[1][3] = -(
loadmodel->brushq3.num_lightgrid_imins[1] - 0.5f) / texturesize[1];
6596 lightgridmatrix[2][3] = -(
loadmodel->brushq3.num_lightgrid_imins[2] - 1.5f) / texturesize[2];
6597 lightgridmatrix[3][3] = 1;
6616 for (i = 0;i <
loadmodel->brush.num_leafs;i++)
6621 totalchains =
loadmodel->brush.num_pvsclusterbytes *
loadmodel->brush.num_pvsclusters;
6623 memset(
loadmodel->brush.data_pvsclusters, 0xFF, totalchains);
6633 if (
loadmodel->brush.num_pvsclusterbytes < ((
loadmodel->brush.num_pvsclusters + 7) / 8))
6634 Host_Error(
"Mod_Q3BSP_LoadPVS: (chainlength = %i) < ((numclusters = %i) + 7) / 8",
loadmodel->brush.num_pvsclusterbytes,
loadmodel->brush.num_pvsclusters);
6635 totalchains =
loadmodel->brush.num_pvsclusterbytes *
loadmodel->brush.num_pvsclusters;
6636 if (l->
filelen < totalchains + (
int)
sizeof(*in))
6637 Host_Error(
"Mod_Q3BSP_LoadPVS: lump too small ((numclusters = %i) * (chainlength = %i) + sizeof(q3dpvs_t) == %i bytes, lump is %i bytes)",
loadmodel->brush.num_pvsclusters,
loadmodel->brush.num_pvsclusterbytes, (
int)(totalchains +
sizeof(*in)), l->
filelen);
6640 memcpy(
loadmodel->brush.data_pvsclusters, (
unsigned char *)(in + 1), totalchains);
6645 int i, j, k,
index[3];
6646 float transformed[3], blend1, blend2, blend, stylescale = 1;
6654 if (!
model->brushq3.num_lightgrid)
6656 ambientcolor[0] = stylescale;
6657 ambientcolor[1] = stylescale;
6658 ambientcolor[2] = stylescale;
6665 transformed[0] =
bound(0, transformed[0],
model->brushq3.num_lightgrid_isize[0] - 1);
6666 transformed[1] =
bound(0, transformed[1],
model->brushq3.num_lightgrid_isize[1] - 1);
6667 transformed[2] =
bound(0, transformed[2],
model->brushq3.num_lightgrid_isize[2] - 1);
6676 for (k = 0;k < 2;k++)
6678 blend1 = (k ? (transformed[2] -
index[2]) : (1 - (transformed[2] -
index[2])));
6679 if (blend1 < 0.001f ||
index[2] + k >=
model->brushq3.num_lightgrid_isize[2])
6681 for (j = 0;j < 2;j++)
6683 blend2 = blend1 * (j ? (transformed[1] -
index[1]) : (1 - (transformed[1] -
index[1])));
6684 if (blend2 < 0.001f ||
index[1] + j >=
model->brushq3.num_lightgrid_isize[1])
6686 for (i = 0;i < 2;i++)
6688 blend = blend2 * (i ? (transformed[0] -
index[0]) : (1 - (transformed[0] -
index[0]))) * stylescale;
6689 if (blend < 0.001f ||
index[0] + i >=
model->brushq3.num_lightgrid_isize[0])
6691 s =
a + (k *
model->brushq3.num_lightgrid_isize[1] + j) *
model->brushq3.num_lightgrid_isize[0] + i;
6713 double midf, mid[3];
6721 if (plane->
type < 3)
6723 t1 = p1[plane->
type] - plane->
dist;
6724 t2 = p2[plane->
type] - plane->
dist;
6751 midf = t1 / (t1 - t2);
6769 return ((
mleaf_t *)node)->clusterindex < 0;
6782 double tracestart[3], traceend[3], traceendpos[3];
6787 return BoxesOverlap(traceendpos, traceendpos, acceptmins, acceptmaxs);
6799 int nodestackpos = 0;
6800 int nodestack[1024];
6802 memset(trace, 0,
sizeof(*trace));
6808 bih = &
model->collision_bih;
6813 nodestack[nodestackpos++] = nodenum;
6814 while (nodestackpos)
6816 nodenum = nodestack[--nodestackpos];
6817 node = bih->
nodes + nodenum;
6825 if(nodestackpos > 1024 - 2)
6830 nodestack[nodestackpos++] = node->
front;
6831 if (start[axis] <= node->
backmax)
6832 nodestack[nodestackpos++] = node->
back;
6868 vec3_t nodebigmins, nodebigmaxs, nodestart, nodeend, sweepnodemins, sweepnodemaxs;
6869 vec_t d1, d2, d3, d4,
f, nodestackline[1024][6];
6870 int axis, nodenum, nodestackpos = 0, nodestack[1024];
6883 memset(trace, 0,
sizeof(*trace));
6890 nodestackline[nodestackpos][0] = start[0];
6891 nodestackline[nodestackpos][1] = start[1];
6892 nodestackline[nodestackpos][2] = start[2];
6893 nodestackline[nodestackpos][3] = end[0];
6894 nodestackline[nodestackpos][4] = end[1];
6895 nodestackline[nodestackpos][5] = end[2];
6896 nodestack[nodestackpos++] = nodenum;
6897 while (nodestackpos)
6899 nodenum = nodestack[--nodestackpos];
6900 node = bih->
nodes + nodenum;
6901 VectorCopy(nodestackline[nodestackpos], nodestart);
6902 VectorCopy(nodestackline[nodestackpos] + 3, nodeend);
6903 sweepnodemins[0] =
min(nodestart[0], nodeend[0]) - 1;
6904 sweepnodemins[1] =
min(nodestart[1], nodeend[1]) - 1;
6905 sweepnodemins[2] =
min(nodestart[2], nodeend[2]) - 1;
6906 sweepnodemaxs[0] =
max(nodestart[0], nodeend[0]) + 1;
6907 sweepnodemaxs[1] =
max(nodestart[1], nodeend[1]) + 1;
6908 sweepnodemaxs[2] =
max(nodestart[2], nodeend[2]) + 1;
6914 if(nodestackpos > 1024 - 2)
6919 d1 = node->
backmax - nodestart[axis];
6920 d2 = node->
backmax - nodeend[axis];
6921 d3 = nodestart[axis] - node->
frontmin;
6922 d4 = nodeend[axis] - node->
frontmin;
6923 f = 1.f / (nodeend[axis] - nodestart[axis]);
6925 d1 = d2 = d3 = d4 = 1;
6926 switch((d1 < 0) | ((d2 < 0) << 1) | ((d3 < 0) << 2) | ((d4 < 0) << 3))
6929 VectorCopy(nodestart, nodestackline[nodestackpos]);
6930 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6931 nodestack[nodestackpos++] = node->
back;
6932 VectorCopy(nodestart, nodestackline[nodestackpos]);
6933 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6934 nodestack[nodestackpos++] = node->
front;
6937 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
6938 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6939 nodestack[nodestackpos++] = node->
back;
6940 VectorCopy(nodestart, nodestackline[nodestackpos]);
6941 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6942 nodestack[nodestackpos++] = node->
front;
6945 VectorCopy(nodestart, nodestackline[nodestackpos]);
6946 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
6947 nodestack[nodestackpos++] = node->
back;
6948 VectorCopy(nodestart, nodestackline[nodestackpos]);
6949 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6950 nodestack[nodestackpos++] = node->
front;
6953 VectorCopy(nodestart, nodestackline[nodestackpos]);
6954 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6955 nodestack[nodestackpos++] = node->
front;
6958 VectorCopy(nodestart, nodestackline[nodestackpos]);
6959 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6960 nodestack[nodestackpos++] = node->
back;
6961 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
6962 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6963 nodestack[nodestackpos++] = node->
front;
6966 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
6967 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6968 nodestack[nodestackpos++] = node->
back;
6969 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
6970 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6971 nodestack[nodestackpos++] = node->
front;
6974 VectorCopy(nodestart, nodestackline[nodestackpos]);
6975 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
6976 nodestack[nodestackpos++] = node->
back;
6977 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
6978 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6979 nodestack[nodestackpos++] = node->
front;
6982 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
6983 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6984 nodestack[nodestackpos++] = node->
front;
6987 VectorCopy(nodestart, nodestackline[nodestackpos]);
6988 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6989 nodestack[nodestackpos++] = node->
back;
6990 VectorCopy(nodestart, nodestackline[nodestackpos]);
6991 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
6992 nodestack[nodestackpos++] = node->
front;
6995 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
6996 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
6997 nodestack[nodestackpos++] = node->
back;
6998 VectorCopy(nodestart, nodestackline[nodestackpos]);
6999 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7000 nodestack[nodestackpos++] = node->
front;
7003 VectorCopy(nodestart, nodestackline[nodestackpos]);
7004 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
7005 nodestack[nodestackpos++] = node->
back;
7006 VectorCopy(nodestart, nodestackline[nodestackpos]);
7007 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7008 nodestack[nodestackpos++] = node->
front;
7011 VectorCopy(nodestart, nodestackline[nodestackpos]);
7012 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7013 nodestack[nodestackpos++] = node->
front;
7016 VectorCopy(nodestart, nodestackline[nodestackpos]);
7017 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7018 nodestack[nodestackpos++] = node->
back;
7021 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
7022 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7023 nodestack[nodestackpos++] = node->
back;
7026 VectorCopy(nodestart, nodestackline[nodestackpos]);
7027 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
7028 nodestack[nodestackpos++] = node->
back;
7041 axis = 0; d1 = nodestart[axis] - nodebigmins[axis]; d2 = nodeend[axis] - nodebigmins[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); } d1 = nodebigmaxs[axis] - nodestart[axis]; d2 = nodebigmaxs[axis] - nodeend[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); }
7042 axis = 1; d1 = nodestart[axis] - nodebigmins[axis]; d2 = nodeend[axis] - nodebigmins[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); } d1 = nodebigmaxs[axis] - nodestart[axis]; d2 = nodebigmaxs[axis] - nodeend[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); }
7043 axis = 2; d1 = nodestart[axis] - nodebigmins[axis]; d2 = nodeend[axis] - nodebigmins[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); } d1 = nodebigmaxs[axis] - nodestart[axis]; d2 = nodebigmaxs[axis] - nodeend[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); }
7046 sweepnodemins[0] =
min(nodestart[0], nodeend[0]) - 1;
7047 sweepnodemins[1] =
min(nodestart[1], nodeend[1]) - 1;
7048 sweepnodemins[2] =
min(nodestart[2], nodeend[2]) - 1;
7049 sweepnodemaxs[0] =
max(nodestart[0], nodeend[0]) + 1;
7050 sweepnodemaxs[1] =
max(nodestart[1], nodeend[1]) + 1;
7051 sweepnodemaxs[2] =
max(nodestart[2], nodeend[2]) + 1;
7100 vec3_t start, end, startmins, startmaxs, endmins, endmaxs,
mins,
maxs;
7101 vec3_t nodebigmins, nodebigmaxs, nodestart, nodeend, sweepnodemins, sweepnodemaxs;
7102 vec_t d1, d2, d3, d4,
f, nodestackline[1024][6];
7103 int axis, nodenum, nodestackpos = 0, nodestack[1024];
7114 bih = &
model->collision_bih;
7120 memset(trace, 0,
sizeof(*trace));
7135 mins[0] =
min(startmins[0], endmins[0]);
7136 mins[1] =
min(startmins[1], endmins[1]);
7137 mins[2] =
min(startmins[2], endmins[2]);
7138 maxs[0] =
max(startmaxs[0], endmaxs[0]);
7139 maxs[1] =
max(startmaxs[1], endmaxs[1]);
7140 maxs[2] =
max(startmaxs[2], endmaxs[2]);
7143 nodestackline[nodestackpos][0] = start[0];
7144 nodestackline[nodestackpos][1] = start[1];
7145 nodestackline[nodestackpos][2] = start[2];
7146 nodestackline[nodestackpos][3] = end[0];
7147 nodestackline[nodestackpos][4] = end[1];
7148 nodestackline[nodestackpos][5] = end[2];
7149 nodestack[nodestackpos++] = nodenum;
7150 while (nodestackpos)
7152 nodenum = nodestack[--nodestackpos];
7153 node = bih->
nodes + nodenum;
7154 VectorCopy(nodestackline[nodestackpos], nodestart);
7155 VectorCopy(nodestackline[nodestackpos] + 3, nodeend);
7156 sweepnodemins[0] =
min(nodestart[0], nodeend[0]) +
mins[0] - 1;
7157 sweepnodemins[1] =
min(nodestart[1], nodeend[1]) +
mins[1] - 1;
7158 sweepnodemins[2] =
min(nodestart[2], nodeend[2]) +
mins[2] - 1;
7159 sweepnodemaxs[0] =
max(nodestart[0], nodeend[0]) +
maxs[0] + 1;
7160 sweepnodemaxs[1] =
max(nodestart[1], nodeend[1]) +
maxs[1] + 1;
7161 sweepnodemaxs[2] =
max(nodestart[2], nodeend[2]) +
maxs[2] + 1;
7167 if(nodestackpos > 1024 - 2)
7172 d1 = node->
backmax -
mins[axis] - nodestart[axis];
7176 f = 1.f / (nodeend[axis] - nodestart[axis]);
7177 switch((d1 < 0) | ((d2 < 0) << 1) | ((d3 < 0) << 2) | ((d4 < 0) << 3))
7180 VectorCopy(nodestart, nodestackline[nodestackpos]);
7181 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7182 nodestack[nodestackpos++] = node->
back;
7183 VectorCopy(nodestart, nodestackline[nodestackpos]);
7184 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7185 nodestack[nodestackpos++] = node->
front;
7188 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
7189 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7190 nodestack[nodestackpos++] = node->
back;
7191 VectorCopy(nodestart, nodestackline[nodestackpos]);
7192 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7193 nodestack[nodestackpos++] = node->
front;
7196 VectorCopy(nodestart, nodestackline[nodestackpos]);
7197 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
7198 nodestack[nodestackpos++] = node->
back;
7199 VectorCopy(nodestart, nodestackline[nodestackpos]);
7200 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7201 nodestack[nodestackpos++] = node->
front;
7204 VectorCopy(nodestart, nodestackline[nodestackpos]);
7205 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7206 nodestack[nodestackpos++] = node->
front;
7209 VectorCopy(nodestart, nodestackline[nodestackpos]);
7210 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7211 nodestack[nodestackpos++] = node->
back;
7212 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
7213 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7214 nodestack[nodestackpos++] = node->
front;
7217 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
7218 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7219 nodestack[nodestackpos++] = node->
back;
7220 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
7221 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7222 nodestack[nodestackpos++] = node->
front;
7225 VectorCopy(nodestart, nodestackline[nodestackpos]);
7226 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
7227 nodestack[nodestackpos++] = node->
back;
7228 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
7229 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7230 nodestack[nodestackpos++] = node->
front;
7233 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos]);
7234 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7235 nodestack[nodestackpos++] = node->
front;
7238 VectorCopy(nodestart, nodestackline[nodestackpos]);
7239 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7240 nodestack[nodestackpos++] = node->
back;
7241 VectorCopy(nodestart, nodestackline[nodestackpos]);
7242 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7243 nodestack[nodestackpos++] = node->
front;
7246 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
7247 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7248 nodestack[nodestackpos++] = node->
back;
7249 VectorCopy(nodestart, nodestackline[nodestackpos]);
7250 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7251 nodestack[nodestackpos++] = node->
front;
7254 VectorCopy(nodestart, nodestackline[nodestackpos]);
7255 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
7256 nodestack[nodestackpos++] = node->
back;
7257 VectorCopy(nodestart, nodestackline[nodestackpos]);
7258 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7259 nodestack[nodestackpos++] = node->
front;
7262 VectorCopy(nodestart, nodestackline[nodestackpos]);
7263 VectorLerp(nodestart, -d3 *
f, nodeend, nodestackline[nodestackpos] + 3);
7264 nodestack[nodestackpos++] = node->
front;
7267 VectorCopy(nodestart, nodestackline[nodestackpos]);
7268 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7269 nodestack[nodestackpos++] = node->
back;
7272 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos]);
7273 VectorCopy(nodeend, nodestackline[nodestackpos] + 3);
7274 nodestack[nodestackpos++] = node->
back;
7277 VectorCopy(nodestart, nodestackline[nodestackpos]);
7278 VectorLerp(nodestart, d1 *
f, nodeend, nodestackline[nodestackpos] + 3);
7279 nodestack[nodestackpos++] = node->
back;
7292 axis = 0; d1 = nodestart[axis] - nodebigmins[axis]; d2 = nodeend[axis] - nodebigmins[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); } d1 = nodebigmaxs[axis] - nodestart[axis]; d2 = nodebigmaxs[axis] - nodeend[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); }
7293 axis = 1; d1 = nodestart[axis] - nodebigmins[axis]; d2 = nodeend[axis] - nodebigmins[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); } d1 = nodebigmaxs[axis] - nodestart[axis]; d2 = nodebigmaxs[axis] - nodeend[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); }
7294 axis = 2; d1 = nodestart[axis] - nodebigmins[axis]; d2 = nodeend[axis] - nodebigmins[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); } d1 = nodebigmaxs[axis] - nodestart[axis]; d2 = nodebigmaxs[axis] - nodeend[axis];
if (d1 < 0) {
if (d2 < 0)
continue;
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodestart); }
else if (d2 < 0) {
f = d1 / (d1 - d2);
VectorLerp(nodestart,
f, nodeend, nodeend); }
7297 sweepnodemins[0] =
min(nodestart[0], nodeend[0]) +
mins[0] - 1;
7298 sweepnodemins[1] =
min(nodestart[1], nodeend[1]) +
mins[1] - 1;
7299 sweepnodemins[2] =
min(nodestart[2], nodeend[2]) +
mins[2] - 1;
7300 sweepnodemaxs[0] =
max(nodestart[0], nodeend[0]) +
maxs[0] + 1;
7301 sweepnodemaxs[1] =
max(nodestart[1], nodeend[1]) +
maxs[1] + 1;
7302 sweepnodemaxs[2] =
max(nodestart[2], nodeend[2]) +
maxs[2] + 1;
7332void Mod_CollisionBIH_TraceBox(
model_t *
model,
const frameblend_t *frameblend,
const skeleton_t *skeleton,
trace_t *trace,
const vec3_t start,
const vec3_t boxmins,
const vec3_t boxmaxs,
const vec3_t end,
int hitsupercontentsmask,
int skipsupercontentsmask,
int skipmaterialflagsmask)
7335 vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
7338 VectorAdd(start, boxmins, boxstartmins);
7339 VectorAdd(start, boxmaxs, boxstartmaxs);
7367 int hitsupercontents;
7370 memset(trace, 0,
sizeof(*trace));
7378 memset(trace, 0,
sizeof(*trace));
7394 memset(&trace, 0,
sizeof(trace));
7420 int nummodelbrushes =
model->nummodelbrushes;
7422 const int *collisionelement3i;
7423 const float *collisionvertex3f;
7424 const int *renderelement3i;
7425 const float *rendervertex3f;
7429 int *temp_leafsortscratch;
7435 if (userendersurfaces)
7437 for (j =
model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
7438 bihnumleafs +=
model->data_surfaces[j].num_triangles;
7442 for (brushindex = 0, brush =
model->brush.data_brushes + brushindex+
model->firstmodelbrush;brushindex < nummodelbrushes;brushindex++, brush++)
7445 for (j =
model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
7448 bihnumleafs +=
model->data_surfaces[j].num_triangles +
model->data_surfaces[j].num_collisiontriangles;
7450 bihnumleafs +=
model->data_surfaces[j].num_collisiontriangles;
7464 renderelement3i =
model->surfmesh.data_element3i;
7465 rendervertex3f =
model->surfmesh.data_vertex3f;
7466 for (j =
model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
7468 surface =
model->data_surfaces + j;
7469 for (triangleindex = 0, e = renderelement3i + 3*surface->
num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
7477 bihleafs[bihleafindex].
mins[0] =
min(rendervertex3f[3*e[0]+0],
min(rendervertex3f[3*e[1]+0], rendervertex3f[3*e[2]+0])) - 1;
7478 bihleafs[bihleafindex].
mins[1] =
min(rendervertex3f[3*e[0]+1],
min(rendervertex3f[3*e[1]+1], rendervertex3f[3*e[2]+1])) - 1;
7479 bihleafs[bihleafindex].
mins[2] =
min(rendervertex3f[3*e[0]+2],
min(rendervertex3f[3*e[1]+2], rendervertex3f[3*e[2]+2])) - 1;
7480 bihleafs[bihleafindex].
maxs[0] =
max(rendervertex3f[3*e[0]+0],
max(rendervertex3f[3*e[1]+0], rendervertex3f[3*e[2]+0])) + 1;
7481 bihleafs[bihleafindex].
maxs[1] =
max(rendervertex3f[3*e[0]+1],
max(rendervertex3f[3*e[1]+1], rendervertex3f[3*e[2]+1])) + 1;
7482 bihleafs[bihleafindex].
maxs[2] =
max(rendervertex3f[3*e[0]+2],
max(rendervertex3f[3*e[1]+2], rendervertex3f[3*e[2]+2])) + 1;
7487 if (!userendersurfaces)
7490 for (brushindex = 0, brush =
model->brush.data_brushes + brushindex+
model->firstmodelbrush;brushindex < nummodelbrushes;brushindex++, brush++)
7497 bihleafs[bihleafindex].
itemindex = brushindex+
model->firstmodelbrush;
7504 collisionelement3i =
model->brush.data_collisionelement3i;
7505 collisionvertex3f =
model->brush.data_collisionvertex3f;
7506 for (j =
model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
7508 surface =
model->data_surfaces + j;
7509 for (triangleindex = 0, e = collisionelement3i + 3*surface->
num_firstcollisiontriangle;triangleindex < surface->num_collisiontriangles;triangleindex++, e += 3)
7515 bihleafs[bihleafindex].
mins[0] =
min(collisionvertex3f[3*e[0]+0],
min(collisionvertex3f[3*e[1]+0], collisionvertex3f[3*e[2]+0])) - 1;
7516 bihleafs[bihleafindex].
mins[1] =
min(collisionvertex3f[3*e[0]+1],
min(collisionvertex3f[3*e[1]+1], collisionvertex3f[3*e[2]+1])) - 1;
7517 bihleafs[bihleafindex].
mins[2] =
min(collisionvertex3f[3*e[0]+2],
min(collisionvertex3f[3*e[1]+2], collisionvertex3f[3*e[2]+2])) - 1;
7518 bihleafs[bihleafindex].
maxs[0] =
max(collisionvertex3f[3*e[0]+0],
max(collisionvertex3f[3*e[1]+0], collisionvertex3f[3*e[2]+0])) + 1;
7519 bihleafs[bihleafindex].
maxs[1] =
max(collisionvertex3f[3*e[0]+1],
max(collisionvertex3f[3*e[1]+1], collisionvertex3f[3*e[2]+1])) + 1;
7520 bihleafs[bihleafindex].
maxs[2] =
max(collisionvertex3f[3*e[0]+2],
max(collisionvertex3f[3*e[1]+2], collisionvertex3f[3*e[2]+2])) + 1;
7527 bihmaxnodes = bihnumleafs + 1;
7530 temp_leafsortscratch = temp_leafsort + bihnumleafs;
7533 BIH_Build(out, bihnumleafs, bihleafs, bihmaxnodes, bihnodes, temp_leafsort, temp_leafsortscratch);
7550 int supercontents = 0;
7575 return supercontents;
7580 int nativecontents = 0;
7605 return nativecontents;
7617 if (
loadmodel->brush.num_leafs < numleafs)
7625 float corner[3], yawradius, modelradius;
7627 mod->modeldatatypestring =
"Q3BSP";
7630 mod->brush.ishlbsp =
false;
7631 mod->brush.isbsp2rmqe =
false;
7632 mod->brush.isbsp2 =
false;
7633 mod->brush.isq2bsp =
false;
7634 mod->brush.isq3bsp =
true;
7635 mod->brush.skymasking =
true;
7641 Host_Error(
"Mod_Q3BSP_Load: %s is smaller than its header",
mod->name);
7647 mod->soundfromcenter =
true;
7665 mod->brush.AmbientSoundLevelsForPoint =
NULL;
7666 mod->brush.RoundUpToHullSize =
NULL;
7677 mod_base = (
unsigned char *)header;
7683 for (i = 0;i < lumps;i++)
7686 if((
char *) bufferend < (
char *)
buffer + j)
7687 Host_Error(
"Mod_Q3BSP_Load: %s has a lump that starts outside the file!",
mod->name);
7689 if((
char *) bufferend < (
char *)
buffer + j)
7690 Host_Error(
"Mod_Q3BSP_Load: %s has a lump that ends outside the file!",
mod->name);
7705 mod->brush.qw_md4sum = 0;
7706 mod->brush.qw_md4sum2 = 0;
7707 for (i = 0;i < lumps;i++)
7751 loadmodel->brush.supportwateralpha =
true;
7761 for (i = 0;i <
loadmodel->brush.numsubmodels;i++)
7779 mod->brush.BoxTouchingPVS =
NULL;
7780 mod->brush.BoxTouchingLeafPVS =
NULL;
7781 mod->brush.BoxTouchingVisibleLeafs =
NULL;
7782 mod->brush.FindBoxClusters =
NULL;
7784 mod->brush.AmbientSoundLevelsForPoint =
NULL;
7786 mod->brush.submodel = i;
7791 mod->submodelsurfaces_start =
mod->brushq3.data_models[i].firstface;
7792 mod->submodelsurfaces_end =
mod->brushq3.data_models[i].firstface +
mod->brushq3.data_models[i].numfaces;
7793 mod->firstmodelbrush =
mod->brushq3.data_models[i].firstbrush;
7794 mod->nummodelbrushes =
mod->brushq3.data_models[i].numbrushes;
7804 for (j =
mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
7813 mod->normalmins[0] =
min(
mod->normalmins[0],
v[0]);
7814 mod->normalmins[1] =
min(
mod->normalmins[1],
v[1]);
7815 mod->normalmins[2] =
min(
mod->normalmins[2],
v[2]);
7816 mod->normalmaxs[0] =
max(
mod->normalmaxs[0],
v[0]);
7817 mod->normalmaxs[1] =
max(
mod->normalmaxs[1],
v[1]);
7818 mod->normalmaxs[2] =
max(
mod->normalmaxs[2],
v[2]);
7825 modelradius =
sqrt(corner[0]*corner[0]+corner[1]*corner[1]+corner[2]*corner[2]);
7826 yawradius =
sqrt(corner[0]*corner[0]+corner[1]*corner[1]);
7827 mod->rotatedmins[0] =
mod->rotatedmins[1] =
mod->rotatedmins[2] = -modelradius;
7828 mod->rotatedmaxs[0] =
mod->rotatedmaxs[1] =
mod->rotatedmaxs[2] = modelradius;
7829 mod->yawmaxs[0] =
mod->yawmaxs[1] = yawradius;
7830 mod->yawmins[0] =
mod->yawmins[1] = -yawradius;
7831 mod->yawmins[2] =
mod->normalmins[2];
7832 mod->yawmaxs[2] =
mod->normalmaxs[2];
7833 mod->radius = modelradius;
7834 mod->radius2 = modelradius * modelradius;
7873 Con_DPrintf(
"Stats for q3bsp model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n",
loadmodel->name,
loadmodel->num_surfaces,
loadmodel->brush.num_nodes,
loadmodel->brush.num_leafs,
mod->brush.num_pvsclusters,
loadmodel->brush.num_portals,
loadmodel->surfmesh.num_vertices,
loadmodel->surfmesh.num_triangles,
loadmodel->num_surfaces);
7884 Host_Error(
"Mod_IBSP_Load: unknown/unsupported version %i", i);
7901 int structsize = 12;
7911 for ( i=0 ; i<
count ; i++, out++)
7933 for ( i=0 ; i<
count ; i++, out++)
7938 if ((
int)out->
v[0] >=
loadmodel->brushq1.numvertexes || (
int)out->
v[1] >=
loadmodel->brushq1.numvertexes)
7940 Con_Printf(
"Mod_VBSP_LoadEdges: %s has invalid vertex indices in edge %i (vertices %i %i >= numvertices %i)\n",
loadmodel->name, i, out->
v[0], out->
v[1],
loadmodel->brushq1.numvertexes);
7942 Host_Error(
"Mod_VBSP_LoadEdges: %s has edges but no vertexes, cannot fix\n",
loadmodel->name);
7960 for (i = 0;i <
loadmodel->brushq1.numsurfedges;i++)
7973 int structsize = 20;
7980 for (i = 0;i <
loadmodel->brush.num_planes;i++, out++)
7994 int i, j, k,
count, miptex;
7995 int structsize = 72;
8005 for (i = 0;i <
count;i++, out++)
8007 for (k = 0;k < 2;k++)
8008 for (j = 0;j < 4;j++)
8011 for (k = 0;k < 2;k++)
8012 for (j = 0;j < 4;j++)
8032 if ((
unsigned int) miptex >= (
unsigned int)
loadmodel->num_textures)
8043 int i, j,
count, surfacenum, planenum, smax, tmax, ssize, tsize, firstedge, numedges, totalverts, totaltris, lightmapnumber, lightmapsize, totallightmapsamples, lightmapoffset, texinfoindex;
8044 float texmins[2], texmaxs[2], val;
8045 rtexture_t *lightmaptexture, *deluxemaptexture;
8047 int structsize = 56;
8062 for (surfacenum = 0;surfacenum <
count;surfacenum++)
8065 totalverts += numedges;
8066 totaltris += numedges - 2;
8071 lightmaptexture =
NULL;
8075 totallightmapsamples = 0;
8079 for (surfacenum = 0, surface =
loadmodel->data_surfaces;surfacenum <
count;surfacenum++, surface++)
8093 if ((
unsigned int) firstedge > (
unsigned int)
loadmodel->brushq1.numsurfedges || (
unsigned int) numedges > (
unsigned int)
loadmodel->brushq1.numsurfedges || (
unsigned int) firstedge + (
unsigned int) numedges > (
unsigned int)
loadmodel->brushq1.numsurfedges)
8094 Host_Error(
"Mod_VBSP_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)", firstedge, numedges,
loadmodel->brushq1.numsurfedges);
8095 if ((
unsigned int) texinfoindex >= (
unsigned int)
loadmodel->brushq1.numtexinfo)
8096 Host_Error(
"Mod_VBSP_LoadFaces: invalid texinfo index %i(model has %i texinfos)", texinfoindex,
loadmodel->brushq1.numtexinfo);
8097 if ((
unsigned int) planenum >= (
unsigned int)
loadmodel->brush.num_planes)
8098 Host_Error(
"Mod_VBSP_LoadFaces: invalid plane index %i (model has %i planes)", planenum,
loadmodel->brush.num_planes);
8105 lightmapoffset = -1;
8116 totalverts += numedges;
8117 totaltris += numedges - 2;
8122 int lindex =
loadmodel->brushq1.surfedges[firstedge + i];
8155 for (j = 0;j < 2;j++)
8158 texmins[j] =
min(texmins[j], val);
8159 texmaxs[j] =
max(texmaxs[j], val);
8162 for (i = 0;i < 2;i++)
8176 if (lightmapoffset == -1)
8195 if (ssize > 256 || tsize > 256)
8198 if (lightmapsize < ssize)
8199 lightmapsize = ssize;
8200 if (lightmapsize < tsize)
8201 lightmapsize = tsize;
8203 totallightmapsamples += ssize*tsize;
8210 loadmodel->brushq1.lightmapupdateflags[surfacenum] =
true;
8222 for (lightmapsize = 64; (lightmapsize < i) && (lightmapsize <
bound(128,
gl_max_lightmapsize.integer, (
int)
vid.maxtexturesize_2d)) && (totallightmapsamples > lightmapsize*lightmapsize); lightmapsize*=2)
8228 int stainmapsize = 0;
8232 for (surfacenum = 0, surface =
loadmodel->data_surfaces;surfacenum <
count;surfacenum++, surface++)
8234 int iu, iv, lightmapx = 0, lightmapy = 0;
8235 float u,
v, ubase, vbase, uscale, vscale;
8237 if (!
loadmodel->brushq1.lightmapupdateflags[surfacenum])
8244 stainmapsize += ssize * tsize * 3;
8252 loadmodel->brushq3.num_mergedlightmaps = lightmapnumber + 1;
8255 loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"lightmap%i", lightmapnumber), lightmapsize, lightmapsize,
NULL,
TEXTYPE_BGRA,
TEXF_FORCELINEAR |
TEXF_ALLOWUPDATES, -1,
NULL);
8257 loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture =
R_LoadTexture2D(
loadmodel->texturepool,
va(vabuf,
sizeof(vabuf),
"deluxemap%i", lightmapnumber), lightmapsize, lightmapsize,
NULL,
TEXTYPE_BGRA,
TEXF_FORCELINEAR |
TEXF_ALLOWUPDATES, -1,
NULL);
8267 uscale = 1.0f / (
float)lightmapsize;
8268 vscale = 1.0f / (
float)lightmapsize;
8269 ubase = lightmapx * uscale;
8270 vbase = lightmapy * vscale;
8288 unsigned char *stainsamples =
NULL;
8290 memset(stainsamples, 255, stainmapsize);
8292 for (surfacenum = 0, surface =
loadmodel->data_surfaces;surfacenum <
count;surfacenum++, surface++)
8294 if (!
loadmodel->brushq1.lightmapupdateflags[surfacenum])
8299 stainsamples += ssize * tsize * 3;
8306 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
8319 if(!testing || !testing->
integer)
8323 Host_Error(
"Mod_VBSP_Load: not yet fully implemented. Change the now-generated \"mod_bsp_vbsptest\" to 1 if you wish to test this");
8335 mod->modeldatatypestring =
"VBSP";
8351 mod->soundfromcenter =
true;
8369 mod->brush.AmbientSoundLevelsForPoint =
NULL;
8370 mod->brush.RoundUpToHullSize =
NULL;
8401 Host_Error(
"Mod_MAP_Load: not yet implemented");
8404typedef struct objvertex_s
8419 const char *textbase = (
char *)
buffer, *text = textbase;
8424 int i, j, l, numvertices, firstvertex, firsttriangle, elementindex, vertexindex, surfacevertices, surfacetriangles, surfaceelements, submodelindex = 0;
8425 int index1, index2, index3;
8429 int numtriangles = 0;
8430 int maxtriangles = 0;
8433 int maxtextures = 0, numtextures = 0, textureindex = 0;
8434 int maxv = 0, numv = 1;
8435 int maxvt = 0, numvt = 1;
8436 int maxvn = 0, numvn = 1;
8437 char *texturenames =
NULL;
8438 float dist, modelradius, modelyawradius, yawradius;
8439 float *obj_v =
NULL;
8440 float *obj_vt =
NULL;
8441 float *obj_vn =
NULL;
8446 int vertexhashindex;
8447 int *vertexhashtable =
NULL;
8450 int vertexhashsize = 0;
8451 int vertexhashcount = 0;
8454 int *submodelfirstsurface;
8458 memset(&vfirst, 0,
sizeof(vfirst));
8459 memset(&vprev, 0,
sizeof(vprev));
8460 memset(&vcurrent, 0,
sizeof(vcurrent));
8505 loadmodel->skinscenes[i].firstframe = i;
8506 loadmodel->skinscenes[i].framecount = 1;
8508 loadmodel->skinscenes[i].framerate = 10;
8520 static char emptyarg[1] =
"";
8525 for (linelen = 0;text[linelen] && text[linelen] !=
'\r' && text[linelen] !=
'\n';linelen++)
8526 line[linelen] = text[linelen];
8528 for (argc = 0;argc < 4;argc++)
8529 argv[argc] = emptyarg;
8532 while (*s ==
' ' || *s ==
'\t')
8542 while (*s ==
' ' || *s ==
'\t')
8552 if (
argv[0][0] ==
'#')
8554 if (!strcmp(
argv[0],
"v"))
8558 maxv =
max(maxv * 2, 1024);
8563 obj_v[numv*3+0] = atof(
argv[1]);
8564 obj_v[numv*3+2] = atof(
argv[2]);
8565 obj_v[numv*3+1] = atof(
argv[3]);
8569 obj_v[numv*3+0] = atof(
argv[1]);
8570 obj_v[numv*3+1] = atof(
argv[2]);
8571 obj_v[numv*3+2] = atof(
argv[3]);
8575 else if (!strcmp(
argv[0],
"vt"))
8579 maxvt =
max(maxvt * 2, 1024);
8582 obj_vt[numvt*2+0] = atof(
argv[1]);
8583 obj_vt[numvt*2+1] = 1-atof(
argv[2]);
8586 else if (!strcmp(
argv[0],
"vn"))
8590 maxvn =
max(maxvn * 2, 1024);
8595 obj_vn[numvn*3+0] = atof(
argv[1]);
8596 obj_vn[numvn*3+2] = atof(
argv[2]);
8597 obj_vn[numvn*3+1] = atof(
argv[3]);
8601 obj_vn[numvn*3+0] = atof(
argv[1]);
8602 obj_vn[numvn*3+1] = atof(
argv[2]);
8603 obj_vn[numvn*3+2] = atof(
argv[3]);
8607 else if (!strcmp(
argv[0],
"f"))
8611 if (maxtextures <= numtextures)
8613 maxtextures =
max(maxtextures * 2, 256);
8616 textureindex = numtextures++;
8619 for (j = 1;j < argc;j++)
8621 index1 = atoi(
argv[j]);
8622 while(
argv[j][0] &&
argv[j][0] !=
'/')
8626 index2 = atoi(
argv[j]);
8627 while(
argv[j][0] &&
argv[j][0] !=
'/')
8631 index3 = atoi(
argv[j]);
8636 index1 = numv - index1;
8638 index2 = numvt - index2;
8640 index3 = numvn - index3;
8644 if (obj_v && index1 >= 0 && index1 < numv)
8646 if (obj_vt && index2 >= 0 && index2 < numvt)
8648 if (obj_vn && index3 >= 0 && index3 < numvn)
8650 if (numtriangles == 0)
8668 if (maxtriangles <= numtriangles)
8670 maxtriangles =
max(maxtriangles * 2, 32768);
8675 vertices[numtriangles*3+0] = vfirst;
8676 vertices[numtriangles*3+1] = vprev;
8677 vertices[numtriangles*3+2] = vcurrent;
8681 vertices[numtriangles*3+0] = vfirst;
8682 vertices[numtriangles*3+2] = vprev;
8683 vertices[numtriangles*3+1] = vcurrent;
8690 else if (!strcmp(
argv[0],
"o") || !strcmp(
argv[0],
"g"))
8692 submodelindex = atof(
argv[1]);
8695 else if (!strcmp(
argv[0],
"usemtl"))
8697 for (i = 0;i < numtextures;i++)
8700 if (i < numtextures)
8704 if (maxtextures <= numtextures)
8706 maxtextures =
max(maxtextures * 2, 256);
8709 textureindex = numtextures++;
8722 modelyawradius = dist*dist+modelyawradius*modelyawradius;
8724 modelradius = modelyawradius + modelradius * modelradius;
8725 modelyawradius =
sqrt(modelyawradius);
8726 modelradius =
sqrt(modelradius);
8734 loadmodel->radius2 = modelradius * modelradius;
8739 vertexhashsize = numtriangles*2;
8740 vertexhashtable = (
int *)
Mem_Alloc(
loadmodel->mempool,
sizeof(
int) * vertexhashsize);
8741 memset(vertexhashtable, 0xFF,
sizeof(
int) * vertexhashsize);
8743 vertexhashcount = 0;
8753 tempsurface = tempsurfaces;
8754 for (submodelindex = 0;submodelindex <
loadmodel->brush.numsubmodels;submodelindex++)
8756 submodelfirstsurface[submodelindex] =
loadmodel->num_surfaces;
8757 for (textureindex = 0;textureindex < numtextures;textureindex++)
8759 for (vertexindex = 0;vertexindex < numtriangles*3;vertexindex++)
8761 thisvertex = vertices + vertexindex;
8766 if (vertexindex == numtriangles*3)
8769 surfacevertices = 0;
8770 surfaceelements = 0;
8776 for (;vertexindex < numtriangles*3;vertexindex++)
8778 thisvertex = vertices + vertexindex;
8784 tempsurface->
mins[0] =
min(tempsurface->
mins[0], thisvertex->
v[0]);
8785 tempsurface->
mins[1] =
min(tempsurface->
mins[1], thisvertex->
v[1]);
8786 tempsurface->
mins[2] =
min(tempsurface->
mins[2], thisvertex->
v[2]);
8787 tempsurface->
maxs[0] =
max(tempsurface->
maxs[0], thisvertex->
v[0]);
8788 tempsurface->
maxs[1] =
max(tempsurface->
maxs[1], thisvertex->
v[1]);
8789 tempsurface->
maxs[2] =
max(tempsurface->
maxs[2], thisvertex->
v[2]);
8792 vertexhashindex = (
unsigned int)(thisvertex->
v[0] * 3571 + thisvertex->
v[0] * 1777 + thisvertex->
v[0] * 457) % (
unsigned int)vertexhashsize;
8793 for (i = vertexhashtable[vertexhashindex];i >= 0;i = vertexhashdata[i].
nextindex)
8795 vdata = vertexhashdata + i;
8801 i = vertexhashcount++;
8802 vdata = vertexhashdata + i;
8803 *vdata = *thisvertex;
8804 vdata->
nextindex = vertexhashtable[vertexhashindex];
8805 vertexhashtable[vertexhashindex] = i;
8808 loadmodel->surfmesh.data_element3i[elementindex++] = i;
8811 surfacetriangles = surfaceelements / 3;
8822 submodelfirstsurface[submodelindex] =
loadmodel->num_surfaces;
8823 numvertices = firstvertex;
8825 tempsurfaces =
NULL;
8829 loadmodel->num_texturesperskin = numtextures;
8834 loadmodel->surfmesh.num_vertices = numvertices;
8835 loadmodel->surfmesh.num_triangles = numtriangles;
8836 loadmodel->surfmesh.data_vertex3f = (
float *)
data;
data += numvertices *
sizeof(
float[3]);
8837 loadmodel->surfmesh.data_svector3f = (
float *)
data;
data += numvertices *
sizeof(
float[3]);
8838 loadmodel->surfmesh.data_tvector3f = (
float *)
data;
data += numvertices *
sizeof(
float[3]);
8839 loadmodel->surfmesh.data_normal3f = (
float *)
data;
data += numvertices *
sizeof(
float[3]);
8840 loadmodel->surfmesh.data_texcoordtexture2f = (
float *)
data;
data += numvertices *
sizeof(
float[2]);
8842 if (
loadmodel->surfmesh.num_vertices <= 65536) {
8843 loadmodel->surfmesh.data_element3s = (
unsigned short *)
data;
data +=
loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3]);
8846 for (j = 0;j <
loadmodel->surfmesh.num_vertices;j++)
8854 for (textureindex = 0;textureindex < numtextures;textureindex++)
8859 for (i = 0;i <
loadmodel->num_surfaces;i++)
8873 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
8889 loadmodel->brush.num_pvsclusterbytes = 1;
8896 loadmodel->brush.data_leafs->combinedsupercontents = 0;
8897 loadmodel->brush.data_leafs->clusterindex = 0;
8898 loadmodel->brush.data_leafs->areaindex = 0;
8901 loadmodel->brush.data_leafs->numleafbrushes = 0;
8903 loadmodel->brush.supportwateralpha =
true;
8909 for (i = 0;i <
loadmodel->brush.numsubmodels;i++)
8927 mod->brush.BoxTouchingPVS =
NULL;
8928 mod->brush.BoxTouchingLeafPVS =
NULL;
8929 mod->brush.BoxTouchingVisibleLeafs =
NULL;
8930 mod->brush.FindBoxClusters =
NULL;
8932 mod->brush.AmbientSoundLevelsForPoint =
NULL;
8934 mod->brush.submodel = i;
8939 mod->submodelsurfaces_start = submodelfirstsurface[i];
8940 mod->submodelsurfaces_end = submodelfirstsurface[i+1];
8941 mod->firstmodelbrush = 0;
8942 mod->nummodelbrushes = 0;
8947 for (j =
mod->submodelsurfaces_start;j < mod->submodelsurfaces_end;j++)
8962 mod->normalmins[0] =
min(
mod->normalmins[0], v3f[0]);
8963 mod->normalmins[1] =
min(
mod->normalmins[1], v3f[1]);
8964 mod->normalmins[2] =
min(
mod->normalmins[2], v3f[2]);
8965 mod->normalmaxs[0] =
max(
mod->normalmaxs[0], v3f[0]);
8966 mod->normalmaxs[1] =
max(
mod->normalmaxs[1], v3f[1]);
8967 mod->normalmaxs[2] =
max(
mod->normalmaxs[2], v3f[2]);
8973 modelradius =
sqrt(corner[0]*corner[0]+corner[1]*corner[1]+corner[2]*corner[2]);
8974 yawradius =
sqrt(corner[0]*corner[0]+corner[1]*corner[1]);
8975 mod->rotatedmins[0] =
mod->rotatedmins[1] =
mod->rotatedmins[2] = -modelradius;
8976 mod->rotatedmaxs[0] =
mod->rotatedmaxs[1] =
mod->rotatedmaxs[2] = modelradius;
8977 mod->yawmaxs[0] =
mod->yawmaxs[1] = yawradius;
8978 mod->yawmins[0] =
mod->yawmins[1] = -yawradius;
8979 mod->yawmins[2] =
mod->normalmins[2];
8980 mod->yawmaxs[2] =
mod->normalmaxs[2];
8981 mod->radius = modelradius;
8982 mod->radius2 = modelradius * modelradius;
8987 mod->render_bih =
mod->collision_bih;
8999 Con_DPrintf(
"Stats for obj model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n",
loadmodel->name,
loadmodel->num_surfaces,
loadmodel->brush.num_nodes,
loadmodel->brush.num_leafs,
mod->brush.num_pvsclusters,
loadmodel->brush.num_portals,
loadmodel->surfmesh.num_vertices,
loadmodel->surfmesh.num_triangles,
loadmodel->num_surfaces);
int BIH_Build(bih_t *bih, int numleafs, bih_leaf_t *leafs, int maxnodes, bih_node_t *nodes, int *temp_leafsort, int *temp_leafsortscratch)
#define BIH_MAXUNORDEREDCHILDREN
#define CONTENTSQ2_MONSTERCLIP
#define SUPERCONTENTS_SKY
#define CONTENTSQ3_MONSTERCLIP
#define SUPERCONTENTS_BODY
#define SUPERCONTENTS_OPAQUE
#define SUPERCONTENTS_LAVA
#define SUPERCONTENTS_DONOTENTER
#define SUPERCONTENTS_MONSTERCLIP
#define CONTENTSQ3_BOTCLIP
#define CONTENTSQ2_DEADMONSTER
#define SUPERCONTENTS_BOTCLIP
#define CONTENTSQ3_TRANSLUCENT
#define CONTENTSQ2_MONSTER
#define SUPERCONTENTS_SLIME
#define CONTENTSQ2_TRANSLUCENT
#define SUPERCONTENTS_SOLID
#define SUPERCONTENTS_LIQUIDSMASK
#define SUPERCONTENTS_VISBLOCKERMASK
#define SUPERCONTENTS_CORPSE
#define CONTENTSQ3_DONOTENTER
#define LUMP_MARKSURFACES
#define CONTENTSQ3_NODROP
#define CONTENTSQ2_PLAYERCLIP
#define SUPERCONTENTS_PLAYERCLIP
#define CONTENTSQ3_PLAYERCLIP
#define CONTENTSQ3_CORPSE
#define SUPERCONTENTS_NODROP
#define SUPERCONTENTS_WATER
void CL_KeepaliveMessage(qbool readmessages)
#define CF_SERVER
cvar/command that only the server can change/execute
#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
void Collision_TraceLineTriangleFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, const float *point0, const float *point1, const float *point2, int supercontents, int q3surfaceflags, const texture_t *texture)
cvar_t collision_bih_fullrecursion
colbrushf_t * Collision_NewBrushFromPlanes(mempool_t *mempool, int numoriginalplanes, const colplanef_t *originalplanes, int supercontents, int q3surfaceflags, const texture_t *texture, int hasaabbplanes)
void Collision_TracePointBrushFloat(trace_t *trace, const vec3_t linestart, const colbrushf_t *other_start)
void Collision_TraceBrushTriangleFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, const float *v0, const float *v1, const float *v2, int supercontents, int q3surfaceflags, const texture_t *texture)
void Collision_BrushForBox(colboxbrushf_t *boxbrush, const vec3_t mins, const vec3_t maxs, int supercontents, int q3surfaceflags, const texture_t *texture)
void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *trace_start, const colbrushf_t *trace_end, const colbrushf_t *other_start, const colbrushf_t *other_end)
void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, const colbrushf_t *other_start, const colbrushf_t *other_end)
cvar_t collision_impactnudge
unsigned short CRC_Block(const unsigned char *data, size_t size)
@ GAME_TENEBRAE
full of evil hackery
float MSG_ReadLittleFloat(sizebuf_t *sb)
size_t MSG_ReadBytes(sizebuf_t *sb, size_t numbytes, unsigned char *out)
short BuffLittleShort(const unsigned char *buffer)
Extract a little endian 16bit short from the given buffer.
void MSG_InitReadBuffer(sizebuf_t *buf, unsigned char *data, int size)
int BuffLittleLong(const unsigned char *buffer)
Extract a little endian 32bit int from the given buffer.
int MSG_ReadLittleLong(sizebuf_t *sb)
int MSG_ReadLittleShort(sizebuf_t *sb)
char com_token[MAX_INPUTLINE]
char * va(char *buf, size_t buflen, const char *format,...)
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 ...
unsigned Com_BlockChecksum(void *buffer, int length)
#define dp_strlcat(dst, src, dsize)
#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.
float mod(float dividend, float divisor)
void Q3PatchTriangleElements(int *elements, int width, int height, int firstvertex)
void Q3PatchTesselateFloat(int numcomponents, int outputstride, float *outputvertices, int patchwidth, int patchheight, int inputstride, float *patchvertices, int tesselationwidth, int tesselationheight)
int Q3PatchTesselationOnY(int patchwidth, int patchheight, int components, const float *in, float tolerance)
int Q3PatchAdjustTesselation(int numcomponents, patchinfo_t *patch1, float *patchvertices1, patchinfo_t *patch2, float *patchvertices2)
int Q3PatchTesselationOnX(int patchwidth, int patchheight, int components, const float *in, float tolerance)
int Q3PatchDimForTess(int size, int tess)
#define PATCH_LOD_COLLISION
void Cvar_SetQuick(cvar_t *var, const char *value)
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
cvar_t * Cvar_Get(cvar_state_t *cvars, const char *name, const char *value, unsigned flags, const char *newdescription)
allocates a cvar by name and returns its address, or merely sets its value if it already exists.
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
static int(ZEXPORT *qz_inflate)(z_stream *strm
void FS_StripExtension(const char *in, char *out, size_t size_out)
skinframe_t * R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
cvar_t r_smoothnormals_areaweighting
skinframe_t * R_SkinFrame_LoadExternal(const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
skinframe_t * R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qbool sRGB)
rtexture_t * r_texture_blanknormalmap
skinframe_t * R_SkinFrame_LoadMissing(void)
void R_Mod_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist)
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_DrawDepth(entity_render_t *ent)
void R_Mod_DrawPrepass(entity_render_t *ent)
cvar_t gl_texturecompression_q3bsplightmaps
int R_TextureHeight(rtexture_t *rt)
int R_TextureWidth(rtexture_t *rt)
rtexturepool_t * R_AllocTexturePool(void)
rtexture_t * R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
cvar_t gl_texturecompression_q3bspdeluxemaps
cvar_t gl_max_lightmapsize
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
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
GLenum GLenum GLsizei count
GLint GLenum GLint GLint y
GLsizeiptr const GLvoid * data
GLuint GLuint GLintptr offset
GLint GLenum GLenum GLvoid * pixels
void Host_Error(const char *error,...)
qbool LoadWAL_GetMetadata(const unsigned char *f, int filesize, int *retwidth, int *retheight, int *retflags, int *retvalue, int *retcontents, char *retanimname32c)
void Image_MakesRGBColorsFromLinear_Lightmap(unsigned char *pout, const unsigned char *pin, int numpixels)
unsigned char * loadimagepixelsbgra(const char *filename, qbool complain, qbool allowFixtrans, qbool convertsRGB, int *miplevel)
#define Image_LinearFloatFromsRGB(c)
#define Image_sRGBFloatFromLinear_Lightmap(c)
void BoxFromPoints(vec3_t mins, vec3_t maxs, int numpoints, vec_t *point3f)
unsigned int CeilPowerOf2(unsigned int value)
returns the smallest integer greater than or equal to "value", or 0 if "value" is too big
void PlaneClassify(mplane_t *p)
int BoxOnPlaneSide(const vec3_t emins, const vec3_t emaxs, const mplane_t *p)
#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 VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, out)
#define Vector4Set(vec, r, g, b, a)
#define VectorSet(vec, x, y, z)
#define VectorSubtract(a, b, out)
#define CrossProduct(a, b, out)
#define VectorCompare(a, b)
#define Vector2Compare(a, b)
#define TriangleNormal(a, b, c, n)
#define PlaneDiff(point, plane)
#define VectorCopy(in, out)
#define VectorScale(in, scale, out)
#define VectorAdd(a, b, out)
#define VectorMA(a, scale, b, out)
#define VectorNormalizeDouble(v)
#define VectorM(scale1, b1, out)
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
void Matrix4x4_CreateScale3(matrix4x4_t *out, double x, double y, double z)
void Matrix4x4_ConcatTranslate(matrix4x4_t *out, double x, double y, double z)
void Matrix4x4_FromArrayDoubleD3D(matrix4x4_t *out, const double in[4][4])
void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, const char *meshname, const char *shadername)
#define HULLCHECKSTATE_SOLID
static int Mod_Q1BSP_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
static void Mod_Q3BSP_LoadLeafs(lump_t *l)
#define HULLCHECKSTATE_EMPTY
static void Mod_Q1BSP_LoadVertexes(sizebuf_t *sb)
static void Mod_BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
static void Mod_Q3BSP_LoadPlanes(lump_t *l)
static void Mod_Q3BSP_RecursiveFindNumLeafs(mnode_t *node)
static void Mod_Q3BSP_LoadLightGrid(lump_t *l)
static int Mod_Q1BSP_RecursiveHullCheckPoint(RecursiveHullCheckTraceInfo_t *t, int num)
#define HULLCHECKSTATE_DONE
static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
static memexpandablearray_t portalarray
cvar_t mod_q3bsp_curves_subdivisions_maxtess
static texture_t mod_q1bsp_texture_sky
static void Mod_VBSP_LoadEdges(sizebuf_t *sb)
static int Mod_Q3BSP_SuperContentsFromNativeContents(int nativecontents)
static void Mod_Q3BSP_LoadTextures(lump_t *l)
cvar_t mod_q3bsp_curves_subdivisions_maxvertices
static qbool Mod_Q3BSP_TraceLineOfSight(struct model_s *model, const vec3_t start, const vec3_t end, const vec3_t acceptmins, const vec3_t acceptmaxs)
cvar_t mod_q3shader_force_addalpha
static void Mod_Q1BSP_LoadTextures(sizebuf_t *sb)
int Mod_Q1BSP_SuperContentsFromNativeContents(int nativecontents)
static void Mod_Q2BSP_LoadTexinfo(sizebuf_t *sb)
static void Mod_Q2BSP_LoadAreas(sizebuf_t *sb)
int Mod_CollisionBIH_PointSuperContents_Mesh(struct model_s *model, int frame, const vec3_t start)
void Mod_CollisionBIH_TracePoint_Mesh(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
void Mod_CollisionBIH_TraceBox(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static void Mod_Q3BSP_LoadEntities(lump_t *l)
static void Mod_Q1BSP_LoadLeafs(sizebuf_t *sb)
static void Mod_BSP_DecompressVis(const unsigned char *in, const unsigned char *inend, unsigned char *out, unsigned char *outend)
static void Mod_Q3BSP_LoadLeafBrushes(lump_t *l)
void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q3BSP_LoadBrushes(lump_t *l)
static void Mod_Q3BSP_LoadModels(lump_t *l)
static const texture_t * Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(RecursiveHullCheckTraceInfo_t *t, const model_t *model, const mnode_t *node, double mid[3])
static texture_t mod_q1bsp_texture_solid
static unsigned char * Mod_BSP_GetPVS(model_t *model, const vec3_t p)
static void Mod_Q2BSP_LoadLeafBrushes(sizebuf_t *sb)
static void Mod_Q1BSP_LoadClipnodes(sizebuf_t *sb, hullinfo_t *hullinfo)
static void Mod_Q3BSP_LoadBrushSides_IG(lump_t *l)
cvar_t mod_q2bsp_littransparentsurfaces
static void Mod_Q3BSP_LoadTriangles(lump_t *l)
cvar_t mod_q3bsp_lightgrid_world_surfaces
static void Mod_Q2BSP_LoadLighting(sizebuf_t *sb)
static void Mod_Q1BSP_LoadPlanes(sizebuf_t *sb)
static void Mod_BSP_FindNonSolidLocation_r_Triangle(findnonsolidlocationinfo_t *info, msurface_t *surface, int k)
static void Mod_Q2BSP_LoadLeafs(sizebuf_t *sb)
static int portalpointsbufferoffset
static void Mod_Q2BSP_LoadPOP(sizebuf_t *sb)
int Mod_Q1BSP_NativeContentsFromSuperContents(int supercontents)
static void Mod_CollisionBIH_TraceLineShared(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, const bih_t *bih)
static int Mod_Q3BSP_NativeContentsFromSuperContents(int supercontents)
cvar_t mod_q3shader_default_polygonfactor
static void Mod_BSP_FinalizePortals(void)
void Mod_HLBSP_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q3BSP_LoadEffects(lump_t *l)
static void Mod_Q3BSP_LoadBrushSides(lump_t *l)
static qbool Mod_Q1BSP_CheckWaterAlphaSupport(void)
static void Mod_Q2BSP_LoadVisibility(sizebuf_t *sb)
cvar_t mod_q3bsp_lightmapmergepower
qbool Mod_CollisionBIH_TraceLineOfSight(struct model_s *model, const vec3_t start, const vec3_t end, const vec3_t acceptmins, const vec3_t acceptmaxs)
static void Mod_Q1BSP_LoadTexinfo(sizebuf_t *sb)
static int Mod_BSP_BoxTouchingLeafPVS(model_t *model, const unsigned char *pvs, const vec3_t mins, const vec3_t maxs)
cvar_t mod_noshader_default_offsetmapping
static void Mod_BSP_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, mnode_t *node)
void Mod_IBSP_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q1BSP_LoadLighting(sizebuf_t *sb)
void Mod_CollisionBIH_TraceLineAgainstSurfaces(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
int Mod_Q2BSP_SuperContentsFromNativeContents(int nativecontents)
cvar_t mod_q3bsp_curves_subdivisions_mintess
static void Mod_Q3BSP_LoadVertices(lump_t *l)
static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static size_t Mod_BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, unsigned char **pvsbuffer, mempool_t *pool, qbool merge)
static void Mod_VBSP_LoadPlanes(sizebuf_t *sb)
cvar_t mod_q3bsp_nolightmaps
static void Mod_Q1BSP_LoadEntities(sizebuf_t *sb)
static texture_t mod_q1bsp_texture_lava
void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
cvar_t mod_q3bsp_lightgrid_texture
#define PORTAL_DIST_EPSILON
static void Mod_Q2BSP_FindSubmodelBrushRange_r(model_t *mod, mnode_t *node, int *first, int *last)
static void Mod_BSP_LoadNodes_RecursiveSetParent(mnode_t *node, mnode_t *parent)
cvar_t mod_q3bsp_curves_subdivisions_tolerance
cvar_t mod_q3shader_default_offsetmapping_scale
static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs)
static void Mod_Q3BSP_LoadLeafFaces(lump_t *l)
static void Mod_BSP_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *info, mleaf_t *leaf)
static void Mod_Q3BSP_LoadFaces(lump_t *l)
cvar_t mod_recalculatenodeboxes
static void Mod_Q3BSP_LoadNodes(lump_t *l)
static int Mod_Q1BSP_RecursiveHullCheck(RecursiveHullCheckTraceInfo_t *t, int num, double p1f, double p2f, double p1[3], double p2[3])
static void Mod_VBSP_LoadEntities(sizebuf_t *sb)
static int Mod_BSP_FindBoxClusters(model_t *model, const vec3_t mins, const vec3_t maxs, int maxclusters, int *clusterlist)
cvar_t mod_q3bsp_sRGBlightmaps
static void Mod_Q1BSP_TraceLine(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static void Mod_VBSP_LoadVertexes(sizebuf_t *sb)
static void Mod_Q1BSP_LoadFaces(sizebuf_t *sb)
static void Mod_Q1BSP_TracePoint(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static void Mod_Q2BSP_LoadBrushSides(sizebuf_t *sb)
void Mod_CollisionBIH_TracePoint(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
cvar_t mod_q3bsp_tracelineofsight_brushes
static void Mod_BSP_FindNonSolidLocation(model_t *model, const vec3_t in, vec3_t out, float radius)
static void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q1BSP_AssignNoShadowSkySurfaces(model_t *mod)
static texture_t mod_q1bsp_texture_slime
cvar_t mod_q3shader_default_polygonoffset
static void Mod_VBSP_LoadSurfedges(sizebuf_t *sb)
static int portalpointsbuffersize
cvar_t mod_q3shader_default_offsetmapping_bias
static void Mod_Q2BSP_LoadNodes(sizebuf_t *sb)
static int Mod_BSP_BoxTouchingPVS(model_t *model, const unsigned char *pvs, const vec3_t mins, const vec3_t maxs)
static int Mod_BSP_LightPoint_RecursiveBSPNode(model_t *model, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const mnode_t *node, float x, float y, float startz, float endz)
static void Mod_Q3BSP_LoadPVS(lump_t *l)
static double * portalpointsbuffer
void Mod_2PSB_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q1BSP_LoadSurfedges(sizebuf_t *sb)
static void Mod_BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t radius, unsigned char *pvsbuffer, int pvsbytes, mnode_t *node)
static void Mod_Q1BSP_ParseWadsFromEntityLump(const char *data)
cvar_t mod_q3bsp_lightgrid_bsp_surfaces
cvar_t mod_q3shader_default_offsetmapping
static void Mod_Q3BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
void Mod_CollisionBIH_TraceLine(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static void Mod_Q1BSP_LoadLeaffaces(sizebuf_t *sb)
int Mod_CollisionBIH_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
static mleaf_t * Mod_BSP_PointInLeaf(model_t *model, const vec3_t p)
static int Mod_Q3BSP_TraceLineOfSight_RecursiveNodeCheck(mnode_t *node, double p1[3], double p2[3], double endpos[3])
static unsigned char nobsp_pvs[1]
static void AddPortalToNodes(portal_t *p, mnode_t *front, mnode_t *back)
void Mod_VBSP_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_Q1BSP_LoadEdges(sizebuf_t *sb)
cvar_t mod_q3bsp_curves_collisions
static void Mod_Q1BSP_LoadNodes(sizebuf_t *sb)
int Mod_Q2BSP_NativeContentsFromSuperContents(int supercontents)
static void RemovePortalFromNodes(portal_t *portal)
bih_t * Mod_MakeCollisionBIH(model_t *model, qbool userendersurfaces, bih_t *out)
static void Mod_Q1BSP_AmbientSoundLevelsForPoint(model_t *model, const vec3_t p, unsigned char *out, int outsize)
static int Mod_BSP_BoxTouchingVisibleLeafs(model_t *model, const unsigned char *visibleleafs, const vec3_t mins, const vec3_t maxs)
void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_q1bsp_zero_hullsize_cutoff
static void Mod_BSP_RecursiveRecalcNodeBBox(mnode_t *node)
cvar_t mod_q3bsp_optimizedtraceline
static void Mod_Q1BSP_MakeHull0(void)
static void Mod_Q1BSP_LoadVisibility(sizebuf_t *sb)
void Mod_BSP2_Load(model_t *mod, void *buffer, void *bufferend)
static qbool Mod_Q1BSP_TraceLineOfSight(struct model_s *model, const vec3_t start, const vec3_t end, const vec3_t acceptmins, const vec3_t acceptmaxs)
static void Mod_Q2BSP_LoadBrushes(sizebuf_t *sb)
static void Mod_Q1BSP_LoadSplitSky(unsigned char *src, int width, int height, int bytesperpixel)
static int Mod_Q1BSP_TraceLineAgainstSurfacesRecursiveBSPNode(RecursiveHullCheckTraceInfo_t *t, const model_t *model, const mnode_t *node, const double p1[3], const double p2[3])
static void Mod_VBSP_LoadTexinfo(sizebuf_t *sb)
static void Mod_BSP_RecursiveNodePortals(mnode_t *node)
#define PATCHTESS_SAME_LODGROUP(a, b)
cvar_t r_subdivisions_mintess
cvar_t mod_q1bsp_polygoncollisions
static void Mod_Q1BSP_LoadMapBrushes(void)
static texture_t mod_q1bsp_texture_water
cvar_t r_subdivisions_tolerance
static void Mod_Q2BSP_LoadAreaPortals(sizebuf_t *sb)
cvar_t mod_q1bsp_traceoutofsolid
cvar_t mod_q3shader_force_terrain_alphaflag
void Mod_MAP_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t r_subdivisions_maxvertices
void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
static void Mod_BSP_MakePortals(void)
static void Mod_VBSP_LoadFaces(sizebuf_t *sb)
cvar_t r_subdivisions_maxtess
static void Mod_BSP_LoadSubmodels(sizebuf_t *sb, hullinfo_t *hullinfo)
cvar_t mod_obj_orientation
cvar_t mod_q3shader_default_refractive_index
static void Mod_VBSP_LoadTextures(sizebuf_t *sb)
void Mod_CollisionBIH_TraceBrush(model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *thisbrush_start, colbrushf_t *thisbrush_end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static void Mod_Q1BSP_TraceBox(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
#define MATERIALFLAG_FULLBRIGHT
#define MATERIALFLAG_ALPHA
#define MATERIALFLAG_NODRAW
#define MATERIALFLAG_ALPHATEST
#define MATERIALFLAG_BLENDED
#define MATERIALFLAG_WATERALPHA
#define CHECKPVSBIT(pvs, b)
#define MATERIALFLAG_WATERSHADER
#define MATERIALFLAGMASK_TRANSLUCENT
#define MATERIALFLAG_WALL
#define MATERIALFLAG_NOSHADOW
#define MATERIALFLAG_MESHCOLLISIONS
#define MATERIALFLAG_REFLECTION
#define MATERIALFLAG_LIGHTBOTHSIDES
#define MATERIALFLAG_WATERSCROLL
#define Q2LUMP_LEAFBRUSHES
#define Q2LUMP_BRUSHSIDES
#define Q2LUMP_VISIBILITY
#define Q2CONTENTS_TRANSLUCENT
#define Q2CONTENTS_DETAIL
#define Q2LUMP_AREAPORTALS
#define Q2CONTENTS_MONSTERCLIP
#define Q2CONTENTS_WINDOW
#define Q2CONTENTS_PLAYERCLIP
#define Q3LUMP_BRUSHSIDES
#define Q3SURFACEFLAG_SKY
#define Q3SURFACEFLAG_NOMARKS
#define Q3HEADER_LUMPS_LIVE
#define Q3SURFACEFLAG_NOIMPACT
#define Q3BSPVERSION_LIVE
#define Q3SURFACEFLAG_NOLIGHTMAP
#define Q3SURFACEFLAG_NODLIGHT
#define Q3LUMP_LEAFBRUSHES
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_AllocLightmap_Reset(mod_alloclightmap_state_t *state)
void Mod_AllocLightmap_Init(mod_alloclightmap_state_t *state, mempool_t *mempool, int width, int height)
skinfile_t * Mod_LoadSkinFiles(void)
void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qbool areaweighting)
texture_shaderpass_t * Mod_CreateShaderPass(mempool_t *mempool, skinframe_t *skinframe)
void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qbool lightmapoffsets, qbool vertexcolors)
qbool Mod_AllocLightmap_Block(mod_alloclightmap_state_t *state, int blockwidth, int blockheight, int *outx, int *outy)
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)
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_FreeSkinFiles(skinfile_t *skinfile)
void Mod_MakeSortedSurfaces(model_t *mod)
qbool Mod_ValidateElements(int *element3i, unsigned short *element3s, int numtriangles, int firstvertex, int numvertices, const char *filename, int fileline)
void Mod_SetDrawSkyAndWater(model_t *mod)
Sets the mod->DrawSky and mod->DrawAddWaterPlanes pointers conditionally based on whether surfaces in...
#define HL2LUMP_SURFEDGES
unsigned char palette_rgb[256][3]
unsigned int palette_bgra_complete[256]
void PolygonD_QuadForPlane(double *outpoints, double planenormalx, double planenormaly, double planenormalz, double planedist, double quadsize)
void PolygonD_Divide(int innumpoints, const double *inpoints, double planenormalx, double planenormaly, double planenormalz, double planedist, double epsilon, int outfrontmaxpoints, double *outfrontpoints, int *neededfrontpoints, int outbackmaxpoints, double *outbackpoints, int *neededbackpoints, int *oncountpointer)
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
#define MAX_QPATH
max length of a quake game pathname
@ TRANSPARENTSORT_DISTANCE
#define TEXF_ALLOWUPDATES
cvar_t sv_gameplayfix_q1bsptracelinereportstexture
int children[BIH_MAXUNORDEREDCHILDREN]
const struct texture_s * texture
float hullsizes[MAX_MAP_HULLS][2][3]
unsigned char ambient_sound_level[NUM_AMBIENTS]
int containscollisionsurfaces
struct mportal_s * portals
int combinedsupercontents
int headnode[MAX_MAP_HULLS]
int combinedsupercontents
struct mportal_s * portals
struct mnode_s * children[2]
unsigned int firstsurface
hull_t hulls[MAX_MAP_HULLS]
msurface_t * data_surfaces
unsigned char * stainsamples
unsigned char styles[MAXLIGHTMAPS]
unsigned char * nmapsamples
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
int num_collisiontriangles
msurface_lightmapinfo_t * lightmapinfo
lightmaptexture rebuild information not used in q3bsp
int num_triangles
range of triangles and vertices in model->surfmesh
int num_firstcollisiontriangle
mesh information for collisions (only used by q3bsp curves)
texture_t * texture
the texture to use on the surface
vec3_t mins
bounding box for onscreen checks
struct q3deffect_s * effect
fog volume info in q3bsp
int num_collisionvertices
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
struct patchinfo_t::@365377244355024320263367246016345364004032125114 lods[PATCH_LODS_NUM]
double points[3 *MAX_PORTALPOINTS]
struct portal_s * next[2]
char shadername[Q3PATHLENGTH]
struct q3dface_t::@102227026313010303173342365044233312062100334277::@016005341134005011122101042370201136240313001330 patch
union q3dface_t::@102227026313010303173342365044233312062100334277 specific
unsigned char diffusergb[3]
unsigned char ambientrgb[3]
unsigned char diffusepitch
unsigned char color4ub[4]
struct colbrushf_s * colbrushf
struct q3mbrushside_s * firstbrushside
struct texture_s * texture
struct texture_s * texture
float parms[Q3TCMOD_MAXPARMS]
q3shaderinfo_layer_tcmod_t tcmods[Q3MAXTCMODS]
struct skinframe_s * skinframes[TEXTURE_MAXFRAMES]
texture_shaderpass_t * shaderpasses[Q3SHADER_MAXLAYERS]
dptransparentsortcategory_t transparentsort
dpoffsetmapping_technique_t offsetmapping
struct texture_s * currentframe
struct texture_s * skynoshadowtexture
this points to a variant of the sky texture that has MATERIALFLAG_NOSHADOW, for the e1m5 logo shadow ...
texture_shaderpass_t * materialshaderpass
struct skinframe_s * currentskinframe
struct texture_s * anim_frames[2][10]
const struct texture_s * hittexture
int skipsupercontentsmask
int skipmaterialflagsmask
viddef_t vid
global video state
void W_LoadTextureWadFile(char *filename, int complain)
unsigned char * W_GetTextureBGRA(char *name)
unsigned char * W_ConvertWAD3TextureBGRA(sizebuf_t *sb)
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_AllocRecord(memexpandablearray_t *l)
void * Mem_ExpandableArray_RecordAtIndex(const memexpandablearray_t *l, size_t index)
void Mem_ExpandableArray_FreeArray(memexpandablearray_t *l)
#define Mem_Alloc(pool, size)
static size_t Mem_Size(void *data)
Returns the current size of an allocation.
#define Mem_Realloc(pool, data, size)
#define Mem_AllocType(pool, type, size)