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; }
// Given a model handle, and a bone name, we want to remove this bone from the bone override list qboolean G2_Remove_Bone (CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index==-1) { return false; } return G2_Remove_Bone_Index(blist, index); }
qboolean G2_Pause_Bone_Anim(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const int currentTime) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index==-1) { return qfalse; } return (G2_Pause_Bone_Anim_Index( blist, index, currentTime,ghlInfo->aHeader->numFrames) ); }
int G2_Get_Bone_Index(CGhoul2Info *ghoul2, const char *boneName, qboolean bAddIfNotFound) { if (bAddIfNotFound) { return G2_Add_Bone(ghoul2->animModel, ghoul2->mBlist, boneName); } else { return G2_Find_Bone(ghoul2, ghoul2->mBlist, boneName); } }
// given a model, bonelist and bonename, lets stop an anim if it's playing. qboolean G2_Stop_Bone_Angles(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index != -1) { blist[index].flags &= ~(BONE_ANGLES_TOTAL); return G2_Remove_Bone_Index(blist, index); } assert(0); return qfalse; }
qboolean G2_Get_Bone_Anim_Range(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, int *startFrame, int *endFrame) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index==-1) { return qfalse; } if (G2_Get_Bone_Anim_Range_Index( blist, index, startFrame, endFrame)) { assert(*startFrame>=0&&*startFrame<ghlInfo->aHeader->numFrames); assert(*endFrame>0&&*endFrame<=ghlInfo->aHeader->numFrames); return qtrue; } return qfalse; }
qboolean G2_IsPaused(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index != -1) { // are we paused? if (blist[index].pauseTime) { // yup. paused. return qtrue; } return qfalse; } return qfalse; }
// 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; }
// 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(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const mdxaBone_t &matrix, const int flags,const int blendTime, const int currentTime) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index == -1) { index = G2_Add_Bone(ghlInfo->animModel, blist, boneName); } if (index != -1) { 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; } return qfalse; }
// given a model, bonelist and bonename, return the current frame, startframe and endframe of the current animation // NOTE if we aren't running an animation, then qfalse is returned qboolean G2_Get_Bone_Anim(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const int currentTime, float *currentFrame, int *startFrame, int *endFrame, int *flags, float *retAnimSpeed) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index==-1) { return qfalse; } assert(ghlInfo->aHeader); if (G2_Get_Bone_Anim_Index(blist, index, currentTime, currentFrame, startFrame, endFrame, flags, retAnimSpeed,ghlInfo->aHeader->numFrames)) { assert(*startFrame>=0&&*startFrame<ghlInfo->aHeader->numFrames); assert(*endFrame>0&&*endFrame<=ghlInfo->aHeader->numFrames); assert(*currentFrame>=0.0f&&((int)(*currentFrame))<ghlInfo->aHeader->numFrames); return qtrue; } return qfalse; }
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; }
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; }
// Given a model handle, and a bone name, we want to set angles specifically for overriding qboolean G2_Set_Bone_Angles(CGhoul2Info *ghlInfo, boneInfo_v &blist, const char *boneName, const float *angles, const int flags, const Eorientations up, const Eorientations left, const Eorientations forward, const int blendTime, const int currentTime) { int index = G2_Find_Bone(ghlInfo, blist, boneName); if (index == -1) { index = G2_Add_Bone(ghlInfo->animModel, blist, boneName); } if (index != -1) { blist[index].flags &= ~(BONE_ANGLES_TOTAL); blist[index].flags |= flags; blist[index].boneBlendStart = currentTime; blist[index].boneBlendTime = blendTime; G2_Generate_Matrix(ghlInfo->animModel, blist, index, angles, flags, up, left, forward); return qtrue; } return qfalse; }
// 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; }
// 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(CGhoul2Info *ghlInfo, 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) { int modFlags = flags; int index = G2_Find_Bone(ghlInfo, blist, boneName); // sanity check to see if setfram is within animation bounds if (setFrame != -1) { assert((setFrame >= startFrame) && (setFrame <= endFrame)); } // did we find it? if (index != -1) { return G2_Set_Bone_Anim_Index(blist, index, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime,ghlInfo->aHeader->numFrames); } // no - lets try and add this bone in index = G2_Add_Bone(ghlInfo->animModel, blist, boneName); // did we find a free one? if (index != -1) { blist[index].blendFrame = blist[index].blendLerpFrame = 0; blist[index].blendTime = 0; // we aren't blending, so remove the option to do so modFlags &= ~BONE_ANIM_BLEND; // yes, so set the anim data and flags correctly blist[index].endFrame = endFrame; blist[index].startFrame = startFrame; blist[index].animSpeed = animSpeed; blist[index].pauseTime = 0; // start up the animation:) if (setFrame != -1) { blist[index].startTime = (currentTime - (((setFrame - (float)startFrame) * 50.0)/ animSpeed)); } else { blist[index].startTime = currentTime; } blist[index].flags &= ~BONE_ANIM_TOTAL; blist[index].flags |= modFlags; assert(blist[index].blendFrame>=0&&blist[index].blendFrame<ghlInfo->aHeader->numFrames); assert(blist[index].blendLerpFrame>=0&&blist[index].blendLerpFrame<ghlInfo->aHeader->numFrames); #if DEBUG_G2_TIMING if (index>-10) { const boneInfo_t &bone=blist[index]; char mess[1000]; if (bone.flags&BONE_ANIM_BLEND) { sprintf(mess,"s2b[%2d] %5d %5d (%5d-%5d) %4.2f %4x bt(%5d-%5d) %7.2f %5d\n", index, currentTime, bone.startTime, bone.startFrame, bone.endFrame, bone.animSpeed, bone.flags, bone.blendStart, bone.blendStart+bone.blendTime, bone.blendFrame, bone.blendLerpFrame ); } else { sprintf(mess,"s2a[%2d] %5d %5d (%5d-%5d) %4.2f %4x\n", index, currentTime, bone.startTime, bone.startFrame, bone.endFrame, bone.animSpeed, bone.flags ); } OutputDebugString(mess); } #endif return qtrue; } //assert(index != -1); // no return qfalse; }
// given a model, bonelist and bonename, return the current frame, startframe and endframe of the current animation // NOTE if we aren't running an animation, then qfalse is returned qboolean G2_Get_Bone_Anim(const char *fileName, boneInfo_v &blist, const char *boneName, const int currentTime, float *currentFrame, int *startFrame, int *endFrame, int *flags, float *retAnimSpeed, qhandle_t *modelList, int modelIndex) { 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) { // are we an animating bone? if (blist[index].flags & (BONE_ANIM_OVERRIDE_LOOP | BONE_ANIM_OVERRIDE)) { // yes - add in animation speed to current frame float animSpeed = blist[index].animSpeed; float time = (currentTime - blist[index].startTime) / 50.0f; float mendFrame = (float)blist[index].endFrame ; // are we a paused anim? if (blist[index].pauseTime) { time = (blist[index].pauseTime - blist[index].startTime) / 50.0f; } if (time<0) { time=0; } float newFrame_g = blist[index].startFrame + (time * animSpeed); *currentFrame = newFrame_g; int animSize = blist[index].endFrame - blist[index].startFrame; // we are supposed to be animating right? if (animSize) { // did we run off the end? if (((animSpeed > 0.0f) && (newFrame_g > mendFrame-1)) || ((animSpeed < 0.0f) && (newFrame_g < mendFrame+1))) { // yep - decide what to do if (blist[index].flags & BONE_ANIM_OVERRIDE_LOOP) { // get our new animation frame back within the bounds of the animation set if (animSpeed < 0.0f) { if (newFrame_g <= mendFrame+1) { newFrame_g=mendFrame+fmod(newFrame_g-mendFrame,animSize)-animSize; } } else { if (newFrame_g >= mendFrame) { newFrame_g=mendFrame+fmod(newFrame_g-mendFrame,animSize)-animSize; } } *currentFrame = newFrame_g; } else { // nope, we ran off the end of the current anim if (blist[index].flags & BONE_ANIM_OVERRIDE_FREEZE) { if (animSpeed > 0.0f) { *currentFrame = blist[index].endFrame -1; } else { *currentFrame = blist[index].endFrame +1; } } else { *currentFrame = 0; } } } } else { *currentFrame = blist[index].startFrame; } *startFrame = blist[index].startFrame; *endFrame = blist[index].endFrame; *flags = blist[index].flags; *retAnimSpeed = animSpeed; return qtrue; } } *startFrame =0; *endFrame =1 ; *currentFrame = 0; *flags = 0; //hmmmm this used to be -1 *retAnimSpeed = 1.0f; return qfalse; }