mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Update UI player animation handling to match CGame
Fix "Error parsing animation file" messages in UI. Caused by fixing the handling of missing tokens in animation.cfg parser in a past commit. Fix new Team Arena torso animation frame numbers in UI. Add support for fixedtorso and fixedlegs keywords. Add support for reversed animations (negative numframes).
This commit is contained in:
parent
098d97bdb0
commit
11b3bca555
4 changed files with 135 additions and 17 deletions
|
@ -486,6 +486,9 @@ typedef struct {
|
|||
|
||||
animation_t animations[MAX_ANIMATIONS];
|
||||
|
||||
qboolean fixedlegs; // true if legs yaw is always the same as torso yaw
|
||||
qboolean fixedtorso; // true if torso never changes yaw
|
||||
|
||||
qhandle_t weaponModel;
|
||||
qhandle_t barrelModel;
|
||||
qhandle_t flashModel;
|
||||
|
|
|
@ -363,7 +363,7 @@ UI_RunLerpFrame
|
|||
===============
|
||||
*/
|
||||
static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) {
|
||||
int f;
|
||||
int f, numFrames;
|
||||
animation_t *anim;
|
||||
|
||||
// see if the animation sequence is switching
|
||||
|
@ -379,25 +379,41 @@ static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation
|
|||
|
||||
// get the next frame based on the animation
|
||||
anim = lf->animation;
|
||||
if ( !anim->frameLerp ) {
|
||||
return; // shouldn't happen
|
||||
}
|
||||
if ( dp_realtime < lf->animationTime ) {
|
||||
lf->frameTime = lf->animationTime; // initial lerp
|
||||
} else {
|
||||
lf->frameTime = lf->oldFrameTime + anim->frameLerp;
|
||||
}
|
||||
f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp;
|
||||
if ( f >= anim->numFrames ) {
|
||||
f -= anim->numFrames;
|
||||
|
||||
numFrames = anim->numFrames;
|
||||
if (anim->flipflop) {
|
||||
numFrames *= 2;
|
||||
}
|
||||
if ( f >= numFrames ) {
|
||||
f -= numFrames;
|
||||
if ( anim->loopFrames ) {
|
||||
f %= anim->loopFrames;
|
||||
f += anim->numFrames - anim->loopFrames;
|
||||
} else {
|
||||
f = anim->numFrames - 1;
|
||||
f = numFrames - 1;
|
||||
// the animation is stuck at the end, so it
|
||||
// can immediately transition to another sequence
|
||||
lf->frameTime = dp_realtime;
|
||||
}
|
||||
}
|
||||
lf->frame = anim->firstFrame + f;
|
||||
if ( anim->reversed ) {
|
||||
lf->frame = anim->firstFrame + anim->numFrames - 1 - f;
|
||||
}
|
||||
else if (anim->flipflop && f>=anim->numFrames) {
|
||||
lf->frame = anim->firstFrame + anim->numFrames - 1 - (f%anim->numFrames);
|
||||
}
|
||||
else {
|
||||
lf->frame = anim->firstFrame + f;
|
||||
}
|
||||
if ( dp_realtime > lf->frameTime ) {
|
||||
lf->frameTime = dp_realtime;
|
||||
}
|
||||
|
@ -615,6 +631,16 @@ static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3],
|
|||
UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching );
|
||||
torsoAngles[PITCH] = pi->torso.pitchAngle;
|
||||
|
||||
if ( pi->fixedtorso ) {
|
||||
torsoAngles[PITCH] = 0.0f;
|
||||
}
|
||||
|
||||
if ( pi->fixedlegs ) {
|
||||
legsAngles[YAW] = torsoAngles[YAW];
|
||||
legsAngles[PITCH] = 0.0f;
|
||||
legsAngles[ROLL] = 0.0f;
|
||||
}
|
||||
|
||||
// pull the angles back out of the hierarchial chain
|
||||
AnglesSubtract( headAngles, torsoAngles, headAngles );
|
||||
AnglesSubtract( torsoAngles, legsAngles, torsoAngles );
|
||||
|
@ -930,7 +956,7 @@ static qboolean UI_RegisterClientSkin( playerInfo_t *pi, const char *modelName,
|
|||
UI_ParseAnimationFile
|
||||
======================
|
||||
*/
|
||||
static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) {
|
||||
static qboolean UI_ParseAnimationFile( const char *filename, playerInfo_t *pi ) {
|
||||
char *text_p, *prev;
|
||||
int len;
|
||||
int i;
|
||||
|
@ -939,9 +965,15 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
int skip;
|
||||
char text[20000];
|
||||
fileHandle_t f;
|
||||
animation_t *animations;
|
||||
|
||||
animations = pi->animations;
|
||||
|
||||
memset( animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS );
|
||||
|
||||
pi->fixedlegs = qfalse;
|
||||
pi->fixedtorso = qfalse;
|
||||
|
||||
// load the file
|
||||
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
||||
if ( len <= 0 ) {
|
||||
|
@ -987,6 +1019,12 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
break;
|
||||
}
|
||||
continue;
|
||||
} else if ( !Q_stricmp( token, "fixedlegs" ) ) {
|
||||
pi->fixedlegs = qtrue;
|
||||
continue;
|
||||
} else if ( !Q_stricmp( token, "fixedtorso" ) ) {
|
||||
pi->fixedtorso = qtrue;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if it is a number, start parsing animations
|
||||
|
@ -1003,6 +1041,16 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token[0] ) {
|
||||
if( i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE ) {
|
||||
animations[i].firstFrame = animations[TORSO_GESTURE].firstFrame;
|
||||
animations[i].frameLerp = animations[TORSO_GESTURE].frameLerp;
|
||||
animations[i].initialLerp = animations[TORSO_GESTURE].initialLerp;
|
||||
animations[i].loopFrames = animations[TORSO_GESTURE].loopFrames;
|
||||
animations[i].numFrames = animations[TORSO_GESTURE].numFrames;
|
||||
animations[i].reversed = qfalse;
|
||||
animations[i].flipflop = qfalse;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
animations[i].firstFrame = atoi( token );
|
||||
|
@ -1010,7 +1058,7 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
if ( i == LEGS_WALKCR ) {
|
||||
skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame;
|
||||
}
|
||||
if ( i >= LEGS_WALKCR ) {
|
||||
if ( i >= LEGS_WALKCR && i<TORSO_GETFLAG) {
|
||||
animations[i].firstFrame -= skip;
|
||||
}
|
||||
|
||||
|
@ -1020,6 +1068,14 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
}
|
||||
animations[i].numFrames = atoi( token );
|
||||
|
||||
animations[i].reversed = qfalse;
|
||||
animations[i].flipflop = qfalse;
|
||||
// if numFrames is negative the animation is reversed
|
||||
if (animations[i].numFrames < 0) {
|
||||
animations[i].numFrames = -animations[i].numFrames;
|
||||
animations[i].reversed = qtrue;
|
||||
}
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token[0] ) {
|
||||
break;
|
||||
|
@ -1110,7 +1166,7 @@ qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName
|
|||
|
||||
// load the animations
|
||||
Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName );
|
||||
if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
|
||||
if ( !UI_ParseAnimationFile( filename, pi ) ) {
|
||||
Com_Printf( "Failed to load animation file %s\n", filename );
|
||||
return qfalse;
|
||||
}
|
||||
|
|
|
@ -533,6 +533,9 @@ typedef struct {
|
|||
|
||||
animation_t animations[MAX_TOTALANIMATIONS];
|
||||
|
||||
qboolean fixedlegs; // true if legs yaw is always the same as torso yaw
|
||||
qboolean fixedtorso; // true if torso never changes yaw
|
||||
|
||||
qhandle_t weaponModel;
|
||||
qhandle_t barrelModel;
|
||||
qhandle_t flashModel;
|
||||
|
|
|
@ -364,7 +364,7 @@ UI_RunLerpFrame
|
|||
===============
|
||||
*/
|
||||
static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) {
|
||||
int f;
|
||||
int f, numFrames;
|
||||
animation_t *anim;
|
||||
|
||||
// see if the animation sequence is switching
|
||||
|
@ -380,25 +380,41 @@ static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation
|
|||
|
||||
// get the next frame based on the animation
|
||||
anim = lf->animation;
|
||||
if ( !anim->frameLerp ) {
|
||||
return; // shouldn't happen
|
||||
}
|
||||
if ( dp_realtime < lf->animationTime ) {
|
||||
lf->frameTime = lf->animationTime; // initial lerp
|
||||
} else {
|
||||
lf->frameTime = lf->oldFrameTime + anim->frameLerp;
|
||||
}
|
||||
f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp;
|
||||
if ( f >= anim->numFrames ) {
|
||||
f -= anim->numFrames;
|
||||
|
||||
numFrames = anim->numFrames;
|
||||
if (anim->flipflop) {
|
||||
numFrames *= 2;
|
||||
}
|
||||
if ( f >= numFrames ) {
|
||||
f -= numFrames;
|
||||
if ( anim->loopFrames ) {
|
||||
f %= anim->loopFrames;
|
||||
f += anim->numFrames - anim->loopFrames;
|
||||
} else {
|
||||
f = anim->numFrames - 1;
|
||||
f = numFrames - 1;
|
||||
// the animation is stuck at the end, so it
|
||||
// can immediately transition to another sequence
|
||||
lf->frameTime = dp_realtime;
|
||||
}
|
||||
}
|
||||
lf->frame = anim->firstFrame + f;
|
||||
if ( anim->reversed ) {
|
||||
lf->frame = anim->firstFrame + anim->numFrames - 1 - f;
|
||||
}
|
||||
else if (anim->flipflop && f>=anim->numFrames) {
|
||||
lf->frame = anim->firstFrame + anim->numFrames - 1 - (f%anim->numFrames);
|
||||
}
|
||||
else {
|
||||
lf->frame = anim->firstFrame + f;
|
||||
}
|
||||
if ( dp_realtime > lf->frameTime ) {
|
||||
lf->frameTime = dp_realtime;
|
||||
}
|
||||
|
@ -616,6 +632,16 @@ static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3],
|
|||
UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching );
|
||||
torsoAngles[PITCH] = pi->torso.pitchAngle;
|
||||
|
||||
if ( pi->fixedtorso ) {
|
||||
torsoAngles[PITCH] = 0.0f;
|
||||
}
|
||||
|
||||
if ( pi->fixedlegs ) {
|
||||
legsAngles[YAW] = torsoAngles[YAW];
|
||||
legsAngles[PITCH] = 0.0f;
|
||||
legsAngles[ROLL] = 0.0f;
|
||||
}
|
||||
|
||||
// pull the angles back out of the hierarchial chain
|
||||
AnglesSubtract( headAngles, torsoAngles, headAngles );
|
||||
AnglesSubtract( torsoAngles, legsAngles, torsoAngles );
|
||||
|
@ -1015,7 +1041,7 @@ static qboolean UI_RegisterClientSkin( playerInfo_t *pi, const char *modelName,
|
|||
UI_ParseAnimationFile
|
||||
======================
|
||||
*/
|
||||
static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) {
|
||||
static qboolean UI_ParseAnimationFile( const char *filename, playerInfo_t *pi ) {
|
||||
char *text_p, *prev;
|
||||
int len;
|
||||
int i;
|
||||
|
@ -1024,9 +1050,15 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
int skip;
|
||||
char text[20000];
|
||||
fileHandle_t f;
|
||||
animation_t *animations;
|
||||
|
||||
animations = pi->animations;
|
||||
|
||||
memset( animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS );
|
||||
|
||||
pi->fixedlegs = qfalse;
|
||||
pi->fixedtorso = qfalse;
|
||||
|
||||
// load the file
|
||||
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
||||
if ( len <= 0 ) {
|
||||
|
@ -1074,6 +1106,12 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
break;
|
||||
}
|
||||
continue;
|
||||
} else if ( !Q_stricmp( token, "fixedlegs" ) ) {
|
||||
pi->fixedlegs = qtrue;
|
||||
continue;
|
||||
} else if ( !Q_stricmp( token, "fixedtorso" ) ) {
|
||||
pi->fixedtorso = qtrue;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if it is a number, start parsing animations
|
||||
|
@ -1090,6 +1128,16 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token[0] ) {
|
||||
if( i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE ) {
|
||||
animations[i].firstFrame = animations[TORSO_GESTURE].firstFrame;
|
||||
animations[i].frameLerp = animations[TORSO_GESTURE].frameLerp;
|
||||
animations[i].initialLerp = animations[TORSO_GESTURE].initialLerp;
|
||||
animations[i].loopFrames = animations[TORSO_GESTURE].loopFrames;
|
||||
animations[i].numFrames = animations[TORSO_GESTURE].numFrames;
|
||||
animations[i].reversed = qfalse;
|
||||
animations[i].flipflop = qfalse;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
animations[i].firstFrame = atoi( token );
|
||||
|
@ -1097,7 +1145,7 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
if ( i == LEGS_WALKCR ) {
|
||||
skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame;
|
||||
}
|
||||
if ( i >= LEGS_WALKCR ) {
|
||||
if ( i >= LEGS_WALKCR && i<TORSO_GETFLAG) {
|
||||
animations[i].firstFrame -= skip;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1155,14 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat
|
|||
}
|
||||
animations[i].numFrames = atoi( token );
|
||||
|
||||
animations[i].reversed = qfalse;
|
||||
animations[i].flipflop = qfalse;
|
||||
// if numFrames is negative the animation is reversed
|
||||
if (animations[i].numFrames < 0) {
|
||||
animations[i].numFrames = -animations[i].numFrames;
|
||||
animations[i].reversed = qtrue;
|
||||
}
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token[0] ) {
|
||||
break;
|
||||
|
@ -1225,9 +1281,9 @@ qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName
|
|||
|
||||
// load the animations
|
||||
Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName );
|
||||
if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
|
||||
if ( !UI_ParseAnimationFile( filename, pi ) ) {
|
||||
Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/animation.cfg", modelName );
|
||||
if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
|
||||
if ( !UI_ParseAnimationFile( filename, pi ) ) {
|
||||
Com_Printf( "Failed to load animation file %s\n", filename );
|
||||
return qfalse;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue