mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-10 14:52:00 +00:00
#6069: Remove md4 model support.
This commit is contained in:
parent
9d9715c63d
commit
6f3edb20b8
11 changed files with 19 additions and 741 deletions
|
@ -178,94 +178,11 @@ typedef struct {
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
MD4 file format
|
||||
MDR file format
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define MD4_IDENT (('4'<<24)+('P'<<16)+('D'<<8)+'I')
|
||||
#define MD4_VERSION 1
|
||||
#define MD4_MAX_BONES 128
|
||||
|
||||
typedef struct {
|
||||
int boneIndex; // these are indexes into the boneReferences,
|
||||
float boneWeight; // not the global per-frame bone list
|
||||
vec3_t offset;
|
||||
} md4Weight_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t normal;
|
||||
vec2_t texCoords;
|
||||
int numWeights;
|
||||
md4Weight_t weights[1]; // variable sized
|
||||
} md4Vertex_t;
|
||||
|
||||
typedef struct {
|
||||
int indexes[3];
|
||||
} md4Triangle_t;
|
||||
|
||||
typedef struct {
|
||||
int ident;
|
||||
|
||||
char name[MAX_QPATH]; // polyset name
|
||||
char shader[MAX_QPATH];
|
||||
int shaderIndex; // for in-game use
|
||||
|
||||
int ofsHeader; // this will be a negative number
|
||||
|
||||
int numVerts;
|
||||
int ofsVerts;
|
||||
|
||||
int numTriangles;
|
||||
int ofsTriangles;
|
||||
|
||||
// Bone references are a set of ints representing all the bones
|
||||
// present in any vertex weights for this surface. This is
|
||||
// needed because a model may have surfaces that need to be
|
||||
// drawn at different sort times, and we don't want to have
|
||||
// to re-interpolate all the bones for each surface.
|
||||
int numBoneReferences;
|
||||
int ofsBoneReferences;
|
||||
|
||||
int ofsEnd; // next surface follows
|
||||
} md4Surface_t;
|
||||
|
||||
typedef struct {
|
||||
float matrix[3][4];
|
||||
} md4Bone_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t bounds[2]; // bounds of all surfaces of all LOD's for this frame
|
||||
vec3_t localOrigin; // midpoint of bounds, used for sphere cull
|
||||
float radius; // dist from localOrigin to corner
|
||||
md4Bone_t bones[1]; // [numBones]
|
||||
} md4Frame_t;
|
||||
|
||||
typedef struct {
|
||||
int numSurfaces;
|
||||
int ofsSurfaces; // first surface, others follow
|
||||
int ofsEnd; // next lod follows
|
||||
} md4LOD_t;
|
||||
|
||||
typedef struct {
|
||||
int ident;
|
||||
int version;
|
||||
|
||||
char name[MAX_QPATH]; // model name
|
||||
|
||||
// frames and bones are shared by all levels of detail
|
||||
int numFrames;
|
||||
int numBones;
|
||||
int ofsBoneNames; // char name[ MAX_QPATH ]
|
||||
int ofsFrames; // md4Frame_t[numFrames]
|
||||
|
||||
// each level of detail has completely separate sets of surfaces
|
||||
int numLODs;
|
||||
int ofsLODs;
|
||||
|
||||
int ofsEnd; // end of file
|
||||
} md4Header_t;
|
||||
|
||||
/*
|
||||
* Here are the definitions for Ravensoft's model format of md4. Raven stores their
|
||||
* playermodels in .mdr files, in some games, which are pretty much like the md4
|
||||
|
|
|
@ -33,140 +33,6 @@ frame.
|
|||
|
||||
*/
|
||||
|
||||
/*
|
||||
==============
|
||||
R_AddAnimSurfaces
|
||||
==============
|
||||
*/
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent ) {
|
||||
md4Header_t *header;
|
||||
md4Surface_t *surface;
|
||||
md4LOD_t *lod;
|
||||
shader_t *shader;
|
||||
int i;
|
||||
|
||||
header = (md4Header_t *) tr.currentModel->modelData;
|
||||
lod = (md4LOD_t *)( (byte *)header + header->ofsLODs );
|
||||
|
||||
surface = (md4Surface_t *)( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++ ) {
|
||||
shader = R_GetShaderByHandle( surface->shaderIndex );
|
||||
R_AddDrawSurf( (void *)surface, shader, 0 /*fogNum*/, qfalse );
|
||||
surface = (md4Surface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_SurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_SurfaceAnim( md4Surface_t *surface ) {
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
int *triangles;
|
||||
int indexes;
|
||||
int baseIndex, baseVertex;
|
||||
int numVerts;
|
||||
md4Vertex_t *v;
|
||||
md4Bone_t bones[MD4_MAX_BONES];
|
||||
md4Bone_t *bonePtr, *bone;
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
md4Frame_t *oldFrame;
|
||||
int frameSize;
|
||||
|
||||
|
||||
if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
|
||||
backlerp = 0;
|
||||
frontlerp = 1;
|
||||
} else {
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
frontlerp = 1.0f - backlerp;
|
||||
}
|
||||
header = (md4Header_t *)((byte *)surface + surface->ofsHeader);
|
||||
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
frame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.frame * frameSize );
|
||||
oldFrame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.oldframe * frameSize );
|
||||
|
||||
RB_CheckOverflow( surface->numVerts, surface->numTriangles * 3 );
|
||||
|
||||
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
|
||||
indexes = surface->numTriangles * 3;
|
||||
baseIndex = tess.numIndexes;
|
||||
baseVertex = tess.numVertexes;
|
||||
for (j = 0 ; j < indexes ; j++) {
|
||||
tess.indexes[baseIndex + j] = baseIndex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
|
||||
//
|
||||
// lerp all the needed bones
|
||||
//
|
||||
if ( !backlerp ) {
|
||||
// no lerping needed
|
||||
bonePtr = frame->bones;
|
||||
} else {
|
||||
bonePtr = bones;
|
||||
for ( i = 0 ; i < header->numBones*12 ; i++ ) {
|
||||
((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i]
|
||||
+ backlerp * ((float *)oldFrame->bones)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// deform the vertexes by the lerped bones
|
||||
//
|
||||
numVerts = surface->numVerts;
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts);
|
||||
for ( j = 0; j < numVerts; j++ ) {
|
||||
vec3_t tempVert, tempNormal;
|
||||
md4Weight_t *w;
|
||||
|
||||
VectorClear( tempVert );
|
||||
VectorClear( tempNormal );
|
||||
w = v->weights;
|
||||
for ( k = 0 ; k < v->numWeights ; k++, w++ ) {
|
||||
bone = bonePtr + w->boneIndex;
|
||||
|
||||
tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
|
||||
tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
|
||||
tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
|
||||
|
||||
tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
|
||||
tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
|
||||
tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
|
||||
}
|
||||
|
||||
tess.xyz[baseVertex + j][0] = tempVert[0];
|
||||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
tess.normal[baseVertex + j][0] = tempNormal[0];
|
||||
tess.normal[baseVertex + j][1] = tempNormal[1];
|
||||
tess.normal[baseVertex + j][2] = tempNormal[2];
|
||||
|
||||
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
|
||||
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)&v->weights[v->numWeights];
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
}
|
||||
|
||||
|
||||
// copied and adapted from tr_mesh.c
|
||||
|
||||
|
@ -195,7 +61,7 @@ static int R_MDRCullModel( mdrHeader_t *header, trRefEntity_t *ent ) {
|
|||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
// Ummm... yeah yeah I know we don't really have an md3 here.. but we pretend
|
||||
// we do. After all, the purpose of md4s are not that different, are they?
|
||||
// we do. After all, the purpose of mdrs are not that different, are they?
|
||||
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
|
@ -442,7 +308,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
|
|||
RB_MDRSurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
|
||||
{
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
|
@ -454,7 +320,7 @@ void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
|||
mdrHeader_t *header;
|
||||
mdrFrame_t *frame;
|
||||
mdrFrame_t *oldFrame;
|
||||
mdrBone_t bones[MD4_MAX_BONES], *bonePtr, *bone;
|
||||
mdrBone_t bones[MDR_MAX_BONES], *bonePtr, *bone;
|
||||
|
||||
int frameSize;
|
||||
|
||||
|
|
|
@ -473,7 +473,6 @@ typedef enum {
|
|||
SF_TRIANGLES,
|
||||
SF_POLY,
|
||||
SF_MD3,
|
||||
SF_MD4,
|
||||
SF_MDR,
|
||||
SF_IQM,
|
||||
SF_FLARE,
|
||||
|
@ -732,7 +731,6 @@ typedef enum {
|
|||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_MESH,
|
||||
MOD_MD4,
|
||||
MOD_MDR,
|
||||
MOD_IQM
|
||||
} modtype_t;
|
||||
|
@ -745,7 +743,7 @@ typedef struct model_s {
|
|||
int dataSize; // just for listing purposes
|
||||
bmodel_t *bmodel; // only if type == MOD_BRUSH
|
||||
md3Header_t *md3[MD3_MAX_LODS]; // only if type == MOD_MESH
|
||||
void *modelData; // only if type == (MOD_MD4 | MOD_MDR | MOD_IQM)
|
||||
void *modelData; // only if type == (MOD_MDR | MOD_IQM)
|
||||
|
||||
int numLods;
|
||||
} model_t;
|
||||
|
@ -1391,9 +1389,8 @@ ANIMATED MODELS
|
|||
|
||||
// void R_MakeAnimModel( model_t *model ); haven't seen this one really, so not needed I guess.
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_SurfaceAnim( md4Surface_t *surfType );
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface );
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface );
|
||||
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
|
||||
void R_AddIQMSurfaces( trRefEntity_t *ent );
|
||||
void RB_IQMSurfaceAnim( surfaceType_t *surface );
|
||||
|
|
|
@ -1242,9 +1242,6 @@ void R_AddEntitySurfaces (void) {
|
|||
case MOD_MESH:
|
||||
R_AddMD3Surfaces( ent );
|
||||
break;
|
||||
case MOD_MD4:
|
||||
R_AddAnimSurfaces( ent );
|
||||
break;
|
||||
case MOD_MDR:
|
||||
R_MDRAddAnimSurfaces( ent );
|
||||
break;
|
||||
|
|
|
@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
static qboolean R_LoadMD3(model_t *mod, int lod, void *buffer, const char *name );
|
||||
static qboolean R_LoadMD4(model_t *mod, void *buffer, const char *name );
|
||||
static qboolean R_LoadMDR(model_t *mod, void *buffer, int filesize, const char *name );
|
||||
|
||||
/*
|
||||
|
@ -72,15 +71,10 @@ qhandle_t R_RegisterMD3(const char *name, model_t *mod)
|
|||
continue;
|
||||
|
||||
ident = LittleLong(* (unsigned *) buf.u);
|
||||
if (ident == MD4_IDENT)
|
||||
loaded = R_LoadMD4(mod, buf.u, name);
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, name);
|
||||
else
|
||||
{
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, name);
|
||||
else
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
}
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
|
||||
ri.FS_FreeFile(buf.v);
|
||||
|
||||
|
@ -200,7 +194,6 @@ static modelExtToLoaderMap_t modelLoaders[ ] =
|
|||
{
|
||||
{ "iqm", R_RegisterIQM },
|
||||
{ "mdr", R_RegisterMDR },
|
||||
{ "md4", R_RegisterMD3 },
|
||||
{ "md3", R_RegisterMD3 }
|
||||
};
|
||||
|
||||
|
@ -576,7 +569,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
LL(pinmodel->ofsFrames);
|
||||
|
||||
// This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target md4.
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target mdr.
|
||||
if(pinmodel->ofsFrames < 0)
|
||||
{
|
||||
// mdrFrame_t is larger than mdrCompFrame_t:
|
||||
|
@ -873,162 +866,6 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LoadMD4
|
||||
=================
|
||||
*/
|
||||
|
||||
static qboolean R_LoadMD4( model_t *mod, void *buffer, const char *mod_name ) {
|
||||
int i, j, k, lodindex;
|
||||
md4Header_t *pinmodel, *md4;
|
||||
md4Frame_t *frame;
|
||||
md4LOD_t *lod;
|
||||
md4Surface_t *surf;
|
||||
md4Triangle_t *tri;
|
||||
md4Vertex_t *v;
|
||||
int version;
|
||||
int size;
|
||||
shader_t *sh;
|
||||
int frameSize;
|
||||
|
||||
pinmodel = (md4Header_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
if (version != MD4_VERSION) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has wrong version (%i should be %i)\n",
|
||||
mod_name, version, MD4_VERSION);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->type = MOD_MD4;
|
||||
size = LittleLong(pinmodel->ofsEnd);
|
||||
mod->dataSize += size;
|
||||
mod->modelData = md4 = ri.Hunk_Alloc( size, h_low );
|
||||
|
||||
Com_Memcpy(md4, buffer, size);
|
||||
|
||||
LL(md4->ident);
|
||||
LL(md4->version);
|
||||
LL(md4->numFrames);
|
||||
LL(md4->numBones);
|
||||
LL(md4->numLODs);
|
||||
LL(md4->ofsFrames);
|
||||
LL(md4->ofsLODs);
|
||||
md4->ofsEnd = size;
|
||||
|
||||
if ( md4->numFrames < 1 ) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has no frames\n", mod_name );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// we don't need to swap tags in the renderer, they aren't used
|
||||
|
||||
// swap all the frames
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ md4->numBones ] );
|
||||
for ( i = 0 ; i < md4->numFrames ; i++) {
|
||||
frame = (md4Frame_t *) ( (byte *)md4 + md4->ofsFrames + i * frameSize );
|
||||
frame->radius = LittleFloat( frame->radius );
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
|
||||
frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
|
||||
frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
|
||||
}
|
||||
for ( j = 0 ; j < md4->numBones * sizeof( md4Bone_t ) / 4 ; j++ ) {
|
||||
((float *)frame->bones)[j] = LittleFloat( ((float *)frame->bones)[j] );
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the LOD's
|
||||
lod = (md4LOD_t *) ( (byte *)md4 + md4->ofsLODs );
|
||||
for ( lodindex = 0 ; lodindex < md4->numLODs ; lodindex++ ) {
|
||||
|
||||
// swap all the surfaces
|
||||
surf = (md4Surface_t *) ( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++) {
|
||||
LL(surf->ident);
|
||||
LL(surf->numTriangles);
|
||||
LL(surf->ofsTriangles);
|
||||
LL(surf->numVerts);
|
||||
LL(surf->ofsVerts);
|
||||
LL(surf->ofsEnd);
|
||||
|
||||
if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i verts on %s (%i).\n",
|
||||
mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numVerts );
|
||||
return qfalse;
|
||||
}
|
||||
if ( surf->numTriangles*3 >= SHADER_MAX_INDEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i triangles on %s (%i).\n",
|
||||
mod_name, ( SHADER_MAX_INDEXES / 3 ) - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numTriangles );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// change to surface identifier
|
||||
surf->ident = SF_MD4;
|
||||
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surf->name );
|
||||
|
||||
// register the shaders
|
||||
sh = R_FindShader( surf->shader, LIGHTMAP_NONE, qtrue );
|
||||
if ( sh->defaultShader ) {
|
||||
surf->shaderIndex = 0;
|
||||
} else {
|
||||
surf->shaderIndex = sh->index;
|
||||
}
|
||||
|
||||
// swap all the triangles
|
||||
tri = (md4Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
|
||||
for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
|
||||
LL(tri->indexes[0]);
|
||||
LL(tri->indexes[1]);
|
||||
LL(tri->indexes[2]);
|
||||
}
|
||||
|
||||
// swap all the vertexes
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts);
|
||||
for ( j = 0 ; j < surf->numVerts ; j++ ) {
|
||||
v->normal[0] = LittleFloat( v->normal[0] );
|
||||
v->normal[1] = LittleFloat( v->normal[1] );
|
||||
v->normal[2] = LittleFloat( v->normal[2] );
|
||||
|
||||
v->texCoords[0] = LittleFloat( v->texCoords[0] );
|
||||
v->texCoords[1] = LittleFloat( v->texCoords[1] );
|
||||
|
||||
v->numWeights = LittleLong( v->numWeights );
|
||||
|
||||
for ( k = 0 ; k < v->numWeights ; k++ ) {
|
||||
v->weights[k].boneIndex = LittleLong( v->weights[k].boneIndex );
|
||||
v->weights[k].boneWeight = LittleFloat( v->weights[k].boneWeight );
|
||||
v->weights[k].offset[0] = LittleFloat( v->weights[k].offset[0] );
|
||||
v->weights[k].offset[1] = LittleFloat( v->weights[k].offset[1] );
|
||||
v->weights[k].offset[2] = LittleFloat( v->weights[k].offset[2] );
|
||||
}
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights]);
|
||||
}
|
||||
|
||||
// find the next surface
|
||||
surf = (md4Surface_t *)( (byte *)surf + surf->ofsEnd );
|
||||
}
|
||||
|
||||
// find the next LOD
|
||||
lod = (md4LOD_t *)( (byte *)lod + lod->ofsEnd );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1265,17 +1102,6 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
|
|||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MD4) {
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
|
||||
header = (md4Header_t *)model->modelData;
|
||||
frame = (md4Frame_t *) ((byte *)header + header->ofsFrames);
|
||||
|
||||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MDR) {
|
||||
mdrHeader_t *header;
|
||||
|
|
|
@ -1233,7 +1233,6 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
|
|||
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
|
||||
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
|
||||
(void(*)(void*))RB_SurfaceMesh, // SF_MD3,
|
||||
(void(*)(void*))RB_SurfaceAnim, // SF_MD4,
|
||||
(void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR,
|
||||
(void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM,
|
||||
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
|
||||
|
|
|
@ -33,143 +33,6 @@ frame.
|
|||
|
||||
*/
|
||||
|
||||
/*
|
||||
==============
|
||||
R_AddAnimSurfaces
|
||||
==============
|
||||
*/
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent ) {
|
||||
md4Header_t *header;
|
||||
md4Surface_t *surface;
|
||||
md4LOD_t *lod;
|
||||
shader_t *shader;
|
||||
int cubemapIndex;
|
||||
int i;
|
||||
|
||||
header = (md4Header_t *) tr.currentModel->modelData;
|
||||
lod = (md4LOD_t *)( (byte *)header + header->ofsLODs );
|
||||
cubemapIndex = R_CubemapForPoint(ent->e.origin);
|
||||
|
||||
surface = (md4Surface_t *)( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++ ) {
|
||||
shader = R_GetShaderByHandle( surface->shaderIndex );
|
||||
R_AddDrawSurf( (void *)surface, shader, 0 /*fogNum*/, qfalse, qfalse, cubemapIndex );
|
||||
surface = (md4Surface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_SurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_SurfaceAnim( md4Surface_t *surface ) {
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
int *triangles;
|
||||
int indexes;
|
||||
int baseIndex, baseVertex;
|
||||
int numVerts;
|
||||
md4Vertex_t *v;
|
||||
md4Bone_t bones[MD4_MAX_BONES];
|
||||
md4Bone_t *bonePtr, *bone;
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
md4Frame_t *oldFrame;
|
||||
int frameSize;
|
||||
|
||||
|
||||
if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
|
||||
backlerp = 0;
|
||||
frontlerp = 1;
|
||||
} else {
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
frontlerp = 1.0f - backlerp;
|
||||
}
|
||||
header = (md4Header_t *)((byte *)surface + surface->ofsHeader);
|
||||
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
frame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.frame * frameSize );
|
||||
oldFrame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.oldframe * frameSize );
|
||||
|
||||
RB_CheckOverflow( surface->numVerts, surface->numTriangles * 3 );
|
||||
|
||||
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
|
||||
indexes = surface->numTriangles * 3;
|
||||
baseIndex = tess.numIndexes;
|
||||
baseVertex = tess.numVertexes;
|
||||
for (j = 0 ; j < indexes ; j++) {
|
||||
tess.indexes[baseIndex + j] = baseIndex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
|
||||
//
|
||||
// lerp all the needed bones
|
||||
//
|
||||
if ( !backlerp ) {
|
||||
// no lerping needed
|
||||
bonePtr = frame->bones;
|
||||
} else {
|
||||
bonePtr = bones;
|
||||
for ( i = 0 ; i < header->numBones*12 ; i++ ) {
|
||||
((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i]
|
||||
+ backlerp * ((float *)oldFrame->bones)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// deform the vertexes by the lerped bones
|
||||
//
|
||||
numVerts = surface->numVerts;
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts);
|
||||
for ( j = 0; j < numVerts; j++ ) {
|
||||
vec3_t tempVert, tempNormal;
|
||||
md4Weight_t *w;
|
||||
|
||||
VectorClear( tempVert );
|
||||
VectorClear( tempNormal );
|
||||
w = v->weights;
|
||||
for ( k = 0 ; k < v->numWeights ; k++, w++ ) {
|
||||
bone = bonePtr + w->boneIndex;
|
||||
|
||||
tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
|
||||
tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
|
||||
tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
|
||||
|
||||
tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
|
||||
tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
|
||||
tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
|
||||
}
|
||||
|
||||
tess.xyz[baseVertex + j][0] = tempVert[0];
|
||||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
tess.normal[baseVertex + j][0] = (uint8_t)(tempNormal[0] * 127.5f + 128.0f);
|
||||
tess.normal[baseVertex + j][1] = (uint8_t)(tempNormal[1] * 127.5f + 128.0f);
|
||||
tess.normal[baseVertex + j][2] = (uint8_t)(tempNormal[2] * 127.5f + 128.0f);
|
||||
|
||||
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
|
||||
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)&v->weights[v->numWeights];
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// copied and adapted from tr_mesh.c
|
||||
|
||||
|
@ -198,7 +61,7 @@ static int R_MDRCullModel( mdrHeader_t *header, trRefEntity_t *ent ) {
|
|||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
// Ummm... yeah yeah I know we don't really have an md3 here.. but we pretend
|
||||
// we do. After all, the purpose of md4s are not that different, are they?
|
||||
// we do. After all, the purpose of mdrs are not that different, are they?
|
||||
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
|
@ -448,7 +311,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
|
|||
RB_MDRSurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
|
||||
{
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
|
@ -460,7 +323,7 @@ void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
|||
mdrHeader_t *header;
|
||||
mdrFrame_t *frame;
|
||||
mdrFrame_t *oldFrame;
|
||||
mdrBone_t bones[MD4_MAX_BONES], *bonePtr, *bone;
|
||||
mdrBone_t bones[MDR_MAX_BONES], *bonePtr, *bone;
|
||||
|
||||
int frameSize;
|
||||
|
||||
|
|
|
@ -924,7 +924,6 @@ typedef enum {
|
|||
SF_TRIANGLES,
|
||||
SF_POLY,
|
||||
SF_MDV,
|
||||
SF_MD4,
|
||||
SF_MDR,
|
||||
SF_IQM,
|
||||
SF_FLARE,
|
||||
|
@ -1342,7 +1341,6 @@ typedef enum {
|
|||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_MESH,
|
||||
MOD_MD4,
|
||||
MOD_MDR,
|
||||
MOD_IQM
|
||||
} modtype_t;
|
||||
|
@ -1355,7 +1353,7 @@ typedef struct model_s {
|
|||
int dataSize; // just for listing purposes
|
||||
bmodel_t *bmodel; // only if type == MOD_BRUSH
|
||||
mdvModel_t *mdv[MD3_MAX_LODS]; // only if type == MOD_MESH
|
||||
void *modelData; // only if type == (MOD_MD4 | MOD_MDR | MOD_IQM)
|
||||
void *modelData; // only if type == (MOD_MDR | MOD_IQM)
|
||||
|
||||
int numLods;
|
||||
} model_t;
|
||||
|
@ -2347,9 +2345,8 @@ ANIMATED MODELS
|
|||
|
||||
// void R_MakeAnimModel( model_t *model ); haven't seen this one really, so not needed I guess.
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_SurfaceAnim( md4Surface_t *surfType );
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface );
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface );
|
||||
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
|
||||
void R_AddIQMSurfaces( trRefEntity_t *ent );
|
||||
void RB_IQMSurfaceAnim( surfaceType_t *surface );
|
||||
|
|
|
@ -1915,9 +1915,6 @@ static void R_AddEntitySurface (int entityNum)
|
|||
case MOD_MESH:
|
||||
R_AddMD3Surfaces( ent );
|
||||
break;
|
||||
case MOD_MD4:
|
||||
R_AddAnimSurfaces( ent );
|
||||
break;
|
||||
case MOD_MDR:
|
||||
R_MDRAddAnimSurfaces( ent );
|
||||
break;
|
||||
|
@ -2204,12 +2201,6 @@ void R_RenderPshadowMaps(const refdef_t *fd)
|
|||
}
|
||||
break;
|
||||
|
||||
case MOD_MD4:
|
||||
{
|
||||
// FIXME: actually calculate the radius and bounds, this is a horrible hack
|
||||
radius = r_pshadowDist->value / 2.0f;
|
||||
}
|
||||
break;
|
||||
case MOD_MDR:
|
||||
{
|
||||
// FIXME: never actually tested this
|
||||
|
|
|
@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
static qboolean R_LoadMD3(model_t *mod, int lod, void *buffer, int bufferSize, const char *modName);
|
||||
static qboolean R_LoadMD4(model_t *mod, void *buffer, const char *name );
|
||||
static qboolean R_LoadMDR(model_t *mod, void *buffer, int filesize, const char *name );
|
||||
|
||||
/*
|
||||
|
@ -73,15 +72,10 @@ qhandle_t R_RegisterMD3(const char *name, model_t *mod)
|
|||
continue;
|
||||
|
||||
ident = LittleLong(* (unsigned *) buf.u);
|
||||
if (ident == MD4_IDENT)
|
||||
loaded = R_LoadMD4(mod, buf.u, name);
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, size, name);
|
||||
else
|
||||
{
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, size, name);
|
||||
else
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
}
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
|
||||
ri.FS_FreeFile(buf.v);
|
||||
|
||||
|
@ -201,7 +195,6 @@ static modelExtToLoaderMap_t modelLoaders[ ] =
|
|||
{
|
||||
{ "iqm", R_RegisterIQM },
|
||||
{ "mdr", R_RegisterMDR },
|
||||
{ "md4", R_RegisterMD3 },
|
||||
{ "md3", R_RegisterMD3 }
|
||||
};
|
||||
|
||||
|
@ -835,7 +828,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
LL(pinmodel->ofsFrames);
|
||||
|
||||
// This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target md4.
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target mdr.
|
||||
if(pinmodel->ofsFrames < 0)
|
||||
{
|
||||
// mdrFrame_t is larger than mdrCompFrame_t:
|
||||
|
@ -1132,162 +1125,6 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LoadMD4
|
||||
=================
|
||||
*/
|
||||
|
||||
static qboolean R_LoadMD4( model_t *mod, void *buffer, const char *mod_name ) {
|
||||
int i, j, k, lodindex;
|
||||
md4Header_t *pinmodel, *md4;
|
||||
md4Frame_t *frame;
|
||||
md4LOD_t *lod;
|
||||
md4Surface_t *surf;
|
||||
md4Triangle_t *tri;
|
||||
md4Vertex_t *v;
|
||||
int version;
|
||||
int size;
|
||||
shader_t *sh;
|
||||
int frameSize;
|
||||
|
||||
pinmodel = (md4Header_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
if (version != MD4_VERSION) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has wrong version (%i should be %i)\n",
|
||||
mod_name, version, MD4_VERSION);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->type = MOD_MD4;
|
||||
size = LittleLong(pinmodel->ofsEnd);
|
||||
mod->dataSize += size;
|
||||
mod->modelData = md4 = ri.Hunk_Alloc( size, h_low );
|
||||
|
||||
Com_Memcpy(md4, buffer, size);
|
||||
|
||||
LL(md4->ident);
|
||||
LL(md4->version);
|
||||
LL(md4->numFrames);
|
||||
LL(md4->numBones);
|
||||
LL(md4->numLODs);
|
||||
LL(md4->ofsFrames);
|
||||
LL(md4->ofsLODs);
|
||||
md4->ofsEnd = size;
|
||||
|
||||
if ( md4->numFrames < 1 ) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has no frames\n", mod_name );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// we don't need to swap tags in the renderer, they aren't used
|
||||
|
||||
// swap all the frames
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ md4->numBones ] );
|
||||
for ( i = 0 ; i < md4->numFrames ; i++) {
|
||||
frame = (md4Frame_t *) ( (byte *)md4 + md4->ofsFrames + i * frameSize );
|
||||
frame->radius = LittleFloat( frame->radius );
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
|
||||
frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
|
||||
frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
|
||||
}
|
||||
for ( j = 0 ; j < md4->numBones * sizeof( md4Bone_t ) / 4 ; j++ ) {
|
||||
((float *)frame->bones)[j] = LittleFloat( ((float *)frame->bones)[j] );
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the LOD's
|
||||
lod = (md4LOD_t *) ( (byte *)md4 + md4->ofsLODs );
|
||||
for ( lodindex = 0 ; lodindex < md4->numLODs ; lodindex++ ) {
|
||||
|
||||
// swap all the surfaces
|
||||
surf = (md4Surface_t *) ( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++) {
|
||||
LL(surf->ident);
|
||||
LL(surf->numTriangles);
|
||||
LL(surf->ofsTriangles);
|
||||
LL(surf->numVerts);
|
||||
LL(surf->ofsVerts);
|
||||
LL(surf->ofsEnd);
|
||||
|
||||
if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i verts on %s (%i).\n",
|
||||
mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numVerts );
|
||||
return qfalse;
|
||||
}
|
||||
if ( surf->numTriangles*3 >= SHADER_MAX_INDEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i triangles on %s (%i).\n",
|
||||
mod_name, ( SHADER_MAX_INDEXES / 3 ) - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numTriangles );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// change to surface identifier
|
||||
surf->ident = SF_MD4;
|
||||
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surf->name );
|
||||
|
||||
// register the shaders
|
||||
sh = R_FindShader( surf->shader, LIGHTMAP_NONE, qtrue );
|
||||
if ( sh->defaultShader ) {
|
||||
surf->shaderIndex = 0;
|
||||
} else {
|
||||
surf->shaderIndex = sh->index;
|
||||
}
|
||||
|
||||
// swap all the triangles
|
||||
tri = (md4Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
|
||||
for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
|
||||
LL(tri->indexes[0]);
|
||||
LL(tri->indexes[1]);
|
||||
LL(tri->indexes[2]);
|
||||
}
|
||||
|
||||
// swap all the vertexes
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts);
|
||||
for ( j = 0 ; j < surf->numVerts ; j++ ) {
|
||||
v->normal[0] = LittleFloat( v->normal[0] );
|
||||
v->normal[1] = LittleFloat( v->normal[1] );
|
||||
v->normal[2] = LittleFloat( v->normal[2] );
|
||||
|
||||
v->texCoords[0] = LittleFloat( v->texCoords[0] );
|
||||
v->texCoords[1] = LittleFloat( v->texCoords[1] );
|
||||
|
||||
v->numWeights = LittleLong( v->numWeights );
|
||||
|
||||
for ( k = 0 ; k < v->numWeights ; k++ ) {
|
||||
v->weights[k].boneIndex = LittleLong( v->weights[k].boneIndex );
|
||||
v->weights[k].boneWeight = LittleFloat( v->weights[k].boneWeight );
|
||||
v->weights[k].offset[0] = LittleFloat( v->weights[k].offset[0] );
|
||||
v->weights[k].offset[1] = LittleFloat( v->weights[k].offset[1] );
|
||||
v->weights[k].offset[2] = LittleFloat( v->weights[k].offset[2] );
|
||||
}
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights]);
|
||||
}
|
||||
|
||||
// find the next surface
|
||||
surf = (md4Surface_t *)( (byte *)surf + surf->ofsEnd );
|
||||
}
|
||||
|
||||
// find the next LOD
|
||||
lod = (md4LOD_t *)( (byte *)lod + lod->ofsEnd );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1527,17 +1364,6 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
|
|||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MD4) {
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
|
||||
header = (md4Header_t *)model->modelData;
|
||||
frame = (md4Frame_t *) ((byte *)header + header->ofsFrames);
|
||||
|
||||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MDR) {
|
||||
mdrHeader_t *header;
|
||||
|
|
|
@ -1676,7 +1676,6 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
|
|||
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
|
||||
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
|
||||
(void(*)(void*))RB_SurfaceMesh, // SF_MDV,
|
||||
(void(*)(void*))RB_SurfaceAnim, // SF_MD4,
|
||||
(void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR,
|
||||
(void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM,
|
||||
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
|
||||
|
|
Loading…
Reference in a new issue