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"};
79 for (i = 0;i <
model->num_bones;i++)
82 if (
model->data_bones[i].parent >= 0)
85 memcpy(bonepose + i * 12, m,
sizeof(m));
94 for (i = 0;i <
model->num_bones;i++)
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++)
242 scale += newinfluence[i];
245 for (i = 0;i < 4;i++)
247 newweights.
index[i] = newindex[i];
248 newweights.
influence[i] = (
unsigned char)(newinfluence[i] *
scale);
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++)
357 VectorMA(svector3f + i*3,
f, texvecvert->
svec, svector3f + i*3);
358 VectorMA(tvector3f + i*3,
f, texvecvert->
tvec, tvector3f + i*3);
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++)
453 VectorMA(svector3f + i*3,
f, texvecvert->
svec, svector3f + i*3);
454 VectorMA(tvector3f + i*3,
f, texvecvert->
tvec, tvector3f + i*3);
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))
595 for (i = 0;i <
model->num_tags;i++)
596 if (!strcasecmp(tagname,
model->data_tags[i].name))
605 float *outinvmatrix =
loadmodel->data_baseboneposeinverse;
611 for (boneindex = 0;boneindex <
loadmodel->num_bones;boneindex++)
614 if (
loadmodel->data_bones[boneindex].parent >= 0)
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;
651 refvertex3f = vertex3f +
loadmodel->surfmesh.num_vertices * 3;
652 memcpy(refvertex3f, vertex3f,
loadmodel->surfmesh.num_vertices *
sizeof(
float[3]));
656 if (!isanimated && memcmp(refvertex3f, vertex3f,
loadmodel->surfmesh.num_vertices *
sizeof(
float[3])))
659 for (vnum = 0,
v = vertex3f;vnum <
loadmodel->surfmesh.num_vertices;vnum++,
v += 3)
676 dist =
v[0] *
v[0] +
v[1] *
v[1];
677 if (yawradius < dist)
689 for (vnum = 0,
v =
loadmodel->surfmesh.data_vertex3f;vnum < loadmodel->surfmesh.num_vertices;vnum++,
v += 3)
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;
735 loadmodel->surfmesh.data_vertex3f = (
float *)datapointer;datapointer +=
loadmodel->surfmesh.num_vertices *
sizeof(
float[3]);
736 loadmodel->surfmesh.data_svector3f = (
float *)datapointer;datapointer +=
loadmodel->surfmesh.num_vertices *
sizeof(
float[3]);
737 loadmodel->surfmesh.data_tvector3f = (
float *)datapointer;datapointer +=
loadmodel->surfmesh.num_vertices *
sizeof(
float[3]);
738 loadmodel->surfmesh.data_normal3f = (
float *)datapointer;datapointer +=
loadmodel->surfmesh.num_vertices *
sizeof(
float[3]);
741 for (i =
loadmodel->surfmesh.num_morphframes-1;i >= 0;i--)
747 for (j = 0;j <
loadmodel->surfmesh.num_vertices;j++)
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;
788 for (i = 0, surface =
model->data_surfaces;i < model->num_surfaces;i++, surface++)
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;
842 for (i = 0, surface =
model->data_surfaces;i < model->num_surfaces;i++, surface++)
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);
935 for (i = 0;skinfile;skinfile = skinfile->
next, i++,
skin +=
loadmodel->num_surfaces)
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);
1044 loadmodel->effects = (((unsigned)i & 255) << 24) | (i & 0x00FFFF00);
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;
1085 loadmodel->surfmesh.num_morphframes = 0;
1086 for (i = 0;i <
loadmodel->numframes;i++)
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++)
1119 vertonseam[i] =
LittleLong(pinstverts[i].onseam);
1120 vertst[i*2+0] =
LittleLong(pinstverts[i].s) * scales;
1121 vertst[i*2+1] =
LittleLong(pinstverts[i].t) * scalet;
1122 vertst[(i+numverts)*2+0] = vertst[i*2+0] + 0.5;
1123 vertst[(i+numverts)*2+1] = vertst[i*2+1];
1130 for (i = 0;i <
loadmodel->surfmesh.num_triangles;i++)
1131 for (j = 0;j < 3;j++)
1137 for (i = 0;i <
loadmodel->surfmesh.num_triangles;i++)
1139 for (j = 0;j < 3;j++)
1140 if (vertonseam[
loadmodel->surfmesh.data_element3i[i*3+j]])
1141 loadmodel->surfmesh.data_element3i[i*3+j] += numverts;
1144 for (i = 0;i < numverts*2;i++)
1146 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
1147 vertremap[
loadmodel->surfmesh.data_element3i[i]]++;
1150 for (i = 0;i < numverts*2;i++)
1154 vertremap[i] =
loadmodel->surfmesh.num_vertices;
1155 vertst[
loadmodel->surfmesh.num_vertices*2+0] = vertst[i*2+0];
1156 vertst[
loadmodel->surfmesh.num_vertices*2+1] = vertst[i*2+1];
1163 for (i = 0;i <
loadmodel->surfmesh.num_triangles * 3;i++)
1164 loadmodel->surfmesh.data_element3i[i] = vertremap[
loadmodel->surfmesh.data_element3i[i]];
1167 for (i = 0;i <
loadmodel->surfmesh.num_vertices;i++)
1169 loadmodel->surfmesh.data_texcoordtexture2f[i*2+0] = vertst[i*2+0];
1170 loadmodel->surfmesh.data_texcoordtexture2f[i*2+1] = vertst[i*2+1];
1174 if (
loadmodel->surfmesh.num_vertices <= 65536)
1177 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
1202 loadmodel->skinscenes[i].firstframe = i;
1203 loadmodel->skinscenes[i].framecount = 1;
1205 loadmodel->skinscenes[i].framerate = 10;
1215 datapointer = startskins;
1236 interval =
LittleFloat(pinskinintervals[0].interval);
1237 if (interval < 0.01f)
1239 Con_Printf(
"%s has an invalid interval %f, changing to 0.1\n",
loadmodel->name, interval);
1245 loadmodel->skinscenes[i].firstframe = totalskins;
1246 loadmodel->skinscenes[i].framecount = groupskins;
1247 loadmodel->skinscenes[i].framerate = 1.0f / interval;
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;
1277 tempaliasskins =
loadmodel->data_textures;
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;
1447 loadmodel->skinscenes[i].firstframe = i;
1448 loadmodel->skinscenes[i].framecount = 1;
1450 loadmodel->skinscenes[i].framerate = 10;
1460 for (i = 0;i <
loadmodel->surfmesh.num_triangles;i++)
1462 for (j = 0;j < 3;j++)
1465 st = (
unsigned short)
LittleShort (intri[i].index_st[j]);
1468 Con_Printf(
"%s has an invalid xyz index (%i) on triangle %i, resetting to 0\n",
loadmodel->name,
xyz, i);
1473 Con_Printf(
"%s has an invalid st index (%i) on triangle %i, resetting to 0\n",
loadmodel->name, st, i);
1476 hashindex = (
xyz * 256 + st) & 65535;
1477 for (hash = md2verthash[hashindex];hash;hash = hash->next)
1478 if (hash->xyz ==
xyz && hash->st == st)
1482 hash = md2verthashdata +
loadmodel->surfmesh.num_vertices++;
1485 hash->next = md2verthash[hashindex];
1486 md2verthash[hashindex] = hash;
1488 loadmodel->surfmesh.data_element3i[i*3+j] = (hash - md2verthashdata);
1496 for (i = 0;i <
loadmodel->surfmesh.num_vertices;i++)
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);
1509 loadmodel->surfmesh.data_texcoordtexture2f[i*2+0] = sts * iskinwidth;
1510 loadmodel->surfmesh.data_texcoordtexture2f[i*2+1] = stt * iskinheight;
1517 if (
loadmodel->surfmesh.num_vertices <= 65536)
1520 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
1525 for (i = 0;i <
loadmodel->surfmesh.num_morphframes;i++)
1533 for (j = 0;j < 3;j++)
1540 out =
loadmodel->surfmesh.data_morphmdlvertex + i *
loadmodel->surfmesh.num_vertices;
1541 for (k = 0;k <
loadmodel->surfmesh.num_vertices;k++)
1542 out[k] =
v[vertremap[k]];
1546 loadmodel->animscenes[i].firstframe = i;
1547 loadmodel->animscenes[i].framecount = 1;
1548 loadmodel->animscenes[i].framerate = 10;
1580 int i, j, k,
version, meshvertices, meshtriangles;
1581 unsigned char *
data;
1595 Host_Error (
"%s has wrong version number (%i should be %i)",
1619 loadmodel->effects = (((unsigned)i & 255) << 24) | (i & 0x00FFFF00);
1629 loadmodel->skinscenes[i].firstframe = i;
1630 loadmodel->skinscenes[i].framecount = 1;
1632 loadmodel->skinscenes[i].framerate = 10;
1640 loadmodel->animscenes[i].firstframe = i;
1641 loadmodel->animscenes[i].framecount = 1;
1642 loadmodel->animscenes[i].framerate = 10;
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");
1677 loadmodel->surfmesh.num_vertices = meshvertices;
1678 loadmodel->surfmesh.num_triangles = meshtriangles;
1685 meshvertices *
sizeof(
float[2])
1687 + meshtriangles *
sizeof(
int[3])
1688 + (meshvertices <= 65536 ? meshtriangles *
sizeof(
unsigned short[3]) : 0));
1690 loadmodel->surfmesh.data_texcoordtexture2f = (
float *)
data;
data += meshvertices *
sizeof(
float[2]);
1692 loadmodel->surfmesh.data_element3i = (
int *)
data;
data += meshtriangles *
sizeof(
int[3]);
1693 if (meshvertices <= 65536)
1695 loadmodel->surfmesh.data_element3s = (
unsigned short *)
data;
data += meshtriangles *
sizeof(
unsigned short[3]);
1708 Host_Error(
"Mod_IDP3_Load: invalid mesh identifier (not IDP3)");
1731 for (j = 0;j <
loadmodel->numframes;j++)
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);
1863 loadmodel->skinscenes[i].firstframe = i;
1864 loadmodel->skinscenes[i].framecount = 1;
1866 loadmodel->skinscenes[i].framerate = 10;
1871 modelradius = pheader->
radius;
1872 for (i = 0;i < 3;i++)
1876 loadmodel->rotatedmins[i] = -modelradius;
1877 loadmodel->rotatedmaxs[i] = modelradius;
1882 if (
loadmodel->yawmaxs[0] > modelradius)
1888 loadmodel->radius2 = modelradius * modelradius;
1903 if ((
unsigned int)
loadmodel->animscenes[i].firstframe >= (
unsigned int) numposes)
1905 if ((
unsigned int)
loadmodel->animscenes[i].firstframe + (
unsigned int)
loadmodel->animscenes[i].framecount > (
unsigned int) numposes)
1907 if (
loadmodel->animscenes[i].framerate < 0)
1916 for (i = 0;i < pheader->
numbones;i++)
1921 if (
loadmodel->data_bones[i].parent >= i)
1928 for (i = 0;i < pheader->
numverts;i++)
1930 vertbonecounts[i] =
BigLong(bonecount[i]);
1931 if (vertbonecounts[i] != 1)
1932 Host_Error(
"%s bonecount[%i] != 1 (vertex weight support is impossible in this format)",
loadmodel->name, i);
1938 meshtriangles = pheader->
numtris;
1944 loadmodel->surfmesh.num_vertices = meshvertices;
1945 loadmodel->surfmesh.num_triangles = meshtriangles;
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]))
1957 +
loadmodel->num_bones *
sizeof(
float[12]));
1959 loadmodel->surfmesh.data_vertex3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
1960 loadmodel->surfmesh.data_svector3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
1961 loadmodel->surfmesh.data_tvector3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
1962 loadmodel->surfmesh.data_normal3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
1963 loadmodel->surfmesh.data_texcoordtexture2f = (
float *)
data;
data += meshvertices *
sizeof(
float[2]);
1966 loadmodel->surfmesh.data_element3i = (
int *)
data;
data += meshtriangles *
sizeof(
int[3]);
1967 loadmodel->surfmesh.blends = (
unsigned short *)
data;
data += meshvertices *
sizeof(
unsigned short);
1968 if (
loadmodel->surfmesh.num_vertices <= 65536)
1970 loadmodel->surfmesh.data_element3s = (
unsigned short *)
data;
data +=
loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3]);
1973 loadmodel->surfmesh.data_skeletalindex4ub = (
unsigned char *)
data;
data += meshvertices *
sizeof(
unsigned char[4]);
1974 loadmodel->surfmesh.data_skeletalweight4ub = (
unsigned char *)
data;
data += meshvertices *
sizeof(
unsigned char[4]);
1988 for (i = 0;i <
loadmodel->num_bones * numposes * 12;i++)
1991 biggestorigin =
max(biggestorigin,
f);
1993 loadmodel->num_posescale = biggestorigin / 32767.0f;
1995 for (i = 0;i < numposes;i++)
1998 for (j = 0;j <
loadmodel->num_bones;j++)
2002 for (k = 0;k < 12;k++)
2003 pose[k] =
BigFloat(frameposes[j*12+k]);
2007 if (
loadmodel->data_bones[j].parent >= 0)
2009 pose[3] *= modelscale;
2010 pose[7] *= modelscale;
2011 pose[11] *= modelscale;
2029 for (i = 0;i <
loadmodel->num_bones;i++)
2032 for (k = 0;k < 12;k++)
2034 if (
loadmodel->data_bones[i].parent >= 0)
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];
2052 loadmodel->surfmesh.data_vertex3f[j*3+0] = relativeorigin[0] * m[0] + relativeorigin[1] * m[1] + relativeorigin[2] * m[ 2] + m[ 3];
2053 loadmodel->surfmesh.data_vertex3f[j*3+1] = relativeorigin[0] * m[4] + relativeorigin[1] * m[5] + relativeorigin[2] * m[ 6] + m[ 7];
2054 loadmodel->surfmesh.data_vertex3f[j*3+2] = relativeorigin[0] * m[8] + relativeorigin[1] * m[9] + relativeorigin[2] * m[10] + m[11];
2056 loadmodel->surfmesh.blends[j] = boneindex;
2057 loadmodel->surfmesh.data_skeletalindex4ub[j*4 ] = boneindex;
2058 loadmodel->surfmesh.data_skeletalindex4ub[j*4+1] = 0;
2059 loadmodel->surfmesh.data_skeletalindex4ub[j*4+2] = 0;
2060 loadmodel->surfmesh.data_skeletalindex4ub[j*4+3] = 0;
2061 loadmodel->surfmesh.data_skeletalweight4ub[j*4 ] = 255;
2062 loadmodel->surfmesh.data_skeletalweight4ub[j*4+1] = 0;
2063 loadmodel->surfmesh.data_skeletalweight4ub[j*4+2] = 0;
2064 loadmodel->surfmesh.data_skeletalweight4ub[j*4+3] = 0;
2070 outtexcoord2f =
loadmodel->surfmesh.data_texcoordtexture2f;
2072 for (i = 0;i < pheader->
numverts;i++)
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);
2092 for (i = 0;i <
loadmodel->num_surfaces;i++)
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]);
2141 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
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;
2270 loadmodel->surfmesh.num_vertices = meshvertices;
2271 loadmodel->surfmesh.num_triangles = meshtriangles;
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]))
2282 +
loadmodel->num_bones *
sizeof(
float[12]));
2284 loadmodel->surfmesh.data_vertex3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
2285 loadmodel->surfmesh.data_svector3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
2286 loadmodel->surfmesh.data_tvector3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
2287 loadmodel->surfmesh.data_normal3f = (
float *)
data;
data += meshvertices *
sizeof(
float[3]);
2288 loadmodel->surfmesh.data_texcoordtexture2f = (
float *)
data;
data += meshvertices *
sizeof(
float[2]);
2291 loadmodel->surfmesh.data_element3i = (
int *)
data;
data += meshtriangles *
sizeof(
int[3]);
2292 loadmodel->surfmesh.blends = (
unsigned short *)
data;
data += meshvertices *
sizeof(
unsigned short);
2293 if (meshvertices <= 65536)
2295 loadmodel->surfmesh.data_element3s = (
unsigned short *)
data;
data += meshtriangles *
sizeof(
unsigned short[3]);
2298 loadmodel->surfmesh.data_skeletalindex4ub = (
unsigned char *)
data;
data += meshvertices *
sizeof(
unsigned char[4]);
2299 loadmodel->surfmesh.data_skeletalweight4ub = (
unsigned char *)
data;
data += meshvertices *
sizeof(
unsigned char[4]);
2311 loadmodel->skinscenes[i].firstframe = i;
2312 loadmodel->skinscenes[i].framecount = 1;
2314 loadmodel->skinscenes[i].framerate = 10;
2319 for (i = 0;i <
loadmodel->num_bones;i++)
2324 if (
loadmodel->data_bones[i].parent >= i)
2331 poses = (
float *) (pbase +
BigLong(frames[0].ofs_bonepositions));
2337 for (i = 0;i <
loadmodel->numframes;i++)
2340 loadmodel->animscenes[i].firstframe = i;
2341 loadmodel->animscenes[i].framecount = 1;
2343 loadmodel->animscenes[i].framerate = 10;
2345 poses = (
float *) (pbase +
BigLong(frames[i].ofs_bonepositions));
2346 for (j = 0;j <
loadmodel->num_bones*12;j++)
2349 biggestorigin =
max(biggestorigin,
f);
2353 loadmodel->num_posescale = biggestorigin / 32767.0f;
2355 for (i = 0;i <
loadmodel->numframes;i++)
2357 const float *frameposes = (
float *) (pbase +
BigLong(frames[i].ofs_bonepositions));
2358 for (j = 0;j <
loadmodel->num_bones;j++)
2362 for (k = 0;k < 12;k++)
2363 pose[k] =
BigFloat(frameposes[j*12+k]);
2365 if (
loadmodel->data_bones[j].parent >= 0)
2367 pose[3] *= modelscale;
2368 pose[7] *= modelscale;
2369 pose[11] *= modelscale;
2387 poses = (
float *) (pbase +
BigLong(frames[0].ofs_bonepositions));
2389 for (i = 0;i <
loadmodel->num_bones;i++)
2392 for (k = 0;k < 12;k++)
2394 if (
loadmodel->data_bones[i].parent >= 0)
2397 for (k = 0;k < 12;k++)
2398 bonepose[12*i+k] = m[k];
2400 for (i = 0;i <
loadmodel->num_surfaces;i++, dpmmesh++)
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];
2461 loadmodel->surfmesh.data_vertex3f[j*3+0] += relativeorigin[0] * m[0] + relativeorigin[1] * m[1] + relativeorigin[2] * m[ 2] + influence * m[ 3];
2462 loadmodel->surfmesh.data_vertex3f[j*3+1] += relativeorigin[0] * m[4] + relativeorigin[1] * m[5] + relativeorigin[2] * m[ 6] + influence * m[ 7];
2463 loadmodel->surfmesh.data_vertex3f[j*3+2] += relativeorigin[0] * m[8] + relativeorigin[1] * m[9] + relativeorigin[2] * m[10] + influence * m[11];
2464 loadmodel->surfmesh.data_normal3f[j*3+0] += relativenormal[0] * m[0] + relativenormal[1] * m[1] + relativenormal[2] * m[ 2];
2465 loadmodel->surfmesh.data_normal3f[j*3+1] += relativenormal[0] * m[4] + relativenormal[1] * m[5] + relativenormal[2] * m[ 6];
2466 loadmodel->surfmesh.data_normal3f[j*3+2] += relativenormal[0] * m[8] + relativenormal[1] * m[9] + relativenormal[2] * m[10];
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;
2498 loadmodel->surfmesh.data_skeletalindex4ub[j*4 ] = weightindex[0];
2499 loadmodel->surfmesh.data_skeletalindex4ub[j*4+1] = weightindex[1];
2500 loadmodel->surfmesh.data_skeletalindex4ub[j*4+2] = weightindex[2];
2501 loadmodel->surfmesh.data_skeletalindex4ub[j*4+3] = weightindex[3];
2502 loadmodel->surfmesh.data_skeletalweight4ub[j*4 ] = (
unsigned char)(weightinfluence[0]*255.0f);
2503 loadmodel->surfmesh.data_skeletalweight4ub[j*4+1] = (
unsigned char)(weightinfluence[1]*255.0f);
2504 loadmodel->surfmesh.data_skeletalweight4ub[j*4+2] = (
unsigned char)(weightinfluence[2]*255.0f);
2505 loadmodel->surfmesh.data_skeletalweight4ub[j*4+3] = (
unsigned char)(weightinfluence[3]*255.0f);
2513 if (
loadmodel->surfmesh.num_blends < meshvertices)
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"))
2563 Host_Error (
"Mod_PSKMODEL_Load: %s is not an Unreal Engine ActorX (.psk + .psa) model",
loadmodel->name);
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)
2804 Host_Error(
"%s: this loader only supports animations with the same bones as the mesh",
loadmodel->name);
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)
2912 if (numanimkeys != numbones *
loadmodel->numframes)
2913 Host_Error(
"%s: %s has incorrect number of animation keys", animname, pchunk->
id);
2918 meshvertices = numvtxw;
2919 meshtriangles = numfaces;
2931 loadmodel->surfmesh.num_vertices = meshvertices;
2932 loadmodel->surfmesh.num_triangles = meshtriangles;
2937 loadmodel->surfmesh.num_vertices *
sizeof(
float[3])
2938 +
loadmodel->surfmesh.num_vertices *
sizeof(
float[3])
2939 +
loadmodel->surfmesh.num_vertices *
sizeof(
float[3])
2940 +
loadmodel->surfmesh.num_vertices *
sizeof(
float[3])
2941 +
loadmodel->surfmesh.num_vertices *
sizeof(
float[2])
2942 +
loadmodel->num_bones *
sizeof(
float[12])
2944 +
loadmodel->surfmesh.num_triangles *
sizeof(
int[3])
2945 +
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned short)
2946 + ((
loadmodel->surfmesh.num_vertices <= 65536) ? (
loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3])) : 0)
2948 +
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned char[4])
2949 +
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned char[4]));
2961 if (
loadmodel->surfmesh.num_vertices <= 65536)
2963 loadmodel->surfmesh.data_element3s = (
unsigned short *)
data;
data +=
loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3]);
2966 loadmodel->surfmesh.data_skeletalindex4ub = (
unsigned char *)
data;
data +=
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned char[4]);
2967 loadmodel->surfmesh.data_skeletalweight4ub = (
unsigned char *)
data;
data +=
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned char[4]);
2979 loadmodel->skinscenes[i].firstframe = i;
2980 loadmodel->skinscenes[i].framecount = 1;
2982 loadmodel->skinscenes[i].framerate = 10;
3037 float *outinvmatrix =
loadmodel->data_baseboneposeinverse;
3041 for (boneindex = 0;boneindex <
loadmodel->num_bones;boneindex++)
3044 if (
loadmodel->data_bones[boneindex].parent >= 0)
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;
3089 loadmodel->surfmesh.data_skeletalindex4ub[
index*4 ] = weightindex[0];
3090 loadmodel->surfmesh.data_skeletalindex4ub[
index*4+1] = weightindex[1];
3091 loadmodel->surfmesh.data_skeletalindex4ub[
index*4+2] = weightindex[2];
3092 loadmodel->surfmesh.data_skeletalindex4ub[
index*4+3] = weightindex[3];
3093 loadmodel->surfmesh.data_skeletalweight4ub[
index*4 ] = (
unsigned char)(weightinfluence[0]*255.0f);
3094 loadmodel->surfmesh.data_skeletalweight4ub[
index*4+1] = (
unsigned char)(weightinfluence[1]*255.0f);
3095 loadmodel->surfmesh.data_skeletalweight4ub[
index*4+2] = (
unsigned char)(weightinfluence[2]*255.0f);
3096 loadmodel->surfmesh.data_skeletalweight4ub[
index*4+3] = (
unsigned char)(weightinfluence[3]*255.0f);
3109 loadmodel->animscenes[i].firstframe = i;
3110 loadmodel->animscenes[i].framecount = 1;
3124 loadmodel->num_posescale = biggestorigin / 32767.0f;
3151 loadmodel->animscenes[0].firstframe = 0;
3152 loadmodel->animscenes[0].framecount = 1;
3154 loadmodel->animscenes[0].framerate = 10;
3165 loadmodel->num_posescale = biggestorigin / 32767.0f;
3198 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
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);
3436 loadmodel->surfmesh.num_vertices * (
sizeof(
float[14]) + (vcolor4f || vcolor4ub ?
sizeof(
float[4]) : 0))
3437 +
loadmodel->num_bones *
sizeof(
float[12])
3439 +
loadmodel->surfmesh.num_triangles *
sizeof(
int[3])
3440 + (
loadmodel->surfmesh.num_vertices <= 65536 ?
loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3]) : 0)
3442 + (vblendindexes && vblendweights ?
loadmodel->surfmesh.num_vertices * (
sizeof(
unsigned short) +
sizeof(
unsigned char[2][4])) : 0));
3449 if (vcolor4f || vcolor4ub)
3457 if (
loadmodel->surfmesh.num_vertices <= 65536)
3459 loadmodel->surfmesh.data_element3s = (
unsigned short *)
data;
data +=
loadmodel->surfmesh.num_triangles *
sizeof(
unsigned short[3]);
3461 if (vblendindexes && vblendweights)
3465 loadmodel->surfmesh.data_skeletalindex4ub = (
unsigned char *)
data;
data +=
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned char[4]);
3466 loadmodel->surfmesh.data_skeletalweight4ub = (
unsigned char *)
data;
data +=
loadmodel->surfmesh.num_vertices *
sizeof(
unsigned char[4]);
3475 if (vblendindexes && vblendweights)
3480 loadmodel->skinscenes[i].firstframe = i;
3481 loadmodel->skinscenes[i].framecount = 1;
3483 loadmodel->skinscenes[i].framerate = 10;
3493 for (i = 0;i <
loadmodel->num_bones;i++)
3495 matrix4x4_t relbase, relinvbase, pinvbase, invbase;
3498 memcpy(&injoint1, &injoints1[i],
sizeof(
iqmjoint1_t));
3501 for (j = 0;j < 3;j++)
3509 if (
loadmodel->data_bones[i].parent >= i)
3513 if (
loadmodel->data_bones[i].parent >= 0)
3528 for (i = 0;i <
loadmodel->num_bones;i++)
3530 matrix4x4_t relbase, relinvbase, pinvbase, invbase;
3533 memcpy(&injoint, &injoints[i],
sizeof(
iqmjoint_t));
3536 for (j = 0;j < 3;j++)
3545 if (
loadmodel->data_bones[i].parent >= i)
3547 if (joint[i].rotation[3] > 0)
3552 if (
loadmodel->data_bones[i].parent >= 0)
3567 memcpy(&anim, &anims[i],
sizeof(
iqmanim_t));
3582 loadmodel->animscenes[0].firstframe = 0;
3583 loadmodel->animscenes[0].framecount = 1;
3585 loadmodel->animscenes[0].framerate = 10;
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);
3621 for (i = 0;i <
loadmodel->num_bones;i++)
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);
3658 for (i = 0;i <
loadmodel->num_bones;i++)
3667 loadmodel->num_posescale = biggestorigin / 32767.0f;
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;
3688 loadmodel->data_poses7s[k*7 + 3] = 32767.0f * qx;
3689 loadmodel->data_poses7s[k*7 + 4] = 32767.0f * qy;
3690 loadmodel->data_poses7s[k*7 + 5] = 32767.0f * qz;
3691 loadmodel->data_poses7s[k*7 + 6] = 32767.0f * qw;
3693 if(pose1[j].channelmask&64) framedata++;
3694 if(pose1[j].channelmask&128) framedata++;
3695 if(pose1[j].channelmask&256) framedata++;
3700 for (i = 0;i <
loadmodel->num_bones;i++)
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;
3711 loadmodel->data_poses7s[i*7 + 3] = 32767.0f * qx;
3712 loadmodel->data_poses7s[i*7 + 4] = 32767.0f * qy;
3713 loadmodel->data_poses7s[i*7 + 5] = 32767.0f * qz;
3714 loadmodel->data_poses7s[i*7 + 6] = 32767.0f * qw;
3735 loadmodel->data_poses7s[k*7 + 3] = 32767.0f * rot[0];
3736 loadmodel->data_poses7s[k*7 + 4] = 32767.0f * rot[1];
3737 loadmodel->data_poses7s[k*7 + 5] = 32767.0f * rot[2];
3738 loadmodel->data_poses7s[k*7 + 6] = 32767.0f * rot[3];
3740 if(pose[j].channelmask&128) framedata++;
3741 if(pose[j].channelmask&256) framedata++;
3742 if(pose[j].channelmask&512) framedata++;
3747 for (i = 0;i <
loadmodel->num_bones;i++)
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);
3809 outelements =
loadmodel->surfmesh.data_element3i;
3819 for (i = 0;i <
loadmodel->surfmesh.num_triangles*3;i++)
3825 outvertex =
loadmodel->surfmesh.data_vertex3f;
3835 outtexcoord =
loadmodel->surfmesh.data_texcoordtexture2f;
3848 outnormal =
loadmodel->surfmesh.data_normal3f;
3860 if(vnormal && vtangent)
3862 outnormal =
loadmodel->surfmesh.data_normal3f;
3863 outsvector =
loadmodel->surfmesh.data_svector3f;
3864 outtvector =
loadmodel->surfmesh.data_tvector3f;
3882 if (vblendindexes && vblendweights)
3887 memcpy(weights.
index, vblendindexes + i*4, 4);
3888 memcpy(weights.
influence, vblendweights + i*4, 4);
3890 loadmodel->surfmesh.data_skeletalindex4ub[i*4 ] = weights.
index[0];
3891 loadmodel->surfmesh.data_skeletalindex4ub[i*4+1] = weights.
index[1];
3892 loadmodel->surfmesh.data_skeletalindex4ub[i*4+2] = weights.
index[2];
3893 loadmodel->surfmesh.data_skeletalindex4ub[i*4+3] = weights.
index[3];
3903 outcolor =
loadmodel->surfmesh.data_lightmapcolor4f;
3917 outcolor =
loadmodel->surfmesh.data_lightmapcolor4f;
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
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
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)