Here is the source code the Example #3 that comes with Enhanced Animations and the EXE & media for the demo(I obviously cant post the actualy library so you wont be able to compile the code, but you can run the example and look through the code, the product is quite easy once you get your head around how it works...
Which is to take the animation data out of the model, and work with it, then apply it bak to the model(the same or different or whatever...)
This example just shows how EA's interpolation works....
You can have the model walking at the same time as the top half of it is reloading it's gun etc etc.... its quite a useful product...
Im not trying to plug it or anything, lol, just giving you an example of it's use....
//Enhanced Animations for The Game Creators GDK
//Example 03: Limb Specific Animations
//---------------------------------------------
//by: Ron Erickson 23-Oct-07
#pragma warning( disable : 4244 4305 )
#include "DarkGDK.h"
#include "EnhancedAnimations.h"
#include <fstream>
#include <iostream>
using namespace std;
void DarkGDK ( void )
{
// **********************
// Setup
// **********************
dbSyncOn ( );
dbSyncRate (0);
dbBackdropOn ( );
dbAutoCamOff ( );
dbMaximiseWindow( );
dbSetWindowOff( );
dbSetDisplayMode( 1024, 768, 32 );
// **********************
// Load Objects:
// **********************
// Load Character Model
// ---------------------------------------------
dbLoadObject( "media/ai.x", 1 );
dbYRotateObject( 1, 180 );
dbFixObjectPivot( 1 );
dbLoadImage( "media/ai_D2.DDS", 1 );
dbTextureObject( 1, 1 );
dbSetObjectEmissive( 1, dbRgb( 128, 128, 128 ) );
dbPositionObject( 1, 0, 0, 0 );
// Load Gun
// ---------------------------------------------
dbLoadObject( "media/colt 45.x", 2 );
dbLoadImage( "media/colt45.DDS", 2 );
dbTextureObject( 2, 2 );
dbXRotateObject( 2, 90 );
dbZRotateObject( 2, 180 );
dbScaleObject( 2, 75, 75, 75 );
dbOffsetLimb( 2, 0, 0, -2, 0 );
dbFixObjectPivot( 2 );
dbGlueObjectToLimb( 2, 1, 38 );
// Camera
// ---------------------------------------------
dbPositionCamera( 35, 65, 100 );
dbPointCamera( 0, 45, 0);
// Set the default animation play speed (frames per second)
// ----------------------------------------------------------
EnAn_SetDefaultPlaySpeed( 25.0f );
// EXTRACT ANIMATION DATA FROM MODEL
// ************************************************
// Normaly, this would be done outside of your game as you are preparing your media.
// Extracting animations pulls the animation data out of your files
// and puts it into it's own file format
// Note: if you set the EndFrame# variable to -1, it will use the last frame in the model
EnAn_ObjExtractAnimation( 1, "Stand.anim", 0, 0 );
EnAn_ObjExtractAnimation( 1, "Run.anim", 300, 318 );
EnAn_ObjExtractAnimation( 1, "Walk.anim", 235, 259 );
EnAn_ObjExtractAnimation( 1, "StepLeft.anim", 260, 279 );
EnAn_ObjExtractAnimation( 1, "StepRight.anim", 280, 299 );
EnAn_ObjExtractAnimation( 1, "Aim.anim", 554, 571 );
EnAn_ObjExtractAnimation( 1, "Reload.anim", 682, 731 );
EnAn_ObjExtractAnimation( 1, "Throw.anim", 319, 355 );
EnAn_ObjExtractAnimation( 1, "Die.anim", 0, 19 );
EnAn_ObjExtractAnimation( 1, "GetUp.anim", 493, 522 );
// LOAD ANIMATIONS
// ************************************************
DWORD An_Stand = EnAn_AnimLoad("Stand.anim");
DWORD An_Run = EnAn_AnimLoad("Run.anim");
DWORD An_Walk = EnAn_AnimLoad("Walk.anim");
DWORD An_Left = EnAn_AnimLoad("StepLeft.anim");
DWORD An_Right = EnAn_AnimLoad("StepRight.anim");
DWORD An_Aim = EnAn_AnimLoad("Aim.anim");
DWORD An_Reload = EnAn_AnimLoad("Reload.anim");
DWORD An_Throw = EnAn_AnimLoad("Throw.anim");
DWORD An_Die = EnAn_AnimLoad("Die.anim");
DWORD An_GetUp = EnAn_AnimLoad("GetUp.anim");
// CREATE OAC LINK TO OBJECT
// ************************************************
DWORD oacID = EnAn_oacCreate( 1 );
// LIMB HIERARCHY
// ************************************************
// We need to know what limbs numbers go to the limbs that we want to control
// You can easily find out information about your limbs by doing something
// like this:
ofstream myfile( "limb data.txt");
for ( DWORD a = 1; a < EnAn_ObjTotalLimbs(1); a++ )
{
myfile << a << " = " << dbLimbName( 1, a ) << "\n";
myfile << "----------------------------------\n";
myfile << "Parent Limb: " << EnAn_ObjFindLimbParent( 1, a ) << " - " << dbLimbName( 1,EnAn_ObjFindLimbParent( 1, a ) ) << "\n";
myfile << "Direct Children:\n";
for ( DWORD b = 1; b < EnAn_ObjTotalLimbs( 1 ); b++ )
{
if ( EnAn_ObjIsLimbChild( 1, a, b ) == 1 && EnAn_ObjFindLimbParent( 1, b ) == a )
{
myfile << " " << b << " = " << dbLimbName( 1, b ) << "\n";
}
}
myfile << "\n";
}
myfile.close( );
// This model's hierarchy looks like this:
// Base
// |-Pelvis
// |-Spine
// |-ThighRight -> The rest of the model's Right Leg are children of ThighRight
// |-ThighLeft -> The rest of the model's Right Leg are children of ThighLeft
// |-Spine1
// |-Spine2 -> The rest of the model's UpperBody are children of Spine2
// When you want to control the model's upper body, you can simply refer to the Spine1 limb and include it's children
// All of the rest of the limb's actions should be set to what you want the lower body (movement) to do.
// These are the lower body limbs that I will need to apply my movement animation to
DWORD Limb_Base = 1; // This specific limb
DWORD Limb_Pelvis = 2; // This specific limb
DWORD Limb_Spine = 3; // This specific limb
DWORD Limb_ThighRight = 4; // This limb and all of it's children
DWORD Limb_ThighLeft = 12; // This limb and all of it's children
DWORD Limb_Spine1 = 20; // This limb and all of it's children
// This is the upper body limb that I will need to apply my action animation to
DWORD Limb_Spine2 = 21; // This specific limb
// MODES
// ************************************************
// This is just a couple of varibales to keep track of what action is currently happening
// There are two types of actions that can be happening on the model at one time.
// Movement Types:
DWORD Move_Stand = 0;
DWORD Move_Walk = 1;
DWORD Move_Run = 2;
DWORD Move_Left = 3;
DWORD Move_Right = 4;
DWORD Move_Die = 5;
// Action Types:
DWORD Action_None = 0;
DWORD Action_Aim = 1;
DWORD Action_Reload = 2;
DWORD Action_Throw = 3;
// Current settings for each mode
DWORD MoveMode = Move_Stand;
DWORD ActionMode = Action_None;
DWORD dead = 0;
DWORD dieKey = 0;
DWORD CurrentAnim = 0;
double CurrentFrame = 0;
// General Variables
// ************************************************
DWORD transTime = 1000; // This is just a variable that I will use for all of the transition times:
DWORD DoLoop = 1; // Set animation to loop
DWORD NoLoop = 0; // Do Not loop animation
DWORD IncChild = 0; // Include all of the limbs child limbs
DWORD ExcChild = 1; // Only use the specified limb
// PLAY THE STAND ANIMATION
// ************************************************
// Begin by playing the Stand animation on the entire object
EnAn_oacAnimTransition( oacID, 1, An_Stand, 0, 0, -1, transTime, DoLoop, IncChild );
// Get the current time value.
DWORD time = dbTimer();
DWORD elapsedTime = 0;
// **********************
// Main Loop:
// **********************
while ( LoopGDK ( ) )
{
if ( dbEscapeKey ( ) )
return;
// OBJECT ROTATION
// ************************************************
if ( dbScanCode ( ) == 30 )
{ dbTurnObjectRight( 1, -1 );}
if ( dbScanCode ( ) == 31 )
{ dbTurnObjectRight( 1, 1 );}
// ELAPSED TIME
// *****************************************
// Get the amount of elspsed time since the last time check
elapsedTime = dbTimer() - time;
// Reset the time check
time = dbTimer();
// UPDATE THE OAC
// *****************************************
// This will update the object's animation by telling the object how much time has elapsed
EnAn_oacUpdate( oacID, elapsedTime );
// LIMB BASED TRANSITION TO NEW ANIMATIONS
// *****************************************
// Movement Animations
// -------------------------------------------------------------------------
if ( dead == 0 )
{
// Walk:
// If user presses the up key, and character is not already Walking, then set the character to walk
if (dbUpKey()== 1 && MoveMode != Move_Walk && dbDownKey() == 0 && dbRightKey() == 0 && dbLeftKey() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Base, An_Walk, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Base limb (with NO children) to Walk
EnAn_oacAnimTransition( oacID, Limb_Pelvis, An_Walk, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Pelvis limb (with NO children) to Walk
EnAn_oacAnimTransition( oacID, Limb_Spine, An_Walk, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine limb (with NO children) to Walk
EnAn_oacAnimTransition( oacID, Limb_ThighRight, An_Walk, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Right Thigh limb (with ALL children) to Walk
EnAn_oacAnimTransition( oacID, Limb_ThighLeft, An_Walk, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Left Thigh limb (with ALL children) to Walk
EnAn_oacAnimTransition( oacID, Limb_Spine1, An_Walk, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine1 limb (with NO children) to Walk
MoveMode = Move_Walk; //Set Move mode to walk
// If there is no action happening on the upper body, then it is ok to set the upper body to walk too.
if ( ActionMode == Action_None )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Walk, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Walk
}
}
// Step Right:
// If user presses the right key, and character is not already stepping right, then set the character to step right
if (dbRightKey()== 1 && MoveMode != Move_Right && dbDownKey() == 0 && dbUpKey() == 0 && dbLeftKey() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Base, An_Right, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Base limb (with NO children) to Step Right
EnAn_oacAnimTransition( oacID, Limb_Pelvis, An_Right, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Pelvis limb (with NO children) to Step Right
EnAn_oacAnimTransition( oacID, Limb_Spine, An_Right, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine limb (with NO children) to Step Right
EnAn_oacAnimTransition( oacID, Limb_ThighRight, An_Right, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Right Thigh limb (with ALL children) to Step Right
EnAn_oacAnimTransition( oacID, Limb_ThighLeft, An_Right, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Left Thigh limb (with ALL children) to Step Right
EnAn_oacAnimTransition( oacID, Limb_Spine1, An_Right, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine1 limb (with NO children) to Step Right
MoveMode = Move_Right; //Set Move mode to Step Right
// If there is no action happening on the upper body, then it is ok to set the upper body to step right too.
if ( ActionMode == Action_None )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Right, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Step Right
}
}
// Step Left:
// If user presses the left key, and character is not already stepping left, then set the character to step left
if (dbLeftKey()== 1 && MoveMode != Move_Left && dbDownKey() == 0 && dbUpKey() == 0 && dbRightKey() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Base, An_Left, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Base limb (with NO children) to Step Left
EnAn_oacAnimTransition( oacID, Limb_Pelvis, An_Left, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Pelvis limb (with NO children) to Step Left
EnAn_oacAnimTransition( oacID, Limb_Spine, An_Left, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine limb (with NO children) to Step Left
EnAn_oacAnimTransition( oacID, Limb_ThighRight, An_Left, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Right Thigh limb (with ALL children) to Step Left
EnAn_oacAnimTransition( oacID, Limb_ThighLeft, An_Left, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Left Thigh limb (with ALL children) to Step Left
EnAn_oacAnimTransition( oacID, Limb_Spine1, An_Left, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine1 limb (with NO children) to Step Left
MoveMode = Move_Left; //Set Move mode to Step Left
// If there is no action happening on the upper body, then it is ok to set the upper body to step left too.
if ( ActionMode == Action_None )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Left, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Step Left
}
}
// Run:
// If user presses the left key, and character is not already stepping left, then set the character to step left
if (dbDownKey()== 1 && MoveMode != Move_Run && dbLeftKey() == 0 && dbUpKey() == 0 && dbRightKey() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Base, An_Run, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Base limb (with NO children) to Run
EnAn_oacAnimTransition( oacID, Limb_Pelvis, An_Run, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Pelvis limb (with NO children) to Run
EnAn_oacAnimTransition( oacID, Limb_Spine, An_Run, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine limb (with NO children) to Run
EnAn_oacAnimTransition( oacID, Limb_ThighRight, An_Run, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Right Thigh limb (with ALL children) to Run
EnAn_oacAnimTransition( oacID, Limb_ThighLeft, An_Run, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Left Thigh limb (with ALL children) to Run
EnAn_oacAnimTransition( oacID, Limb_Spine1, An_Run, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine1 limb (with NO children) to Run
MoveMode = Move_Run; //Set Move mode to Run
// If there is no action happening on the upper body, then it is ok to set the upper body to Run too.
if ( ActionMode == Action_None )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Run, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Run
}
}
// STOPPING:
// If no movement keys are being pressed and character is not already stopped, then stop
if (dbDownKey()== 0 && dbLeftKey() == 0 && dbUpKey() == 0 && dbRightKey() == 0 && MoveMode != Move_Stand )
{
EnAn_oacAnimTransition( oacID, Limb_Base, An_Stand, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Base limb (with NO children) to Stop
EnAn_oacAnimTransition( oacID, Limb_Pelvis, An_Stand, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Pelvis limb (with NO children) to Stop
EnAn_oacAnimTransition( oacID, Limb_Spine, An_Stand, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine limb (with NO children) to Stop
EnAn_oacAnimTransition( oacID, Limb_ThighRight, An_Stand, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Right Thigh limb (with ALL children) to Stop
EnAn_oacAnimTransition( oacID, Limb_ThighLeft, An_Stand, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Left Thigh limb (with ALL children) to Stop
EnAn_oacAnimTransition( oacID, Limb_Spine1, An_Stand, 0, 0, -1, transTime, DoLoop, ExcChild ); //Set the Spine1 limb (with NO children) to Stop
MoveMode = Move_Stand; //Set Move mode to Stop
// If there is no action happening on the upper body, then it is ok to set the upper body to Stop too.
if ( ActionMode == Action_None )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Stand, 0, 0, -1, transTime, DoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Stop
}
}
// Action Animations
// -------------------------------------------------------------------------
// AIMING THE GUN
// If user presses the left mouse button and character is not already aiming the weapon, then aim
if ( dbMouseClick() == 1 && ActionMode != Action_Aim && dbSpaceKey() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Aim, 0, 0, -1, transTime, NoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Aim
ActionMode = Action_Aim; //Set Action mode to Aim
}
// RELOAD THE GUN
// If user presses the spacebar and character is not already reloading the weapon, then reload
if ( dbSpaceKey() == 1 && ActionMode != Action_Reload && dbMouseClick() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Reload, 0, 0, -1, transTime, NoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Aim
ActionMode = Action_Reload; //Set Action mode to Reload
}
// THROW
// If user presses the right mouse button and character is not already aiming the weapon, then aim
if ( dbMouseClick() == 2 && ActionMode != Action_Throw && dbSpaceKey() == 0 )
{
EnAn_oacAnimTransition( oacID, Limb_Spine2, An_Throw, 0, 0, -1, transTime, NoLoop, IncChild ); //Set the Spine2 limb (with ALL children) to Throw
ActionMode = Action_Throw; //Set Action mode to Throw
}
// NO ACTIONS
// If no action keys are being pressed and character is not already doing no actions, then join the upper body's animation with the movement animation
if ( dbMouseClick() == 0 && dbSpaceKey() == 0 && ActionMode != Action_None && EnAn_oacGetLimbTransIsActive(oacID, Limb_Base) == 0 )
{
//Get the current animation ID of what is playing on the lower body
CurrentAnim = EnAn_oacGetLimbPlayAnimID(oacID, Limb_Base);
//Get the current frame of the animation playing on the lower body
CurrentFrame = EnAn_oacGetCurrentFrame(oacID, Limb_Base);
EnAn_oacAnimTransition( oacID, Limb_Spine2, CurrentAnim, 0, CurrentFrame, -1, transTime, DoLoop, IncChild );
ActionMode = Action_None;
}
}
// Die
// -----------------------------------------
// If the player is alive and the returnkey is pressed, then kill the player
// If the player is dead and the returnkey is pressed then make the player get up
if ( dbReturnKey() == 1 )
{
dieKey = 1;
}
if ( dead == 0 ) //If the player is alive
{
if ( dbReturnKey() == 0 && dieKey == 1 )
{
dead = 1;
EnAn_oacAnimTransition( oacID, Limb_Base, An_Die, 0, 0, -1, transTime, NoLoop, IncChild );
ActionMode = Action_None;
MoveMode = Move_Die;
dieKey = 0;
}
}
else
{
if ( dbReturnKey() == 0 && dieKey == 1 && EnAn_oacGetLimbTransIsActive(oacID, Limb_Base) == 0 )
{
dead = 0;
EnAn_oacPlayAnim( oacID, Limb_Base, An_GetUp, 0, 0, -1, NoLoop, IncChild );
dieKey = 0;
}
}
dbText ( 0,0,dbStr(dbScreenFPS()) );
dbText ( 0,10, "Enhanced Animations for GDK" );
dbText ( 0,20, "Example 03: Limb Specific Animations" );
dbText ( 0,30, "By: Ron Erickson" );
dbText ( 0,40, "visit: www.GameToolshed.com" );
dbText ( 0,50, "----------------------------------------------------------------------------------" );
dbText ( 0,60, " This example shows different animations playing on different limbs of the same object!" );
dbText ( 0,70, " Movement:" );
dbText ( 0,80, " UPKEY = Walk, RIGHTKEY = Step Right, LEFTKEY = Step Left, DOWNKEY = Run" );
dbText ( 0,100, " Actions:" );
dbText ( 0,110, " LEFT MOUSE BUTTON = aim weapon, RIGHT MOUSE BUTTON = Throw, SPACEBAR = Reload" );
dbText ( 0,130, " ENTER to fall down, then ENTER again to get back up" );
dbText ( 0,140, " Rotate Character with 'a' and 's' keys" );
dbText ( 0,150, "----------------------------------------------------------------------------------" );
dbSync ( );
}
}
If it ain't broke.... DONT FIX IT !!!