30static qbool r_skeletal_use_sse_defined =
false;
31cvar_t r_skeletal_use_sse = {
CF_CLIENT,
"r_skeletal_use_sse",
"1",
"use SSE for skeletal model animation"};
82 if (
model->data_bones[
i].parent >= 0)
85 memcpy(bonepose +
i * 12, m,
sizeof(m));
97 const short *
RESTRICT firstpose7s =
model->data_poses7s + 7 * (frameblend[0].subframe *
model->num_bones +
i);
98 float firstlerp = frameblend[0].lerp,
99 firsttx = firstpose7s[0], firstty = firstpose7s[1], firsttz = firstpose7s[2],
100 rx = firstpose7s[3] * firstlerp,
101 ry = firstpose7s[4] * firstlerp,
102 rz = firstpose7s[5] * firstlerp,
103 rw = firstpose7s[6] * firstlerp,
104 dx = firsttx*rw + firstty*rz - firsttz*ry,
105 dy = -firsttx*rz + firstty*rw + firsttz*rx,
106 dz = firsttx*ry - firstty*rx + firsttz*rw,
107 dw = -firsttx*rx - firstty*ry - firsttz*rz,
109 for (blends = 1;blends <
MAX_FRAMEBLENDS && frameblend[blends].lerp > 0;blends++)
111 const short *
RESTRICT blendpose7s =
model->data_poses7s + 7 * (frameblend[blends].subframe *
model->num_bones +
i);
112 float blendlerp = frameblend[blends].lerp,
113 blendtx = blendpose7s[0], blendty = blendpose7s[1], blendtz = blendpose7s[2],
114 qx = blendpose7s[3], qy = blendpose7s[4], qz = blendpose7s[5], qw = blendpose7s[6];
115 if(rx*qx + ry*qy + rz*qz + rw*qw < 0) blendlerp = -blendlerp;
124 dx += blendtx*qw + blendty*qz - blendtz*qy;
125 dy += -blendtx*qz + blendty*qw + blendtz*qx;
126 dz += blendtx*qy - blendty*qx + blendtz*qw;
127 dw += -blendtx*qx - blendty*qy - blendtz*qz;
130 scale = 1.0f / (rx*rx + ry*ry + rz*rz + rw*rw);
135 m[0] =
sw*rw + sx*rx - sy*ry - sz*rz;
136 m[1] = 2*(sx*ry -
sw*rz);
137 m[2] = 2*(sx*rz +
sw*ry);
138 m[3] =
model->num_posescale*(dx*
sw - dy*sz + dz*sy - dw*sx);
139 m[4] = 2*(sx*ry +
sw*rz);
140 m[5] =
sw*rw + sy*ry - sx*rx - sz*rz;
141 m[6] = 2*(sy*rz -
sw*rx);
142 m[7] =
model->num_posescale*(dx*sz + dy*
sw - dz*sx - dw*sy);
143 m[8] = 2*(sx*rz -
sw*ry);
144 m[9] = 2*(sy*rz +
sw*rx);
145 m[10] =
sw*rw + sz*rz - sx*rx - sy*ry;
146 m[11] =
model->num_posescale*(dy*sx + dz*
sw - dx*sy - dw*sz);
152 if (
model->data_bones[
i].parent >= 0)
155 memcpy(bonepose +
i * 12, m,
sizeof(m));
166 if (!
model->surfmesh.num_vertices)
169 if (!
model->num_bones)
171 if (vertex3f) memcpy(vertex3f,
model->surfmesh.data_vertex3f,
model->surfmesh.num_vertices*
sizeof(
float[3]));
172 if (normal3f) memcpy(normal3f,
model->surfmesh.data_normal3f,
model->surfmesh.num_vertices*
sizeof(
float[3]));
173 if (svector3f) memcpy(svector3f,
model->surfmesh.data_svector3f,
model->surfmesh.num_vertices*
sizeof(
float[3]));
174 if (tvector3f) memcpy(tvector3f,
model->surfmesh.data_tvector3f,
model->surfmesh.num_vertices*
sizeof(
float[3]));
179 if(r_skeletal_use_sse_defined)
182 Mod_Skeletal_AnimateVertices_SSE(
model, frameblend, skeleton, vertex3f, normal3f, svector3f, tvector3f);
200 for (
i = 0;
i < 320;
i++)
205 Con_Printf(
"Skeletal animation uses SSE code path\n");
206 r_skeletal_use_sse_defined =
true;
210 Con_Printf(
"Skeletal animation uses generic code path (SSE disabled or not detected)\n");
212 Con_Printf(
"Skeletal animation uses generic code path (SSE not compiled in)\n");
221 return newweights->
index[0];
222 weights =
model->surfmesh.data_blendweights;
223 for (
i = 0;
i <
model->surfmesh.num_blends;
i++, weights++)
226 return model->num_bones +
i;
228 model->surfmesh.num_blends++;
230 return model->num_bones +
i;
241 for (
i = 0;
i < 4;
i++)
245 for (
i = 0;
i < 4;
i++)
247 newweights.
index[
i] = newindex[
i];
253 for (
i = 0;
i < 4;
i++)
255 if(newweights.
influence[
i] > 0 && total > 255)
264 for (
i = 0;
i < 4;
i++)
266 if(newweights.
influence[
i] < 255 && total < 255)
279 int i, numblends, blendnum;
280 int numverts =
model->surfmesh.num_vertices;
285 if (frameblend[blendnum].lerp > 0)
286 numblends = blendnum + 1;
289 for (blendnum = 0;blendnum < numblends;blendnum++)
291 const md3vertex_t *verts =
model->surfmesh.data_morphmd3vertex + numverts * frameblend[blendnum].subframe;
294 float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
297 for (
i = 0;
i < numverts;
i++)
306 for (
i = 0;
i < numverts;
i++)
321 float lerp = frameblend[blendnum].lerp;
324 for (
i = 0;
i < numverts;
i++)
333 for (
i = 0;
i < numverts;
i++)
343 const texvecvertex_t *texvecvert =
model->surfmesh.data_morphtexvecvertex + numverts * frameblend[blendnum].subframe;
344 float f = frameblend[blendnum].lerp * (1.0f / 127.0f);
347 for (
i = 0;
i < numverts;
i++, texvecvert++)
355 for (
i = 0;
i < numverts;
i++, texvecvert++)
367 int i, numblends, blendnum;
368 int numverts =
model->surfmesh.num_vertices;
376 if (
model->surfmesh.data_morphmd2framesize6f)
377 VectorMA(translate, frameblend[blendnum].lerp,
model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6 + 3, translate);
379 VectorMA(translate, frameblend[blendnum].lerp,
model->surfmesh.num_morphmdlframetranslate, translate);
380 if (frameblend[blendnum].lerp > 0)
381 numblends = blendnum + 1;
384 for (blendnum = 0;blendnum < numblends;blendnum++)
386 const trivertx_t *verts =
model->surfmesh.data_morphmdlvertex + numverts * frameblend[blendnum].subframe;
390 if (
model->surfmesh.data_morphmd2framesize6f)
391 VectorScale(
model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp,
scale);
396 for (
i = 0;
i < numverts;
i++)
398 vertex3f[
i * 3 + 0] = translate[0] + verts[
i].
v[0] *
scale[0];
399 vertex3f[
i * 3 + 1] = translate[1] + verts[
i].
v[1] *
scale[1];
400 vertex3f[
i * 3 + 2] = translate[2] + verts[
i].
v[2] *
scale[2];
405 for (
i = 0;
i < numverts;
i++)
407 vertex3f[
i * 3 + 0] += verts[
i].
v[0] *
scale[0];
408 vertex3f[
i * 3 + 1] += verts[
i].
v[1] *
scale[1];
409 vertex3f[
i * 3 + 2] += verts[
i].
v[2] *
scale[2];
419 float lerp = frameblend[blendnum].lerp;
422 for (
i = 0;
i < numverts;
i++)
430 for (
i = 0;
i < numverts;
i++)
433 VectorMA(normal3f +
i*3, lerp, vn, normal3f +
i*3);
439 const texvecvertex_t *texvecvert =
model->surfmesh.data_morphtexvecvertex + numverts * frameblend[blendnum].subframe;
440 float f = frameblend[blendnum].lerp * (1.0f / 127.0f);
443 for (
i = 0;
i < numverts;
i++, texvecvert++)
451 for (
i = 0;
i < numverts;
i++, texvecvert++)
477 if (tagindex < 0 || tagindex >= skeleton->
model->num_bones)
480 while ((tagindex =
model->data_bones[tagindex].parent) >= 0)
486 else if (
model->num_bones)
488 if (tagindex < 0 || tagindex >=
model->num_bones)
491 for (blendindex = 0;blendindex <
MAX_FRAMEBLENDS && frameblend[blendindex].
lerp > 0;blendindex++)
493 lerp = frameblend[blendindex].
lerp;
495 parenttagindex = tagindex;
496 while ((parenttagindex =
model->data_bones[parenttagindex].parent) >= 0)
499 tempbonematrix = bonematrix;
504 *outmatrix = blendmatrix;
506 else if (
model->num_tags)
508 if (tagindex < 0 || tagindex >=
model->num_tags)
510 for (k = 0;k < 12;k++)
512 for (blendindex = 0;blendindex <
MAX_FRAMEBLENDS && frameblend[blendindex].
lerp > 0;blendindex++)
514 lerp = frameblend[blendindex].
lerp;
515 input =
model->data_tags[frameblend[blendindex].
subframe *
model->num_tags + tagindex].matrixgl;
516 for (k = 0;k < 12;k++)
517 blendtag[k] += input[k] * lerp;
540 if (tagindex < 0 || tagindex >= skeleton->
model->num_bones)
542 *parentindex = skeleton->
model->data_bones[tagindex].parent;
543 *tagname = skeleton->
model->data_bones[tagindex].name;
547 else if (
model->num_bones)
549 if (tagindex < 0 || tagindex >=
model->num_bones)
551 *parentindex =
model->data_bones[tagindex].parent;
552 *tagname =
model->data_bones[tagindex].name;
554 for (blendindex = 0;blendindex <
MAX_FRAMEBLENDS && frameblend[blendindex].
lerp > 0;blendindex++)
556 lerp = frameblend[blendindex].
lerp;
560 *tag_localmatrix = blendmatrix;
563 else if (
model->num_tags)
565 if (tagindex < 0 || tagindex >=
model->num_tags)
568 *tagname =
model->data_tags[tagindex].name;
569 for (k = 0;k < 12;k++)
571 for (blendindex = 0;blendindex <
MAX_FRAMEBLENDS && frameblend[blendindex].
lerp > 0;blendindex++)
573 lerp = frameblend[blendindex].
lerp;
574 input =
model->data_tags[frameblend[blendindex].
subframe *
model->num_tags + tagindex].matrixgl;
575 for (k = 0;k < 12;k++)
576 blendtag[k] += input[k] * lerp;
588 if(
skin >= (
unsigned int)
model->numskins)
590 if (
model->num_bones)
591 for (
i = 0;
i <
model->num_bones;
i++)
592 if (!strcasecmp(tagname,
model->data_bones[
i].name))
596 if (!strcasecmp(tagname,
model->data_tags[
i].name))
616 tempbonematrix = bonematrix;
619 basebonepose[boneindex] = bonematrix;
629 qbool firstvertex =
true;
630 float dist, yawradius, radius;
632 qbool isanimated =
false;
639 float *vertex3f, *refvertex3f;
641 memset(frameblend, 0,
sizeof(frameblend));
642 frameblend[0].
lerp = 1;
676 dist =
v[0] *
v[0] +
v[1] *
v[1];
677 if (yawradius < dist)
706 dist =
v[0] *
v[0] +
v[1] *
v[1];
707 if (yawradius < dist)
714 radius =
sqrt(radius);
715 yawradius =
sqrt(yawradius);
731 unsigned char *datapointer;
732 memset(frameblend, 0,
sizeof(frameblend));
733 frameblend[0].
lerp = 1;
758 float segmentmins[3], segmentmaxs[3];
760 float vertex3fbuf[1024 * 3];
761 float *vertex3f = vertex3fbuf;
762 float *freevertex3f =
NULL;
764 if ((frameblend ==
NULL || (frameblend[0].subframe == 0 && frameblend[1].lerp == 0)) && (skeleton ==
NULL || skeleton->
relativetransforms ==
NULL))
769 memset(trace, 0,
sizeof(*trace));
774 segmentmins[0] =
min(start[0], end[0]) - 1;
775 segmentmins[1] =
min(start[1], end[1]) - 1;
776 segmentmins[2] =
min(start[2], end[2]) - 1;
777 segmentmaxs[0] =
max(start[0], end[0]) + 1;
778 segmentmaxs[1] =
max(start[1], end[1]) + 1;
779 segmentmaxs[2] =
max(start[2], end[2]) + 1;
780 if (frameblend ==
NULL || frameblend[0].subframe != 0 || frameblend[0].lerp != 0 || skeleton !=
NULL)
782 if (
model->surfmesh.num_vertices > 1024)
787 vertex3f =
model->surfmesh.data_vertex3f;
789 Collision_TraceLineTriangleMeshFloat(trace, start, end, surface->
num_triangles,
model->surfmesh.data_element3i + 3 * surface->
num_firsttriangle, vertex3f, 0,
NULL,
SUPERCONTENTS_SOLID | (surface->
texture->
basematerialflags &
MATERIALFLAGMASK_TRANSLUCENT ? 0 :
SUPERCONTENTS_OPAQUE), 0, surface->
texture, segmentmins, segmentmaxs);
794static void Mod_MDLMD2MD3_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)
797 vec3_t shiftstart, shiftend;
798 float segmentmins[3], segmentmaxs[3];
800 float vertex3fbuf[1024*3];
801 float *vertex3f = vertex3fbuf;
803 vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
809 Mod_MDLMD2MD3_TraceLine(
model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
815 if ((frameblend ==
NULL || (frameblend[0].subframe == 0 && frameblend[1].lerp == 0)) && (skeleton ==
NULL || skeleton->
relativetransforms ==
NULL))
817 Mod_CollisionBIH_TraceBox(
model, frameblend, skeleton, trace, start, boxmins, boxmaxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
822 memset(trace, 0,
sizeof(*trace));
827 if (
model->surfmesh.num_vertices > 1024)
829 segmentmins[0] =
min(start[0], end[0]) + boxmins[0] - 1;
830 segmentmins[1] =
min(start[1], end[1]) + boxmins[1] - 1;
831 segmentmins[2] =
min(start[2], end[2]) + boxmins[2] - 1;
832 segmentmaxs[0] =
max(start[0], end[0]) + boxmaxs[0] + 1;
833 segmentmaxs[1] =
max(start[1], end[1]) + boxmaxs[1] + 1;
834 segmentmaxs[2] =
max(start[2], end[2]) + boxmaxs[2] + 1;
843 Collision_TraceBrushTriangleMeshFloat(trace, &thisbrush_start.
brush, &thisbrush_end.
brush, surface->
num_triangles,
model->surfmesh.data_element3i + 3 * surface->
num_firsttriangle, vertex3f, 0,
NULL,
SUPERCONTENTS_SOLID | (surface->
texture->
basematerialflags &
MATERIALFLAGMASK_TRANSLUCENT ? 0 :
SUPERCONTENTS_OPAQUE), 0, surface->
texture, segmentmins, segmentmaxs);
844 if (vertex3f != vertex3fbuf)
851 for (
i = 0;
i < inverts;
i++)
853 if (vertremap[
i] < 0 && vertremap[
i+inverts] < 0)
858 j = vertremap[
i+inverts];
866 int i,
f, pose, groupframes;
897 if (interval < 0.01f)
915 for (
i = 0;
i < groupframes;
i++)
931 Con_DPrintf(
"Looking up texture for %s (default: %s)\n", meshname, shadername);
939 for (skinfileitem = skinfile->
items;skinfileitem;skinfileitem = skinfileitem->
next)
942 if (!strcmp(skinfileitem->
name, meshname))
946 Con_DPrintf(
"--> got %s from skin file\n", stripbuf);
970#define BOUNDI(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%d exceeds %d - %d)", loadmodel->name, VALUE, MIN, MAX);
971#define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)", loadmodel->name, VALUE, MIN, MAX);
974 int i, j,
version, totalskins, skinwidth, skinheight, groupframes, groupskins, numverts;
975 float scales, scalet, interval;
986 unsigned char *datapointer, *startframes, *startskins;
992 int *vertonseam, *vertremap;
995 datapointer = (
unsigned char *)
buffer;
996 pinmodel = (
mdl_t *)datapointer;
997 datapointer +=
sizeof(
mdl_t);
1001 Host_Error (
"%s has wrong version number (%i should be %i)",
1031 BOUNDI(skinwidth,0,65536);
1033 BOUNDI(skinheight,0,65536);
1035 BOUNDI(numverts,0,65536);
1049 for (
i = 0;
i < 3;
i++)
1055 startskins = datapointer;
1071 for (j = 0;j < groupskins;j++)
1073 datapointer += skinwidth * skinheight;
1078 pinstverts = (
stvert_t *)datapointer;
1079 datapointer +=
sizeof(
stvert_t) * numverts;
1084 startframes = datapointer;
1100 for (j = 0;j < groupframes;j++)
1103 datapointer +=
sizeof(
trivertx_t) * numverts;
1113 vertonseam = vertremap + numverts * 2;
1115 scales = 1.0 / skinwidth;
1116 scalet = 1.0 / skinheight;
1117 for (
i = 0;
i < numverts;
i++)
1122 vertst[(
i+numverts)*2+0] = vertst[
i*2+0] + 0.5;
1123 vertst[(
i+numverts)*2+1] = vertst[
i*2+1];
1131 for (j = 0;j < 3;j++)
1139 for (j = 0;j < 3;j++)
1144 for (
i = 0;
i < numverts*2;
i++)
1150 for (
i = 0;
i < numverts*2;
i++)
1215 datapointer = startskins;
1236 interval =
LittleFloat(pinskinintervals[0].interval);
1237 if (interval < 0.01f)
1250 for (j = 0;j < groupskins;j++)
1257 Mod_LoadCustomMaterial(
loadmodel->
mempool,
loadmodel->
data_textures + totalskins *
loadmodel->
num_surfaces,
name,
SUPERCONTENTS_SOLID,
MATERIALFLAG_WALL,
R_SkinFrame_LoadInternalQuake(
name, (
r_mipskins.
integer ?
TEXF_MIPMAP : 0) |
TEXF_PICMIP,
true,
r_fullbrights.
integer, (
unsigned char *)datapointer, skinwidth, skinheight));
1258 datapointer += skinwidth * skinheight;
1326 int i, j, hashindex, numxyz, numst,
xyz, st, skinwidth, skinheight, *vertremap,
version, end;
1327 float iskinwidth, iskinheight;
1328 unsigned char *
data;
1331 unsigned char *base, *datapointer;
1335 unsigned short *inst;
1336 struct md2verthash_s
1338 struct md2verthash_s *next;
1342 *hash, **md2verthash, *md2verthashdata;
1346 base = (
unsigned char *)
buffer;
1350 Host_Error (
"%s has wrong version number (%i should be %i)",
1398 iskinwidth = 1.0f / skinwidth;
1399 iskinheight = 1.0f / skinheight;
1462 for (j = 0;j < 3;j++)
1465 st = (
unsigned short)
LittleShort (intri[
i].index_st[j]);
1476 hashindex = (
xyz * 256 + st) & 65535;
1477 for (hash = md2verthash[hashindex];hash;hash = hash->next)
1478 if (hash->xyz ==
xyz && hash->st == st)
1485 hash->next = md2verthash[hashindex];
1486 md2verthash[hashindex] = hash;
1499 hash = md2verthashdata +
i;
1500 vertremap[
i] = hash->xyz;
1503 if (sts < 0 || sts >= skinwidth || stt < 0 || stt >= skinheight)
1505 Con_Printf(
"%s has an invalid skin coordinate (%i %i) on vert %i, changing to 0 0\n",
loadmodel->
name, sts, stt,
i);
1533 for (j = 0;j < 3;j++)
1542 out[k] =
v[vertremap[k]];
1580 int i, j, k,
version, meshvertices, meshtriangles;
1581 unsigned char *
data;
1595 Host_Error (
"%s has wrong version number (%i should be %i)",
1653 for (j = 0;j < 9;j++)
1655 for (j = 0;j < 3;j++)
1666 Host_Error(
"Mod_IDP3_Load: invalid mesh identifier (not IDP3)");
1668 Host_Error(
"Mod_IDP3_Load: mesh numframes differs from header");
1685 meshvertices *
sizeof(
float[2])
1687 + meshtriangles *
sizeof(
int[3])
1688 + (meshvertices <= 65536 ? meshtriangles *
sizeof(
unsigned short[3]) : 0));
1693 if (meshvertices <= 65536)
1708 Host_Error(
"Mod_IDP3_Load: invalid mesh identifier (not IDP3)");
1771 unsigned char *pbase;
1772 int i, j, k, numposes, meshvertices, meshtriangles, *bonecount, *vertbonecounts,
count, *renderlist, *renderlistend, *outelements;
1773 float modelradius, corner[2], *poses, *intexcoord2f, *outtexcoord2f, *bonepose,
f, biggestorigin, tempvec[3], modelscale;
1779 unsigned char *
data;
1783 pbase = (
unsigned char *)
buffer;
1784 if (memcmp(pinmodel->
id,
"ZYMOTICMODEL", 12))
1787 Host_Error (
"Mod_ZYMOTICMODEL_Load: only type 1 (skeletal pose) models are currently supported (name = %s)",
loadmodel->
name);
1871 modelradius = pheader->
radius;
1872 for (
i = 0;
i < 3;
i++)
1930 vertbonecounts[
i] =
BigLong(bonecount[
i]);
1931 if (vertbonecounts[
i] != 1)
1938 meshtriangles = pheader->
numtris;
1953 + meshtriangles *
sizeof(
int[3])
1954 + (meshvertices <= 65536 ? loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3]) : 0)
1955 + meshvertices * (
sizeof(
float[14]) +
sizeof(
unsigned short) +
sizeof(
unsigned char[2][4]))
1991 biggestorigin =
max(biggestorigin,
f);
1995 for (
i = 0;
i < numposes;
i++)
2002 for (k = 0;k < 12;k++)
2003 pose[k] =
BigFloat(frameposes[j*12+k]);
2009 pose[3] *= modelscale;
2010 pose[7] *= modelscale;
2011 pose[11] *= modelscale;
2032 for (k = 0;k < 12;k++)
2037 for (k = 0;k < 12;k++)
2038 bonepose[12*
i+k] = m[k];
2040 for (j = 0;j < pheader->
numverts;j++)
2045 int boneindex =
BigLong(vertdata[j].bonenum);
2046 const float *m = bonepose + 12 * boneindex;
2047 float relativeorigin[3];
2074 outtexcoord2f[
i*2+0] =
BigFloat(intexcoord2f[
i*2+0]);
2076 outtexcoord2f[
i*2+1] = 1 -
BigFloat(intexcoord2f[
i*2+1]);
2090 renderlistend = (
int *) ((
unsigned char *) renderlist + pheader->
lump_render.
length);
2094 int firstvertex, lastvertex;
2095 if (renderlist >= renderlistend)
2098 if (renderlist +
count * 3 > renderlistend || (
i == pheader->
numshaders - 1 && renderlist +
count * 3 != renderlistend))
2112 outelements[j*3+2] =
BigLong(renderlist[0]);
2113 outelements[j*3+1] =
BigLong(renderlist[1]);
2114 outelements[j*3+0] =
BigLong(renderlist[2]);
2117 firstvertex = meshvertices;
2121 if ((
unsigned int)outelements[j] >= (
unsigned int)meshvertices)
2123 firstvertex =
min(firstvertex, outelements[j]);
2124 lastvertex =
max(lastvertex, outelements[j]);
2169 unsigned char *pbase;
2170 int i, j, k, meshvertices, meshtriangles;
2172 unsigned char *
data;
2174 float biggestorigin, tempvec[3], modelscale;
2179 pbase = (
unsigned char *)
buffer;
2180 if (memcmp(pheader->
id,
"DARKPLACESMODEL\0", 16))
2183 Host_Error (
"Mod_DARKPLACESMODEL_Load: only type 2 (hierarchical skeletal pose) models are currently supported (name = %s)",
loadmodel->
name);
2233 for (
i = 0;
i < 3;
i++)
2258 meshvertices += numverts;
2278 + meshtriangles *
sizeof(
int[3])
2279 + (meshvertices <= 65536 ? meshtriangles *
sizeof(
unsigned short[3]) : 0)
2280 + meshvertices * (
sizeof(
float[14]) +
sizeof(
unsigned short) +
sizeof(
unsigned char[2][4]))
2293 if (meshvertices <= 65536)
2331 poses = (
float *) (pbase +
BigLong(frames[0].ofs_bonepositions));
2345 poses = (
float *) (pbase +
BigLong(frames[
i].ofs_bonepositions));
2349 biggestorigin =
max(biggestorigin,
f);
2357 const float *frameposes = (
float *) (pbase +
BigLong(frames[
i].ofs_bonepositions));
2362 for (k = 0;k < 12;k++)
2363 pose[k] =
BigFloat(frameposes[j*12+k]);
2367 pose[3] *= modelscale;
2368 pose[7] *= modelscale;
2369 pose[11] *= modelscale;
2387 poses = (
float *) (pbase +
BigLong(frames[0].ofs_bonepositions));
2392 for (k = 0;k < 12;k++)
2397 for (k = 0;k < 12;k++)
2398 bonepose[12*
i+k] = m[k];
2402 const int *inelements;
2404 unsigned short *outelement3s;
2405 const float *intexcoord;
2429 outelement3s[j * 3 + 0] = outelement3i[j * 3 + 0];
2430 outelement3s[j * 3 + 1] = outelement3i[j * 3 + 1];
2431 outelement3s[j * 3 + 2] = outelement3i[j * 3 + 2];
2442 int weightindex[4] = { 0, 0, 0, 0 };
2443 float weightinfluence[4] = { 0, 0, 0, 0 };
2447 for (k = 0;k < numweights;k++)
2451 const float *m = bonepose + 12 * boneindex;
2453 float relativeorigin[3], relativenormal[3];
2470 weightinfluence[0] = influence;
2471 weightindex[0] = boneindex;
2477 for (l = 0;l < 4;l++)
2479 if (weightinfluence[l] < influence)
2483 for (l2 = 3;l2 > l;l2--)
2485 weightinfluence[l2] = weightinfluence[l2-1];
2486 weightindex[l2] = weightindex[l2-1];
2489 weightinfluence[l] = influence;
2490 weightindex[l] = boneindex;
2539#define PSKQUATNEGATIONS
2542 int i, j,
index,
version, recordsize, numrecords, meshvertices, meshtriangles;
2543 int numpnts, numvtxw, numfaces, nummatts, numbones, numrawweights, numanimbones, numanims, numanimkeys;
2554 void *animfilebuffer, *animbuffer, *animbufferend;
2555 unsigned char *
data;
2559 float biggestorigin;
2562 if (strcmp(pchunk->
id,
"ACTRHEAD"))
2582 dp_strlcat(animname,
".psa",
sizeof(animname));
2584 animbufferend = (
void *)((
unsigned char*)animbuffer + (
int)filesize);
2586 animbufferend = animbuffer;
2605 while (
buffer < bufferend)
2615 Con_Printf (
"%s: chunk %s has unknown version %x (0x1e83b9, 0x1e9179, 0x2e, 0x12f2bc, 0x12f2f0 are currently supported), trying to load anyway!\n",
loadmodel->
name, pchunk->
id,
version);
2616 if (!strcmp(pchunk->
id,
"ACTRHEAD"))
2620 else if (!strcmp(pchunk->
id,
"PNTS0000"))
2623 if (recordsize !=
sizeof(*p))
2626 numpnts = numrecords;
2636 else if (!strcmp(pchunk->
id,
"VTXW0000"))
2639 if (recordsize !=
sizeof(*p))
2642 numvtxw = numrecords;
2657 else if (!strcmp(pchunk->
id,
"FACE0000"))
2660 if (recordsize !=
sizeof(*p))
2663 numfaces = numrecords;
2689 else if (!strcmp(pchunk->
id,
"MATT0000"))
2692 if (recordsize !=
sizeof(*p))
2695 nummatts = numrecords;
2703 else if (!strcmp(pchunk->
id,
"REFSKELT"))
2706 if (recordsize !=
sizeof(*p))
2709 numbones = numrecords;
2726#ifdef PSKQUATNEGATIONS
2748 else if (!strcmp(pchunk->
id,
"RAWWEIGHTS"))
2751 if (recordsize !=
sizeof(*p))
2754 numrawweights = numrecords;
2776 while (animbuffer < animbufferend)
2779 animbuffer = (
void *)((
unsigned char *)animbuffer +
sizeof(
pskchunk_t));
2784 Con_DPrintf(
"%s: %s %x: %i * %i = %i\n", animname, pchunk->
id,
version, recordsize, numrecords, recordsize * numrecords);
2786 Con_Printf (
"%s: chunk %s has unknown version %x (0x1e83b9, 0x1e9179, 0x2e, 0x12f2bc, 0x12f2f0 are currently supported), trying to load anyway!\n", animname, pchunk->
id,
version);
2787 if (!strcmp(pchunk->
id,
"ANIMHEAD"))
2791 else if (!strcmp(pchunk->
id,
"BONENAMES"))
2794 if (recordsize !=
sizeof(*p))
2795 Host_Error(
"%s: %s has unsupported recordsize", animname, pchunk->
id);
2797 numanimbones = numrecords;
2803 if (numanimbones != numbones)
2820#ifdef PSKQUATNEGATIONS
2836 Con_Printf(
"%s: bone->parent %i >= numanimbones %i\n", animname, p->
parent, numanimbones);
2841 Host_Error(
"%s: this loader only supports animations with the same bones as the mesh", animname);
2845 else if (!strcmp(pchunk->
id,
"ANIMINFO"))
2848 if (recordsize !=
sizeof(*p))
2849 Host_Error(
"%s: %s has unsupported recordsize", animname, pchunk->
id);
2851 numanims = numrecords;
2861 Con_Printf(
"%s: animinfo->numbones != numbones, trying to load anyway!\n", animname);
2865 else if (!strcmp(pchunk->
id,
"ANIMKEYS"))
2868 if (recordsize !=
sizeof(*p))
2869 Host_Error(
"%s: %s has unsupported recordsize", animname, pchunk->
id);
2870 numanimkeys = numrecords;
2882#ifdef PSKQUATNEGATIONS
2883 if (
index % numbones)
2901 Con_Printf(
"%s: unknown chunk ID \"%s\"\n", animname, pchunk->
id);
2904 if (!numpnts || !pnts || !numvtxw || !vtxw || !numfaces || !faces || !nummatts || !matts || !numbones || !bones || !numrawweights || !rawweights)
2913 Host_Error(
"%s: %s has incorrect number of animation keys", animname, pchunk->
id);
2918 meshvertices = numvtxw;
2919 meshtriangles = numfaces;
3046 tempbonematrix = bonematrix;
3049 basebonepose[boneindex] = bonematrix;
3060 int weightindex[4] = { 0, 0, 0, 0 };
3061 float weightinfluence[4] = { 0, 0, 0, 0 };
3063 for (j = 0;j < numrawweights;j++)
3065 if (rawweights[j].pntsindex == vtxw[
index].pntsindex)
3067 int boneindex = rawweights[j].
boneindex;
3068 float influence = rawweights[j].
weight;
3069 for (l = 0;l < 4;l++)
3071 if (weightinfluence[l] < influence)
3075 for (l2 = 3;l2 > l;l2--)
3077 weightinfluence[l2] = weightinfluence[l2-1];
3078 weightindex[l2] = weightindex[l2-1];
3081 weightinfluence[l] = influence;
3082 weightindex[l] = boneindex;
3221 unsigned char *
data;
3223 const unsigned char *pbase, *pend;
3227 float biggestorigin;
3228 const unsigned int *inelements;
3230 float *outvertex, *outnormal, *outtexcoord, *outsvector, *outtvector, *outcolor;
3232 const float *vnormal =
NULL;
3233 const float *vposition =
NULL;
3234 const float *vtangent =
NULL;
3235 const float *vtexcoord =
NULL;
3236 const float *vcolor4f =
NULL;
3237 const unsigned char *vblendindexes =
NULL;
3238 const unsigned char *vblendweights =
NULL;
3239 const unsigned char *vcolor4ub =
NULL;
3240 const unsigned short *framedata =
NULL;
3251 pbase = (
unsigned char *)
buffer;
3252 pend = (
unsigned char *)bufferend;
3255 Host_Error (
"Mod_INTERQUAKEMODEL_Load: %s is not an Inter-Quake Model %d",
loadmodel->
name, (
int)(pend - pbase));
3261 if (memcmp(header.
id,
"INTERQUAKEMODEL", 16))
3264 Host_Error (
"Mod_INTERQUAKEMODEL_Load: only version 1 and 2 models are currently supported (name = %s)",
loadmodel->
name);
3358 case IQM_UBYTE: vsize *=
sizeof(
unsigned char);
break;
3361 if (pbase +
va.offset + vsize > pend)
3368 vposition = (
const float *)(pbase +
va.offset);
3372 vtexcoord = (
const float *)(pbase +
va.offset);
3376 vnormal = (
const float *)(pbase +
va.offset);
3380 vtangent = (
const float *)(pbase +
va.offset);
3384 vblendindexes = (
const unsigned char *)(pbase +
va.offset);
3388 vblendweights = (
const unsigned char *)(pbase +
va.offset);
3392 vcolor4f = (
const float *)(pbase +
va.offset);
3394 vcolor4ub = (
const unsigned char *)(pbase +
va.offset);
3449 if (vcolor4f || vcolor4ub)
3461 if (vblendindexes && vblendweights)
3475 if (vblendindexes && vblendweights)
3495 matrix4x4_t relbase, relinvbase, pinvbase, invbase;
3501 for (j = 0;j < 3;j++)
3530 matrix4x4_t relbase, relinvbase, pinvbase, invbase;
3533 memcpy(&injoint, &injoints[
i],
sizeof(
iqmjoint_t));
3536 for (j = 0;j < 3;j++)
3547 if (joint[
i].rotation[3] > 0)
3604 memcpy(&inpose, &inposes1[
i],
sizeof(
iqmpose1_t));
3607 for (j = 0;j < 9;j++)
3612 f =
fabs(pose1[
i].channeloffset[0]); biggestorigin =
max(biggestorigin,
f);
3613 f =
fabs(pose1[
i].channeloffset[1]); biggestorigin =
max(biggestorigin,
f);
3614 f =
fabs(pose1[
i].channeloffset[2]); biggestorigin =
max(biggestorigin,
f);
3615 f =
fabs(pose1[
i].channeloffset[0] + 0xFFFF*pose1[
i].channelscale[0]); biggestorigin =
max(biggestorigin,
f);
3616 f =
fabs(pose1[
i].channeloffset[1] + 0xFFFF*pose1[
i].channelscale[1]); biggestorigin =
max(biggestorigin,
f);
3617 f =
fabs(pose1[
i].channeloffset[2] + 0xFFFF*pose1[
i].channelscale[2]); biggestorigin =
max(biggestorigin,
f);
3641 memcpy(&inpose, &inposes[
i],
sizeof(
iqmpose_t));
3644 for (j = 0;j < 10;j++)
3649 f =
fabs(pose[
i].channeloffset[0]); biggestorigin =
max(biggestorigin,
f);
3650 f =
fabs(pose[
i].channeloffset[1]); biggestorigin =
max(biggestorigin,
f);
3651 f =
fabs(pose[
i].channeloffset[2]); biggestorigin =
max(biggestorigin,
f);
3652 f =
fabs(pose[
i].channeloffset[0] + 0xFFFF*pose[
i].channelscale[0]); biggestorigin =
max(biggestorigin,
f);
3653 f =
fabs(pose[
i].channeloffset[1] + 0xFFFF*pose[
i].channelscale[1]); biggestorigin =
max(biggestorigin,
f);
3654 f =
fabs(pose[
i].channeloffset[2] + 0xFFFF*pose[
i].channelscale[2]); biggestorigin =
max(biggestorigin,
f);
3672 framedata = (
const unsigned short *)(pbase + header.
ofs_frames);
3679 float qx, qy, qz, qw;
3686 qw = 1.0f - (qx*qx + qy*qy + qz*qz);
3687 qw = qw > 0.0f ? -
sqrt(qw) : 0.0f;
3693 if(pose1[j].channelmask&64) framedata++;
3694 if(pose1[j].channelmask&128) framedata++;
3695 if(pose1[j].channelmask&256) framedata++;
3702 float qx, qy, qz, qw;
3709 qw = 1.0f - (qx*qx + qy*qy + qz*qz);
3710 qw = qw > 0.0f ? -
sqrt(qw) : 0.0f;
3740 if(pose[j].channelmask&128) framedata++;
3741 if(pose[j].channelmask&256) framedata++;
3742 if(pose[j].channelmask&512) framedata++;
3763 float xyradius = 0, radius = 0;
3791 if (
bound.xyradius > xyradius)
3792 xyradius =
bound.xyradius;
3793 if (
bound.radius > radius)
3794 radius =
bound.radius;
3808 inelements = (
const unsigned int *)(pbase + header.
ofs_triangles);
3860 if(vnormal && vtangent)
3882 if (vblendindexes && vblendweights)
3887 memcpy(weights.
index, vblendindexes +
i*4, 4);
3888 memcpy(weights.
influence, vblendweights +
i*4, 4);
3921 outcolor[0] = vcolor4ub[0] * (1.0f / 255.0f);
3922 outcolor[1] = vcolor4ub[1] * (1.0f / 255.0f);
3923 outcolor[2] = vcolor4ub[2] * (1.0f / 255.0f);
3924 outcolor[3] = vcolor4ub[3] * (1.0f / 255.0f);
3936 memcpy(&mesh, &meshes[
i],
sizeof(
iqmmesh_t));
3961 if (!vnormal || !vtangent)
#define SUPERCONTENTS_OPAQUE
#define SUPERCONTENTS_SOLID
#define CF_SERVER
cvar/command that only the server can change/execute
#define CF_CLIENT
cvar/command that only the client can change/execute
void Collision_TraceLineTriangleMeshFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, const texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs)
void Collision_TraceBrushTriangleMeshFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, const texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs)
void Collision_BrushForBox(colboxbrushf_t *boxbrush, const vec3_t mins, const vec3_t maxs, int supercontents, int q3surfaceflags, const texture_t *texture)
char * va(char *buf, size_t buflen, const char *format,...)
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
#define dp_strlcat(dst, src, dsize)
#define dp_strlcpy(dst, src, dsize)
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 Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
static int(ZEXPORT *qz_inflate)(z_stream *strm
static int const char * version
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_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_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)
GLenum GLenum GLsizei count
GLsizeiptr const GLvoid * data
void Host_Error(const char *error,...)
void Image_StripImageExtension(const char *in, char *out, size_t size_out)
float m_bytenormals[NUMVERTEXNORMALS][3]
void R_ConcatTransforms(const float in1[3 *4], const float in2[3 *4], float out[3 *4])
#define Vector4Normalize2(v, dest)
#define VectorNormalize(v)
#define bound(min, num, max)
#define Vector4Copy(in, out)
#define VectorSubtract(a, b, out)
#define CrossProduct(a, b, out)
#define Vector4Negate(in, out)
#define VectorCompare(a, b)
#define VectorCopy(in, out)
#define VectorScale(in, scale, out)
#define VectorAdd(a, b, out)
#define VectorMA(a, scale, b, out)
#define VectorScaleCast(in, scale, outtype, out)
void Matrix4x4_Concat(matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2)
void Matrix4x4_FromBonePose7s(matrix4x4_t *m, float originscale, const short *pose7s)
void Matrix4x4_Clear(matrix4x4_t *out)
void Matrix4x4_FromArray12FloatGL(matrix4x4_t *out, const float in[12])
void Matrix4x4_FromOriginQuat(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z, double w)
void Matrix4x4_ToArray12FloatD3D(const matrix4x4_t *in, float out[12])
void Matrix4x4_Normalize3(matrix4x4_t *out, matrix4x4_t *in1)
void Matrix4x4_FromArray12FloatD3D(matrix4x4_t *out, const float in[12])
void Matrix4x4_Invert_Simple(matrix4x4_t *out, const matrix4x4_t *in1)
void Matrix4x4_Accumulate(matrix4x4_t *out, matrix4x4_t *in, double weight)
const matrix4x4_t identitymatrix
void Matrix4x4_ToBonePose7s(const matrix4x4_t *m, float origininvscale, short *pose7s)
void Matrix4x4_FromDoom3Joint(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z)
void Mod_Skeletal_AnimateVertices_Generic(const model_t *RESTRICT model, const frameblend_t *RESTRICT frameblend, const skeleton_t *skeleton, float *RESTRICT vertex3f, float *RESTRICT normal3f, float *RESTRICT svector3f, float *RESTRICT tvector3f)
int Mod_Alias_GetExtendedTagInfoForIndex(const model_t *model, unsigned int skin, const frameblend_t *frameblend, const skeleton_t *skeleton, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
cvar_t r_skeletal_debugbone
cvar_t r_skeletal_debugtranslatey
void * Mod_Skeletal_AnimateVertices_AllocBuffers(size_t nbytes)
static void Mod_MDLMD2MD3_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_Skeletal_AnimateVertices(const model_t *RESTRICT model, const frameblend_t *RESTRICT frameblend, const skeleton_t *skeleton, float *RESTRICT vertex3f, float *RESTRICT normal3f, float *RESTRICT svector3f, float *RESTRICT tvector3f)
void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, const char *meshname, const char *shadername)
static int Mod_Skeletal_CompressBlend(model_t *model, const int *newindex, const float *newinfluence)
static void Mod_Alias_MorphMesh_CompileFrames(void)
void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t r_skeletal_debugbonecomponent
static void * Mod_Skeletal_AnimateVertices_bonepose
static void Mod_MDL_AnimateVertices(const model_t *RESTRICT model, const frameblend_t *RESTRICT frameblend, const skeleton_t *skeleton, float *RESTRICT vertex3f, float *RESTRICT normal3f, float *RESTRICT svector3f, float *RESTRICT tvector3f)
static int Mod_Skeletal_AddBlend(model_t *model, const blendweights_t *newweights)
#define BOUNDI(VALUE, MIN, MAX)
cvar_t mod_alias_force_animated
static size_t Mod_Skeletal_AnimateVertices_maxbonepose
static void Mod_ConvertAliasVerts(int inverts, trivertx_t *v, trivertx_t *out, int *vertremap)
void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_Skeletal_FreeBuffers(void)
void Mod_Skeletal_BuildTransforms(const model_t *RESTRICT model, const frameblend_t *RESTRICT frameblend, const skeleton_t *skeleton, float *RESTRICT bonepose, float *RESTRICT boneposerelative)
void Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer, void *bufferend)
static void Mod_MDLMD2MD3_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_MD3_AnimateVertices(const model_t *RESTRICT model, const frameblend_t *RESTRICT frameblend, const skeleton_t *skeleton, float *RESTRICT vertex3f, float *RESTRICT normal3f, float *RESTRICT svector3f, float *RESTRICT tvector3f)
void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t r_skeletal_debugtranslatez
int Mod_Alias_GetTagMatrix(const model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, int tagindex, matrix4x4_t *outmatrix)
static void Mod_MDL_LoadFrames(unsigned char *datapointer, int inverts, int *vertremap)
cvar_t r_skeletal_debugtranslatex
int Mod_Alias_GetTagIndexForName(const model_t *model, unsigned int skin, const char *tagname)
void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t mod_alias_supporttagscale
void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
cvar_t r_skeletal_debugbonevalue
static void Mod_BuildBaseBonePoses(void)
static qbool Mod_Alias_CalculateBoundingBox(void)
void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
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)
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)
bih_t * Mod_MakeCollisionBIH(model_t *model, qbool userendersurfaces, bih_t *out)
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)
#define MATERIALFLAG_NODRAW
#define MATERIALFLAGMASK_TRANSLUCENT
#define MATERIALFLAG_WALL
#define MATERIALFLAG_NOSHADOW
qbool Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qbool warnmissing, qbool fallback, int defaulttexflags, int defaultmaterialflags)
skinfile_t * Mod_LoadSkinFiles(void)
void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qbool areaweighting)
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_LoadCustomMaterial(mempool_t *mempool, texture_t *texture, const char *name, int supercontents, int materialflags, skinframe_t *skinframe)
#define ZYMSCENEFLAG_NOLOOP
#define MAX_QPATH
max length of a quake game pathname
unsigned char influence[4]
unsigned int ofs_texcoords
unsigned int num_triangles
unsigned int num_vertexes
unsigned int first_vertex
unsigned int first_triangle
void(* AnimateVertices)(const struct model_s *RESTRICT model, const struct frameblend_s *RESTRICT frameblend, const struct skeleton_s *skeleton, float *RESTRICT vertex3f, float *RESTRICT normal3f, float *RESTRICT svector3f, float *RESTRICT tvector3f)
void(* DrawDepth)(struct entity_render_s *ent)
float * data_baseboneposeinverse
int(* PointSuperContents)(struct model_s *model, int frame, const vec3_t point)
int * modelsurfaces_sorted
surface indices of model in an optimal draw order (submodelindex -> texture -> lightmap -> index)
msurface_t * data_surfaces
void(* Draw)(struct entity_render_s *ent)
int submodelsurfaces_start
void(* DrawPrepass)(struct entity_render_s *ent)
void(* TraceBox)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
void(* DrawShadowMap)(int side, struct entity_render_s *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist, const unsigned char *surfacesides, const vec3_t lightmins, const vec3_t lightmaxs)
void(* TracePoint)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
void(* DrawDebug)(struct entity_render_s *ent)
void(* TraceBrush)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, struct colbrushf_s *start, struct colbrushf_s *end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
struct mempool_s * mempool
void(* CompileShadowMap)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist)
const char * modeldatatypestring
texture_t * data_textures
void(* DrawLight)(struct entity_render_s *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs)
void(* TraceLine)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
int num_triangles
range of triangles and vertices in model->surfmesh
texture_t * texture
the texture to use on the surface
unsigned short vtxwindex[3]
const struct model_s * model
struct matrix4x4_s * relativetransforms
char replacement[MAX_QPATH]
struct skinfileitem_s * next
struct texvecvertex_s * data_morphtexvecvertex
float num_morphmdlframetranslate[3]
float * data_lightmapcolor4f
unsigned char * data_skeletalweight4ub
float num_morphmdlframescale[3]
unsigned char * data_skeletalindex4ub
unsigned short * data_element3s
struct trivertx_s * data_morphmdlvertex
struct blendweights_s * data_blendweights
float * data_morphmd2framesize6f
struct md3vertex_s * data_morphmd3vertex
float * data_texcoordtexture2f
struct texture_s * currentframe
int skipsupercontentsmask
int skipmaterialflagsmask
unsigned char lightnormalindex
#define Mem_Alloc(pool, size)
#define Mem_ReallocType(pool, data, type, size)
#define Mem_AllocType(pool, type, size)