mod_md3_sin[i] = sin(i * M_PI * 2.0f / 256.0);
}
-void Mod_Skeletal_AnimateVertices(const dp_model_t *model, const frameblend_t *frameblend, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f)
+void Mod_Skeletal_AnimateVertices(const dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f)
{
#define MAX_BONES 256
// vertex weighted skeletal
float boneposerelative[MAX_BONES][12];
float *matrix, m[12], bonepose[MAX_BONES][12];
- // interpolate matrices and concatenate them to their parents
- for (i = 0;i < model->num_bones;i++)
+ if (skeleton && !skeleton->relativetransforms)
+ skeleton = NULL;
+
+ // interpolate matrices
+ if (skeleton)
{
- for (k = 0;k < 12;k++)
- m[k] = 0;
- VectorClear(desiredscale);
- for (blends = 0;blends < MAX_FRAMEBLENDS && frameblend[blends].lerp > 0;blends++)
+ for (i = 0;i < model->num_bones;i++)
{
- matrix = model->data_poses + (frameblend[blends].subframe * model->num_bones + i) * 12;
- for (k = 0;k < 12;k++)
- m[k] += matrix[k] * frameblend[blends].lerp;
- desiredscale[0] += frameblend[blends].lerp * VectorLength(matrix );
- desiredscale[1] += frameblend[blends].lerp * VectorLength(matrix + 4);
- desiredscale[2] += frameblend[blends].lerp * VectorLength(matrix + 8);
+ Matrix4x4_ToArray12FloatD3D(&skeleton->relativetransforms[i], m);
+ if (model->data_bones[i].parent >= 0)
+ R_ConcatTransforms(bonepose[model->data_bones[i].parent], m, bonepose[i]);
+ else
+ for (k = 0;k < 12;k++)
+ bonepose[i][k] = m[k];
+
+ // create a relative deformation matrix to describe displacement
+ // from the base mesh, which is used by the actual weighting
+ R_ConcatTransforms(bonepose[i], model->data_baseboneposeinverse + i * 12, boneposerelative[i]);
}
- VectorNormalize(m );
- VectorNormalize(m + 4);
- VectorNormalize(m + 8);
- VectorScale(m , desiredscale[0], m );
- VectorScale(m + 4, desiredscale[1], m + 4);
- VectorScale(m + 8, desiredscale[2], m + 8);
- if (i == r_skeletal_debugbone.integer)
- m[r_skeletal_debugbonecomponent.integer % 12] += r_skeletal_debugbonevalue.value;
- m[3] *= r_skeletal_debugtranslatex.value;
- m[7] *= r_skeletal_debugtranslatey.value;
- m[11] *= r_skeletal_debugtranslatez.value;
- if (model->data_bones[i].parent >= 0)
- R_ConcatTransforms(bonepose[model->data_bones[i].parent], m, bonepose[i]);
- else
+ }
+ else
+ {
+ for (i = 0;i < model->num_bones;i++)
+ {
for (k = 0;k < 12;k++)
- bonepose[i][k] = m[k];
- // create a relative deformation matrix to describe displacement
- // from the base mesh, which is used by the actual weighting
- R_ConcatTransforms(bonepose[i], model->data_baseboneposeinverse + i * 12, boneposerelative[i]);
+ m[k] = 0;
+ VectorClear(desiredscale);
+ for (blends = 0;blends < MAX_FRAMEBLENDS && frameblend[blends].lerp > 0;blends++)
+ {
+ matrix = model->data_poses + (frameblend[blends].subframe * model->num_bones + i) * 12;
+ for (k = 0;k < 12;k++)
+ m[k] += matrix[k] * frameblend[blends].lerp;
+ desiredscale[0] += frameblend[blends].lerp * VectorLength(matrix );
+ desiredscale[1] += frameblend[blends].lerp * VectorLength(matrix + 4);
+ desiredscale[2] += frameblend[blends].lerp * VectorLength(matrix + 8);
+ }
+ VectorNormalize(m );
+ VectorNormalize(m + 4);
+ VectorNormalize(m + 8);
+ VectorScale(m , desiredscale[0], m );
+ VectorScale(m + 4, desiredscale[1], m + 4);
+ VectorScale(m + 8, desiredscale[2], m + 8);
+ if (i == r_skeletal_debugbone.integer)
+ m[r_skeletal_debugbonecomponent.integer % 12] += r_skeletal_debugbonevalue.value;
+ m[3] *= r_skeletal_debugtranslatex.value;
+ m[7] *= r_skeletal_debugtranslatey.value;
+ m[11] *= r_skeletal_debugtranslatez.value;
+ if (model->data_bones[i].parent >= 0)
+ R_ConcatTransforms(bonepose[model->data_bones[i].parent], m, bonepose[i]);
+ else
+ for (k = 0;k < 12;k++)
+ bonepose[i][k] = m[k];
+ // create a relative deformation matrix to describe displacement
+ // from the base mesh, which is used by the actual weighting
+ R_ConcatTransforms(bonepose[i], model->data_baseboneposeinverse + i * 12, boneposerelative[i]);
+ }
}
+
// blend the vertex bone weights
// special case for the extremely common wf[0] == 1 because it saves 3 multiplies per array when compared to the other case (w[0] is always 1 if only one bone controls this vertex, artists only use multiple bones for certain special cases)
// special case for the first bone because it avoids the need to memset the arrays before filling
+ if (vertex3f)
{
const float *v = model->surfmesh.data_vertex3f;
const int *wi = model->surfmesh.data_vertexweightindex4i;
}
}
-void Mod_MD3_AnimateVertices(const dp_model_t *model, const frameblend_t *frameblend, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f)
+void Mod_MD3_AnimateVertices(const dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f)
{
// vertex morph
int i, numblends, blendnum;
for (blendnum = 0;blendnum < numblends;blendnum++)
{
const md3vertex_t *verts = model->surfmesh.data_morphmd3vertex + numverts * frameblend[blendnum].subframe;
- float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
- if (blendnum == 0)
+ if (vertex3f)
{
- for (i = 0;i < numverts;i++)
+ float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
+ if (blendnum == 0)
{
- vertex3f[i * 3 + 0] = verts[i].origin[0] * scale;
- vertex3f[i * 3 + 1] = verts[i].origin[1] * scale;
- vertex3f[i * 3 + 2] = verts[i].origin[2] * scale;
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] = verts[i].origin[0] * scale;
+ vertex3f[i * 3 + 1] = verts[i].origin[1] * scale;
+ vertex3f[i * 3 + 2] = verts[i].origin[2] * scale;
+ }
}
- }
- else
- {
- for (i = 0;i < numverts;i++)
+ else
{
- vertex3f[i * 3 + 0] += verts[i].origin[0] * scale;
- vertex3f[i * 3 + 1] += verts[i].origin[1] * scale;
- vertex3f[i * 3 + 2] += verts[i].origin[2] * scale;
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] += verts[i].origin[0] * scale;
+ vertex3f[i * 3 + 1] += verts[i].origin[1] * scale;
+ vertex3f[i * 3 + 2] += verts[i].origin[2] * scale;
+ }
}
}
// the yaw and pitch stored in md3 models are 8bit quantized angles
}
}
-void Mod_MDL_AnimateVertices(const dp_model_t *model, const frameblend_t *frameblend, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f)
+void Mod_MDL_AnimateVertices(const dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f)
{
// vertex morph
int i, numblends, blendnum;
for (blendnum = 0;blendnum < numblends;blendnum++)
{
const trivertx_t *verts = model->surfmesh.data_morphmdlvertex + numverts * frameblend[blendnum].subframe;
- float scale[3];
- if (model->surfmesh.data_morphmd2framesize6f)
- VectorScale(model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp, scale);
- else
- VectorScale(model->surfmesh.num_morphmdlframescale, frameblend[blendnum].lerp, scale);
- if (blendnum == 0)
+ if (vertex3f)
{
- for (i = 0;i < numverts;i++)
+ float scale[3];
+ if (model->surfmesh.data_morphmd2framesize6f)
+ VectorScale(model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp, scale);
+ else
+ VectorScale(model->surfmesh.num_morphmdlframescale, frameblend[blendnum].lerp, scale);
+ if (blendnum == 0)
{
- vertex3f[i * 3 + 0] = translate[0] + verts[i].v[0] * scale[0];
- vertex3f[i * 3 + 1] = translate[1] + verts[i].v[1] * scale[1];
- vertex3f[i * 3 + 2] = translate[2] + verts[i].v[2] * scale[2];
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] = translate[0] + verts[i].v[0] * scale[0];
+ vertex3f[i * 3 + 1] = translate[1] + verts[i].v[1] * scale[1];
+ vertex3f[i * 3 + 2] = translate[2] + verts[i].v[2] * scale[2];
+ }
}
- }
- else
- {
- for (i = 0;i < numverts;i++)
+ else
{
- vertex3f[i * 3 + 0] += verts[i].v[0] * scale[0];
- vertex3f[i * 3 + 1] += verts[i].v[1] * scale[1];
- vertex3f[i * 3 + 2] += verts[i].v[2] * scale[2];
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] += verts[i].v[0] * scale[0];
+ vertex3f[i * 3 + 1] += verts[i].v[1] * scale[1];
+ vertex3f[i * 3 + 2] += verts[i].v[2] * scale[2];
+ }
}
}
// the vertex normals in mdl models are an index into a table of
}
}
-int Mod_Alias_GetTagMatrix(const dp_model_t *model, int poseframe, int tagindex, matrix4x4_t *outmatrix)
+int Mod_Alias_GetTagMatrix(const dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, int tagindex, matrix4x4_t *outmatrix)
{
+ matrix4x4_t temp;
const float *boneframe;
- float tempbonematrix[12], bonematrix[12];
+ const float *input;
+ int blendindex;
+ int parenttagindex;
+ int k;
+ float lerp;
+ float tempbonematrix[12], bonematrix[12], blendmatrix[12];
*outmatrix = identitymatrix;
- if (model->num_bones)
+ if (skeleton && skeleton->relativetransforms)
+ {
+ if (tagindex < 0 || tagindex >= skeleton->model->num_bones)
+ return 4;
+ *outmatrix = skeleton->relativetransforms[tagindex];
+ while ((tagindex = model->data_bones[tagindex].parent) >= 0)
+ {
+ temp = *outmatrix;
+ Matrix4x4_Concat(outmatrix, &skeleton->relativetransforms[tagindex], &temp);
+ }
+ }
+ else if (model->num_bones)
{
if (tagindex < 0 || tagindex >= model->num_bones)
return 4;
- if (poseframe >= model->num_poses)
- return 6;
- boneframe = model->data_poses + poseframe * model->num_bones * 12;
- memcpy(bonematrix, boneframe + tagindex * 12, sizeof(float[12]));
- while (model->data_bones[tagindex].parent >= 0)
+ for (k = 0;k < 12;k++)
+ blendmatrix[k] = 0;
+ for (blendindex = 0;blendindex < MAX_FRAMEBLENDS && frameblend[blendindex].lerp > 0;blendindex++)
{
- memcpy(tempbonematrix, bonematrix, sizeof(float[12]));
- R_ConcatTransforms(boneframe + model->data_bones[tagindex].parent * 12, tempbonematrix, bonematrix);
- tagindex = model->data_bones[tagindex].parent;
+ lerp = frameblend[blendindex].lerp;
+ boneframe = model->data_poses + frameblend[blendindex].subframe * model->num_bones * 12;
+ input = boneframe + tagindex * 12;
+ for (k = 0;k < 12;k++)
+ bonematrix[k] = input[k];
+ parenttagindex = tagindex;
+ while ((parenttagindex = model->data_bones[parenttagindex].parent) >= 0)
+ {
+ for (k = 0;k < 12;k++)
+ tempbonematrix[k] = bonematrix[k];
+ input = boneframe + parenttagindex * 12;
+ R_ConcatTransforms(input, tempbonematrix, bonematrix);
+ }
+ for (k = 0;k < 12;k++)
+ blendmatrix[k] += bonematrix[k] * lerp;
}
- Matrix4x4_FromArray12FloatD3D(outmatrix, bonematrix);
+ Matrix4x4_FromArray12FloatD3D(outmatrix, blendmatrix);
}
else if (model->num_tags)
{
if (tagindex < 0 || tagindex >= model->num_tags)
return 4;
- if (poseframe >= model->num_tagframes)
- return 6;
- Matrix4x4_FromArray12FloatGL(outmatrix, model->data_tags[poseframe * model->num_tags + tagindex].matrixgl);
+ for (k = 0;k < 12;k++)
+ blendmatrix[k] = 0;
+ for (blendindex = 0;blendindex < MAX_FRAMEBLENDS && frameblend[blendindex].lerp > 0;blendindex++)
+ {
+ lerp = frameblend[blendindex].lerp;
+ input = model->data_tags[frameblend[blendindex].subframe * model->num_tags + tagindex].matrixgl;
+ for (k = 0;k < 12;k++)
+ blendmatrix[k] += input[k] * lerp;
+ }
+ Matrix4x4_FromArray12FloatGL(outmatrix, blendmatrix);
}
if(!mod_alias_supporttagscale.integer)
return 0;
}
-int Mod_Alias_GetExtendedTagInfoForIndex(const dp_model_t *model, unsigned int skin, int poseframe, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
+int Mod_Alias_GetExtendedTagInfoForIndex(const dp_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)
{
const float *boneframe;
+ const float *input;
+ int blendindex;
+ int k;
+ float lerp;
+ float blendmatrix[12];
- if(skin >= (unsigned int)model->numskins)
- skin = 0;
-
- if (model->num_bones)
+ if (skeleton && skeleton->relativetransforms)
+ {
+ if (tagindex < 0 || tagindex >= skeleton->model->num_bones)
+ return 1;
+ *parentindex = skeleton->model->data_bones[tagindex].parent;
+ *tagname = skeleton->model->data_bones[tagindex].name;
+ *tag_localmatrix = skeleton->relativetransforms[tagindex];
+ return 0;
+ }
+ else if (model->num_bones)
{
if(tagindex >= model->num_bones || tagindex < 0)
return 1;
- if (poseframe >= model->num_poses)
- return 2;
-
- boneframe = model->data_poses + poseframe * model->num_bones * 12;
*parentindex = model->data_bones[tagindex].parent;
*tagname = model->data_bones[tagindex].name;
- Matrix4x4_FromArray12FloatD3D(tag_localmatrix, boneframe + tagindex * 12);
+ for (blendindex = 0;blendindex < MAX_FRAMEBLENDS && frameblend[blendindex].lerp > 0;blendindex++)
+ {
+ lerp = frameblend[blendindex].lerp;
+ boneframe = model->data_poses + frameblend[blendindex].subframe * model->num_bones * 12;
+ input = boneframe + tagindex * 12;
+ for (k = 0;k < 12;k++)
+ blendmatrix[k] += input[k] * lerp;
+ }
+ Matrix4x4_FromArray12FloatD3D(tag_localmatrix, blendmatrix);
return 0;
}
-
- if (model->num_tags)
+ else if (model->num_tags)
{
if(tagindex >= model->num_tags || tagindex < 0)
return 1;
- if (poseframe >= model->num_tagframes)
- return 2;
+ *parentindex = -1;
*tagname = model->data_tags[tagindex].name;
- Matrix4x4_FromArray12FloatGL(tag_localmatrix, model->data_tags[poseframe * model->num_tags + tagindex].matrixgl);
+ for (blendindex = 0;blendindex < MAX_FRAMEBLENDS && frameblend[blendindex].lerp > 0;blendindex++)
+ {
+ lerp = frameblend[blendindex].lerp;
+ input = model->data_tags[frameblend[blendindex].subframe * model->num_tags + tagindex].matrixgl;
+ for (k = 0;k < 12;k++)
+ blendmatrix[k] += input[k] * lerp;
+ }
+ Matrix4x4_FromArray12FloatGL(tag_localmatrix, blendmatrix);
return 0;
}
{
int i, k;
double scale;
- float *basebonepose = (float *) Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
+ float *basebonepose;
float *in12f = loadmodel->data_poses;
- float *out12f = basebonepose;
+ float *out12f;
float *outinv12f = loadmodel->data_baseboneposeinverse;
+ if (!loadmodel->num_bones)
+ return;
+ out12f = basebonepose = (float *) Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
for (i = 0;i < loadmodel->num_bones;i++, in12f += 12, out12f += 12, outinv12f += 12)
{
if (loadmodel->data_bones[i].parent >= 0)
radius = 0;
for (frameblend[0].subframe = 0;frameblend[0].subframe < loadmodel->num_poses;frameblend[0].subframe++)
{
- loadmodel->AnimateVertices(loadmodel, frameblend, vertex3f, NULL, NULL, NULL);
+ loadmodel->AnimateVertices(loadmodel, frameblend, NULL, vertex3f, NULL, NULL, NULL);
for (vnum = 0, v = vertex3f;vnum < loadmodel->surfmesh.num_vertices;vnum++, v += 3)
{
if (firstvertex)
for (i = loadmodel->surfmesh.num_morphframes-1;i >= 0;i--)
{
frameblend[0].subframe = i;
- loadmodel->AnimateVertices(loadmodel, frameblend, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_normal3f, NULL, NULL);
- Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer);
+ loadmodel->AnimateVertices(loadmodel, frameblend, NULL, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_normal3f, NULL, NULL);
+ Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0);
// encode the svector and tvector in 3 byte format for permanent storage
for (j = 0;j < loadmodel->surfmesh.num_vertices;j++)
{
}
}
-static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, int frame, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
+static void Mod_MDLMD2MD3_TraceLine(dp_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 i;
float segmentmins[3], segmentmaxs[3];
- frameblend_t frameblend[MAX_FRAMEBLENDS];
msurface_t *surface;
static int maxvertices = 0;
static float *vertex3f = NULL;
trace->fraction = 1;
trace->realfraction = 1;
trace->hitsupercontentsmask = hitsupercontentsmask;
- memset(frameblend, 0, sizeof(frameblend));
- frameblend[0].subframe = frame;
- frameblend[0].lerp = 1;
if (maxvertices < model->surfmesh.num_vertices)
{
if (vertex3f)
maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
}
- if (VectorLength2(boxmins) + VectorLength2(boxmaxs) == 0)
+ segmentmins[0] = min(start[0], end[0]) - 1;
+ segmentmins[1] = min(start[1], end[1]) - 1;
+ segmentmins[2] = min(start[2], end[2]) - 1;
+ segmentmaxs[0] = max(start[0], end[0]) + 1;
+ segmentmaxs[1] = max(start[1], end[1]) + 1;
+ segmentmaxs[2] = max(start[2], end[2]) + 1;
+ model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL);
+ for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+ Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
+}
+
+static int maxvertices = 0;
+static float *vertex3f = NULL;
+
+static void Mod_MDLMD2MD3_TraceBox(dp_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 i;
+ vec3_t shiftstart, shiftend;
+ float segmentmins[3], segmentmaxs[3];
+ msurface_t *surface;
+ colboxbrushf_t thisbrush_start, thisbrush_end;
+ vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
+
+ if (VectorCompare(boxmins, boxmaxs))
{
- // line trace
- segmentmins[0] = min(start[0], end[0]) - 1;
- segmentmins[1] = min(start[1], end[1]) - 1;
- segmentmins[2] = min(start[2], end[2]) - 1;
- segmentmaxs[0] = max(start[0], end[0]) + 1;
- segmentmaxs[1] = max(start[1], end[1]) + 1;
- segmentmaxs[2] = max(start[2], end[2]) + 1;
- for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
- {
- model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
- Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
- }
+ VectorAdd(start, boxmins, shiftstart);
+ VectorAdd(end, boxmins, shiftend);
+ Mod_MDLMD2MD3_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask);
+ VectorSubtract(trace->endpos, boxmins, trace->endpos);
+ return;
}
- else
+
+ // box trace, performed as brush trace
+ memset(trace, 0, sizeof(*trace));
+ trace->fraction = 1;
+ trace->realfraction = 1;
+ trace->hitsupercontentsmask = hitsupercontentsmask;
+ if (maxvertices < model->surfmesh.num_vertices)
{
- // box trace, performed as brush trace
- colbrushf_t *thisbrush_start, *thisbrush_end;
- vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
- segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
- segmentmins[1] = min(start[1], end[1]) + boxmins[1] - 1;
- segmentmins[2] = min(start[2], end[2]) + boxmins[2] - 1;
- segmentmaxs[0] = max(start[0], end[0]) + boxmaxs[0] + 1;
- segmentmaxs[1] = max(start[1], end[1]) + boxmaxs[1] + 1;
- segmentmaxs[2] = max(start[2], end[2]) + boxmaxs[2] + 1;
- VectorAdd(start, boxmins, boxstartmins);
- VectorAdd(start, boxmaxs, boxstartmaxs);
- VectorAdd(end, boxmins, boxendmins);
- VectorAdd(end, boxmaxs, boxendmaxs);
- thisbrush_start = Collision_BrushForBox(&identitymatrix, boxstartmins, boxstartmaxs, 0, 0, NULL);
- thisbrush_end = Collision_BrushForBox(&identitymatrix, boxendmins, boxendmaxs, 0, 0, NULL);
- for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
- {
- if (maxvertices < model->surfmesh.num_vertices)
- {
- if (vertex3f)
- Z_Free(vertex3f);
- maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
- vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
- }
- model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
- Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
- }
+ if (vertex3f)
+ Z_Free(vertex3f);
+ maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
+ vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
}
+ segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
+ segmentmins[1] = min(start[1], end[1]) + boxmins[1] - 1;
+ segmentmins[2] = min(start[2], end[2]) + boxmins[2] - 1;
+ segmentmaxs[0] = max(start[0], end[0]) + boxmaxs[0] + 1;
+ segmentmaxs[1] = max(start[1], end[1]) + boxmaxs[1] + 1;
+ segmentmaxs[2] = max(start[2], end[2]) + boxmaxs[2] + 1;
+ VectorAdd(start, boxmins, boxstartmins);
+ VectorAdd(start, boxmaxs, boxstartmaxs);
+ VectorAdd(end, boxmins, boxendmins);
+ VectorAdd(end, boxmaxs, boxendmaxs);
+ Collision_BrushForBox(&thisbrush_start, boxstartmins, boxstartmaxs, 0, 0, NULL);
+ Collision_BrushForBox(&thisbrush_end, boxendmins, boxendmaxs, 0, 0, NULL);
+ if (maxvertices < model->surfmesh.num_vertices)
+ {
+ if (vertex3f)
+ Z_Free(vertex3f);
+ maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
+ vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
+ }
+ model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL);
+ for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+ Collision_TraceBrushTriangleMeshFloat(trace, &thisbrush_start.brush, &thisbrush_end.brush, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
}
static void Mod_ConvertAliasVerts (int inverts, trivertx_t *v, trivertx_t *out, int *vertremap)
//texture->textureflags = 0;
texture->basematerialflags = MATERIALFLAG_WALL;
- if (texture->currentskinframe->fog)
+ if (texture->currentskinframe->hasalpha)
texture->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
texture->currentmaterialflags = texture->basematerialflags;
}
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
loadmodel->PointSuperContents = NULL;
loadmodel->num_surfaces = 1;
// generate ushort elements array if possible
if (loadmodel->surfmesh.num_vertices <= 65536)
- {
loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles);
+ if (loadmodel->surfmesh.data_element3s)
for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
// load the frames
loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes);
dpsnprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i, j);
else
dpsnprintf (name, sizeof(name), "%s_%i", loadmodel->name, i);
- if (!Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, false, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS))
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, R_SkinFrame_LoadInternalQuake(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight));
+ if (!Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, false, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS | TEXF_PRECACHE))
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, R_SkinFrame_LoadInternalQuake(name, TEXF_PRECACHE | (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight));
datapointer += skinwidth * skinheight;
totalskins++;
}
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
loadmodel->PointSuperContents = NULL;
if (LittleLong(pinmodel->num_tris) < 1 || LittleLong(pinmodel->num_tris) > 65536)
// generate ushort elements array if possible
if (loadmodel->surfmesh.num_vertices <= 65536)
- {
loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles);
+ if (loadmodel->surfmesh.data_element3s)
for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
// load the frames
datapointer = (base + LittleLong(pinmodel->ofs_frames));
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
loadmodel->PointSuperContents = NULL;
loadmodel->synctype = ST_RAND;
// convert model flags to EF flags (MF_ROCKET becomes EF_ROCKET, etc)
loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]);
loadmodel->surfmesh.data_morphmd3vertex = (md3vertex_t *)data;data += meshvertices * loadmodel->numframes * sizeof(md3vertex_t);
if (meshvertices <= 65536)
- {
loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]);
- for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
- loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
meshvertices = 0;
meshtriangles = 0;
Mod_ValidateElements(loadmodel->surfmesh.data_element3i + surface->num_firsttriangle * 3, surface->num_triangles, surface->num_firstvertex, surface->num_vertices, __FILE__, __LINE__);
}
+ if (loadmodel->surfmesh.data_element3s)
+ for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+ loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
Mod_Alias_MorphMesh_CompileFrames();
Mod_Alias_CalculateBoundingBox();
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
loadmodel->PointSuperContents = NULL;
loadmodel->numframes = pheader->numscenes;
//zymlump_t lump_bones; // zymbone_t bone[numbones];
loadmodel->num_bones = pheader->numbones;
- loadmodel->data_bones = (aliasbone_t *)Mem_Alloc(loadmodel->mempool, pheader->numbones * sizeof(aliasbone_t));
+ loadmodel->data_bones = (aliasbone_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_bones * sizeof(aliasbone_t));
bone = (zymbone_t *) (pheader->lump_bones.start + pbase);
for (i = 0;i < pheader->numbones;i++)
{
Host_Error("%s bonecount[%i] != 1 (vertex weight support is impossible in this format)", loadmodel->name, i);
}
- loadmodel->num_poses = pheader->lump_poses.length / sizeof(float[3][4]);
+ loadmodel->num_poses = pheader->lump_poses.length / sizeof(float[3][4]) / loadmodel->num_bones;
meshvertices = pheader->numverts;
meshtriangles = pheader->numtris;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[14]) + meshvertices * sizeof(int[4]) + meshvertices * sizeof(float[4]) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]));
+ data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[14]) + meshvertices * sizeof(int[4]) + meshvertices * sizeof(float[4]) + loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]));
loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]);
loadmodel->surfmesh.data_vertexweightindex4i = (int *)data;data += meshvertices * sizeof(int[4]);
loadmodel->surfmesh.data_vertexweightinfluence4f = (float *)data;data += meshvertices * sizeof(float[4]);
- loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * sizeof(float[12]);
+ loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]);
loadmodel->data_baseboneposeinverse = (float *)data;data += loadmodel->num_bones * sizeof(float[12]);
if (loadmodel->surfmesh.num_vertices <= 65536)
- {
loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]);
- for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
- loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
//zymlump_t lump_poses; // float pose[numposes][numbones][3][4]; // animation data
poses = (float *) (pheader->lump_poses.start + pbase);
Mod_MakeSortedSurfaces(loadmodel);
// compute all the mesh information that was not loaded from the file
+ if (loadmodel->surfmesh.data_element3s)
+ for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+ loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
Mod_ValidateElements(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles, 0, loadmodel->surfmesh.num_vertices, __FILE__, __LINE__);
Mod_BuildBaseBonePoses();
Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, true);
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
loadmodel->PointSuperContents = NULL;
// model bbox
loadmodel->numframes = pheader->num_frames;
loadmodel->num_bones = pheader->num_bones;
- loadmodel->num_poses = loadmodel->num_bones * loadmodel->numframes;
+ loadmodel->num_poses = loadmodel->numframes;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces = pheader->num_meshs;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
// do most allocations as one merged chunk
- data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshtriangles * sizeof(int[3]) + meshvertices * (sizeof(float[14]) + sizeof(int[4]) + sizeof(float[4])) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
+ data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshtriangles * sizeof(int[3]) + meshvertices * (sizeof(float[14]) + sizeof(int[4]) + sizeof(float[4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]);
loadmodel->surfmesh.data_vertexweightindex4i = (int *)data;data += meshvertices * sizeof(int[4]);
loadmodel->surfmesh.data_vertexweightinfluence4f = (float *)data;data += meshvertices * sizeof(float[4]);
- loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * sizeof(float[12]);
+ loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]);
loadmodel->data_baseboneposeinverse = (float *)data;data += loadmodel->num_bones * sizeof(float[12]);
loadmodel->skinscenes = (animscene_t *)data;data += loadmodel->numskins * sizeof(animscene_t);
loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t);
loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
if (meshvertices <= 65536)
- {
loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]);
- for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
- loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
for (i = 0;i < loadmodel->numskins;i++)
{
Mod_MakeSortedSurfaces(loadmodel);
// compute all the mesh information that was not loaded from the file
+ if (loadmodel->surfmesh.data_element3s)
+ for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+ loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
Mod_BuildBaseBonePoses();
Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true);
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
loadmodel->PointSuperContents = NULL;
loadmodel->synctype = ST_RAND;
if (loadmodel->numskins < 1)
loadmodel->numskins = 1;
loadmodel->num_bones = numbones;
- loadmodel->num_poses = loadmodel->num_bones * loadmodel->numframes;
+ loadmodel->num_poses = loadmodel->numframes;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces = nummatts;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
loadmodel->surfmesh.num_vertices = meshvertices;
loadmodel->surfmesh.num_triangles = meshtriangles;
// do most allocations as one merged chunk
- size = loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * sizeof(int[4]) + loadmodel->surfmesh.num_vertices * sizeof(float[4]) + /*loadmodel->num_poses * sizeof(float[12]) + */loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t) + ((loadmodel->surfmesh.num_vertices <= 65536) ? (loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3])) : 0);
+ size = loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * sizeof(int[4]) + loadmodel->surfmesh.num_vertices * sizeof(float[4]) + loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t) + ((loadmodel->surfmesh.num_vertices <= 65536) ? (loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3])) : 0);
data = (unsigned char *)Mem_Alloc(loadmodel->mempool, size);
loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[2]);
loadmodel->surfmesh.data_vertexweightindex4i = (int *)data;data += loadmodel->surfmesh.num_vertices * sizeof(int[4]);
loadmodel->surfmesh.data_vertexweightinfluence4f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[4]);
- //loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * sizeof(float[12]);
+ loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]);
loadmodel->data_baseboneposeinverse = (float *)data;data += loadmodel->num_bones * sizeof(float[12]);
loadmodel->skinscenes = (animscene_t *)data;data += loadmodel->numskins * sizeof(animscene_t);
loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t);
loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
if (loadmodel->surfmesh.num_vertices <= 65536)
- {
loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]);
- for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
- loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
- loadmodel->data_poses = (float *) Mem_Alloc(loadmodel->mempool, loadmodel->num_poses * sizeof(float[12]));
for (i = 0;i < loadmodel->numskins;i++)
{
// compute all the mesh information that was not loaded from the file
// TODO: honor smoothing groups somehow?
+ if (loadmodel->surfmesh.data_element3s)
+ for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+ loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
Mod_ValidateElements(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles, 0, loadmodel->surfmesh.num_vertices, __FILE__, __LINE__);
Mod_BuildBaseBonePoses();
Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, true);
loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
}
-
-void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
-{
-#if 0
- const char *textbase = (char *)buffer, *text = textbase;
- char *s;
- char *argv[512];
- char line[1024];
- char materialname[MAX_QPATH];
- int j, index1, index2, index3, first, prev, index;
- int argc;
- int linelen;
- int numtriangles = 0;
- int maxtriangles = 32768;
- int *element3i = Mem_Alloc(tempmempool, maxtriangles * sizeof(int[3]));
- int *oldelement3i;
- int numsurfaces = 0;
- int maxsurfaces = 0;
- msurface_t *surfaces = NULL;
- int linenumber = 0;
- int hashindex;
- float *v, *vt, *vn;
- float *oldv, *oldvt, *oldvn;
- int maxv = 65536, numv = 1;
- int maxvt = 65536, numvt = 1;
- int maxvn = 65536, numvn = 1;
- int maxverthash = 65536, numverthash = 0;
- int numhashindex = 65536;
- struct objverthash_s
- {
- struct objverthash_s *next;
- int s;
- int v;
- int vt;
- int vn;
- }
- *hash, **verthash = Mem_Alloc(tempmempool, numhashindex * sizeof(*verthash)), *verthashdata = Mem_Alloc(tempmempool, maxverthash * sizeof(*verthashdata)), *oldverthashdata;
- skinfile_t *skinfiles;
-
- dpsnprintf(materialname, sizeof(materialname), "%s", loadmodel->name);
-
- skinfiles = Mod_LoadSkinFiles();
-
- loadmodel->modeldatatypestring = "OBJ";
-
- loadmodel->type = mod_alias;
- loadmodel->AnimateVertices = NULL;
- loadmodel->DrawSky = NULL;
- loadmodel->DrawAddWaterPlanes = NULL;
- loadmodel->Draw = R_Q1BSP_Draw;
- loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
- loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
- loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
- loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
- loadmodel->DrawLight = R_Q1BSP_DrawLight;
- loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
- loadmodel->PointSuperContents = NULL;
-
- // parse the OBJ text now
- for(;;)
- {
- if (!*text)
- break;
- linenumber++;
- linelen = 0;
- for (linelen = 0;text[linelen] && text[linelen] != '\r' && text[linelen] != '\n';linelen++)
- line[linelen] = text[linelen];
- line[linelen] = 0;
- for (argc = 0;argc < (int)(sizeof(argv)/sizeof(argv[0]));argc++)
- argv[argc] = "";
- argc = 0;
- s = line;
- while (*s == ' ' || *s == '\t')
- s++;
- while (*s)
- {
- argv[argc++] = s;
- while (*s > ' ')
- s++;
- if (!*s)
- break;
- *s++ = 0;
- while (*s == ' ' || *s == '\t')
- s++;
- }
- if (!argc)
- continue;
- if (argv[0][0] == '#')
- continue;
- if (!strcmp(argv[0], "v"))
- {
- if (maxv <= numv)
- {
- maxv *= 2;
- oldv = v;
- v = Mem_Alloc(tempmempool, maxv * sizeof(float[3]));
- if (oldv)
- {
- memcpy(v, oldv, numv * sizeof(float[3]));
- Mem_Free(oldv);
- }
- }
- v[numv*3+0] = atof(argv[1]);
- v[numv*3+1] = atof(argv[2]);
- v[numv*3+2] = atof(argv[3]);
- numv++;
- }
- else if (!strcmp(argv[0], "vt"))
- {
- if (maxvt <= numvt)
- {
- maxvt *= 2;
- oldvt = vt;
- vt = Mem_Alloc(tempmempool, maxvt * sizeof(float[2]));
- if (oldvt)
- {
- memcpy(vt, oldvt, numvt * sizeof(float[2]));
- Mem_Free(oldvt);
- }
- }
- vt[numvt*2+0] = atof(argv[1]);
- vt[numvt*2+1] = atof(argv[2]);
- numvt++;
- }
- else if (!strcmp(argv[0], "vn"))
- {
- if (maxvn <= numvn)
- {
- maxvn *= 2;
- oldvn = vn;
- vn = Mem_Alloc(tempmempool, maxvn * sizeof(float[3]));
- if (oldvn)
- {
- memcpy(vn, oldvn, numvn * sizeof(float[3]));
- Mem_Free(oldvn);
- }
- }
- vn[numvn*3+0] = atof(argv[1]);
- vn[numvn*3+1] = atof(argv[2]);
- vn[numvn*3+2] = atof(argv[3]);
- numvn++;
- }
- else if (!strcmp(argv[0], "f"))
- {
- if (!surface)
- {
- if (maxsurfaces <= numsurfaces)
- {
- maxsurfaces++;
- oldsurfaces = surfaces;
- surfaces = Mem_Alloc(tempmempool, maxsurfaces * sizeof(*surfaces));
- if (oldsurfaces)
- {
- memcpy(surfaces, oldsurfaces, numsurfaces * sizeof(*surfaces));
- Mem_Free(oldsurfaces);
- }
- }
- surface = surfaces + numsurfaces++;
- surface->
- }
- for (j = 1;j < argc;j++)
- {
- index1 = atoi(argv[j]);
- while(argv[j][0] && argv[j][0] != '/')
- argv[j]++;
- if (argv[j][0])
- argv[j]++;
- if (index1 < 0)
- index1 = numv + 1 - index1;
- index2 = atoi(argv[j]);
- if (index2 < 0)
- index2 = numvt + 1 - index2;
- while(argv[j][0] && argv[j][0] != '/')
- argv[j]++;
- if (argv[j][0])
- argv[j]++;
- index3 = atoi(argv[j]);
- if (index3 < 0)
- index3 = numvn + 1 - index3;
- hashindex = (index1 + index2 * 3571 + index3 * 42589) & (numhashindex - 1);
- for (hash = verthash[hashindex];hash;hash = hash->next)
- if (hash->surface == numsurfaces-1 && hash->v == index1 && hash->vt == index2 && hash->vn == index3)
- break;
- if (!hash)
- {
- if (maxverthash <= numverthash)
- {
- maxverthash *= 2;
- oldverthashdata = verthashdata;
- verthashdata = Mem_Alloc(tempmempool, maxverthash * sizeof(*verthashdata));
- if (oldverthashdata)
- {
- memcpy(verthashdata, oldverthashdata, numverthash * sizeof(*verthashdata));
- Mem_Free(oldverthashdata);
- }
- }
- hash = verthashdata + numverthash++;
- hash->next = verthash[hashindex];
- hash->s = numsurfaces;
- hash->v = index1;
- hash->vt = index2;
- hash->vn = index3;
- verthash[hashindex] = hash;
- }
- index = (int)((size_t)(hash - verthashdata));
- if (j == 1)
- first = index;
- else if (j >= 3)
- {
- if (maxtriangles <= numtriangles)
- {
- maxtriangles *= 2;
- oldelement3i = element3i;
- element3i = Mem_Alloc(tempmempool, numtriangles * sizeof(int[3]));
- if (oldelement3i)
- {
- memcpy(element3i, oldelement3i, numtriangles * sizeof(int[3]));
- Mem_Free(oldelement3i);
- }
- }
- element3i[numtriangles*3+0] = first;
- element3i[numtriangles*3+1] = prev;
- element3i[numtriangles*3+2] = index;
- numtriangles++;
- }
- prev = index;
- }
- }
- else if (!strcmp(argv[0], "o") || !strcmp(argv[0], "g"))
- surface = NULL;
- else if (!!strcmp(argv[0], "usemtl"))
- {
- surface = NULL;
- strlcpy(materialname, argv[1], sizeof(materialname);
- }
- text += linelen;
- if (*text == '\r')
- text++;
- if (*text == '\n')
- text++;
- }
-
- if (skinfiles)
- Mod_FreeSkinFiles(skinfiles);
-
- // now that we have the OBJ data loaded as-is, we can convert it
- loadmodel->numskins = LittleLong(pinmodel->num_skins);
- numxyz = LittleLong(pinmodel->num_xyz);
- numst = LittleLong(pinmodel->num_st);
- loadmodel->surfmesh.num_triangles = LittleLong(pinmodel->num_tris);
- loadmodel->numframes = LittleLong(pinmodel->num_frames);
- loadmodel->surfmesh.num_morphframes = loadmodel->numframes;
- loadmodel->num_poses = loadmodel->surfmesh.num_morphframes;
- skinwidth = LittleLong(pinmodel->skinwidth);
- skinheight = LittleLong(pinmodel->skinheight);
- iskinwidth = 1.0f / skinwidth;
- iskinheight = 1.0f / skinheight;
-
- loadmodel->num_surfaces = 1;
- loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
- data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]));
- loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
- loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
- loadmodel->sortedmodelsurfaces[0] = 0;
- loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
- loadmodel->surfmesh.data_morphmd2framesize6f = (float *)data;data += loadmodel->numframes * sizeof(float[6]);
- loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]);
- loadmodel->surfmesh.data_neighbor3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]);
-
- loadmodel->synctype = ST_RAND;
-
- // load the skins
- inskin = (char *)(base + LittleLong(pinmodel->ofs_skins));
- skinfiles = Mod_LoadSkinFiles();
- if (skinfiles)
- {
- loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
- loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
- Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures, skinfiles, "default", "");
- Mod_FreeSkinFiles(skinfiles);
- }
- else if (loadmodel->numskins)
- {
- // skins found (most likely not a player model)
- loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
- loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
- for (i = 0;i < loadmodel->numskins;i++, inskin += MD2_SKINNAME)
- Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP | TEXF_COMPRESS);
- }
- else
- {
- // no skins (most likely a player model)
- loadmodel->numskins = 1;
- loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
- loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures, NULL);
- }
-
- loadmodel->skinscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
- for (i = 0;i < loadmodel->numskins;i++)
- {
- loadmodel->skinscenes[i].firstframe = i;
- loadmodel->skinscenes[i].framecount = 1;
- loadmodel->skinscenes[i].loop = true;
- loadmodel->skinscenes[i].framerate = 10;
- }
-
- // load the triangles and stvert data
- inst = (unsigned short *)(base + LittleLong(pinmodel->ofs_st));
- intri = (md2triangle_t *)(base + LittleLong(pinmodel->ofs_tris));
- md2verthash = (struct md2verthash_s **)Mem_Alloc(tempmempool, 65536 * sizeof(hash));
- md2verthashdata = (struct md2verthash_s *)Mem_Alloc(tempmempool, loadmodel->surfmesh.num_triangles * 3 * sizeof(*hash));
- // swap the triangle list
- loadmodel->surfmesh.num_vertices = 0;
- for (i = 0;i < loadmodel->surfmesh.num_triangles;i++)
- {
- for (j = 0;j < 3;j++)
- {
- xyz = (unsigned short) LittleShort (intri[i].index_xyz[j]);
- st = (unsigned short) LittleShort (intri[i].index_st[j]);
- if (xyz >= numxyz)
- {
- Con_Printf("%s has an invalid xyz index (%i) on triangle %i, resetting to 0\n", loadmodel->name, xyz, i);
- xyz = 0;
- }
- if (st >= numst)
- {
- Con_Printf("%s has an invalid st index (%i) on triangle %i, resetting to 0\n", loadmodel->name, st, i);
- st = 0;
- }
- hashindex = (xyz * 256 + st) & 65535;
- for (hash = md2verthash[hashindex];hash;hash = hash->next)
- if (hash->xyz == xyz && hash->st == st)
- break;
- if (hash == NULL)
- {
- hash = md2verthashdata + loadmodel->surfmesh.num_vertices++;
- hash->xyz = xyz;
- hash->st = st;
- hash->next = md2verthash[hashindex];
- md2verthash[hashindex] = hash;
- }
- loadmodel->surfmesh.data_element3i[i*3+j] = (hash - md2verthashdata);
- }
- }
-
- vertremap = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(int));
- data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * loadmodel->surfmesh.num_morphframes * sizeof(trivertx_t));
- loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[2]);
- loadmodel->surfmesh.data_morphmdlvertex = (trivertx_t *)data;data += loadmodel->surfmesh.num_vertices * loadmodel->surfmesh.num_morphframes * sizeof(trivertx_t);
- for (i = 0;i < loadmodel->surfmesh.num_vertices;i++)
- {
- int sts, stt;
- hash = md2verthashdata + i;
- vertremap[i] = hash->xyz;
- sts = LittleShort(inst[hash->st*2+0]);
- stt = LittleShort(inst[hash->st*2+1]);
- if (sts < 0 || sts >= skinwidth || stt < 0 || stt >= skinheight)
- {
- Con_Printf("%s has an invalid skin coordinate (%i %i) on vert %i, changing to 0 0\n", loadmodel->name, sts, stt, i);
- sts = 0;
- stt = 0;
- }
- loadmodel->surfmesh.data_texcoordtexture2f[i*2+0] = sts * iskinwidth;
- loadmodel->surfmesh.data_texcoordtexture2f[i*2+1] = stt * iskinheight;
- }
-
- Mem_Free(md2verthash);
- Mem_Free(md2verthashdata);
-
- // generate ushort elements array if possible
- if (loadmodel->surfmesh.num_vertices <= 65536)
- {
- loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles);
- for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
- loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
- }
-
- // load the frames
- datapointer = (base + LittleLong(pinmodel->ofs_frames));
- for (i = 0;i < loadmodel->surfmesh.num_morphframes;i++)
- {
- int k;
- trivertx_t *v;
- trivertx_t *out;
- pinframe = (md2frame_t *)datapointer;
- datapointer += sizeof(md2frame_t);
- // store the frame scale/translate into the appropriate array
- for (j = 0;j < 3;j++)
- {
- loadmodel->surfmesh.data_morphmd2framesize6f[i*6+j] = LittleFloat(pinframe->scale[j]);
- loadmodel->surfmesh.data_morphmd2framesize6f[i*6+3+j] = LittleFloat(pinframe->translate[j]);
- }
- // convert the vertices
- v = (trivertx_t *)datapointer;
- out = loadmodel->surfmesh.data_morphmdlvertex + i * loadmodel->surfmesh.num_vertices;
- for (k = 0;k < loadmodel->surfmesh.num_vertices;k++)
- out[k] = v[vertremap[k]];
- datapointer += numxyz * sizeof(trivertx_t);
-
- strlcpy(loadmodel->animscenes[i].name, pinframe->name, sizeof(loadmodel->animscenes[i].name));
- loadmodel->animscenes[i].firstframe = i;
- loadmodel->animscenes[i].framecount = 1;
- loadmodel->animscenes[i].framerate = 10;
- loadmodel->animscenes[i].loop = true;
- }
-
- Mem_Free(vertremap);
-
- Mod_MakeSortedSurfaces(loadmodel);
- Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
- Mod_Alias_CalculateBoundingBox();
- Mod_Alias_MorphMesh_CompileFrames();
-
- surface = loadmodel->data_surfaces;
- surface->texture = loadmodel->data_textures;
- surface->num_firsttriangle = 0;
- surface->num_triangles = loadmodel->surfmesh.num_triangles;
- surface->num_firstvertex = 0;
- surface->num_vertices = loadmodel->surfmesh.num_vertices;
-
- loadmodel->surfmesh.isanimated = false;
-#endif
-}