2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# pragma hdrstop
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
# include "../Game_local.h"
2012-11-28 15:47:07 +00:00
static const char * channelNames [ ANIM_NumAnimChannels ] =
{
2012-11-26 18:58:24 +00:00
" all " , " torso " , " legs " , " head " , " eyelids "
} ;
/***********************************************************************
idAnim
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : idAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnim : : idAnim ( )
{
2012-11-26 18:58:24 +00:00
modelDef = NULL ;
numAnims = 0 ;
memset ( anims , 0 , sizeof ( anims ) ) ;
memset ( & flags , 0 , sizeof ( flags ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : idAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnim : : idAnim ( const idDeclModelDef * modelDef , const idAnim * anim )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
this - > modelDef = modelDef ;
numAnims = anim - > numAnims ;
name = anim - > name ;
realname = anim - > realname ;
flags = anim - > flags ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( anims , 0 , sizeof ( anims ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numAnims ; i + + )
{
2012-11-26 18:58:24 +00:00
anims [ i ] = anim - > anims [ i ] ;
anims [ i ] - > IncreaseRefs ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
frameLookup . SetNum ( anim - > frameLookup . Num ( ) ) ;
memcpy ( frameLookup . Ptr ( ) , anim - > frameLookup . Ptr ( ) , frameLookup . MemoryUsed ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
frameCommands . SetNum ( anim - > frameCommands . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < frameCommands . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
frameCommands [ i ] = anim - > frameCommands [ i ] ;
2012-11-28 15:47:07 +00:00
if ( anim - > frameCommands [ i ] . string )
{
frameCommands [ i ] . string = new ( TAG_ANIM ) idStr ( * anim - > frameCommands [ i ] . string ) ;
2012-11-26 18:58:24 +00:00
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : ~ idAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnim : : ~ idAnim ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numAnims ; i + + )
{
2012-11-26 18:58:24 +00:00
anims [ i ] - > DecreaseRefs ( ) ;
}
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < frameCommands . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
delete frameCommands [ i ] . string ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : SetAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnim : : SetAnim ( const idDeclModelDef * modelDef , const char * sourcename , const char * animname , int num , const idMD5Anim * md5anims [ ANIM_MaxSyncedAnims ] )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
this - > modelDef = modelDef ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numAnims ; i + + )
{
2012-11-26 18:58:24 +00:00
anims [ i ] - > DecreaseRefs ( ) ;
anims [ i ] = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( ( num > 0 ) & & ( num < = ANIM_MaxSyncedAnims ) ) ;
numAnims = num ;
realname = sourcename ;
name = animname ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
anims [ i ] = md5anims [ i ] ;
anims [ i ] - > IncreaseRefs ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & flags , 0 , sizeof ( flags ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < frameCommands . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
delete frameCommands [ i ] . string ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
frameLookup . Clear ( ) ;
frameCommands . Clear ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : Name
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnim : : Name ( ) const
{
2012-11-26 18:58:24 +00:00
return name ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : FullName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnim : : FullName ( ) const
{
2012-11-26 18:58:24 +00:00
return realname ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : MD5Anim
index 0 will never be NULL . Any anim > = NumAnims will return NULL .
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idMD5Anim * idAnim : : MD5Anim ( int num ) const
{
if ( anims [ 0 ] = = NULL )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
return anims [ num ] ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : ModelDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idDeclModelDef * idAnim : : ModelDef ( ) const
{
2012-11-26 18:58:24 +00:00
return modelDef ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : Length
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnim : : Length ( ) const
{
if ( ! anims [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return anims [ 0 ] - > Length ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : NumFrames
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnim : : NumFrames ( ) const
{
if ( ! anims [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
return anims [ 0 ] - > NumFrames ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : NumAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnim : : NumAnims ( ) const
{
2012-11-26 18:58:24 +00:00
return numAnims ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : TotalMovementDelta
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idVec3 & idAnim : : TotalMovementDelta ( ) const
{
if ( ! anims [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return vec3_zero ;
}
return anims [ 0 ] - > TotalMovementDelta ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : GetOrigin
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnim : : GetOrigin ( idVec3 & offset , int animNum , int currentTime , int cyclecount ) const
{
if ( ! anims [ animNum ] )
{
2012-11-26 18:58:24 +00:00
offset . Zero ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anims [ animNum ] - > GetOrigin ( offset , currentTime , cyclecount ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : GetOriginRotation
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnim : : GetOriginRotation ( idQuat & rotation , int animNum , int currentTime , int cyclecount ) const
{
if ( ! anims [ animNum ] )
{
2012-11-26 18:58:24 +00:00
rotation . Set ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anims [ animNum ] - > GetOriginRotation ( rotation , currentTime , cyclecount ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : GetBounds
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
ID_INLINE bool idAnim : : GetBounds ( idBounds & bounds , int animNum , int currentTime , int cyclecount ) const
{
if ( ! anims [ animNum ] )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anims [ animNum ] - > GetBounds ( bounds , currentTime , cyclecount ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : AddFrameCommand
Returns NULL if no error .
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnim : : AddFrameCommand ( const idDeclModelDef * modelDef , int framenum , idLexer & src , const idDict * def )
{
2012-11-26 18:58:24 +00:00
int i ;
int index ;
idStr text ;
idStr funcname ;
frameCommand_t fc ;
idToken token ;
2012-11-28 15:47:07 +00:00
const jointInfo_t * jointInfo ;
2012-11-26 18:58:24 +00:00
// make sure we're within bounds
2012-11-28 15:47:07 +00:00
if ( ( framenum < 1 ) | | ( framenum > anims [ 0 ] - > NumFrames ( ) ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Frame %d out of range " , framenum ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// frame numbers are 1 based in .def files, but 0 based internally
framenum - - ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & fc , 0 , sizeof ( fc ) ) ;
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( token = = " call " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SCRIPTFUNCTION ;
fc . function = gameLocal . program . FindFunction ( token ) ;
2012-11-28 15:47:07 +00:00
if ( ! fc . function )
{
2012-11-26 18:58:24 +00:00
return va ( " Function '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " object_call " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SCRIPTFUNCTIONOBJECT ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " event " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_EVENTFUNCTION ;
2012-11-28 15:47:07 +00:00
const idEventDef * ev = idEventDef : : FindEvent ( token ) ;
if ( ! ev )
{
2012-11-26 18:58:24 +00:00
return va ( " Event '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( ev - > GetNumArgs ( ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
return va ( " Event '%s' has arguments " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " sound " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_voice " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_VOICE ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_voice2 " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_VOICE2 ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_body " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_BODY ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_body2 " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_BODY2 ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_body3 " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_BODY3 ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_weapon " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_WEAPON ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_global " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_GLOBAL ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_item " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_ITEM ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " sound_chatter " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SOUND_CHATTER ;
2012-11-28 15:47:07 +00:00
if ( ! token . Cmpn ( " snd_ " , 4 ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else
{
2012-11-26 18:58:24 +00:00
fc . soundShader = declManager - > FindSound ( token ) ;
2012-11-28 15:47:07 +00:00
if ( fc . soundShader - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Sound '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " skin " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_SKIN ;
2012-11-28 15:47:07 +00:00
if ( token = = " none " )
{
2012-11-26 18:58:24 +00:00
fc . skin = NULL ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
fc . skin = declManager - > FindSkin ( token ) ;
2012-11-28 15:47:07 +00:00
if ( ! fc . skin )
{
2012-11-26 18:58:24 +00:00
return va ( " Skin '%s' not found " , token . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " fx " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_FX ;
2012-11-28 15:47:07 +00:00
if ( ! declManager - > FindType ( DECL_FX , token . c_str ( ) ) )
{
2012-11-26 18:58:24 +00:00
return va ( " fx '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " trigger " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_TRIGGER ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " triggerSmokeParticle " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_TRIGGER_SMOKE_PARTICLE ;
2012-11-28 15:47:07 +00:00
if ( ! declManager - > FindType ( DECL_PARTICLE , token . c_str ( ) ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Particle '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " melee " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_MELEE ;
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . FindEntityDef ( token . c_str ( ) , false ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Unknown entityDef '%s' " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " direct_damage " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_DIRECTDAMAGE ;
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . FindEntityDef ( token . c_str ( ) , false ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Unknown entityDef '%s' " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " attack_begin " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_BEGINATTACK ;
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . FindEntityDef ( token . c_str ( ) , false ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Unknown entityDef '%s' " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " attack_end " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_ENDATTACK ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " muzzle_flash " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( ( token ! = " " ) & & ! modelDef - > FindJoint ( token ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Joint '%s' not found " , token . c_str ( ) ) ;
}
fc . type = FC_MUZZLEFLASH ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " create_missile " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( ! modelDef - > FindJoint ( token ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Joint '%s' not found " , token . c_str ( ) ) ;
}
fc . type = FC_CREATEMISSILE ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " launch_missile " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( ! modelDef - > FindJoint ( token ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Joint '%s' not found " , token . c_str ( ) ) ;
}
fc . type = FC_LAUNCHMISSILE ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " fire_missile_at_target " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
jointInfo = modelDef - > FindJoint ( token ) ;
2012-11-28 15:47:07 +00:00
if ( ! jointInfo )
{
2012-11-26 18:58:24 +00:00
return va ( " Joint '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_FIREMISSILEATTARGET ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
2012-11-26 18:58:24 +00:00
fc . index = jointInfo - > num ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " launch_projectile " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( ! declManager - > FindDeclWithoutParsing ( DECL_ENTITYDEF , token , false ) )
{
2012-11-26 18:58:24 +00:00
return " Unknown projectile def " ;
}
fc . type = FC_LAUNCH_PROJECTILE ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " trigger_fx " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
jointInfo = modelDef - > FindJoint ( token ) ;
2012-11-28 15:47:07 +00:00
if ( ! jointInfo )
{
2012-11-26 18:58:24 +00:00
return va ( " Joint '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( ! declManager - > FindType ( DECL_FX , token , false ) )
{
2012-11-26 18:58:24 +00:00
return " Unknown FX def " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fc . type = FC_TRIGGER_FX ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
2012-11-26 18:58:24 +00:00
fc . index = jointInfo - > num ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " start_emitter " )
{
2012-11-26 18:58:24 +00:00
idStr str ;
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
str = token + " " ;
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
jointInfo = modelDef - > FindJoint ( token ) ;
2012-11-28 15:47:07 +00:00
if ( ! jointInfo )
{
2012-11-26 18:58:24 +00:00
return va ( " Joint '%s' not found " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
2012-11-28 15:47:07 +00:00
if ( ! declManager - > FindType ( DECL_PARTICLE , token . c_str ( ) ) )
{
2012-11-26 18:58:24 +00:00
return va ( " Particle '%s' not found " , token . c_str ( ) ) ;
}
str + = token ;
fc . type = FC_START_EMITTER ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( str ) ;
2012-11-26 18:58:24 +00:00
fc . index = jointInfo - > num ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " stop_emitter " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_STOP_EMITTER ;
2012-11-28 15:47:07 +00:00
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
}
else if ( token = = " footstep " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_FOOTSTEP ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " leftfoot " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_LEFTFOOT ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " rightfoot " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_RIGHTFOOT ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " enableEyeFocus " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_ENABLE_EYE_FOCUS ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " disableEyeFocus " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_DISABLE_EYE_FOCUS ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " disableGravity " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_DISABLE_GRAVITY ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " enableGravity " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_ENABLE_GRAVITY ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " jump " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_JUMP ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " enableClip " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_ENABLE_CLIP ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " disableClip " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_DISABLE_CLIP ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " enableWalkIK " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_ENABLE_WALK_IK ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " disableWalkIK " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_DISABLE_WALK_IK ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " enableLegIK " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_ENABLE_LEG_IK ;
fc . index = atoi ( token ) ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " disableLegIK " )
{
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
return " Unexpected end of line " ;
}
fc . type = FC_DISABLE_LEG_IK ;
fc . index = atoi ( token ) ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " recordDemo " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_RECORDDEMO ;
2012-11-28 15:47:07 +00:00
if ( src . ReadTokenOnLine ( & token ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " aviGame " )
{
2012-11-26 18:58:24 +00:00
fc . type = FC_AVIGAME ;
2012-11-28 15:47:07 +00:00
if ( src . ReadTokenOnLine ( & token ) )
{
fc . string = new ( TAG_ANIM ) idStr ( token ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return va ( " Unknown command '%s' " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check if we've initialized the frame loopup table
2012-11-28 15:47:07 +00:00
if ( ! frameLookup . Num ( ) )
{
2012-11-26 18:58:24 +00:00
// we haven't, so allocate the table and initialize it
frameLookup . SetGranularity ( 1 ) ;
frameLookup . SetNum ( anims [ 0 ] - > NumFrames ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < frameLookup . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
frameLookup [ i ] . num = 0 ;
frameLookup [ i ] . firstCommand = 0 ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// allocate space for a new command
frameCommands . Alloc ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// calculate the index of the new command
index = frameLookup [ framenum ] . firstCommand + frameLookup [ framenum ] . num ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// move all commands from our index onward up one to give us space for our new command
2012-11-28 15:47:07 +00:00
for ( i = frameCommands . Num ( ) - 1 ; i > index ; i - - )
{
2012-11-26 18:58:24 +00:00
frameCommands [ i ] = frameCommands [ i - 1 ] ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// fix the indices of any later frames to account for the inserted command
2012-11-28 15:47:07 +00:00
for ( i = framenum + 1 ; i < frameLookup . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
frameLookup [ i ] . firstCommand + + ;
}
2012-11-28 15:47:07 +00:00
// store the new command
2012-11-26 18:58:24 +00:00
frameCommands [ index ] = fc ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// increase the number of commands on this frame
frameLookup [ framenum ] . num + + ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// return with no error
return NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : CallFrameCommands
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnim : : CallFrameCommands ( idEntity * ent , int from , int to ) const
{
2012-11-26 18:58:24 +00:00
int index ;
int end ;
int frame ;
int numframes ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numframes = anims [ 0 ] - > NumFrames ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
frame = from ;
2012-11-28 15:47:07 +00:00
while ( frame ! = to )
{
2012-11-26 18:58:24 +00:00
frame + + ;
2012-11-28 15:47:07 +00:00
if ( frame > = numframes )
{
2012-11-26 18:58:24 +00:00
frame = 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
index = frameLookup [ frame ] . firstCommand ;
end = index + frameLookup [ frame ] . num ;
2012-11-28 15:47:07 +00:00
while ( index < end )
{
const frameCommand_t & command = frameCommands [ index + + ] ;
switch ( command . type )
{
case FC_SCRIPTFUNCTION :
{
2012-11-26 18:58:24 +00:00
gameLocal . CallFrameCommand ( ent , command . function ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SCRIPTFUNCTIONOBJECT :
{
2012-11-26 18:58:24 +00:00
gameLocal . CallObjectFrameCommand ( ent , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_EVENTFUNCTION :
{
const idEventDef * ev = idEventDef : : FindEvent ( command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( ev ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_ANY , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_ANY , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_VOICE :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_VOICE , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_voice' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_VOICE , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_VOICE2 :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_VOICE2 , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_voice2' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_VOICE2 , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_BODY :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_BODY , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_body' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_BODY2 :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_BODY2 , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_body2' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_BODY2 , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_BODY3 :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_BODY3 , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_body3' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_BODY3 , 0 , false , NULL ) ;
}
break ;
2012-11-28 15:47:07 +00:00
}
case FC_SOUND_WEAPON :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_WEAPON , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_weapon' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_WEAPON , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_GLOBAL :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_ANY , SSF_GLOBAL , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_global' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_ANY , SSF_GLOBAL , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_ITEM :
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_ITEM , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_item' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_ITEM , 0 , false , NULL ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SOUND_CHATTER :
{
if ( ent - > CanPlayChatterSounds ( ) )
{
if ( ! command . soundShader )
{
if ( ! ent - > StartSound ( command . string - > c_str ( ) , SND_CHANNEL_VOICE , 0 , false , NULL ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'sound_chatter' on entity '%s', anim '%s', frame %d: Could not find sound '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > StartSoundShader ( command . soundShader , SND_CHANNEL_VOICE , 0 , false , NULL ) ;
}
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_FX :
{
2012-11-26 18:58:24 +00:00
idEntityFx : : StartFx ( command . string - > c_str ( ) , NULL , NULL , ent , true ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_SKIN :
{
2012-11-26 18:58:24 +00:00
ent - > SetSkin ( command . skin ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_TRIGGER :
{
idEntity * target ;
2012-11-26 18:58:24 +00:00
target = gameLocal . FindEntity ( command . string - > c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( target )
{
SetTimeState ts ( target - > timeGroup ) ;
2012-11-26 18:58:24 +00:00
target - > Signal ( SIG_TRIGGER ) ;
target - > ProcessEvent ( & EV_Activate , ent ) ;
target - > TriggerGuis ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Framecommand 'trigger' on entity '%s', anim '%s', frame %d: Could not find entity '%s' " ,
2012-11-28 15:47:07 +00:00
ent - > name . c_str ( ) , FullName ( ) , frame + 1 , command . string - > c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_TRIGGER_SMOKE_PARTICLE :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_TriggerParticles , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_MELEE :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_AttackMelee , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_DIRECTDAMAGE :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_DirectDamage , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_BEGINATTACK :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_BeginAttack , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_ENDATTACK :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_EndAttack ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_MUZZLEFLASH :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_MuzzleFlash , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_CREATEMISSILE :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_CreateMissile , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_LAUNCHMISSILE :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_AttackMissile , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_FIREMISSILEATTARGET :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_FireMissileAtTarget , modelDef - > GetJointName ( command . index ) , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_LAUNCH_PROJECTILE :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_LaunchProjectile , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_TRIGGER_FX :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_TriggerFX , modelDef - > GetJointName ( command . index ) , command . string - > c_str ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_START_EMITTER :
{
int index = command . string - > Find ( " " ) ;
if ( index > = 0 )
{
idStr name = command . string - > Left ( index ) ;
idStr particle = command . string - > Right ( command . string - > Length ( ) - index - 1 ) ;
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_StartEmitter , name . c_str ( ) , modelDef - > GetJointName ( command . index ) , particle . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
case FC_STOP_EMITTER :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_StopEmitter , command . string - > c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
case FC_FOOTSTEP :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_Footstep ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_LEFTFOOT :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_FootstepLeft ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_RIGHTFOOT :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_FootstepRight ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_ENABLE_EYE_FOCUS :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_EnableEyeFocus ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_DISABLE_EYE_FOCUS :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_DisableEyeFocus ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_DISABLE_GRAVITY :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_DisableGravity ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_ENABLE_GRAVITY :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_EnableGravity ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_JUMP :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_JumpFrame ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_ENABLE_CLIP :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_EnableClip ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_DISABLE_CLIP :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & AI_DisableClip ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_ENABLE_WALK_IK :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_EnableWalkIK ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_DISABLE_WALK_IK :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_DisableWalkIK ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_ENABLE_LEG_IK :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_EnableLegIK , command . index ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_DISABLE_LEG_IK :
{
2012-11-26 18:58:24 +00:00
ent - > ProcessEvent ( & EV_DisableLegIK , command . index ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case FC_RECORDDEMO :
{
if ( command . string )
{
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_NOW , va ( " recordDemo %s " , command . string - > c_str ( ) ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_NOW , " stoprecording " ) ;
}
break ;
}
2012-11-28 15:47:07 +00:00
case FC_AVIGAME :
{
if ( command . string )
{
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_NOW , va ( " aviGame %s " , command . string - > c_str ( ) ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_NOW , " aviGame " ) ;
}
break ;
}
}
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : FindFrameForFrameCommand
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnim : : FindFrameForFrameCommand ( frameCommandType_t framecommand , const frameCommand_t * * command ) const
{
2012-11-26 18:58:24 +00:00
int frame ;
int index ;
int numframes ;
int end ;
2012-11-28 15:47:07 +00:00
if ( ! frameCommands . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return - 1 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numframes = anims [ 0 ] - > NumFrames ( ) ;
2012-11-28 15:47:07 +00:00
for ( frame = 0 ; frame < numframes ; frame + + )
{
2012-11-26 18:58:24 +00:00
end = frameLookup [ frame ] . firstCommand + frameLookup [ frame ] . num ;
2012-11-28 15:47:07 +00:00
for ( index = frameLookup [ frame ] . firstCommand ; index < end ; index + + )
{
if ( frameCommands [ index ] . type = = framecommand )
{
if ( command )
{
2012-11-26 18:58:24 +00:00
* command = & frameCommands [ index ] ;
}
return frame ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( command )
{
2012-11-26 18:58:24 +00:00
* command = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return - 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : HasFrameCommands
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnim : : HasFrameCommands ( ) const
{
if ( ! frameCommands . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : SetAnimFlags
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnim : : SetAnimFlags ( const animFlags_t & animflags )
{
2012-11-26 18:58:24 +00:00
flags = animflags ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnim : : GetAnimFlags
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const animFlags_t & idAnim : : GetAnimFlags ( ) const
{
2012-11-26 18:58:24 +00:00
return flags ;
}
/***********************************************************************
idAnimBlend
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : idAnimBlend
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnimBlend : : idAnimBlend ( )
{
2012-11-26 18:58:24 +00:00
Reset ( NULL ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : Save
archives object for save game file
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : Save ( idSaveGame * savefile ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( starttime ) ;
savefile - > WriteInt ( endtime ) ;
savefile - > WriteInt ( timeOffset ) ;
savefile - > WriteFloat ( rate ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( blendStartTime ) ;
savefile - > WriteInt ( blendDuration ) ;
savefile - > WriteFloat ( blendStartValue ) ;
savefile - > WriteFloat ( blendEndValue ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxSyncedAnims ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteFloat ( animWeights [ i ] ) ;
}
savefile - > WriteShort ( cycle ) ;
savefile - > WriteShort ( frame ) ;
savefile - > WriteShort ( animNum ) ;
savefile - > WriteBool ( allowMove ) ;
savefile - > WriteBool ( allowFrameCommands ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : Restore
unarchives object from save game file
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : Restore ( idRestoreGame * savefile , const idDeclModelDef * modelDef )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
this - > modelDef = modelDef ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( starttime ) ;
savefile - > ReadInt ( endtime ) ;
savefile - > ReadInt ( timeOffset ) ;
savefile - > ReadFloat ( rate ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( blendStartTime ) ;
savefile - > ReadInt ( blendDuration ) ;
savefile - > ReadFloat ( blendStartValue ) ;
savefile - > ReadFloat ( blendEndValue ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxSyncedAnims ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > ReadFloat ( animWeights [ i ] ) ;
}
savefile - > ReadShort ( cycle ) ;
savefile - > ReadShort ( frame ) ;
savefile - > ReadShort ( animNum ) ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
animNum = 0 ;
2012-11-28 15:47:07 +00:00
}
else if ( ( animNum < 0 ) | | ( animNum > modelDef - > NumAnims ( ) ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Anim number %d out of range for model '%s' during save game " , animNum , modelDef - > GetModelName ( ) ) ;
animNum = 0 ;
}
savefile - > ReadBool ( allowMove ) ;
savefile - > ReadBool ( allowFrameCommands ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : Reset
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : Reset ( const idDeclModelDef * _modelDef )
{
2012-11-26 18:58:24 +00:00
modelDef = _modelDef ;
cycle = 1 ;
starttime = 0 ;
endtime = 0 ;
timeOffset = 0 ;
rate = 1.0f ;
frame = 0 ;
allowMove = true ;
allowFrameCommands = true ;
animNum = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( animWeights , 0 , sizeof ( animWeights ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blendStartValue = 0.0f ;
blendEndValue = 0.0f ;
2012-11-28 15:47:07 +00:00
blendStartTime = 0 ;
2012-11-26 18:58:24 +00:00
blendDuration = 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : FullName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnimBlend : : AnimFullName ( ) const
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return " " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return anim - > FullName ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : AnimName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnimBlend : : AnimName ( ) const
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return " " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return anim - > Name ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : NumFrames
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : NumFrames ( ) const
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return anim - > NumFrames ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : Length
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : Length ( ) const
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return anim - > Length ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetWeight
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idAnimBlend : : GetWeight ( int currentTime ) const
{
2012-11-26 18:58:24 +00:00
int timeDelta ;
float frac ;
float w ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
timeDelta = currentTime - blendStartTime ;
2012-11-28 15:47:07 +00:00
if ( timeDelta < = 0 )
{
2012-11-26 18:58:24 +00:00
w = blendStartValue ;
2012-11-28 15:47:07 +00:00
}
else if ( timeDelta > = blendDuration )
{
2012-11-26 18:58:24 +00:00
w = blendEndValue ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
frac = ( float ) timeDelta / ( float ) blendDuration ;
w = blendStartValue + ( blendEndValue - blendStartValue ) * frac ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return w ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetFinalWeight
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idAnimBlend : : GetFinalWeight ( ) const
{
2012-11-26 18:58:24 +00:00
return blendEndValue ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : SetWeight
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : SetWeight ( float newweight , int currentTime , int blendTime )
{
2012-11-26 18:58:24 +00:00
blendStartValue = GetWeight ( currentTime ) ;
blendEndValue = newweight ;
2012-11-28 15:47:07 +00:00
blendStartTime = currentTime - 1 ;
2012-11-26 18:58:24 +00:00
blendDuration = blendTime ;
2012-11-28 15:47:07 +00:00
if ( ! newweight )
{
2012-11-26 18:58:24 +00:00
endtime = currentTime + blendTime ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : NumSyncedAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : NumSyncedAnims ( ) const
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return anim - > NumAnims ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : SetSyncedAnimWeight
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimBlend : : SetSyncedAnimWeight ( int num , float weight )
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ( num < 0 ) | | ( num > anim - > NumAnims ( ) ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animWeights [ num ] = weight ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : SetFrame
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : SetFrame ( const idDeclModelDef * modelDef , int _animNum , int _frame , int currentTime , int blendTime )
{
2012-11-26 18:58:24 +00:00
Reset ( modelDef ) ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * _anim = modelDef - > GetAnim ( _animNum ) ;
if ( ! _anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idMD5Anim * md5anim = _anim - > MD5Anim ( 0 ) ;
if ( modelDef - > Joints ( ) . Num ( ) ! = md5anim - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Model '%s' has different # of joints than anim '%s' " , modelDef - > GetModelName ( ) , md5anim - > Name ( ) ) ;
return ;
}
animNum = _animNum ;
starttime = currentTime ;
endtime = - 1 ;
cycle = - 1 ;
animWeights [ 0 ] = 1.0f ;
frame = _frame ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// a frame of 0 means it's not a single frame blend, so we set it to frame + 1
2012-11-28 15:47:07 +00:00
if ( frame < = 0 )
{
2012-11-26 18:58:24 +00:00
frame = 1 ;
2012-11-28 15:47:07 +00:00
}
else if ( frame > _anim - > NumFrames ( ) )
{
2012-11-26 18:58:24 +00:00
frame = _anim - > NumFrames ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set up blend
blendEndValue = 1.0f ;
blendStartTime = currentTime - 1 ;
blendDuration = blendTime ;
blendStartValue = 0.0f ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : CycleAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : CycleAnim ( const idDeclModelDef * modelDef , int _animNum , int currentTime , int blendTime )
{
2012-11-26 18:58:24 +00:00
Reset ( modelDef ) ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * _anim = modelDef - > GetAnim ( _animNum ) ;
if ( ! _anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idMD5Anim * md5anim = _anim - > MD5Anim ( 0 ) ;
if ( modelDef - > Joints ( ) . Num ( ) ! = md5anim - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Model '%s' has different # of joints than anim '%s' " , modelDef - > GetModelName ( ) , md5anim - > Name ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animNum = _animNum ;
animWeights [ 0 ] = 1.0f ;
endtime = - 1 ;
cycle = - 1 ;
2012-11-28 15:47:07 +00:00
if ( _anim - > GetAnimFlags ( ) . random_cycle_start )
{
2012-11-26 18:58:24 +00:00
// start the animation at a random time so that characters don't walk in sync
starttime = currentTime - gameLocal . random . RandomFloat ( ) * _anim - > Length ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
starttime = currentTime ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set up blend
blendEndValue = 1.0f ;
blendStartTime = currentTime - 1 ;
blendDuration = blendTime ;
blendStartValue = 0.0f ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : PlayAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : PlayAnim ( const idDeclModelDef * modelDef , int _animNum , int currentTime , int blendTime )
{
2012-11-26 18:58:24 +00:00
Reset ( modelDef ) ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * _anim = modelDef - > GetAnim ( _animNum ) ;
if ( ! _anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idMD5Anim * md5anim = _anim - > MD5Anim ( 0 ) ;
if ( modelDef - > Joints ( ) . Num ( ) ! = md5anim - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Model '%s' has different # of joints than anim '%s' " , modelDef - > GetModelName ( ) , md5anim - > Name ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animNum = _animNum ;
starttime = currentTime ;
endtime = starttime + _anim - > Length ( ) ;
cycle = 1 ;
animWeights [ 0 ] = 1.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set up blend
blendEndValue = 1.0f ;
blendStartTime = currentTime - 1 ;
blendDuration = blendTime ;
blendStartValue = 0.0f ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : Clear
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : Clear ( int currentTime , int clearTime )
{
if ( ! clearTime )
{
2012-11-26 18:58:24 +00:00
Reset ( modelDef ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
SetWeight ( 0.0f , currentTime , clearTime ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : IsDone
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimBlend : : IsDone ( int currentTime ) const
{
if ( ! frame & & ( endtime > 0 ) & & ( currentTime > = endtime ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
if ( ( blendEndValue < = 0.0f ) & & ( currentTime > = ( blendStartTime + blendDuration ) ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : FrameHasChanged
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimBlend : : FrameHasChanged ( int currentTime ) const
{
2012-11-26 18:58:24 +00:00
// if we don't have an anim, no change
2012-11-28 15:47:07 +00:00
if ( ! animNum )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if anim is done playing, no change
2012-11-28 15:47:07 +00:00
if ( ( endtime > 0 ) & & ( currentTime > endtime ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if our blend weight changes, we need to update
2012-11-28 15:47:07 +00:00
if ( ( currentTime < ( blendStartTime + blendDuration ) & & ( blendStartValue ! = blendEndValue ) ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we're a single frame anim and this isn't the frame we started on, we don't need to update
2012-11-28 15:47:07 +00:00
if ( ( frame | | ( NumFrames ( ) = = 1 ) ) & & ( currentTime ! = starttime ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetCycleCount
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : GetCycleCount ( ) const
{
2012-11-26 18:58:24 +00:00
return cycle ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : SetCycleCount
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : SetCycleCount ( int count )
{
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
cycle = - 1 ;
endtime = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
cycle = count ;
2012-11-28 15:47:07 +00:00
if ( cycle < 0 )
{
2012-11-26 18:58:24 +00:00
cycle = - 1 ;
endtime = - 1 ;
2012-11-28 15:47:07 +00:00
}
else if ( cycle = = 0 )
{
2012-11-26 18:58:24 +00:00
cycle = 1 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion
2012-11-28 15:47:07 +00:00
if ( rate = = 1.0f )
{
2012-11-26 18:58:24 +00:00
endtime = starttime - timeOffset + anim - > Length ( ) ;
2012-11-28 15:47:07 +00:00
}
else if ( rate ! = 0.0f )
{
2012-11-26 18:58:24 +00:00
endtime = starttime - timeOffset + anim - > Length ( ) / rate ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
endtime = - 1 ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion
2012-11-28 15:47:07 +00:00
if ( rate = = 1.0f )
{
2012-11-26 18:58:24 +00:00
endtime = starttime - timeOffset + anim - > Length ( ) * cycle ;
2012-11-28 15:47:07 +00:00
}
else if ( rate ! = 0.0f )
{
2012-11-26 18:58:24 +00:00
endtime = starttime - timeOffset + ( anim - > Length ( ) * cycle ) / rate ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
endtime = - 1 ;
}
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : SetPlaybackRate
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : SetPlaybackRate ( int currentTime , float newRate )
{
2012-11-26 18:58:24 +00:00
int animTime ;
2012-11-28 15:47:07 +00:00
if ( rate = = newRate )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animTime = AnimTime ( currentTime ) ;
2012-11-28 15:47:07 +00:00
if ( newRate = = 1.0f )
{
2012-11-26 18:58:24 +00:00
timeOffset = animTime - ( currentTime - starttime ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
timeOffset = animTime - ( currentTime - starttime ) * newRate ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
rate = newRate ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update the anim endtime
SetCycleCount ( cycle ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetPlaybackRate
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idAnimBlend : : GetPlaybackRate ( ) const
{
2012-11-26 18:58:24 +00:00
return rate ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : SetStartTime
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : SetStartTime ( int _startTime )
{
2012-11-26 18:58:24 +00:00
starttime = _startTime ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update the anim endtime
SetCycleCount ( cycle ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetStartTime
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : GetStartTime ( ) const
{
if ( ! animNum )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return starttime ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetEndTime
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : GetEndTime ( ) const
{
if ( ! animNum )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return endtime ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : PlayLength
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : PlayLength ( ) const
{
if ( ! animNum )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
if ( endtime < 0 )
{
2012-11-26 18:58:24 +00:00
return - 1 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return endtime - starttime + timeOffset ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : AllowMovement
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : AllowMovement ( bool allow )
{
2012-11-26 18:58:24 +00:00
allowMove = allow ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : AllowFrameCommands
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : AllowFrameCommands ( bool allow )
{
2012-11-26 18:58:24 +00:00
allowFrameCommands = allow ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : Anim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idAnim * idAnimBlend : : Anim ( ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = modelDef - > GetAnim ( animNum ) ;
2012-11-26 18:58:24 +00:00
return anim ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : AnimNum
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : AnimNum ( ) const
{
2012-11-26 18:58:24 +00:00
return animNum ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : AnimTime
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : AnimTime ( int currentTime ) const
{
2012-11-26 18:58:24 +00:00
int time ;
int length ;
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( anim )
{
if ( frame )
{
2012-11-26 18:58:24 +00:00
return FRAME2MS ( frame - 1 ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion
2012-11-28 15:47:07 +00:00
if ( rate = = 1.0f )
{
2012-11-26 18:58:24 +00:00
time = currentTime - starttime + timeOffset ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
time = static_cast < int > ( ( currentTime - starttime ) * rate ) + timeOffset ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// given enough time, we can easily wrap time around in our frame calculations, so
// keep cycling animations' time within the length of the anim.
length = anim - > Length ( ) ;
2012-11-28 15:47:07 +00:00
if ( ( cycle < 0 ) & & ( length > 0 ) )
{
2012-11-26 18:58:24 +00:00
time % = length ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// time will wrap after 24 days (oh no!), resulting in negative results for the %.
// adding the length gives us the proper result.
2012-11-28 15:47:07 +00:00
if ( time < 0 )
{
2012-11-26 18:58:24 +00:00
time + = length ;
}
}
return time ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : GetFrameNumber
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimBlend : : GetFrameNumber ( int currentTime ) const
{
const idMD5Anim * md5anim ;
2012-11-26 18:58:24 +00:00
frameBlend_t frameinfo ;
int animTime ;
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return 1 ;
}
2012-11-28 15:47:07 +00:00
if ( frame )
{
2012-11-26 18:58:24 +00:00
return frame ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
md5anim = anim - > MD5Anim ( 0 ) ;
animTime = AnimTime ( currentTime ) ;
md5anim - > ConvertTimeToFrame ( animTime , cycle , frameinfo ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return frameinfo . frame1 + 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : CallFrameCommands
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : CallFrameCommands ( idEntity * ent , int fromtime , int totime ) const
{
const idMD5Anim * md5anim ;
2012-11-26 18:58:24 +00:00
frameBlend_t frame1 ;
frameBlend_t frame2 ;
int fromFrameTime ;
int toFrameTime ;
2012-11-28 15:47:07 +00:00
if ( ! allowFrameCommands | | ! ent | | frame | | ( ( endtime > 0 ) & & ( fromtime > endtime ) ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim | | ! anim - > HasFrameCommands ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( totime < = starttime )
{
2012-11-26 18:58:24 +00:00
// don't play until next frame or we'll play commands twice.
// this happens on the player sometimes.
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fromFrameTime = AnimTime ( fromtime ) ;
toFrameTime = AnimTime ( totime ) ;
2012-11-28 15:47:07 +00:00
if ( toFrameTime < fromFrameTime )
{
2012-11-26 18:58:24 +00:00
toFrameTime + = anim - > Length ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
md5anim = anim - > MD5Anim ( 0 ) ;
md5anim - > ConvertTimeToFrame ( fromFrameTime , cycle , frame1 ) ;
md5anim - > ConvertTimeToFrame ( toFrameTime , cycle , frame2 ) ;
2012-11-28 15:47:07 +00:00
if ( fromFrameTime < = 0 )
{
2012-11-26 18:58:24 +00:00
// make sure first frame is called
anim - > CallFrameCommands ( ent , - 1 , frame2 . frame1 ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
anim - > CallFrameCommands ( ent , frame1 . frame1 , frame2 . frame1 ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : BlendAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimBlend : : BlendAnim ( int currentTime , int channel , int numJoints , idJointQuat * blendFrame , float & blendWeight , bool removeOriginOffset , bool overrideBlend , bool printInfo ) const
{
2012-11-26 18:58:24 +00:00
int i ;
float lerp ;
float mixWeight ;
2012-11-28 15:47:07 +00:00
const idMD5Anim * md5anim ;
idJointQuat * ptr ;
2012-11-26 18:58:24 +00:00
frameBlend_t frametime = { 0 } ;
2012-11-28 15:47:07 +00:00
idJointQuat * jointFrame ;
idJointQuat * mixFrame ;
2012-11-26 18:58:24 +00:00
int numAnims ;
int time ;
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float weight = GetWeight ( currentTime ) ;
2012-11-28 15:47:07 +00:00
if ( blendWeight > 0.0f )
{
if ( ( endtime > = 0 ) & & ( currentTime > = endtime ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! weight )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( overrideBlend )
{
2012-11-26 18:58:24 +00:00
blendWeight = 1.0f - weight ;
}
}
2012-11-28 15:47:07 +00:00
if ( ( channel = = ANIMCHANNEL_ALL ) & & ! blendWeight )
{
2012-11-26 18:58:24 +00:00
// we don't need a temporary buffer, so just store it directly in the blend frame
jointFrame = blendFrame ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// allocate a temporary buffer to copy the joints from
2012-11-28 15:47:07 +00:00
jointFrame = ( idJointQuat * ) _alloca16 ( numJoints * sizeof ( * jointFrame ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time = AnimTime ( currentTime ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numAnims = anim - > NumAnims ( ) ;
2012-11-28 15:47:07 +00:00
if ( numAnims = = 1 )
{
2012-11-26 18:58:24 +00:00
md5anim = anim - > MD5Anim ( 0 ) ;
2012-11-28 15:47:07 +00:00
if ( frame )
{
2012-11-26 18:58:24 +00:00
md5anim - > GetSingleFrame ( frame - 1 , jointFrame , modelDef - > GetChannelJoints ( channel ) , modelDef - > NumJointsOnChannel ( channel ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
md5anim - > ConvertTimeToFrame ( time , cycle , frametime ) ;
md5anim - > GetInterpolatedFrame ( frametime , jointFrame , modelDef - > GetChannelJoints ( channel ) , modelDef - > NumJointsOnChannel ( channel ) ) ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
//
// need to mix the multipoint anim together first
//
// allocate a temporary buffer to copy the joints to
2012-11-28 15:47:07 +00:00
mixFrame = ( idJointQuat * ) _alloca16 ( numJoints * sizeof ( * jointFrame ) ) ;
if ( ! frame )
{
2012-11-26 18:58:24 +00:00
anim - > MD5Anim ( 0 ) - > ConvertTimeToFrame ( time , cycle , frametime ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ptr = jointFrame ;
mixWeight = 0.0f ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numAnims ; i + + )
{
if ( animWeights [ i ] > 0.0f )
{
2012-11-26 18:58:24 +00:00
mixWeight + = animWeights [ i ] ;
lerp = animWeights [ i ] / mixWeight ;
md5anim = anim - > MD5Anim ( i ) ;
2012-11-28 15:47:07 +00:00
if ( frame )
{
2012-11-26 18:58:24 +00:00
md5anim - > GetSingleFrame ( frame - 1 , ptr , modelDef - > GetChannelJoints ( channel ) , modelDef - > NumJointsOnChannel ( channel ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
md5anim - > GetInterpolatedFrame ( frametime , ptr , modelDef - > GetChannelJoints ( channel ) , modelDef - > NumJointsOnChannel ( channel ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// only blend after the first anim is mixed in
2012-11-28 15:47:07 +00:00
if ( ptr ! = jointFrame )
{
2012-11-26 18:58:24 +00:00
SIMDProcessor - > BlendJoints ( jointFrame , ptr , lerp , modelDef - > GetChannelJoints ( channel ) , modelDef - > NumJointsOnChannel ( channel ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ptr = mixFrame ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! mixWeight )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
2012-11-28 15:47:07 +00:00
if ( removeOriginOffset )
{
if ( allowMove )
{
2012-11-26 18:58:24 +00:00
# ifdef VELOCITY_MOVE
jointFrame [ 0 ] . t . x = 0.0f ;
# else
jointFrame [ 0 ] . t . Zero ( ) ;
# endif
}
2012-11-28 15:47:07 +00:00
if ( anim - > GetAnimFlags ( ) . anim_turn )
{
2012-11-26 18:58:24 +00:00
jointFrame [ 0 ] . q . Set ( - 0.70710677f , 0.0f , 0.0f , 0.70710677f ) ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! blendWeight )
{
2012-11-26 18:58:24 +00:00
blendWeight = weight ;
2012-11-28 15:47:07 +00:00
if ( channel ! = ANIMCHANNEL_ALL )
{
const int * index = modelDef - > GetChannelJoints ( channel ) ;
2012-11-26 18:58:24 +00:00
const int num = modelDef - > NumJointsOnChannel ( channel ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
int j = index [ i ] ;
blendFrame [ j ] . t = jointFrame [ j ] . t ;
blendFrame [ j ] . q = jointFrame [ j ] . q ;
}
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
blendWeight + = weight ;
lerp = weight / blendWeight ;
SIMDProcessor - > BlendJoints ( blendFrame , jointFrame , lerp , modelDef - > GetChannelJoints ( channel ) , modelDef - > NumJointsOnChannel ( channel ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( printInfo )
{
if ( frame )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %s: '%s', %d, %.2f%% \n " , channelNames [ channel ] , anim - > FullName ( ) , frame , weight * 100.0f ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %s: '%s', %.3f, %.2f%% \n " , channelNames [ channel ] , anim - > FullName ( ) , ( float ) frametime . frame1 + frametime . backlerp , weight * 100.0f ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : BlendOrigin
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : BlendOrigin ( int currentTime , idVec3 & blendPos , float & blendWeight , bool removeOriginOffset ) const
{
2012-11-26 18:58:24 +00:00
float lerp ;
idVec3 animpos ;
idVec3 pos ;
int time ;
int num ;
int i ;
2012-11-28 15:47:07 +00:00
if ( frame | | ( ( endtime > 0 ) & & ( currentTime > endtime ) ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( allowMove & & removeOriginOffset )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float weight = GetWeight ( currentTime ) ;
2012-11-28 15:47:07 +00:00
if ( ! weight )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time = AnimTime ( currentTime ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
pos . Zero ( ) ;
num = anim - > NumAnims ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
anim - > GetOrigin ( animpos , i , time , cycle ) ;
pos + = animpos * animWeights [ i ] ;
}
2012-11-28 15:47:07 +00:00
if ( ! blendWeight )
{
2012-11-26 18:58:24 +00:00
blendPos = pos ;
blendWeight = weight ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
lerp = weight / ( blendWeight + weight ) ;
blendPos + = lerp * ( pos - blendPos ) ;
blendWeight + = weight ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : BlendDelta
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : BlendDelta ( int fromtime , int totime , idVec3 & blendDelta , float & blendWeight ) const
{
2012-11-26 18:58:24 +00:00
idVec3 pos1 ;
idVec3 pos2 ;
idVec3 animpos ;
idVec3 delta ;
int time1 ;
int time2 ;
float lerp ;
int num ;
int i ;
2012-11-28 15:47:07 +00:00
if ( frame | | ! allowMove | | ( ( endtime > 0 ) & & ( fromtime > endtime ) ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float weight = GetWeight ( totime ) ;
2012-11-28 15:47:07 +00:00
if ( ! weight )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time1 = AnimTime ( fromtime ) ;
time2 = AnimTime ( totime ) ;
2012-11-28 15:47:07 +00:00
if ( time2 < time1 )
{
2012-11-26 18:58:24 +00:00
time2 + = anim - > Length ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
num = anim - > NumAnims ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
pos1 . Zero ( ) ;
pos2 . Zero ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
anim - > GetOrigin ( animpos , i , time1 , cycle ) ;
pos1 + = animpos * animWeights [ i ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anim - > GetOrigin ( animpos , i , time2 , cycle ) ;
pos2 + = animpos * animWeights [ i ] ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
delta = pos2 - pos1 ;
2012-11-28 15:47:07 +00:00
if ( ! blendWeight )
{
2012-11-26 18:58:24 +00:00
blendDelta = delta ;
blendWeight = weight ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
lerp = weight / ( blendWeight + weight ) ;
blendDelta + = lerp * ( delta - blendDelta ) ;
blendWeight + = weight ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : BlendDeltaRotation
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimBlend : : BlendDeltaRotation ( int fromtime , int totime , idQuat & blendDelta , float & blendWeight ) const
{
2012-11-26 18:58:24 +00:00
idQuat q1 ;
idQuat q2 ;
idQuat q3 ;
int time1 ;
int time2 ;
float lerp ;
float mixWeight ;
int num ;
int i ;
2012-11-28 15:47:07 +00:00
if ( frame | | ! allowMove | | ( ( endtime > 0 ) & & ( fromtime > endtime ) ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim | | ! anim - > GetAnimFlags ( ) . anim_turn )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float weight = GetWeight ( totime ) ;
2012-11-28 15:47:07 +00:00
if ( ! weight )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time1 = AnimTime ( fromtime ) ;
time2 = AnimTime ( totime ) ;
2012-11-28 15:47:07 +00:00
if ( time2 < time1 )
{
2012-11-26 18:58:24 +00:00
time2 + = anim - > Length ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
q1 . Set ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
q2 . Set ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
mixWeight = 0.0f ;
num = anim - > NumAnims ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
if ( animWeights [ i ] > 0.0f )
{
2012-11-26 18:58:24 +00:00
mixWeight + = animWeights [ i ] ;
2012-11-28 15:47:07 +00:00
if ( animWeights [ i ] = = mixWeight )
{
2012-11-26 18:58:24 +00:00
anim - > GetOriginRotation ( q1 , i , time1 , cycle ) ;
anim - > GetOriginRotation ( q2 , i , time2 , cycle ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
lerp = animWeights [ i ] / mixWeight ;
anim - > GetOriginRotation ( q3 , i , time1 , cycle ) ;
q1 . Slerp ( q1 , q3 , lerp ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anim - > GetOriginRotation ( q3 , i , time2 , cycle ) ;
q2 . Slerp ( q1 , q3 , lerp ) ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
q3 = q1 . Inverse ( ) * q2 ;
2012-11-28 15:47:07 +00:00
if ( ! blendWeight )
{
2012-11-26 18:58:24 +00:00
blendDelta = q3 ;
blendWeight = weight ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
lerp = weight / ( blendWeight + weight ) ;
blendDelta . Slerp ( blendDelta , q3 , lerp ) ;
blendWeight + = weight ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimBlend : : AddBounds
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimBlend : : AddBounds ( int currentTime , idBounds & bounds , bool removeOriginOffset ) const
{
2012-11-26 18:58:24 +00:00
int i ;
int num ;
idBounds b ;
int time ;
idVec3 pos ;
bool addorigin ;
2012-11-28 15:47:07 +00:00
if ( ( endtime > 0 ) & & ( currentTime > endtime ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = Anim ( ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float weight = GetWeight ( currentTime ) ;
2012-11-28 15:47:07 +00:00
if ( ! weight )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time = AnimTime ( currentTime ) ;
num = anim - > NumAnims ( ) ;
addorigin = ! allowMove | | ! removeOriginOffset ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
if ( anim - > GetBounds ( b , i , time , cycle ) )
{
if ( addorigin )
{
2012-11-26 18:58:24 +00:00
anim - > GetOrigin ( pos , i , time , cycle ) ;
b . TranslateSelf ( pos ) ;
}
bounds . AddBounds ( b ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/***********************************************************************
idDeclModelDef
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : idDeclModelDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idDeclModelDef : : idDeclModelDef ( )
{
2012-11-26 18:58:24 +00:00
modelHandle = NULL ;
skin = NULL ;
offset . Zero ( ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
2012-11-26 18:58:24 +00:00
channelJoints [ i ] . Clear ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : ~ idDeclModelDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idDeclModelDef : : ~ idDeclModelDef ( )
{
2012-11-26 18:58:24 +00:00
FreeData ( ) ;
}
/*
= = = = = = = = = = = = = = = = =
idDeclModelDef : : Size
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
size_t idDeclModelDef : : Size ( ) const
{
2012-11-26 18:58:24 +00:00
return sizeof ( idDeclModelDef ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : CopyDecl
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idDeclModelDef : : CopyDecl ( const idDeclModelDef * decl )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
FreeData ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
offset = decl - > offset ;
modelHandle = decl - > modelHandle ;
skin = decl - > skin ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anims . SetNum ( decl - > anims . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < anims . Num ( ) ; i + + )
{
anims [ i ] = new ( TAG_ANIM ) idAnim ( this , decl - > anims [ i ] ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
joints . SetNum ( decl - > joints . Num ( ) ) ;
memcpy ( joints . Ptr ( ) , decl - > joints . Ptr ( ) , decl - > joints . Num ( ) * sizeof ( joints [ 0 ] ) ) ;
jointParents . SetNum ( decl - > jointParents . Num ( ) ) ;
memcpy ( jointParents . Ptr ( ) , decl - > jointParents . Ptr ( ) , decl - > jointParents . Num ( ) * sizeof ( jointParents [ 0 ] ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
2012-11-26 18:58:24 +00:00
channelJoints [ i ] = decl - > channelJoints [ i ] ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : FreeData
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idDeclModelDef : : FreeData ( )
{
2012-11-26 18:58:24 +00:00
anims . DeleteContents ( true ) ;
joints . Clear ( ) ;
jointParents . Clear ( ) ;
modelHandle = NULL ;
skin = NULL ;
offset . Zero ( ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
2012-11-26 18:58:24 +00:00
channelJoints [ i ] . Clear ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idDeclModelDef : : DefaultDefinition
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idDeclModelDef : : DefaultDefinition ( ) const
{
2012-11-26 18:58:24 +00:00
return " { } " ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : FindJoint
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const jointInfo_t * idDeclModelDef : : FindJoint ( const char * name ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
const idMD5Joint * joint ;
if ( ! modelHandle )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
joint = modelHandle - > GetJoints ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < joints . Num ( ) ; i + + , joint + + )
{
if ( ! joint - > name . Icmp ( name ) )
{
2012-11-26 18:58:24 +00:00
return & joints [ i ] ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : ModelHandle
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idDeclModelDef : : ModelHandle ( ) const
{
return ( idRenderModel * ) modelHandle ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetJointList
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idDeclModelDef : : GetJointList ( const char * jointnames , idList < jointHandle_t > & jointList ) const
{
const char * pos ;
2012-11-26 18:58:24 +00:00
idStr jointname ;
2012-11-28 15:47:07 +00:00
const jointInfo_t * joint ;
const jointInfo_t * child ;
2012-11-26 18:58:24 +00:00
int i ;
int num ;
bool getChildren ;
bool subtract ;
2012-11-28 15:47:07 +00:00
if ( ! modelHandle )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
jointList . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
num = modelHandle - > NumJoints ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// scan through list of joints and add each to the joint list
pos = jointnames ;
2012-11-28 15:47:07 +00:00
while ( * pos )
{
2012-11-26 18:58:24 +00:00
// skip over whitespace
2012-11-28 15:47:07 +00:00
while ( ( * pos ! = 0 ) & & isspace ( ( unsigned char ) * pos ) )
{
2012-11-26 18:58:24 +00:00
pos + + ;
}
2012-11-28 15:47:07 +00:00
if ( ! * pos )
{
2012-11-26 18:58:24 +00:00
// no more names
break ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// copy joint name
jointname = " " ;
2012-11-28 15:47:07 +00:00
if ( * pos = = ' - ' )
{
2012-11-26 18:58:24 +00:00
subtract = true ;
pos + + ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
subtract = false ;
}
2012-11-28 15:47:07 +00:00
if ( * pos = = ' * ' )
{
2012-11-26 18:58:24 +00:00
getChildren = true ;
pos + + ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
getChildren = false ;
}
2012-11-28 15:47:07 +00:00
while ( ( * pos ! = 0 ) & & ! isspace ( ( unsigned char ) * pos ) )
{
2012-11-26 18:58:24 +00:00
jointname + = * pos ;
pos + + ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
joint = FindJoint ( jointname ) ;
2012-11-28 15:47:07 +00:00
if ( ! joint )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Unknown joint '%s' in '%s' for model '%s' " , jointname . c_str ( ) , jointnames , GetName ( ) ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( ! subtract )
{
2012-11-26 18:58:24 +00:00
jointList . AddUnique ( joint - > num ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
jointList . Remove ( joint - > num ) ;
}
2012-11-28 15:47:07 +00:00
if ( getChildren )
{
2012-11-26 18:58:24 +00:00
// include all joint's children
child = joint + 1 ;
2012-11-28 15:47:07 +00:00
for ( i = joint - > num + 1 ; i < num ; i + + , child + + )
{
2012-11-26 18:58:24 +00:00
// all children of the joint should follow it in the list.
// once we reach a joint without a parent or with a parent
// who is earlier in the list than the specified joint, then
// we've gone through all it's children.
2012-11-28 15:47:07 +00:00
if ( child - > parentNum < joint - > num )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
if ( ! subtract )
{
2012-11-26 18:58:24 +00:00
jointList . AddUnique ( child - > num ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
jointList . Remove ( child - > num ) ;
}
}
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : Touch
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idDeclModelDef : : Touch ( ) const
{
if ( modelHandle )
{
2012-11-26 18:58:24 +00:00
renderModelManager - > FindModel ( modelHandle - > Name ( ) ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetDefaultSkin
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idDeclSkin * idDeclModelDef : : GetDefaultSkin ( ) const
{
2012-11-26 18:58:24 +00:00
return skin ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetDefaultPose
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idJointQuat * idDeclModelDef : : GetDefaultPose ( ) const
{
2012-11-26 18:58:24 +00:00
return modelHandle - > GetDefaultPose ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : SetupJoints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idDeclModelDef : : SetupJoints ( int * numJoints , idJointMat * * jointList , idBounds & frameBounds , bool removeOriginOffset ) const
{
2012-11-26 18:58:24 +00:00
int num ;
2012-11-28 15:47:07 +00:00
const idJointQuat * pose ;
idJointMat * list ;
if ( ! modelHandle | | modelHandle - > IsDefaultModel ( ) )
{
Mem_Free16 ( ( * jointList ) ) ;
( * jointList ) = NULL ;
2012-11-26 18:58:24 +00:00
frameBounds . Clear ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the number of joints
num = modelHandle - > NumJoints ( ) ;
2012-11-28 15:47:07 +00:00
if ( ! num )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " model '%s' has no joints " , modelHandle - > Name ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set up initial pose for model (with no pose, model is just a jumbled mess)
2012-11-28 15:47:07 +00:00
list = ( idJointMat * ) Mem_Alloc16 ( SIMD_ROUND_JOINTS ( num ) * sizeof ( list [ 0 ] ) , TAG_JOINTMAT ) ;
2012-11-26 18:58:24 +00:00
pose = GetDefaultPose ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// convert the joint quaternions to joint matrices
SIMDProcessor - > ConvertJointQuatsToJointMats ( list , pose , joints . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check if we offset the model by the origin joint
2012-11-28 15:47:07 +00:00
if ( removeOriginOffset )
{
2012-11-26 18:58:24 +00:00
# ifdef VELOCITY_MOVE
list [ 0 ] . SetTranslation ( idVec3 ( offset . x , offset . y + pose [ 0 ] . t . y , offset . z + pose [ 0 ] . t . z ) ) ;
# else
list [ 0 ] . SetTranslation ( offset ) ;
# endif
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
list [ 0 ] . SetTranslation ( pose [ 0 ] . t + offset ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform the joint hierarchy
SIMDProcessor - > TransformJoints ( list , jointParents . Ptr ( ) , 1 , joints . Num ( ) - 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
SIMD_INIT_LAST_JOINT ( list , num ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
* numJoints = num ;
* jointList = list ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the bounds of the default pose
frameBounds = modelHandle - > Bounds ( NULL ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : ParseAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idDeclModelDef : : ParseAnim ( idLexer & src , int numDefaultAnims )
{
2012-11-26 18:58:24 +00:00
int i ;
int len ;
2012-11-28 15:47:07 +00:00
idAnim * anim ;
const idMD5Anim * md5anims [ ANIM_MaxSyncedAnims ] ;
const idMD5Anim * md5anim ;
2012-11-26 18:58:24 +00:00
idStr alias ;
idToken realname ;
idToken token ;
int numAnims ;
animFlags_t flags ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numAnims = 0 ;
memset ( md5anims , 0 , sizeof ( md5anims ) ) ;
2012-11-28 15:47:07 +00:00
if ( ! src . ReadToken ( & realname ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
alias = realname ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < anims . Num ( ) ; i + + )
{
if ( ! strcmp ( anims [ i ] - > FullName ( ) , realname ) )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
if ( ( i < anims . Num ( ) ) & & ( i > = numDefaultAnims ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Duplicate anim '%s' " , realname . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
if ( i < numDefaultAnims )
{
2012-11-26 18:58:24 +00:00
anim = anims [ i ] ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// create the alias associated with this animation
2012-11-28 15:47:07 +00:00
anim = new ( TAG_ANIM ) idAnim ( ) ;
2012-11-26 18:58:24 +00:00
anims . Append ( anim ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// random anims end with a number. find the numeric suffix of the animation.
len = alias . Length ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = len - 1 ; i > 0 ; i - - )
{
if ( ! isdigit ( ( unsigned char ) alias [ i ] ) )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check for zero length name, or a purely numeric name
2012-11-28 15:47:07 +00:00
if ( i < = 0 )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Invalid animation name '%s' " , alias . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// remove the numeric suffix
alias . CapLength ( i + 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// parse the anims from the string
2012-11-28 15:47:07 +00:00
do
{
if ( ! src . ReadToken ( & token ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// lookup the animation
md5anim = animationLib . GetAnim ( token ) ;
2012-11-28 15:47:07 +00:00
if ( ! md5anim )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Couldn't load anim '%s' " , token . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
md5anim - > CheckModelHierarchy ( modelHandle ) ;
2012-11-28 15:47:07 +00:00
if ( numAnims > 0 )
{
2012-11-26 18:58:24 +00:00
// make sure it's the same length as the other anims
2012-11-28 15:47:07 +00:00
if ( md5anim - > Length ( ) ! = md5anims [ 0 ] - > Length ( ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Anim '%s' does not match length of anim '%s' " , md5anim - > Name ( ) , md5anims [ 0 ] - > Name ( ) ) ;
MakeDefault ( ) ;
return false ;
}
}
2012-11-28 15:47:07 +00:00
if ( numAnims > = ANIM_MaxSyncedAnims )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Exceeded max synced anims (%d) " , ANIM_MaxSyncedAnims ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add it to our list
md5anims [ numAnims ] = md5anim ;
numAnims + + ;
2012-11-28 15:47:07 +00:00
}
while ( src . CheckTokenString ( " , " ) ) ;
if ( ! numAnims )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " No animation specified " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anim - > SetAnim ( this , realname , alias , numAnims , md5anims ) ;
memset ( & flags , 0 , sizeof ( flags ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// parse any frame commands or animflags
2012-11-28 15:47:07 +00:00
if ( src . CheckTokenString ( " { " ) )
{
while ( 1 )
{
if ( ! src . ReadToken ( & token ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
if ( token = = " } " )
{
2012-11-26 18:58:24 +00:00
break ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " prevent_idle_override " )
{
2012-11-26 18:58:24 +00:00
flags . prevent_idle_override = true ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " random_cycle_start " )
{
2012-11-26 18:58:24 +00:00
flags . random_cycle_start = true ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " ai_no_turn " )
{
2012-11-26 18:58:24 +00:00
flags . ai_no_turn = true ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " anim_turn " )
{
2012-11-26 18:58:24 +00:00
flags . anim_turn = true ;
2012-11-28 15:47:07 +00:00
}
else if ( token = = " frame " )
{
2012-11-26 18:58:24 +00:00
// create a frame command
int framenum ;
2012-11-28 15:47:07 +00:00
const char * err ;
2012-11-26 18:58:24 +00:00
// make sure we don't have any line breaks while reading the frame command so the error line # will be correct
2012-11-28 15:47:07 +00:00
if ( ! src . ReadTokenOnLine ( & token ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Missing frame # after 'frame' " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
if ( token . type = = TT_PUNCTUATION & & token = = " - " )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Invalid frame # after 'frame' " ) ;
MakeDefault ( ) ;
return false ;
2012-11-28 15:47:07 +00:00
}
else if ( token . type ! = TT_NUMBER | | token . subtype = = TT_FLOAT )
{
2012-11-26 18:58:24 +00:00
src . Error ( " expected integer value, found '%s' " , token . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the frame number
framenum = token . GetIntValue ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// put the command on the specified frame of the animation
err = anim - > AddFrameCommand ( this , framenum , src , NULL ) ;
2012-11-28 15:47:07 +00:00
if ( err )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " %s " , err ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unknown command '%s' " , token . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the flags
anim - > SetAnimFlags ( flags ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = =
idDeclModelDef : : Parse
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idDeclModelDef : : Parse ( const char * text , const int textLength , bool allowBinaryVersion )
{
2012-11-26 18:58:24 +00:00
int i ;
int num ;
idStr filename ;
idStr extension ;
2012-11-28 15:47:07 +00:00
const idMD5Joint * md5joint ;
const idMD5Joint * md5joints ;
2012-11-26 18:58:24 +00:00
idLexer src ;
idToken token ;
idToken token2 ;
idStr jointnames ;
int channel ;
jointHandle_t jointnum ;
idList < jointHandle_t > jointList ;
int numDefaultAnims ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
src . LoadMemory ( text , textLength , GetFileName ( ) , GetLineNum ( ) ) ;
src . SetFlags ( DECL_LEXER_FLAGS ) ;
src . SkipUntilString ( " { " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numDefaultAnims = 0 ;
2012-11-28 15:47:07 +00:00
while ( 1 )
{
if ( ! src . ReadToken ( & token ) )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
if ( ! token . Icmp ( " } " ) )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
if ( token = = " inherit " )
{
if ( ! src . ReadToken ( & token2 ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
const idDeclModelDef * copy = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , token2 , false ) ) ;
if ( ! copy )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " Unknown model definition '%s' " , token2 . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( copy - > GetState ( ) = = DS_DEFAULTED )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " inherited model definition '%s' defaulted " , token2 . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
CopyDecl ( copy ) ;
numDefaultAnims = anims . Num ( ) ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " skin " )
{
if ( ! src . ReadToken ( & token2 ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
skin = declManager - > FindSkin ( token2 ) ;
2012-11-28 15:47:07 +00:00
if ( ! skin )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Skin '%s' not found " , token2 . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " mesh " )
{
if ( ! src . ReadToken ( & token2 ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
filename = token2 ;
filename . ExtractFileExtension ( extension ) ;
2012-11-28 15:47:07 +00:00
if ( extension ! = MD5_MESH_EXT )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Invalid model for MD5 mesh " ) ;
MakeDefault ( ) ;
return false ;
}
modelHandle = renderModelManager - > FindModel ( filename ) ;
2012-11-28 15:47:07 +00:00
if ( ! modelHandle )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Model '%s' not found " , filename . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
if ( modelHandle - > IsDefaultModel ( ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Model '%s' defaulted " , filename . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the number of joints
num = modelHandle - > NumJoints ( ) ;
2012-11-28 15:47:07 +00:00
if ( ! num )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Model '%s' has no joints " , filename . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set up the joint hierarchy
joints . SetGranularity ( 1 ) ;
joints . SetNum ( num ) ;
jointParents . SetNum ( num ) ;
channelJoints [ 0 ] . SetNum ( num ) ;
md5joints = modelHandle - > GetJoints ( ) ;
md5joint = md5joints ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + , md5joint + + )
{
2012-11-26 18:58:24 +00:00
joints [ i ] . channel = ANIMCHANNEL_ALL ;
joints [ i ] . num = static_cast < jointHandle_t > ( i ) ;
2012-11-28 15:47:07 +00:00
if ( md5joint - > parent )
{
2012-11-26 18:58:24 +00:00
joints [ i ] . parentNum = static_cast < jointHandle_t > ( md5joint - > parent - md5joints ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
joints [ i ] . parentNum = INVALID_JOINT ;
}
jointParents [ i ] = joints [ i ] . parentNum ;
channelJoints [ 0 ] [ i ] = i ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " remove " )
{
2012-11-26 18:58:24 +00:00
// removes any anims whos name matches
2012-11-28 15:47:07 +00:00
if ( ! src . ReadToken ( & token2 ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
num = 0 ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < anims . Num ( ) ; i + + )
{
if ( ( token2 = = anims [ i ] - > Name ( ) ) | | ( token2 = = anims [ i ] - > FullName ( ) ) )
{
2012-11-26 18:58:24 +00:00
delete anims [ i ] ;
anims . RemoveIndex ( i ) ;
2012-11-28 15:47:07 +00:00
if ( i > = numDefaultAnims )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Anim '%s' was not inherited. Anim should be removed from the model def. " , token2 . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
i - - ;
numDefaultAnims - - ;
num + + ;
continue ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! num )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Couldn't find anim '%s' to remove " , token2 . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " anim " )
{
if ( ! modelHandle )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Must specify mesh before defining anims " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! ParseAnim ( src , numDefaultAnims ) )
{
2012-11-26 18:58:24 +00:00
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " offset " )
{
if ( ! src . Parse1DMatrix ( 3 , offset . ToFloatPtr ( ) ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Expected vector following 'offset' " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
}
else if ( token = = " channel " )
{
if ( ! modelHandle )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Must specify mesh before defining channels " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the channel for a group of joints
2012-11-28 15:47:07 +00:00
if ( ! src . ReadToken ( & token2 ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! src . CheckTokenString ( " ( " ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Expected { after '%s' \n " , token2 . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL + 1 ; i < ANIM_NumAnimChannels ; i + + )
{
if ( ! idStr : : Icmp ( channelNames [ i ] , token2 ) )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
if ( i > = ANIM_NumAnimChannels )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unknown channel '%s' " , token2 . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
channel = i ;
jointnames = " " ;
2012-11-28 15:47:07 +00:00
while ( ! src . CheckTokenString ( " ) " ) )
{
if ( ! src . ReadToken ( & token2 ) )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Unexpected end of file " ) ;
MakeDefault ( ) ;
return false ;
}
jointnames + = token2 ;
2012-11-28 15:47:07 +00:00
if ( ( token2 ! = " * " ) & & ( token2 ! = " - " ) )
{
2012-11-26 18:58:24 +00:00
jointnames + = " " ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
GetJointList ( jointnames , jointList ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
channelJoints [ channel ] . SetNum ( jointList . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( num = i = 0 ; i < jointList . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
jointnum = jointList [ i ] ;
2012-11-28 15:47:07 +00:00
if ( joints [ jointnum ] . channel ! = ANIMCHANNEL_ALL )
{
2012-11-26 18:58:24 +00:00
src . Warning ( " Joint '%s' assigned to multiple channels " , modelHandle - > GetJointName ( jointnum ) ) ;
continue ;
}
joints [ jointnum ] . channel = channel ;
channelJoints [ channel ] [ num + + ] = jointnum ;
}
channelJoints [ channel ] . SetNum ( num ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
src . Warning ( " unknown token '%s' " , token . c_str ( ) ) ;
MakeDefault ( ) ;
return false ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// shrink the anim list down to save space
anims . SetGranularity ( 1 ) ;
anims . SetNum ( anims . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : HasAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idDeclModelDef : : HasAnim ( const char * name ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// find any animations with same name
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < anims . Num ( ) ; i + + )
{
if ( ! strcmp ( anims [ i ] - > Name ( ) , name ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
}
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : NumAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idDeclModelDef : : NumAnims ( ) const
{
2012-11-26 18:58:24 +00:00
return anims . Num ( ) + 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetSpecificAnim
Gets the exact anim for the name , without randomization .
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idDeclModelDef : : GetSpecificAnim ( const char * name ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// find a specific animation
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < anims . Num ( ) ; i + + )
{
if ( ! strcmp ( anims [ i ] - > FullName ( ) , name ) )
{
2012-11-26 18:58:24 +00:00
return i + 1 ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// didn't find it
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idAnim * idDeclModelDef : : GetAnim ( int index ) const
{
if ( ( index < 1 ) | | ( index > anims . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
return anims [ index - 1 ] ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idDeclModelDef : : GetAnim ( const char * name ) const
{
2012-11-26 18:58:24 +00:00
int i ;
int which ;
const int MAX_ANIMS = 64 ;
int animList [ MAX_ANIMS ] ;
int numAnims ;
int len ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
len = strlen ( name ) ;
2012-11-28 15:47:07 +00:00
if ( len & & idStr : : CharIsNumeric ( name [ len - 1 ] ) )
{
2012-11-26 18:58:24 +00:00
// find a specific animation
return GetSpecificAnim ( name ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// find all animations with same name
numAnims = 0 ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < anims . Num ( ) ; i + + )
{
if ( ! strcmp ( anims [ i ] - > Name ( ) , name ) )
{
2012-11-26 18:58:24 +00:00
animList [ numAnims + + ] = i ;
2012-11-28 15:47:07 +00:00
if ( numAnims > = MAX_ANIMS )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( ! numAnims )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get a random anim
//FIXME: don't access gameLocal here?
which = gameLocal . random . RandomInt ( numAnims ) ;
return animList [ which ] + 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetSkin
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idDeclSkin * idDeclModelDef : : GetSkin ( ) const
{
2012-11-26 18:58:24 +00:00
return skin ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetModelName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idDeclModelDef : : GetModelName ( ) const
{
if ( modelHandle )
{
2012-11-26 18:58:24 +00:00
return modelHandle - > Name ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return " " ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : Joints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idList < jointInfo_t > & idDeclModelDef : : Joints ( ) const
{
2012-11-26 18:58:24 +00:00
return joints ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : JointParents
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const int * idDeclModelDef : : JointParents ( ) const
{
2012-11-26 18:58:24 +00:00
return jointParents . Ptr ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : NumJoints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idDeclModelDef : : NumJoints ( ) const
{
2012-11-26 18:58:24 +00:00
return joints . Num ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetJoint
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const jointInfo_t * idDeclModelDef : : GetJoint ( int jointHandle ) const
{
if ( ( jointHandle < 0 ) | | ( jointHandle > joints . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idDeclModelDef::GetJoint : joint handle out of range " ) ;
}
return & joints [ jointHandle ] ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetJointName
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idDeclModelDef : : GetJointName ( int jointHandle ) const
{
const idMD5Joint * joint ;
if ( ! modelHandle )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
if ( ( jointHandle < 0 ) | | ( jointHandle > joints . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idDeclModelDef::GetJointName : joint handle out of range " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
joint = modelHandle - > GetJoints ( ) ;
return joint [ jointHandle ] . name . c_str ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : NumJointsOnChannel
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idDeclModelDef : : NumJointsOnChannel ( int channel ) const
{
if ( ( channel < 0 ) | | ( channel > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idDeclModelDef::NumJointsOnChannel : channel out of range " ) ;
return 0 ;
}
return channelJoints [ channel ] . Num ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetChannelJoints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const int * idDeclModelDef : : GetChannelJoints ( int channel ) const
{
if ( ( channel < 0 ) | | ( channel > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idDeclModelDef::GetChannelJoints : channel out of range " ) ;
return NULL ;
}
return channelJoints [ channel ] . Ptr ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idDeclModelDef : : GetVisualOffset
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idVec3 & idDeclModelDef : : GetVisualOffset ( ) const
{
2012-11-26 18:58:24 +00:00
return offset ;
}
/***********************************************************************
idAnimator
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : idAnimator
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnimator : : idAnimator ( )
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
modelDef = NULL ;
entity = NULL ;
numJoints = 0 ;
joints = NULL ;
lastTransformTime = - 1 ;
stoppedAnimatingUpdate = false ;
removeOriginOffset = false ;
forceUpdate = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
frameBounds . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
AFPoseJoints . SetGranularity ( 1 ) ;
AFPoseJointMods . SetGranularity ( 1 ) ;
AFPoseJointFrame . SetGranularity ( 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ClearAFPose ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + )
{
2012-11-26 18:58:24 +00:00
channels [ i ] [ j ] . Reset ( NULL ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ~ idAnimator
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnimator : : ~ idAnimator ( )
{
2012-11-26 18:58:24 +00:00
FreeData ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : Allocated
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
size_t idAnimator : : Allocated ( ) const
{
2012-11-26 18:58:24 +00:00
size_t size ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
size = jointMods . Allocated ( ) + numJoints * sizeof ( joints [ 0 ] ) + jointMods . Num ( ) * sizeof ( jointMods [ 0 ] ) + AFPoseJointMods . Allocated ( ) + AFPoseJointFrame . Allocated ( ) + AFPoseJoints . Allocated ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return size ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : Save
archives object for save game file
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : Save ( idSaveGame * savefile ) const
{
2012-11-26 18:58:24 +00:00
int i ;
int j ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteModelDef ( modelDef ) ;
savefile - > WriteObject ( entity ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( jointMods . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < jointMods . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( jointMods [ i ] - > jointnum ) ;
savefile - > WriteMat3 ( jointMods [ i ] - > mat ) ;
savefile - > WriteVec3 ( jointMods [ i ] - > pos ) ;
2012-11-28 15:47:07 +00:00
savefile - > WriteInt ( ( int & ) jointMods [ i ] - > transform_pos ) ;
savefile - > WriteInt ( ( int & ) jointMods [ i ] - > transform_axis ) ;
2012-11-26 18:58:24 +00:00
}
savefile - > WriteInt ( numJoints ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numJoints ; i + + )
{
float * data = joints [ i ] . ToFloatPtr ( ) ;
for ( j = 0 ; j < 12 ; j + + )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteFloat ( data [ j ] ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( lastTransformTime ) ;
savefile - > WriteBool ( stoppedAnimatingUpdate ) ;
savefile - > WriteBool ( forceUpdate ) ;
savefile - > WriteBounds ( frameBounds ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteFloat ( AFPoseBlendWeight ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( AFPoseJoints . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJoints . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( AFPoseJoints [ i ] ) ;
}
savefile - > WriteInt ( AFPoseJointMods . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJointMods . Num ( ) ; i + + )
{
savefile - > WriteInt ( ( int & ) AFPoseJointMods [ i ] . mod ) ;
2012-11-26 18:58:24 +00:00
savefile - > WriteMat3 ( AFPoseJointMods [ i ] . axis ) ;
savefile - > WriteVec3 ( AFPoseJointMods [ i ] . origin ) ;
}
savefile - > WriteInt ( AFPoseJointFrame . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJointFrame . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteFloat ( AFPoseJointFrame [ i ] . q . x ) ;
savefile - > WriteFloat ( AFPoseJointFrame [ i ] . q . y ) ;
savefile - > WriteFloat ( AFPoseJointFrame [ i ] . q . z ) ;
savefile - > WriteFloat ( AFPoseJointFrame [ i ] . q . w ) ;
savefile - > WriteVec3 ( AFPoseJointFrame [ i ] . t ) ;
}
savefile - > WriteBounds ( AFPoseBounds ) ;
savefile - > WriteInt ( AFPoseTime ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( removeOriginOffset ) ;
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + )
{
2012-11-26 18:58:24 +00:00
channels [ i ] [ j ] . Save ( savefile ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : Restore
unarchives object from save game file
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : Restore ( idRestoreGame * savefile )
{
2012-11-26 18:58:24 +00:00
int i ;
int j ;
int num ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadModelDef ( modelDef ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( entity ) ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( num ) ;
jointMods . SetNum ( num ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
jointMods [ i ] = new ( TAG_ANIM ) jointMod_t ;
savefile - > ReadInt ( ( int & ) jointMods [ i ] - > jointnum ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadMat3 ( jointMods [ i ] - > mat ) ;
savefile - > ReadVec3 ( jointMods [ i ] - > pos ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadInt ( ( int & ) jointMods [ i ] - > transform_pos ) ;
savefile - > ReadInt ( ( int & ) jointMods [ i ] - > transform_axis ) ;
2012-11-26 18:58:24 +00:00
}
savefile - > ReadInt ( numJoints ) ;
2012-11-28 15:47:07 +00:00
joints = ( idJointMat * ) Mem_Alloc16 ( SIMD_ROUND_JOINTS ( numJoints ) * sizeof ( joints [ 0 ] ) , TAG_JOINTMAT ) ;
for ( i = 0 ; i < numJoints ; i + + )
{
float * data = joints [ i ] . ToFloatPtr ( ) ;
for ( j = 0 ; j < 12 ; j + + )
{
2012-11-26 18:58:24 +00:00
savefile - > ReadFloat ( data [ j ] ) ;
}
}
SIMD_INIT_LAST_JOINT ( joints , numJoints ) ;
savefile - > ReadInt ( lastTransformTime ) ;
savefile - > ReadBool ( stoppedAnimatingUpdate ) ;
savefile - > ReadBool ( forceUpdate ) ;
savefile - > ReadBounds ( frameBounds ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadFloat ( AFPoseBlendWeight ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( num ) ;
AFPoseJoints . SetGranularity ( 1 ) ;
AFPoseJoints . SetNum ( num ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJoints . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( AFPoseJoints [ i ] ) ;
}
savefile - > ReadInt ( num ) ;
AFPoseJointMods . SetGranularity ( 1 ) ;
AFPoseJointMods . SetNum ( num ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJointMods . Num ( ) ; i + + )
{
savefile - > ReadInt ( ( int & ) AFPoseJointMods [ i ] . mod ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadMat3 ( AFPoseJointMods [ i ] . axis ) ;
savefile - > ReadVec3 ( AFPoseJointMods [ i ] . origin ) ;
}
savefile - > ReadInt ( num ) ;
AFPoseJointFrame . SetGranularity ( 1 ) ;
AFPoseJointFrame . SetNum ( num ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJointFrame . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > ReadFloat ( AFPoseJointFrame [ i ] . q . x ) ;
savefile - > ReadFloat ( AFPoseJointFrame [ i ] . q . y ) ;
savefile - > ReadFloat ( AFPoseJointFrame [ i ] . q . z ) ;
savefile - > ReadFloat ( AFPoseJointFrame [ i ] . q . w ) ;
savefile - > ReadVec3 ( AFPoseJointFrame [ i ] . t ) ;
}
savefile - > ReadBounds ( AFPoseBounds ) ;
savefile - > ReadInt ( AFPoseTime ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( removeOriginOffset ) ;
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + )
{
2012-11-26 18:58:24 +00:00
channels [ i ] [ j ] . Restore ( savefile , modelDef ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : FreeData
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : FreeData ( )
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeInactive ( TH_ANIMATE ) ;
}
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + )
{
2012-11-26 18:58:24 +00:00
channels [ i ] [ j ] . Reset ( NULL ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
jointMods . DeleteContents ( true ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Mem_Free16 ( joints ) ;
joints = NULL ;
numJoints = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
modelDef = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : PushAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : PushAnims ( int channelNum , int currentTime , int blendTime )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
idAnimBlend * channel ;
2012-11-26 18:58:24 +00:00
channel = channels [ channelNum ] ;
2012-11-28 15:47:07 +00:00
if ( ! channel [ 0 ] . GetWeight ( currentTime ) | | ( channel [ 0 ] . starttime = = currentTime ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
for ( i = ANIM_MaxAnimsPerChannel - 1 ; i > 0 ; i - - )
{
2012-11-26 18:58:24 +00:00
channel [ i ] = channel [ i - 1 ] ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
channel [ 0 ] . Reset ( modelDef ) ;
channel [ 1 ] . Clear ( currentTime , blendTime ) ;
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetModel
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idAnimator : : SetModel ( const char * modelname )
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
FreeData ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check if we're just clearing the model
2012-11-28 15:47:07 +00:00
if ( ! modelname | | ! * modelname )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , modelname , false ) ) ;
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
idRenderModel * renderModel = modelDef - > ModelHandle ( ) ;
if ( ! renderModel )
{
2012-11-26 18:58:24 +00:00
modelDef = NULL ;
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make sure model hasn't been purged
modelDef - > Touch ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
modelDef - > SetupJoints ( & numJoints , & joints , frameBounds , removeOriginOffset ) ;
modelDef - > ModelHandle ( ) - > Reset ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the modelDef on all channels
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + )
{
2012-11-26 18:58:24 +00:00
channels [ i ] [ j ] . Reset ( modelDef ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return modelDef - > ModelHandle ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : Size
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
size_t idAnimator : : Size ( ) const
{
2012-11-26 18:58:24 +00:00
return sizeof ( * this ) + Allocated ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetEntity
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SetEntity ( idEntity * ent )
{
2012-11-26 18:58:24 +00:00
entity = ent ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetEntity
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idEntity * idAnimator : : GetEntity ( ) const
{
2012-11-26 18:58:24 +00:00
return entity ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : RemoveOriginOffset
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : RemoveOriginOffset ( bool remove )
{
2012-11-26 18:58:24 +00:00
removeOriginOffset = remove ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : RemoveOrigin
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : RemoveOrigin ( ) const
{
2012-11-26 18:58:24 +00:00
return removeOriginOffset ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetJointList
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : GetJointList ( const char * jointnames , idList < jointHandle_t > & jointList ) const
{
if ( modelDef )
{
2012-11-26 18:58:24 +00:00
modelDef - > GetJointList ( jointnames , jointList ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : NumAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : NumAnims ( ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
return modelDef - > NumAnims ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idAnim * idAnimator : : GetAnim ( int index ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
return modelDef - > GetAnim ( index ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : GetAnim ( const char * name ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
return modelDef - > GetAnim ( name ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : HasAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : HasAnim ( const char * name ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return false ;
}
return modelDef - > HasAnim ( name ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : NumJoints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : NumJoints ( ) const
{
2012-11-26 18:58:24 +00:00
return numJoints ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ModelHandle
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idAnimator : : ModelHandle ( ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
return modelDef - > ModelHandle ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ModelDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idDeclModelDef * idAnimator : : ModelDef ( ) const
{
2012-11-26 18:58:24 +00:00
return modelDef ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : CurrentAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idAnimBlend * idAnimator : : CurrentAnim ( int channelNum )
{
if ( ( channelNum < 0 ) | | ( channelNum > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::CurrentAnim : channel out of range " ) ;
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return & channels [ channelNum ] [ 0 ] ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : Clear
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : Clear ( int channelNum , int currentTime , int cleartime )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
idAnimBlend * blend ;
if ( ( channelNum < 0 ) | | ( channelNum > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::Clear : channel out of range " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ channelNum ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > Clear ( currentTime , cleartime ) ;
}
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetFrame
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SetFrame ( int channelNum , int animNum , int frame , int currentTime , int blendTime )
{
if ( ( channelNum < 0 ) | | ( channelNum > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::SetFrame : channel out of range " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > GetAnim ( animNum ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
PushAnims ( channelNum , currentTime , blendTime ) ;
channels [ channelNum ] [ 0 ] . SetFrame ( modelDef , animNum , frame , currentTime , blendTime ) ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeActive ( TH_ANIMATE ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : CycleAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : CycleAnim ( int channelNum , int animNum , int currentTime , int blendTime )
{
if ( ( channelNum < 0 ) | | ( channelNum > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::CycleAnim : channel out of range " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > GetAnim ( animNum ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
PushAnims ( channelNum , currentTime , blendTime ) ;
channels [ channelNum ] [ 0 ] . CycleAnim ( modelDef , animNum , currentTime , blendTime ) ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeActive ( TH_ANIMATE ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : PlayAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : PlayAnim ( int channelNum , int animNum , int currentTime , int blendTime )
{
if ( ( channelNum < 0 ) | | ( channelNum > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::PlayAnim : channel out of range " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > GetAnim ( animNum ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
PushAnims ( channelNum , currentTime , blendTime ) ;
channels [ channelNum ] [ 0 ] . PlayAnim ( modelDef , animNum , currentTime , blendTime ) ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeActive ( TH_ANIMATE ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SyncAnimChannels
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SyncAnimChannels ( int channelNum , int fromChannelNum , int currentTime , int blendTime )
{
if ( ( channelNum < 0 ) | | ( channelNum > = ANIM_NumAnimChannels ) | | ( fromChannelNum < 0 ) | | ( fromChannelNum > = ANIM_NumAnimChannels ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::SyncToChannel : channel out of range " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
idAnimBlend & fromBlend = channels [ fromChannelNum ] [ 0 ] ;
idAnimBlend & toBlend = channels [ channelNum ] [ 0 ] ;
2012-11-26 18:58:24 +00:00
float weight = fromBlend . blendEndValue ;
2012-11-28 15:47:07 +00:00
if ( ( fromBlend . Anim ( ) ! = toBlend . Anim ( ) ) | | ( fromBlend . GetStartTime ( ) ! = toBlend . GetStartTime ( ) ) | | ( fromBlend . GetEndTime ( ) ! = toBlend . GetEndTime ( ) ) )
{
2012-11-26 18:58:24 +00:00
PushAnims ( channelNum , currentTime , blendTime ) ;
toBlend = fromBlend ;
toBlend . blendStartValue = 0.0f ;
toBlend . blendEndValue = 0.0f ;
}
2012-11-28 15:47:07 +00:00
toBlend . SetWeight ( weight , currentTime - 1 , blendTime ) ;
2012-11-26 18:58:24 +00:00
// disable framecommands on the current channel so that commands aren't called twice
toBlend . AllowFrameCommands ( false ) ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeActive ( TH_ANIMATE ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetJointPos
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SetJointPos ( jointHandle_t jointnum , jointModTransform_t transform_type , const idVec3 & pos )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
jointMod_t * jointMod ;
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) | | ( jointnum < 0 ) | | ( jointnum > = numJoints ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
jointMod = NULL ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < jointMods . Num ( ) ; i + + )
{
if ( jointMods [ i ] - > jointnum = = jointnum )
{
2012-11-26 18:58:24 +00:00
jointMod = jointMods [ i ] ;
break ;
2012-11-28 15:47:07 +00:00
}
else if ( jointMods [ i ] - > jointnum > jointnum )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! jointMod )
{
jointMod = new ( TAG_ANIM ) jointMod_t ;
2012-11-26 18:58:24 +00:00
jointMod - > jointnum = jointnum ;
jointMod - > mat . Identity ( ) ;
jointMod - > transform_axis = JOINTMOD_NONE ;
jointMods . Insert ( jointMod , i ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
jointMod - > pos = pos ;
jointMod - > transform_pos = transform_type ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeActive ( TH_ANIMATE ) ;
}
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetJointAxis
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SetJointAxis ( jointHandle_t jointnum , jointModTransform_t transform_type , const idMat3 & mat )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
jointMod_t * jointMod ;
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) | | ( jointnum < 0 ) | | ( jointnum > = numJoints ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
jointMod = NULL ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < jointMods . Num ( ) ; i + + )
{
if ( jointMods [ i ] - > jointnum = = jointnum )
{
2012-11-26 18:58:24 +00:00
jointMod = jointMods [ i ] ;
break ;
2012-11-28 15:47:07 +00:00
}
else if ( jointMods [ i ] - > jointnum > jointnum )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! jointMod )
{
jointMod = new ( TAG_ANIM ) jointMod_t ;
2012-11-26 18:58:24 +00:00
jointMod - > jointnum = jointnum ;
jointMod - > pos . Zero ( ) ;
jointMod - > transform_pos = JOINTMOD_NONE ;
jointMods . Insert ( jointMod , i ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
jointMod - > mat = mat ;
jointMod - > transform_axis = transform_type ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeActive ( TH_ANIMATE ) ;
}
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ClearJoint
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ClearJoint ( jointHandle_t jointnum )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) | | ( jointnum < 0 ) | | ( jointnum > = numJoints ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < jointMods . Num ( ) ; i + + )
{
if ( jointMods [ i ] - > jointnum = = jointnum )
{
2012-11-26 18:58:24 +00:00
delete jointMods [ i ] ;
jointMods . RemoveIndex ( i ) ;
ForceUpdate ( ) ;
break ;
2012-11-28 15:47:07 +00:00
}
else if ( jointMods [ i ] - > jointnum > jointnum )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ClearAllJoints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ClearAllJoints ( )
{
if ( jointMods . Num ( ) )
{
2012-11-26 18:58:24 +00:00
ForceUpdate ( ) ;
}
jointMods . DeleteContents ( true ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ClearAllAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ClearAllAnims ( int currentTime , int cleartime )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
2012-11-26 18:58:24 +00:00
Clear ( i , currentTime , cleartime ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ClearAFPose ( ) ;
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idAnimator : : GetDelta
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : GetDelta ( int fromtime , int totime , idVec3 & delta ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
2012-11-26 18:58:24 +00:00
float blendWeight ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) | | ( fromtime = = totime ) )
{
2012-11-26 18:58:24 +00:00
delta . Zero ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
delta . Zero ( ) ;
blendWeight = 0.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ ANIMCHANNEL_ALL ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > BlendDelta ( fromtime , totime , delta , blendWeight ) ;
}
2012-11-28 15:47:07 +00:00
if ( modelDef - > Joints ( ) [ 0 ] . channel )
{
2012-11-26 18:58:24 +00:00
blend = channels [ modelDef - > Joints ( ) [ 0 ] . channel ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > BlendDelta ( fromtime , totime , delta , blendWeight ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = =
idAnimator : : GetDeltaRotation
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : GetDeltaRotation ( int fromtime , int totime , idMat3 & delta ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
2012-11-26 18:58:24 +00:00
float blendWeight ;
idQuat q ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) | | ( fromtime = = totime ) )
{
2012-11-26 18:58:24 +00:00
delta . Identity ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
q . Set ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
blendWeight = 0.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ ANIMCHANNEL_ALL ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > BlendDeltaRotation ( fromtime , totime , q , blendWeight ) ;
}
2012-11-28 15:47:07 +00:00
if ( modelDef - > Joints ( ) [ 0 ] . channel )
{
2012-11-26 18:58:24 +00:00
blend = channels [ modelDef - > Joints ( ) [ 0 ] . channel ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > BlendDeltaRotation ( fromtime , totime , q , blendWeight ) ;
}
}
2012-11-28 15:47:07 +00:00
if ( blendWeight > 0.0f )
{
2012-11-26 18:58:24 +00:00
delta = q . ToMat3 ( ) ;
return true ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
delta . Identity ( ) ;
return false ;
}
}
/*
= = = = = = = = = = = = = = = = = = = =
idAnimator : : GetOrigin
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : GetOrigin ( int currentTime , idVec3 & pos ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
2012-11-26 18:58:24 +00:00
float blendWeight ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
pos . Zero ( ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
pos . Zero ( ) ;
blendWeight = 0.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ ANIMCHANNEL_ALL ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > BlendOrigin ( currentTime , pos , blendWeight , removeOriginOffset ) ;
}
2012-11-28 15:47:07 +00:00
if ( modelDef - > Joints ( ) [ 0 ] . channel )
{
2012-11-26 18:58:24 +00:00
blend = channels [ modelDef - > Joints ( ) [ 0 ] . channel ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_MaxAnimsPerChannel ; i + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > BlendOrigin ( currentTime , pos , blendWeight , removeOriginOffset ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
pos + = modelDef - > GetVisualOffset ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idAnimator : : GetBounds
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : GetBounds ( int currentTime , idBounds & bounds )
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
2012-11-26 18:58:24 +00:00
int count ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( AFPoseJoints . Num ( ) )
{
2012-11-26 18:58:24 +00:00
bounds = AFPoseBounds ;
count = 1 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
bounds . Clear ( ) ;
count = 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ 0 ] ;
2012-11-28 15:47:07 +00:00
for ( i = ANIMCHANNEL_ALL ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
if ( blend - > AddBounds ( currentTime , bounds , removeOriginOffset ) )
{
2012-11-26 18:58:24 +00:00
count + + ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( ! count )
{
if ( ! frameBounds . IsCleared ( ) )
{
2012-11-26 18:58:24 +00:00
bounds = frameBounds ;
return true ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
bounds . Zero ( ) ;
return false ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
bounds . TranslateSelf ( modelDef - > GetVisualOffset ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( g_debugBounds . GetBool ( ) )
{
if ( bounds [ 1 ] [ 0 ] - bounds [ 0 ] [ 0 ] > 2048 | | bounds [ 1 ] [ 1 ] - bounds [ 0 ] [ 1 ] > 2048 )
{
if ( entity )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " big frameBounds on entity '%s' with model '%s': %f,%f " , entity - > name . c_str ( ) , modelDef - > ModelHandle ( ) - > Name ( ) , bounds [ 1 ] [ 0 ] - bounds [ 0 ] [ 0 ] , bounds [ 1 ] [ 1 ] - bounds [ 0 ] [ 1 ] ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " big frameBounds on model '%s': %f,%f " , modelDef - > ModelHandle ( ) - > Name ( ) , bounds [ 1 ] [ 0 ] - bounds [ 0 ] [ 0 ] , bounds [ 1 ] [ 1 ] - bounds [ 0 ] [ 1 ] ) ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
frameBounds = bounds ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : InitAFPose
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : InitAFPose ( )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
AFPoseJoints . SetNum ( modelDef - > Joints ( ) . Num ( ) ) ;
AFPoseJoints . SetNum ( 0 ) ;
AFPoseJointMods . SetNum ( modelDef - > Joints ( ) . Num ( ) ) ;
AFPoseJointFrame . SetNum ( modelDef - > Joints ( ) . Num ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetAFPoseJointMod
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SetAFPoseJointMod ( const jointHandle_t jointNum , const AFJointModType_t mod , const idMat3 & axis , const idVec3 & origin )
{
2012-11-26 18:58:24 +00:00
AFPoseJointMods [ jointNum ] . mod = mod ;
AFPoseJointMods [ jointNum ] . axis = axis ;
AFPoseJointMods [ jointNum ] . origin = origin ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int index = idBinSearch_GreaterEqual < int > ( AFPoseJoints . Ptr ( ) , AFPoseJoints . Num ( ) , jointNum ) ;
2012-11-28 15:47:07 +00:00
if ( index > = AFPoseJoints . Num ( ) | | jointNum ! = AFPoseJoints [ index ] )
{
2012-11-26 18:58:24 +00:00
AFPoseJoints . Insert ( jointNum , index ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : FinishAFPose
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : FinishAFPose ( int animNum , const idBounds & bounds , const int time )
{
2012-11-26 18:58:24 +00:00
int i , j ;
int numJoints ;
int parentNum ;
int jointMod ;
int jointNum ;
2012-11-28 15:47:07 +00:00
const int * jointParent ;
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
const idAnim * anim = modelDef - > GetAnim ( animNum ) ;
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numJoints = modelDef - > Joints ( ) . Num ( ) ;
2012-11-28 15:47:07 +00:00
if ( ! numJoints )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
idRenderModel * md5 = modelDef - > ModelHandle ( ) ;
const idMD5Anim * md5anim = anim - > MD5Anim ( 0 ) ;
if ( numJoints ! = md5anim - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Model '%s' has different # of joints than anim '%s' " , md5 - > Name ( ) , md5anim - > Name ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
idJointQuat * jointFrame = ( idJointQuat * ) _alloca16 ( numJoints * sizeof ( * jointFrame ) ) ;
2012-11-26 18:58:24 +00:00
md5anim - > GetSingleFrame ( 0 , jointFrame , modelDef - > GetChannelJoints ( ANIMCHANNEL_ALL ) , modelDef - > NumJointsOnChannel ( ANIMCHANNEL_ALL ) ) ;
2012-11-28 15:47:07 +00:00
if ( removeOriginOffset )
{
2012-11-26 18:58:24 +00:00
# ifdef VELOCITY_MOVE
jointFrame [ 0 ] . t . x = 0.0f ;
# else
jointFrame [ 0 ] . t . Zero ( ) ;
# endif
}
2012-11-28 15:47:07 +00:00
idJointMat * joints = ( idJointMat * ) _alloca16 ( numJoints * sizeof ( * joints ) ) ;
2012-11-26 18:58:24 +00:00
// convert the joint quaternions to joint matrices
SIMDProcessor - > ConvertJointQuatsToJointMats ( joints , jointFrame , numJoints ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// first joint is always root of entire hierarchy
2012-11-28 15:47:07 +00:00
if ( AFPoseJoints . Num ( ) & & AFPoseJoints [ 0 ] = = 0 )
{
switch ( AFPoseJointMods [ 0 ] . mod )
{
case AF_JOINTMOD_AXIS :
{
2012-11-26 18:58:24 +00:00
joints [ 0 ] . SetRotation ( AFPoseJointMods [ 0 ] . axis ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case AF_JOINTMOD_ORIGIN :
{
2012-11-26 18:58:24 +00:00
joints [ 0 ] . SetTranslation ( AFPoseJointMods [ 0 ] . origin ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case AF_JOINTMOD_BOTH :
{
2012-11-26 18:58:24 +00:00
joints [ 0 ] . SetRotation ( AFPoseJointMods [ 0 ] . axis ) ;
joints [ 0 ] . SetTranslation ( AFPoseJointMods [ 0 ] . origin ) ;
break ;
}
}
j = 1 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
j = 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// pointer to joint info
jointParent = modelDef - > JointParents ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform the child joints
2012-11-28 15:47:07 +00:00
for ( i = 1 ; j < AFPoseJoints . Num ( ) ; j + + , i + + )
{
2012-11-26 18:58:24 +00:00
jointMod = AFPoseJoints [ j ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform any joints preceding the joint modifier
SIMDProcessor - > TransformJoints ( joints , jointParent , i , jointMod - 1 ) ;
i = jointMod ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
parentNum = jointParent [ i ] ;
2012-11-28 15:47:07 +00:00
switch ( AFPoseJointMods [ jointMod ] . mod )
{
case AF_JOINTMOD_AXIS :
{
2012-11-26 18:58:24 +00:00
joints [ i ] . SetRotation ( AFPoseJointMods [ jointMod ] . axis ) ;
joints [ i ] . SetTranslation ( joints [ parentNum ] . ToVec3 ( ) + joints [ i ] . ToVec3 ( ) * joints [ parentNum ] . ToMat3 ( ) ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case AF_JOINTMOD_ORIGIN :
{
2012-11-26 18:58:24 +00:00
joints [ i ] . SetRotation ( joints [ i ] . ToMat3 ( ) * joints [ parentNum ] . ToMat3 ( ) ) ;
joints [ i ] . SetTranslation ( AFPoseJointMods [ jointMod ] . origin ) ;
break ;
}
2012-11-28 15:47:07 +00:00
case AF_JOINTMOD_BOTH :
{
2012-11-26 18:58:24 +00:00
joints [ i ] . SetRotation ( AFPoseJointMods [ jointMod ] . axis ) ;
joints [ i ] . SetTranslation ( AFPoseJointMods [ jointMod ] . origin ) ;
break ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform the rest of the hierarchy
SIMDProcessor - > TransformJoints ( joints , jointParent , i , numJoints - 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// untransform hierarchy
SIMDProcessor - > UntransformJoints ( joints , jointParent , 1 , numJoints - 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// convert joint matrices back to joint quaternions
SIMDProcessor - > ConvertJointMatsToJointQuats ( AFPoseJointFrame . Ptr ( ) , joints , numJoints ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// find all modified joints and their parents
2012-11-28 15:47:07 +00:00
bool * blendJoints = ( bool * ) _alloca16 ( numJoints * sizeof ( bool ) ) ;
2012-11-26 18:58:24 +00:00
memset ( blendJoints , 0 , numJoints * sizeof ( bool ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// mark all modified joints and their parents
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < AFPoseJoints . Num ( ) ; i + + )
{
for ( jointNum = AFPoseJoints [ i ] ; jointNum ! = INVALID_JOINT ; jointNum = jointParent [ jointNum ] )
{
2012-11-26 18:58:24 +00:00
blendJoints [ jointNum ] = true ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// lock all parents of modified joints
AFPoseJoints . SetNum ( 0 ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numJoints ; i + + )
{
if ( blendJoints [ i ] )
{
2012-11-26 18:58:24 +00:00
AFPoseJoints . Append ( i ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
AFPoseBounds = bounds ;
AFPoseTime = time ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ForceUpdate ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : SetAFPoseBlendWeight
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : SetAFPoseBlendWeight ( float blendWeight )
{
2012-11-26 18:58:24 +00:00
AFPoseBlendWeight = blendWeight ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : BlendAFPose
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : BlendAFPose ( idJointQuat * blendFrame ) const
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( ! AFPoseJoints . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
SIMDProcessor - > BlendJoints ( blendFrame , AFPoseJointFrame . Ptr ( ) , AFPoseBlendWeight , AFPoseJoints . Ptr ( ) , AFPoseJoints . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ClearAFPose
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ClearAFPose ( )
{
if ( AFPoseJoints . Num ( ) )
{
2012-11-26 18:58:24 +00:00
ForceUpdate ( ) ;
}
AFPoseBlendWeight = 1.0f ;
AFPoseJoints . SetNum ( 0 ) ;
AFPoseBounds . Clear ( ) ;
AFPoseTime = 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ServiceAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ServiceAnims ( int fromtime , int totime )
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
idAnimBlend * blend ;
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
blend = channels [ 0 ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
2012-11-26 18:58:24 +00:00
blend - > CallFrameCommands ( entity , fromtime , totime ) ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( ! IsAnimating ( totime ) )
{
2012-11-26 18:58:24 +00:00
stoppedAnimatingUpdate = true ;
2012-11-28 15:47:07 +00:00
if ( entity )
{
2012-11-26 18:58:24 +00:00
entity - > BecomeInactive ( TH_ANIMATE ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// present one more time with stopped animations so the renderer can properly recreate interactions
entity - > BecomeActive ( TH_UPDATEVISUALS ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : IsAnimating
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : IsAnimating ( int currentTime ) const
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if animating with an articulated figure
2012-11-28 15:47:07 +00:00
if ( AFPoseJoints . Num ( ) & & currentTime < = AFPoseTime )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ 0 ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
if ( ! blend - > IsDone ( currentTime ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : FrameHasChanged
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : FrameHasChanged ( int currentTime ) const
{
2012-11-26 18:58:24 +00:00
int i , j ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if animating with an articulated figure
2012-11-28 15:47:07 +00:00
if ( AFPoseJoints . Num ( ) & & currentTime < = AFPoseTime )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
blend = channels [ 0 ] ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < ANIM_NumAnimChannels ; i + + )
{
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
if ( blend - > FrameHasChanged ( currentTime ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( forceUpdate & & IsAnimating ( currentTime ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : CreateFrame
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : CreateFrame ( int currentTime , bool force )
{
2012-11-26 18:58:24 +00:00
int i , j ;
int numJoints ;
int parentNum ;
bool hasAnim ;
bool debugInfo ;
float baseBlend ;
float blendWeight ;
2012-11-28 15:47:07 +00:00
const idAnimBlend * blend ;
const int * jointParent ;
const jointMod_t * jointMod ;
const idJointQuat * defaultPose ;
static idCVar r_showSkel ( " r_showSkel " , " 0 " , CVAR_RENDERER | CVAR_INTEGER , " " , 0 , 2 , idCmdSystem : : ArgCompletion_Integer < 0 , 2 > ) ;
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! force & & ! r_showSkel . GetInteger ( ) )
{
if ( lastTransformTime = = currentTime )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( lastTransformTime ! = - 1 & & ! stoppedAnimatingUpdate & & ! IsAnimating ( currentTime ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
lastTransformTime = currentTime ;
stoppedAnimatingUpdate = false ;
2012-11-28 15:47:07 +00:00
if ( entity & & ( ( g_debugAnim . GetInteger ( ) = = entity - > entityNumber ) | | ( g_debugAnim . GetInteger ( ) = = - 2 ) ) )
{
2012-11-26 18:58:24 +00:00
debugInfo = true ;
gameLocal . Printf ( " --------------- \n %d: entity '%s': \n " , gameLocal . time , entity - > GetName ( ) ) ;
2012-11-28 15:47:07 +00:00
gameLocal . Printf ( " model '%s': \n " , modelDef - > GetModelName ( ) ) ;
}
else
{
2012-11-26 18:58:24 +00:00
debugInfo = false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// init the joint buffer
2012-11-28 15:47:07 +00:00
if ( AFPoseJoints . Num ( ) )
{
2012-11-26 18:58:24 +00:00
// initialize with AF pose anim for the case where there are no other animations and no AF pose joint modifications
defaultPose = AFPoseJointFrame . Ptr ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
defaultPose = modelDef - > GetDefaultPose ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! defaultPose )
{
2012-11-26 18:58:24 +00:00
//gameLocal.Warning( "idAnimator::CreateFrame: no defaultPose on '%s'", modelDef->Name() );
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numJoints = modelDef - > Joints ( ) . Num ( ) ;
2012-11-28 15:47:07 +00:00
idJointQuat * jointFrame = ( idJointQuat * ) _alloca16 ( numJoints * sizeof ( jointFrame [ 0 ] ) ) ;
2012-11-26 18:58:24 +00:00
SIMDProcessor - > Memcpy ( jointFrame , defaultPose , numJoints * sizeof ( jointFrame [ 0 ] ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
hasAnim = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// blend the all channel
baseBlend = 0.0f ;
blend = channels [ ANIMCHANNEL_ALL ] ;
2012-11-28 15:47:07 +00:00
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
if ( blend - > BlendAnim ( currentTime , ANIMCHANNEL_ALL , numJoints , jointFrame , baseBlend , removeOriginOffset , false , debugInfo ) )
{
2012-11-26 18:58:24 +00:00
hasAnim = true ;
2012-11-28 15:47:07 +00:00
if ( baseBlend > = 1.0f )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// only blend other channels if there's enough space to blend into
2012-11-28 15:47:07 +00:00
if ( baseBlend < 1.0f )
{
for ( i = ANIMCHANNEL_ALL + 1 ; i < ANIM_NumAnimChannels ; i + + )
{
if ( ! modelDef - > NumJointsOnChannel ( i ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( i = = ANIMCHANNEL_EYELIDS )
{
2012-11-26 18:58:24 +00:00
// eyelids blend over any previous anims, so skip it and blend it later
continue ;
}
blendWeight = baseBlend ;
blend = channels [ i ] ;
2012-11-28 15:47:07 +00:00
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
if ( blend - > BlendAnim ( currentTime , i , numJoints , jointFrame , blendWeight , removeOriginOffset , false , debugInfo ) )
{
2012-11-26 18:58:24 +00:00
hasAnim = true ;
2012-11-28 15:47:07 +00:00
if ( blendWeight > = 1.0f )
{
2012-11-26 18:58:24 +00:00
// fully blended
break ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( debugInfo & & ! AFPoseJoints . Num ( ) & & ! blendWeight )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %d: %s using default pose in model '%s' \n " , gameLocal . time , channelNames [ i ] , modelDef - > GetModelName ( ) ) ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// blend in the eyelids
2012-11-28 15:47:07 +00:00
if ( modelDef - > NumJointsOnChannel ( ANIMCHANNEL_EYELIDS ) )
{
2012-11-26 18:58:24 +00:00
blend = channels [ ANIMCHANNEL_EYELIDS ] ;
blendWeight = baseBlend ;
2012-11-28 15:47:07 +00:00
for ( j = 0 ; j < ANIM_MaxAnimsPerChannel ; j + + , blend + + )
{
if ( blend - > BlendAnim ( currentTime , ANIMCHANNEL_EYELIDS , numJoints , jointFrame , blendWeight , removeOriginOffset , true , debugInfo ) )
{
2012-11-26 18:58:24 +00:00
hasAnim = true ;
2012-11-28 15:47:07 +00:00
if ( blendWeight > = 1.0f )
{
2012-11-26 18:58:24 +00:00
// fully blended
break ;
}
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// blend the articulated figure pose
2012-11-28 15:47:07 +00:00
if ( BlendAFPose ( jointFrame ) )
{
2012-11-26 18:58:24 +00:00
hasAnim = true ;
}
2012-11-28 15:47:07 +00:00
if ( ! hasAnim & & ! jointMods . Num ( ) )
{
2012-11-26 18:58:24 +00:00
// no animations were updated
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// convert the joint quaternions to rotation matrices
SIMDProcessor - > ConvertJointQuatsToJointMats ( joints , jointFrame , numJoints ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check if we need to modify the origin
2012-11-28 15:47:07 +00:00
if ( jointMods . Num ( ) & & ( jointMods [ 0 ] - > jointnum = = 0 ) )
{
2012-11-26 18:58:24 +00:00
jointMod = jointMods [ 0 ] ;
2012-11-28 15:47:07 +00:00
switch ( jointMod - > transform_axis )
{
2012-11-26 18:58:24 +00:00
case JOINTMOD_NONE :
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL :
joints [ 0 ] . SetRotation ( jointMod - > mat * joints [ 0 ] . ToMat3 ( ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_WORLD :
joints [ 0 ] . SetRotation ( joints [ 0 ] . ToMat3 ( ) * jointMod - > mat ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL_OVERRIDE :
case JOINTMOD_WORLD_OVERRIDE :
joints [ 0 ] . SetRotation ( jointMod - > mat ) ;
break ;
}
2012-11-28 15:47:07 +00:00
switch ( jointMod - > transform_pos )
{
2012-11-26 18:58:24 +00:00
case JOINTMOD_NONE :
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL :
joints [ 0 ] . SetTranslation ( joints [ 0 ] . ToVec3 ( ) + jointMod - > pos ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL_OVERRIDE :
case JOINTMOD_WORLD :
case JOINTMOD_WORLD_OVERRIDE :
joints [ 0 ] . SetTranslation ( jointMod - > pos ) ;
break ;
}
j = 1 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
j = 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add in the model offset
joints [ 0 ] . SetTranslation ( joints [ 0 ] . ToVec3 ( ) + modelDef - > GetVisualOffset ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// pointer to joint info
jointParent = modelDef - > JointParents ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add in any joint modifications
2012-11-28 15:47:07 +00:00
for ( i = 1 ; j < jointMods . Num ( ) ; j + + , i + + )
{
2012-11-26 18:58:24 +00:00
jointMod = jointMods [ j ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform any joints preceding the joint modifier
SIMDProcessor - > TransformJoints ( joints , jointParent , i , jointMod - > jointnum - 1 ) ;
i = jointMod - > jointnum ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
parentNum = jointParent [ i ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// modify the axis
2012-11-28 15:47:07 +00:00
switch ( jointMod - > transform_axis )
{
2012-11-26 18:58:24 +00:00
case JOINTMOD_NONE :
joints [ i ] . SetRotation ( joints [ i ] . ToMat3 ( ) * joints [ parentNum ] . ToMat3 ( ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL :
joints [ i ] . SetRotation ( jointMod - > mat * ( joints [ i ] . ToMat3 ( ) * joints [ parentNum ] . ToMat3 ( ) ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL_OVERRIDE :
joints [ i ] . SetRotation ( jointMod - > mat * joints [ parentNum ] . ToMat3 ( ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_WORLD :
joints [ i ] . SetRotation ( ( joints [ i ] . ToMat3 ( ) * joints [ parentNum ] . ToMat3 ( ) ) * jointMod - > mat ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_WORLD_OVERRIDE :
joints [ i ] . SetRotation ( jointMod - > mat ) ;
break ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// modify the position
2012-11-28 15:47:07 +00:00
switch ( jointMod - > transform_pos )
{
2012-11-26 18:58:24 +00:00
case JOINTMOD_NONE :
joints [ i ] . SetTranslation ( joints [ parentNum ] . ToVec3 ( ) + joints [ i ] . ToVec3 ( ) * joints [ parentNum ] . ToMat3 ( ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL :
joints [ i ] . SetTranslation ( joints [ parentNum ] . ToVec3 ( ) + ( joints [ i ] . ToVec3 ( ) + jointMod - > pos ) * joints [ parentNum ] . ToMat3 ( ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_LOCAL_OVERRIDE :
joints [ i ] . SetTranslation ( joints [ parentNum ] . ToVec3 ( ) + jointMod - > pos * joints [ parentNum ] . ToMat3 ( ) ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_WORLD :
joints [ i ] . SetTranslation ( joints [ parentNum ] . ToVec3 ( ) + joints [ i ] . ToVec3 ( ) * joints [ parentNum ] . ToMat3 ( ) + jointMod - > pos ) ;
break ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
case JOINTMOD_WORLD_OVERRIDE :
joints [ i ] . SetTranslation ( jointMod - > pos ) ;
break ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform the rest of the hierarchy
SIMDProcessor - > TransformJoints ( joints , jointParent , i , numJoints - 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ForceUpdate
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ForceUpdate ( )
{
2012-11-26 18:58:24 +00:00
lastTransformTime = - 1 ;
forceUpdate = true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : ClearForceUpdate
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : ClearForceUpdate ( )
{
2012-11-26 18:58:24 +00:00
forceUpdate = false ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetJointTransform > gamex86 . dll ! idAnimator : : ForceUpdate ( ) Line 4268 C + +
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : GetJointTransform ( jointHandle_t jointHandle , int currentTime , idVec3 & offset , idMat3 & axis )
{
if ( ! modelDef | | ( jointHandle < 0 ) | | ( jointHandle > = modelDef - > NumJoints ( ) ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
CreateFrame ( currentTime , false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
offset = joints [ jointHandle ] . ToVec3 ( ) ;
axis = joints [ jointHandle ] . ToMat3 ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetJointLocalTransform
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idAnimator : : GetJointLocalTransform ( jointHandle_t jointHandle , int currentTime , idVec3 & offset , idMat3 & axis )
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
const idList < jointInfo_t > & modelJoints = modelDef - > Joints ( ) ;
if ( ( jointHandle < 0 ) | | ( jointHandle > = modelJoints . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// FIXME: overkill
CreateFrame ( currentTime , false ) ;
2012-11-28 15:47:07 +00:00
2013-01-13 23:24:11 +00:00
// RB: long neck GCC compiler bug workaround from dhewm3 ...
if ( jointHandle = = 0 )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
offset = joints [ jointHandle ] . ToVec3 ( ) ;
axis = joints [ jointHandle ] . ToMat3 ( ) ;
2013-01-13 23:24:11 +00:00
return true ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2013-01-13 23:24:11 +00:00
idJointMat m = joints [ jointHandle ] ;
m / = joints [ modelJoints [ jointHandle ] . parentNum ] ;
offset = m . ToVec3 ( ) ;
axis = m . ToMat3 ( ) ;
// RB end
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetJointHandle
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
jointHandle_t idAnimator : : GetJointHandle ( const char * name ) const
{
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return INVALID_JOINT ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return modelDef - > ModelHandle ( ) - > GetJointHandle ( name ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetJointName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnimator : : GetJointName ( jointHandle_t handle ) const
{
if ( ! modelDef | | ! modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return " " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return modelDef - > ModelHandle ( ) - > GetJointName ( handle ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetChannelForJoint
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : GetChannelForJoint ( jointHandle_t joint ) const
{
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::GetChannelForJoint: NULL model " ) ;
return - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( ( joint < 0 ) | | ( joint > = numJoints ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " idAnimator::GetChannelForJoint: invalid joint num (%d) " , joint ) ;
return - 1 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return modelDef - > GetJoint ( joint ) - > channel ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetFirstChild
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
jointHandle_t idAnimator : : GetFirstChild ( const char * name ) const
{
2012-11-26 18:58:24 +00:00
return GetFirstChild ( GetJointHandle ( name ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetFirstChild
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
jointHandle_t idAnimator : : GetFirstChild ( jointHandle_t jointnum ) const
{
2012-11-26 18:58:24 +00:00
int i ;
int num ;
2012-11-28 15:47:07 +00:00
const jointInfo_t * joint ;
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return INVALID_JOINT ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
num = modelDef - > NumJoints ( ) ;
2012-11-28 15:47:07 +00:00
if ( ! num )
{
2012-11-26 18:58:24 +00:00
return jointnum ;
}
joint = modelDef - > GetJoint ( 0 ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + , joint + + )
{
if ( joint - > parentNum = = jointnum )
{
2012-11-26 18:58:24 +00:00
return ( jointHandle_t ) joint - > num ;
}
}
return jointnum ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetJoints
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idAnimator : : GetJoints ( int * numJoints , idJointMat * * jointsPtr )
{
2012-11-26 18:58:24 +00:00
* numJoints = this - > numJoints ;
* jointsPtr = this - > joints ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : GetAnimFlags
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const animFlags_t idAnimator : : GetAnimFlags ( int animNum ) const
{
2012-11-26 18:58:24 +00:00
animFlags_t result ;
2012-11-28 15:47:07 +00:00
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > GetAnimFlags ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & result , 0 , sizeof ( result ) ) ;
return result ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : NumFrames
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : NumFrames ( int animNum ) const
{
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > NumFrames ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : NumSyncedAnims
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : NumSyncedAnims ( int animNum ) const
{
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > NumAnims ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : AnimName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnimator : : AnimName ( int animNum ) const
{
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > Name ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return " " ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : AnimFullName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idAnimator : : AnimFullName ( int animNum ) const
{
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > FullName ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return " " ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : AnimLength
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idAnimator : : AnimLength ( int animNum ) const
{
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > Length ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idAnimator : : TotalMovementDelta
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idVec3 & idAnimator : : TotalMovementDelta ( int animNum ) const
{
const idAnim * anim = GetAnim ( animNum ) ;
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > TotalMovementDelta ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return vec3_origin ;
}
}
/***********************************************************************
Util functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
ANIM_GetModelDefFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idDeclModelDef * ANIM_GetModelDefFromEntityDef ( const idDict * args )
{
const idDeclModelDef * modelDef ;
2012-11-26 18:58:24 +00:00
idStr name = args - > GetString ( " model " ) ;
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , name , false ) ) ;
if ( modelDef ! = NULL & & modelDef - > ModelHandle ( ) )
{
2012-11-26 18:58:24 +00:00
return modelDef ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetModelFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idGameEdit : : ANIM_GetModelFromEntityDef ( const idDict * args )
{
idRenderModel * model ;
const idDeclModelDef * modelDef ;
2012-11-26 18:58:24 +00:00
model = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr name = args - > GetString ( " model " ) ;
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , name , false ) ) ;
if ( modelDef ! = NULL )
{
2012-11-26 18:58:24 +00:00
model = modelDef - > ModelHandle ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( model = = NULL )
{
2012-11-26 18:58:24 +00:00
model = renderModelManager - > FindModel ( name ) ;
}
2012-11-28 15:47:07 +00:00
if ( model ! = NULL & & model - > IsDefaultModel ( ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return model ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetModelFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idGameEdit : : ANIM_GetModelFromEntityDef ( const char * classname )
{
const idDict * args ;
2012-11-26 18:58:24 +00:00
args = gameLocal . FindEntityDefDict ( classname , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! args )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return ANIM_GetModelFromEntityDef ( args ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetModelOffsetFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idVec3 & idGameEdit : : ANIM_GetModelOffsetFromEntityDef ( const char * classname )
{
const idDict * args ;
const idDeclModelDef * modelDef ;
2012-11-26 18:58:24 +00:00
args = gameLocal . FindEntityDefDict ( classname , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! args )
{
2012-11-26 18:58:24 +00:00
return vec3_origin ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
modelDef = ANIM_GetModelDefFromEntityDef ( args ) ;
2012-11-28 15:47:07 +00:00
if ( ! modelDef )
{
2012-11-26 18:58:24 +00:00
return vec3_origin ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return modelDef - > GetVisualOffset ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetModelFromName
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idGameEdit : : ANIM_GetModelFromName ( const char * modelName )
{
const idDeclModelDef * modelDef ;
idRenderModel * model ;
2012-11-26 18:58:24 +00:00
model = NULL ;
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , modelName , false ) ) ;
if ( modelDef )
{
2012-11-26 18:58:24 +00:00
model = modelDef - > ModelHandle ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! model )
{
2012-11-26 18:58:24 +00:00
model = renderModelManager - > FindModel ( modelName ) ;
}
return model ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetAnimFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idMD5Anim * idGameEdit : : ANIM_GetAnimFromEntityDef ( const char * classname , const char * animname )
{
const idDict * args ;
const idMD5Anim * md5anim ;
const idAnim * anim ;
2012-11-26 18:58:24 +00:00
int animNum ;
2012-11-28 15:47:07 +00:00
const char * modelname ;
const idDeclModelDef * modelDef ;
2012-11-26 18:58:24 +00:00
args = gameLocal . FindEntityDefDict ( classname , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! args )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
md5anim = NULL ;
modelname = args - > GetString ( " model " ) ;
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , modelname , false ) ) ;
if ( modelDef )
{
2012-11-26 18:58:24 +00:00
animNum = modelDef - > GetAnim ( animname ) ;
2012-11-28 15:47:07 +00:00
if ( animNum )
{
2012-11-26 18:58:24 +00:00
anim = modelDef - > GetAnim ( animNum ) ;
2012-11-28 15:47:07 +00:00
if ( anim )
{
2012-11-26 18:58:24 +00:00
md5anim = anim - > MD5Anim ( 0 ) ;
}
}
}
return md5anim ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetNumAnimsFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idGameEdit : : ANIM_GetNumAnimsFromEntityDef ( const idDict * args )
{
const char * modelname ;
const idDeclModelDef * modelDef ;
2012-11-26 18:58:24 +00:00
modelname = args - > GetString ( " model " ) ;
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , modelname , false ) ) ;
if ( modelDef )
{
2012-11-26 18:58:24 +00:00
return modelDef - > NumAnims ( ) ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetAnimNameFromEntityDef
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idGameEdit : : ANIM_GetAnimNameFromEntityDef ( const idDict * args , int animNum )
{
const char * modelname ;
const idDeclModelDef * modelDef ;
2012-11-26 18:58:24 +00:00
modelname = args - > GetString ( " model " ) ;
2012-11-28 15:47:07 +00:00
modelDef = static_cast < const idDeclModelDef * > ( declManager - > FindType ( DECL_MODELDEF , modelname , false ) ) ;
if ( modelDef )
{
2012-11-26 18:58:24 +00:00
const idAnim * anim = modelDef - > GetAnim ( animNum ) ;
2012-11-28 15:47:07 +00:00
if ( anim )
{
2012-11-26 18:58:24 +00:00
return anim - > FullName ( ) ;
}
}
return " " ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const idMD5Anim * idGameEdit : : ANIM_GetAnim ( const char * fileName )
{
2012-11-26 18:58:24 +00:00
return animationLib . GetAnim ( fileName ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetLength
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idGameEdit : : ANIM_GetLength ( const idMD5Anim * anim )
{
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
return anim - > Length ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_GetNumFrames
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idGameEdit : : ANIM_GetNumFrames ( const idMD5Anim * anim )
{
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
return anim - > NumFrames ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_CreateAnimFrame
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idGameEdit : : ANIM_CreateAnimFrame ( const idRenderModel * model , const idMD5Anim * anim , int numJoints , idJointMat * joints , int time , const idVec3 & offset , bool remove_origin_offset )
{
2012-11-26 18:58:24 +00:00
int i ;
frameBlend_t frame ;
2012-11-28 15:47:07 +00:00
const idMD5Joint * md5joints ;
int * index ;
if ( ! model | | model - > IsDefaultModel ( ) | | ! anim )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( numJoints ! = model - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " ANIM_CreateAnimFrame: different # of joints in renderEntity_t than in model (%s) " , model - > Name ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! model - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
// FIXME: Print out a warning?
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! joints )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " ANIM_CreateAnimFrame: NULL joint frame pointer on model (%s) " , model - > Name ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( numJoints ! = anim - > NumJoints ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Model '%s' has different # of joints than anim '%s' " , model - > Name ( ) , anim - > Name ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < numJoints ; i + + )
{
2012-11-26 18:58:24 +00:00
joints [ i ] . SetRotation ( mat3_identity ) ;
joints [ i ] . SetTranslation ( offset ) ;
}
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// create index for all joints
2012-11-28 15:47:07 +00:00
index = ( int * ) _alloca16 ( numJoints * sizeof ( int ) ) ;
for ( i = 0 ; i < numJoints ; i + + )
{
2012-11-26 18:58:24 +00:00
index [ i ] = i ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// create the frame
anim - > ConvertTimeToFrame ( time , 1 , frame ) ;
2012-11-28 15:47:07 +00:00
idJointQuat * jointFrame = ( idJointQuat * ) _alloca16 ( numJoints * sizeof ( * jointFrame ) ) ;
2012-11-26 18:58:24 +00:00
anim - > GetInterpolatedFrame ( frame , jointFrame , index , numJoints ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// convert joint quaternions to joint matrices
SIMDProcessor - > ConvertJointQuatsToJointMats ( joints , jointFrame , numJoints ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// first joint is always root of entire hierarchy
2012-11-28 15:47:07 +00:00
if ( remove_origin_offset )
{
2012-11-26 18:58:24 +00:00
joints [ 0 ] . SetTranslation ( offset ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
joints [ 0 ] . SetTranslation ( joints [ 0 ] . ToVec3 ( ) + offset ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// transform the children
md5joints = model - > GetJoints ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 1 ; i < numJoints ; i + + )
{
2012-11-26 18:58:24 +00:00
joints [ i ] * = joints [ md5joints [ i ] . parent - md5joints ] ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idGameEdit : : ANIM_CreateMeshForAnim
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderModel * idGameEdit : : ANIM_CreateMeshForAnim ( idRenderModel * model , const char * classname , const char * animname , int frame , bool remove_origin_offset )
{
2012-11-26 18:58:24 +00:00
renderEntity_t ent ;
2012-11-28 15:47:07 +00:00
const idDict * args ;
const char * temp ;
idRenderModel * newmodel ;
const idMD5Anim * md5anim ;
2012-11-26 18:58:24 +00:00
idStr filename ;
idStr extension ;
2012-11-28 15:47:07 +00:00
const idAnim * anim ;
2012-11-26 18:58:24 +00:00
int animNum ;
idVec3 offset ;
2012-11-28 15:47:07 +00:00
const idDeclModelDef * modelDef ;
if ( ! model | | model - > IsDefaultModel ( ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
args = gameLocal . FindEntityDefDict ( classname , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! args )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & ent , 0 , sizeof ( ent ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ent . bounds . Clear ( ) ;
ent . suppressSurfaceInViewID = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
modelDef = ANIM_GetModelDefFromEntityDef ( args ) ;
2012-11-28 15:47:07 +00:00
if ( modelDef )
{
2012-11-26 18:58:24 +00:00
animNum = modelDef - > GetAnim ( animname ) ;
2012-11-28 15:47:07 +00:00
if ( ! animNum )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
anim = modelDef - > GetAnim ( animNum ) ;
2012-11-28 15:47:07 +00:00
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
md5anim = anim - > MD5Anim ( 0 ) ;
ent . customSkin = modelDef - > GetDefaultSkin ( ) ;
offset = modelDef - > GetVisualOffset ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
filename = animname ;
filename . ExtractFileExtension ( extension ) ;
2012-11-28 15:47:07 +00:00
if ( ! extension . Length ( ) )
{
2012-11-26 18:58:24 +00:00
animname = args - > GetString ( va ( " anim %s " , animname ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
md5anim = animationLib . GetAnim ( animname ) ;
offset . Zero ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! md5anim )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
temp = args - > GetString ( " skin " , " " ) ;
2012-11-28 15:47:07 +00:00
if ( temp [ 0 ] )
{
2012-11-26 18:58:24 +00:00
ent . customSkin = declManager - > FindSkin ( temp ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ent . numJoints = model - > NumJoints ( ) ;
2012-11-28 15:47:07 +00:00
ent . joints = ( idJointMat * ) Mem_Alloc16 ( SIMD_ROUND_JOINTS ( ent . numJoints ) * sizeof ( * ent . joints ) , TAG_JOINTMAT ) ;
2012-11-26 18:58:24 +00:00
ANIM_CreateAnimFrame ( model , md5anim , ent . numJoints , ent . joints , FRAME2MS ( frame ) , offset , remove_origin_offset ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
SIMD_INIT_LAST_JOINT ( ent . joints , ent . numJoints ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
newmodel = model - > InstantiateDynamicModel ( & ent , NULL , NULL ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Mem_Free16 ( ent . joints ) ;
ent . joints = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return newmodel ;
}