📄 tr_model.c
字号:
{
xyz->xyz[0] = LittleShort( xyz->xyz[0] );
xyz->xyz[1] = LittleShort( xyz->xyz[1] );
xyz->xyz[2] = LittleShort( xyz->xyz[2] );
xyz->normal = LittleShort( xyz->normal );
}
// find the next surface
surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
}
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;
md4 = mod->md4 = ri.Hunk_Alloc( size, h_low );
Com_Memcpy( md4, buffer, LittleLong(pinmodel->ofsEnd) );
LL(md4->ident);
LL(md4->version);
LL(md4->numFrames);
LL(md4->numBones);
LL(md4->numLODs);
LL(md4->ofsFrames);
LL(md4->ofsLODs);
LL(md4->ofsEnd);
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 = (int)( &((md4Frame_t *)0)->bones[ md4->numBones ] );
for ( i = 0 ; i < md4->numFrames ; i++, frame++) {
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.Error (ERR_DROP, "R_LoadMD3: %s has more than %i verts on a surface (%i)",
mod_name, SHADER_MAX_VERTEXES, surf->numVerts );
}
if ( surf->numTriangles*3 > SHADER_MAX_INDEXES ) {
ri.Error (ERR_DROP, "R_LoadMD3: %s has more than %i triangles on a surface (%i)",
mod_name, SHADER_MAX_INDEXES / 3, surf->numTriangles );
}
// 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;
}
//=============================================================================
/*
** RE_BeginRegistration
*/
void RE_BeginRegistration( glconfig_t *glconfigOut ) {
R_Init();
*glconfigOut = glConfig;
R_SyncRenderThread();
tr.viewCluster = -1; // force markleafs to regenerate
R_ClearFlares();
RE_ClearScene();
tr.registered = qtrue;
// NOTE: this sucks, for some reason the first stretch pic is never drawn
// without this we'd see a white flash on a level load because the very
// first time the level shot would not be drawn
RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0);
}
//=============================================================================
/*
===============
R_ModelInit
===============
*/
void R_ModelInit( void ) {
model_t *mod;
// leave a space for NULL model
tr.numModels = 0;
mod = R_AllocModel();
mod->type = MOD_BAD;
}
/*
================
R_Modellist_f
================
*/
void R_Modellist_f( void ) {
int i, j;
model_t *mod;
int total;
int lods;
total = 0;
for ( i = 1 ; i < tr.numModels; i++ ) {
mod = tr.models[i];
lods = 1;
for ( j = 1 ; j < MD3_MAX_LODS ; j++ ) {
if ( mod->md3[j] && mod->md3[j] != mod->md3[j-1] ) {
lods++;
}
}
ri.Printf( PRINT_ALL, "%8i : (%i) %s\n",mod->dataSize, lods, mod->name );
total += mod->dataSize;
}
ri.Printf( PRINT_ALL, "%8i : Total models\n", total );
#if 0 // not working right with new hunk
if ( tr.world ) {
ri.Printf( PRINT_ALL, "\n%8i : %s\n", tr.world->dataSize, tr.world->name );
}
#endif
}
//=============================================================================
/*
================
R_GetTag
================
*/
static md3Tag_t *R_GetTag( md3Header_t *mod, int frame, const char *tagName ) {
md3Tag_t *tag;
int i;
if ( frame >= mod->numFrames ) {
// it is possible to have a bad frame while changing models, so don't error
frame = mod->numFrames - 1;
}
tag = (md3Tag_t *)((byte *)mod + mod->ofsTags) + frame * mod->numTags;
for ( i = 0 ; i < mod->numTags ; i++, tag++ ) {
if ( !strcmp( tag->name, tagName ) ) {
return tag; // found it
}
}
return NULL;
}
/*
================
R_LerpTag
================
*/
int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame,
float frac, const char *tagName ) {
md3Tag_t *start, *end;
int i;
float frontLerp, backLerp;
model_t *model;
model = R_GetModelByHandle( handle );
if ( !model->md3[0] ) {
AxisClear( tag->axis );
VectorClear( tag->origin );
return qfalse;
}
start = R_GetTag( model->md3[0], startFrame, tagName );
end = R_GetTag( model->md3[0], endFrame, tagName );
if ( !start || !end ) {
AxisClear( tag->axis );
VectorClear( tag->origin );
return qfalse;
}
frontLerp = frac;
backLerp = 1.0f - frac;
for ( i = 0 ; i < 3 ; i++ ) {
tag->origin[i] = start->origin[i] * backLerp + end->origin[i] * frontLerp;
tag->axis[0][i] = start->axis[0][i] * backLerp + end->axis[0][i] * frontLerp;
tag->axis[1][i] = start->axis[1][i] * backLerp + end->axis[1][i] * frontLerp;
tag->axis[2][i] = start->axis[2][i] * backLerp + end->axis[2][i] * frontLerp;
}
VectorNormalize( tag->axis[0] );
VectorNormalize( tag->axis[1] );
VectorNormalize( tag->axis[2] );
return qtrue;
}
/*
====================
R_ModelBounds
====================
*/
void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
model_t *model;
md3Header_t *header;
md3Frame_t *frame;
model = R_GetModelByHandle( handle );
if ( model->bmodel ) {
VectorCopy( model->bmodel->bounds[0], mins );
VectorCopy( model->bmodel->bounds[1], maxs );
return;
}
if ( !model->md3[0] ) {
VectorClear( mins );
VectorClear( maxs );
return;
}
header = model->md3[0];
frame = (md3Frame_t *)( (byte *)header + header->ofsFrames );
VectorCopy( frame->bounds[0], mins );
VectorCopy( frame->bounds[1], maxs );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -