int G2_Get_Bone_Index(CGhoul2Info *ghoul2, const char *boneName) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(ghoul2->mFileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); return (G2_Find_Bone(mod_a, ghoul2->mBlist, boneName)); }
// given a model, bonelist and bonename, lets pause an anim if it's playing. qboolean G2_Pause_Bone_Anim(const char *fileName, boneInfo_v &blist, const char *boneName, const int currentTime) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); // did we find it? if (index != -1) { // are we pausing or un pausing? if (blist[index].pauseTime) { int startFrame, endFrame, flags; float currentFrame, animSpeed; // figure out what frame we are on now G2_Get_Bone_Anim(fileName, blist, boneName, blist[index].pauseTime, ¤tFrame, &startFrame, &endFrame, &flags, &animSpeed, NULL, 0); // reset start time so we are actually on this frame right now G2_Set_Bone_Anim(fileName, blist, boneName, startFrame, endFrame, flags, animSpeed, currentTime, currentFrame, 0); // no pausing anymore blist[index].pauseTime = 0; } // ahh, just pausing, the easy bit else { blist[index].pauseTime = currentTime; } return qtrue; } assert(0); return qfalse; }
// Given a model handle, and a bone name, we want to remove this bone from the bone override list qboolean G2_Remove_Bone (const char *fileName, boneInfo_v &blist, const char *boneName) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); return G2_Remove_Bone_Index(blist, index); }
// Given a model handle, and a bone name, we want to set angles specifically for overriding qboolean G2_Set_Bone_Angles(const char *fileName, boneInfo_v &blist, const char *boneName, const float *angles, const int flags, const Eorientations up, const Eorientations left, const Eorientations forward, qhandle_t *modelList, const int modelIndex, const int blendTime, const int currentTime) { model_t *mod_m; if (!fileName[0]) { mod_m = R_GetModelByHandle(modelList[modelIndex]); } else { mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); } model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); // did we find it? if (index != -1) { // yes, so set the angles and flags correctly blist[index].flags &= ~(BONE_ANGLES_TOTAL); blist[index].flags |= flags; blist[index].boneBlendStart = currentTime; blist[index].boneBlendTime = blendTime; #if DEBUG_PCJ OutputDebugString(va("%2d %6d (%6.2f,%6.2f,%6.2f) %d %d %d %d\n",index,currentTime,angles[0],angles[1],angles[2],up,left,forward,flags)); #endif G2_Generate_Matrix(mod_a, blist, index, angles, flags, up, left, forward); return qtrue; } // no - lets try and add this bone in index = G2_Add_Bone(mod_a, blist, boneName); // did we find a free one? if (index != -1) { // yes, so set the angles and flags correctly blist[index].flags &= ~(BONE_ANGLES_TOTAL); blist[index].flags |= flags; blist[index].boneBlendStart = currentTime; blist[index].boneBlendTime = blendTime; #if DEBUG_PCJ OutputDebugString(va("%2d %6d (%6.2f,%6.2f,%6.2f) %d %d %d %d\n",index,currentTime,angles[0],angles[1],angles[2],up,left,forward,flags)); #endif G2_Generate_Matrix(mod_a, blist, index, angles, flags, up, left, forward); return qtrue; } assert(0); // no return qfalse; }
/* ==================== R_ModelBounds ==================== */ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) { model_t *model; mdvModel_t *header; mdvFrame_t *frame; model = R_GetModelByHandle( handle ); if ( model->bsp ) { VectorCopy( model->bsp->bounds[ 0 ], mins ); VectorCopy( model->bsp->bounds[ 1 ], maxs ); } else if ( model->mdv[ 0 ] ) { header = model->mdv[ 0 ]; frame = header->frames; VectorCopy( frame->bounds[ 0 ], mins ); VectorCopy( frame->bounds[ 1 ], maxs ); } else if ( model->md5 ) { VectorCopy( model->md5->bounds[ 0 ], mins ); VectorCopy( model->md5->bounds[ 1 ], maxs ); } else { VectorClear( mins ); VectorClear( maxs ); } }
// adds a simple shadow projector to the scene void R_AddModelShadow( const refEntity_t* ent ) { // shadows? if ( !r_drawentities->integer || r_shadows->integer != 1 || ent->renderfx & RF_NOSHADOW ) { return; } // get model idRenderModel* m = R_GetModelByHandle( ent->hModel ); if ( m == NULL || m->q3_shadowShader == 0 ) { return; } // calculate projection vec4_t projection; VectorSet( projection, 0, 0, -1.0f ); projection[ 3 ] = m->q3_shadowParms[ 4 ]; // push origin vec3_t pushedOrigin; VectorMA( ent->origin, m->q3_shadowParms[ 5 ], projection, pushedOrigin ); // make shadow polygon vec3_t points[ 4 ]; VectorMA( pushedOrigin, m->q3_shadowParms[ 0 ], ent->axis[ 1 ], points[ 0 ] ); VectorMA( points[ 0 ], m->q3_shadowParms[ 1 ], ent->axis[ 0 ], points[ 0 ] ); VectorMA( points[ 0 ], m->q3_shadowParms[ 2 ], ent->axis[ 1 ], points[ 1 ] ); VectorMA( points[ 1 ], m->q3_shadowParms[ 3 ], ent->axis[ 0 ], points[ 2 ] ); VectorMA( points[ 0 ], m->q3_shadowParms[ 3 ], ent->axis[ 0 ], points[ 3 ] ); // add the decal vec4_t color = { 1, 1, 1, 1 }; R_ProjectDecal( m->q3_shadowShader, 4, points, projection, color, -1, -1 ); }
int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { const model_t* model = R_GetModelByHandle( handle ); if ( !model->md3[0] ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return qfalse; } const md3Tag_t* start = R_GetTag( model->md3[0], startFrame, tagName ); const md3Tag_t* end = R_GetTag( model->md3[0], endFrame, tagName ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return qfalse; } float backLerp = 1.0f - frac; for ( int i = 0; i < 3; ++i ) { tag->origin[i] = start->origin[i] * backLerp + end->origin[i] * frac; tag->axis[0][i] = start->axis[0][i] * backLerp + end->axis[0][i] * frac; tag->axis[1][i] = start->axis[1][i] * backLerp + end->axis[1][i] * frac; tag->axis[2][i] = start->axis[2][i] * backLerp + end->axis[2][i] * frac; } VectorNormalize( tag->axis[0] ); VectorNormalize( tag->axis[1] ); VectorNormalize( tag->axis[2] ); return qtrue; }
bool R_LerpTag( orientation_t* tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char* tagName ) { int i; float frontLerp, backLerp; idRenderModel* model = R_GetModelByHandle( handle ); if ( !model->q3_md3[ 0 ].header ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return false; } md3Tag_t* start = R_GetTag( model->q3_md3[ 0 ].header, startFrame, tagName ); md3Tag_t* end = R_GetTag( model->q3_md3[ 0 ].header, endFrame, tagName ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return false; } 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 true; }
int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { md3Tag_t *start, *end; #ifdef RAVENMD4 md3Tag_t start_space, end_space; #endif int i; float frontLerp, backLerp; model_t *model; model = R_GetModelByHandle( handle ); if ( !model->md3[0] ) { #ifdef RAVENMD4 if(model->type == MOD_MDR) { start = &start_space; end = &end_space; R_GetAnimTag((mdrHeader_t *) model->modelData, startFrame, tagName, start); R_GetAnimTag((mdrHeader_t *) model->modelData, endFrame, tagName, end); } else #endif if( model->type == MOD_IQM ) { return R_IQMLerpTag( tag, model->modelData, startFrame, endFrame, frac, tagName ); } else { AxisClear( tag->axis ); VectorClear( &tag->origin ); return qfalse; } } else { 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.data[i] = start->origin.data[i] * backLerp + end->origin.data[i] * frontLerp; tag->axis[0].data[i] = start->axis[0].data[i] * backLerp + end->axis[0].data[i] * frontLerp; tag->axis[1].data[i] = start->axis[1].data[i] * backLerp + end->axis[1].data[i] * frontLerp; tag->axis[2].data[i] = start->axis[2].data[i] * backLerp + end->axis[2].data[i] * frontLerp; } VectorNormalize( &tag->axis[0] ); VectorNormalize( &tag->axis[1] ); VectorNormalize( &tag->axis[2] ); return qtrue; }
// assorted Ghoul 2 functions. // list all surfaces associated with a model void G2_List_Model_Surfaces(const char *fileName) { int i, x; model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); mdxmSurfHierarchy_t *surf; surf = (mdxmSurfHierarchy_t *) ( (byte *)mod_m->mdxm + mod_m->mdxm->ofsSurfHierarchy ); mdxmSurface_t *surface = (mdxmSurface_t *)((byte *)mod_m->mdxm + mod_m->mdxm->ofsLODs + sizeof(mdxmLOD_t)); for ( x = 0 ; x < mod_m->mdxm->numSurfaces ; x++) { Com_Printf("Surface %i Name %s\n", x, surf->name); if (r_verbose->value) { Com_Printf("Num Descendants %i\n", surf->numChildren); for (i=0; i<surf->numChildren; i++) { Com_Printf("Descendant %i\n", surf->childIndexes[i]); } } // find the next surface surf = (mdxmSurfHierarchy_t *)( (byte *)surf + (int)( &((mdxmSurfHierarchy_t *)0)->childIndexes[ surf->numChildren ] )); surface =(mdxmSurface_t *)( (byte *)surface + surface->ofsEnd ); } }
// Use only by Quake and Hexen 2, only .MDL files will have meaningfull flags. int R_ModelFlags( qhandle_t Handle ) { idRenderModel* Model = R_GetModelByHandle( Handle ); if ( Model->type == MOD_MESH1 ) { return Model->q1_flags; } return 0; }
void R_AddModelShadow( refEntity_t *ent ) { model_t *m; vec4_t projection, color = { 1, 1, 1, 1 }; vec3_t pushedOrigin, points[ 4 ]; /* shadows? */ if ( !r_drawentities->integer || r_shadows->integer != 1 || ent->renderfx & RF_NOSHADOW ) { return; } /* get model */ m = R_GetModelByHandle( ent->hModel ); if ( m == NULL || m->shadowShader == 0 ) { return; } /* calculate projection */ VectorSubtract( vec3_origin, ent->axis[ 2 ], projection ); VectorSet( projection, 0, 0, -1.0f ); projection[ 3 ] = m->shadowParms[ 4 ]; /* push origin */ VectorMA( ent->origin, m->shadowParms[ 5 ], projection, pushedOrigin ); /* make shadow polygon */ VectorMA( pushedOrigin, m->shadowParms[ 0 ], ent->axis[ 1 ], points[ 0 ] ); VectorMA( points[ 0 ], m->shadowParms[ 1 ], ent->axis[ 0 ], points[ 0 ] ); VectorMA( points[ 0 ], m->shadowParms[ 2 ], ent->axis[ 1 ], points[ 1 ] ); VectorMA( points[ 1 ], m->shadowParms[ 3 ], ent->axis[ 0 ], points[ 2 ] ); VectorMA( points[ 0 ], m->shadowParms[ 3 ], ent->axis[ 0 ], points[ 3 ] ); /* add the decal */ RE_ProjectDecal( m->shadowShader, 4, points, projection, color, -1, -1 ); }
/* ================ RE_BoneIndex ================ */ int RE_BoneIndex( qhandle_t hModel, const char *boneName ) { int i; md5Bone_t *bone; md5Model_t *md5; model_t *model; model = R_GetModelByHandle( hModel ); if ( !model->md5 ) { return -1; } else { md5 = model->md5; } for ( i = 0, bone = md5->bones; i < md5->numBones; i++, bone++ ) { if ( !Q_stricmp( bone->name, boneName ) ) { return i; } } return -1; }
/* ==================== 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 ); }
/* ==================== R_ModelBounds ==================== */ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) { model_t *model; model = R_GetModelByHandle( handle ); if(model->type == MOD_BRUSH) { VectorCopy( model->bmodel->bounds[0], mins ); VectorCopy( model->bmodel->bounds[1], maxs ); return; } else if (model->type == MOD_MESH) { md3Header_t *header; md3Frame_t *frame; header = model->md3[0]; frame = (md3Frame_t *) ((byte *)header + header->ofsFrames); 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; mdrFrame_t *frame; header = (mdrHeader_t *)model->modelData; frame = (mdrFrame_t *) ((byte *)header + header->ofsFrames); VectorCopy( frame->bounds[0], mins ); VectorCopy( frame->bounds[1], maxs ); return; } else if(model->type == MOD_IQM) { iqmData_t *iqmData; iqmData = model->modelData; if(iqmData->bounds) { VectorCopy(iqmData->bounds, mins); VectorCopy(iqmData->bounds + 3, maxs); return; } } VectorClear( mins ); VectorClear( maxs ); }
// Given a model handle, and a bone name, we want to set angles specifically for overriding - using a matrix directly qboolean G2_Set_Bone_Angles_Matrix(const char *fileName, boneInfo_v &blist, const char *boneName, const mdxaBone_t &matrix, const int flags, qhandle_t *modelList, const int modelIndex, const int blendTime, const int currentTime) { model_t *mod_m; if (!fileName[0]) { mod_m = R_GetModelByHandle(modelList[modelIndex]); } else { mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); } model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); // did we find it? if (index != -1) { // yes, so set the angles and flags correctly blist[index].flags &= ~(BONE_ANGLES_TOTAL); blist[index].flags |= flags; memcpy(&blist[index].matrix, &matrix, sizeof(mdxaBone_t)); memcpy(&blist[index].newMatrix, &matrix, sizeof(mdxaBone_t)); return qtrue; } // no - lets try and add this bone in index = G2_Add_Bone(mod_a, blist, boneName); // did we find a free one? if (index != -1) { // yes, so set the angles and flags correctly blist[index].flags &= ~(BONE_ANGLES_TOTAL); blist[index].flags |= flags; memcpy(&blist[index].matrix, &matrix, sizeof(mdxaBone_t)); memcpy(&blist[index].newMatrix, &matrix, sizeof(mdxaBone_t)); return qtrue; } assert(0); // no return qfalse; }
// given a model, bonelist and bonename, lets stop an anim if it's playing. qboolean G2_Stop_Bone_Angles(const char *fileName, boneInfo_v &blist, const char *boneName) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); // did we find it? if (index != -1) { blist[index].flags &= ~(BONE_ANGLES_TOTAL); // try and remove this bone if we can return G2_Remove_Bone_Index(blist, index); } assert(0); return qfalse; }
char *G2API_GetGLAName(CGhoul2Info_v &ghoul2, int modelIndex) { if (((int)&ghoul2) && (ghoul2.size() > modelIndex)) { model_t *mod = R_GetModelByHandle(RE_RegisterModel(ghoul2[modelIndex].mFileName)); return mod->mdxm->animName; } return NULL; }
void R_AddEntitySurfaces (void) { trRefEntity_t *ent; //MODVIEWREM shader_t *shader; for ( tr.currentEntityNum = 0; tr.currentEntityNum < tr.refdef.num_entities; tr.currentEntityNum++ ) { ent = tr.currentEntity = &tr.refdef.entities[tr.currentEntityNum]; // ent->needDlights = qfalse; // we must set up parts of tr.or for model culling //MODVIEWREM R_RotateForEntity( ent, &tr.viewParms, &tr.or ); tr.currentModel = R_GetModelByHandle( ent->e.hModel ); if (!tr.currentModel) { assert(0); //MODVIEWREM R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0 ); } else { switch ( tr.currentModel->type ) { case MOD_MESH: R_AddMD3Surfaces( ent ); break; case MOD_MD4: R_AddAnimSurfaces( ent ); break; case MOD_MDXM: R_AddGhoulSurfaces( ent); break; case MOD_BRUSH: assert(0); // R_AddBrushModelSurfaces( ent ); break; case MOD_BAD: // null model axis assert(0); /*MODVIEWREM if ( (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal) { break; } shader = R_GetShaderByHandle( ent->e.customShader ); R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0 ); */ break; default: ri.Error( ERR_DROP, "R_AddEntitySurfaces: Bad modeltype" ); break; } } } }
qboolean G2_Get_Bone_Anim_Range(const char *fileName, boneInfo_v &blist, const char *boneName, int *startFrame, int *endFrame) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); // did we find it? if (index != -1) { // are we an animating bone? if (blist[index].flags & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE)) { *startFrame = blist[index].startFrame; *endFrame = blist[index].endFrame; return qtrue; } } return qfalse; }
int R_ModelSyncType( qhandle_t Handle ) { idRenderModel* Model = R_GetModelByHandle( Handle ); switch ( Model->type ) { case MOD_SPRITE: case MOD_MESH1: return Model->q1_synctype; default: return 0; } }
char *G2API_GetGLAName(g2handle_t g2h, int modelIndex) { CGhoul2Info_v *ghoul2 = G2API_GetGhoul2Model(g2h); if (ghoul2 && (unsigned)modelIndex < ghoul2->size()) { model_t *mod = R_GetModelByHandle(RE_RegisterModel((*ghoul2)[modelIndex].mFileName)); return mod->mdxm->animName; } return NULL; }
qboolean G2_IsPaused(const char *fileName, boneInfo_v &blist, const char *boneName) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); // did we find it? if (index != -1) { // are we paused? if (blist[index].pauseTime) { // yup. paused. return qtrue; } return qfalse; } return qfalse; }
/************************************************************************************************ * G2_GetAnimFileName * obtain the .gla filename for a model * * Input * filename of model * * Output * true if we successfully obtained a filename, false otherwise * ************************************************************************************************/ qboolean G2_GetAnimFileName(const char *fileName, char **filename) { // find the model we want model_t *mod = R_GetModelByHandle(RE_RegisterModel(fileName)); if (mod && mod->mdxm && (mod->mdxm->animName[0] != 0)) { *filename = mod->mdxm->animName; return qtrue; } return qfalse; }
void R_CalculateModelScaleOffset( qhandle_t Handle, float ScaleX, float ScaleY, float ScaleZ, float ScaleZOrigin, vec3_t Out ) { idRenderModel* Model = R_GetModelByHandle( Handle ); if ( Model->type != MOD_MESH1 ) { VectorClear( Out ); return; } idSurfaceMDL* AliasHdr = Model->q1_mdl; Out[ 0 ] = -( ScaleX - 1.0 ) * ( AliasHdr->header.scale[ 0 ] * 127.95 + AliasHdr->header.scale_origin[ 0 ] ); Out[ 1 ] = -( ScaleY - 1.0 ) * ( AliasHdr->header.scale[ 1 ] * 127.95 + AliasHdr->header.scale_origin[ 1 ] ); Out[ 2 ] = -( ScaleZ - 1.0 ) * ( ScaleZOrigin * 2.0 * AliasHdr->header.scale[ 2 ] * 127.95 + AliasHdr->header.scale_origin[ 2 ] ); }
static iqmData_t *R_GetIQMModelDataByHandle( qhandle_t hModel, iqmData_t *defaultData ) { model_t *mod; if ( !hModel ) return defaultData; mod = R_GetModelByHandle( hModel ); if ( mod->type != MOD_IQM ) { return defaultData; } return mod->modelData; }
/* ================ R_LerpTag ================ */ int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { md3Tag_t *start, *end; md3Tag_t start_space, end_space; int i; float frontLerp, backLerp; model_t *model; model = R_GetModelByHandle( handle ); if ( !model->md3[0] ) { if(model->type == MOD_MDR) { start = R_GetAnimTag((mdrHeader_t *) model->modelData, startFrame, tagName, &start_space); end = R_GetAnimTag((mdrHeader_t *) model->modelData, endFrame, tagName, &end_space); } else if( model->type == MOD_IQM ) { return R_IQMLerpTag( tag, (iqmData_t *)model->modelData, startFrame, endFrame, frac, tagName ); } else { start = end = NULL; } } else { 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 false; } 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 true; }
void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) { idRenderModel* model = R_GetModelByHandle( handle ); switch ( model->type ) { case MOD_BRUSH29: case MOD_BRUSH29_NON_MAP: case MOD_SPRITE: case MOD_MESH1: VectorCopy( model->q1_mins, mins ); VectorCopy( model->q1_maxs, maxs ); break; case MOD_BRUSH38: case MOD_MESH2: VectorCopy( model->q2_mins, mins ); VectorCopy( model->q2_maxs, maxs ); break; case MOD_BRUSH46: VectorCopy( model->q3_bmodel->bounds[ 0 ], mins ); VectorCopy( model->q3_bmodel->bounds[ 1 ], maxs ); break; case MOD_MESH3: { md3Header_t* header = model->q3_md3[ 0 ].header; md3Frame_t* frame = ( md3Frame_t* )( ( byte* )header + header->ofsFrames ); VectorCopy( frame->bounds[ 0 ], mins ); VectorCopy( frame->bounds[ 1 ], maxs ); } break; case MOD_MDC: { md3Frame_t* frame = ( md3Frame_t* )( ( byte* )model->q3_mdc[ 0 ].header + model->q3_mdc[ 0 ].header->ofsFrames ); VectorCopy( frame->bounds[ 0 ], mins ); VectorCopy( frame->bounds[ 1 ], maxs ); } break; default: VectorClear( mins ); VectorClear( maxs ); break; } }
// list all bones associated with a model void G2_List_Model_Bones(const char *fileName, int frame) { int x, i; mdxaSkel_t *skel; mdxaSkelOffsets_t *offsets; model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); // mdxaFrame_t *aframe=0; // int frameSize; mdxaHeader_t *header = mod_a->mdxa; // figure out where the offset list is offsets = (mdxaSkelOffsets_t *)((byte *)header + sizeof(mdxaHeader_t)); // frameSize = (int)( &((mdxaFrame_t *)0)->boneIndexes[ header->numBones ] ); // aframe = (mdxaFrame_t *)((byte *)header + header->ofsFrames + (frame * frameSize)); // walk each bone and list it's name for (x=0; x< mod_a->mdxa->numBones; x++) { skel = (mdxaSkel_t *)((byte *)header + sizeof(mdxaHeader_t) + offsets->offsets[x]); Com_Printf("Bone %i Name %s\n", x, skel->name); Com_Printf("X pos %f, Y pos %f, Z pos %f\n", skel->BasePoseMat.matrix[0][3], skel->BasePoseMat.matrix[1][3], skel->BasePoseMat.matrix[2][3]); // if we are in verbose mode give us more details if (r_verbose->value) { Com_Printf("Num Descendants %i\n", skel->numChildren); for (i=0; i<skel->numChildren; i++) { Com_Printf("Num Descendants %i\n", skel->numChildren); } } } }
// given a model, bone name, a bonelist, a start/end frame number, a anim speed and some anim flags, set up or modify an existing bone entry for a new set of anims qboolean G2_Set_Bone_Anim(const char *fileName, boneInfo_v &blist, const char *boneName, const int startFrame, const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime) { model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName)); model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex); int index = G2_Find_Bone(mod_a, blist, boneName); if (index == -1) { index = G2_Add_Bone(mod_a, blist, boneName); } if (index != -1) { return G2_Set_Bone_Anim_Index(blist,index,startFrame,endFrame,flags,animSpeed,currentTime,setFrame,blendTime); } return qfalse; }