445 lines
14 KiB
C++
445 lines
14 KiB
C++
#include <p3d/utility.hpp>
|
|
#include <p3d/matrixstack.hpp>
|
|
#include <p3d/anim/multicontroller.hpp>
|
|
#include <p3d/anim/compositedrawable.hpp>
|
|
#include <p3d/anim/animatedobject.hpp>
|
|
#include <p3d/anim/animate.hpp>
|
|
|
|
#include <toollib/chunks16/inc/tlStatePropChunk.hpp>
|
|
#include <toollib/inc/tlFile.hpp>
|
|
#include <toollib/inc/tlFileByteStream.hpp>
|
|
|
|
#include "stateprop.hpp"
|
|
#include "statepropdata.hpp"
|
|
|
|
CStateProp* CStateProp::CreateCStateProp( CStatePropData* statePropData , unsigned int state )
|
|
{
|
|
tAnimatedObjectFactory* objectFactory = statePropData->m_ObjectFactory;
|
|
|
|
if ( !objectFactory )
|
|
{
|
|
objectFactory = p3d::find<tAnimatedObjectFactory>( statePropData->m_FactoryName );
|
|
if ( objectFactory )
|
|
{
|
|
statePropData->m_ObjectFactory = objectFactory;
|
|
statePropData->m_ObjectFactory->AddRef();
|
|
}
|
|
}
|
|
|
|
if ( objectFactory )
|
|
{
|
|
tAnimatedObject* animatedObject = objectFactory->CreateObject(NULL);
|
|
CStateProp* stateProp = new CStateProp( animatedObject , statePropData , state );
|
|
return stateProp;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CStateProp::CStateProp( tAnimatedObject* animatedObject , CStatePropData* statePropData , unsigned int state ) :
|
|
m_StatePropData( NULL ),
|
|
m_AnimatedObject( NULL ),
|
|
m_BaseFrameController( NULL ),
|
|
m_StatePropListener( NULL ),
|
|
m_CurrentState( state )
|
|
{
|
|
//set state data
|
|
P3DASSERT( statePropData );
|
|
m_StatePropData = statePropData;
|
|
m_StatePropData->AddRef();
|
|
|
|
//set animated object
|
|
P3DASSERT( animatedObject );
|
|
m_AnimatedObject = animatedObject;
|
|
m_AnimatedObject->AddRef();
|
|
|
|
//base frame controller is run in milliseconds (ie the 1 is the timer)
|
|
m_BaseFrameController = new tMultiController(0 , 1000.f);
|
|
m_BaseFrameController->AddRef();
|
|
m_BaseFrameController->Reset();
|
|
|
|
//initilize transform
|
|
rmt::Matrix identity;
|
|
identity.Identity();
|
|
SetTransformationMatrix( identity );
|
|
|
|
//initialize the state
|
|
SetState( state );
|
|
}
|
|
|
|
CStateProp::~CStateProp()
|
|
{
|
|
if ( m_BaseFrameController )
|
|
m_BaseFrameController->Release();
|
|
if ( m_StatePropData )
|
|
m_StatePropData->Release();
|
|
if ( m_AnimatedObject )
|
|
m_AnimatedObject->Release();
|
|
}
|
|
|
|
void CStateProp::Update( float dt )
|
|
{
|
|
unsigned int i;
|
|
|
|
float lastFrame = m_BaseFrameController->GetFrame();
|
|
m_BaseFrameController->Advance( dt );
|
|
float newFrame = m_BaseFrameController->GetFrame();
|
|
|
|
//Check out transition
|
|
TransitionData tansdata = m_StatePropData->GetTransitionData( m_CurrentState );
|
|
if ( tansdata.autoTransition )
|
|
{
|
|
if (tansdata.onFrame >= lastFrame && tansdata.onFrame < newFrame)
|
|
{
|
|
SetState( tansdata.toState );
|
|
}
|
|
}
|
|
|
|
//Check callback events
|
|
if ( m_StatePropListener )
|
|
{
|
|
for ( i = 0; i < m_StatePropData->GetNumberOfCallbacks( m_CurrentState ); i++ )
|
|
{
|
|
CallbackData callbackData = m_StatePropData->GetCallbackData( m_CurrentState , i );
|
|
if ( callbackData.onFrame >= lastFrame && callbackData.onFrame < newFrame)
|
|
{
|
|
m_StatePropListener->RecieveEvent( callbackData.callbackID , this );
|
|
}
|
|
}
|
|
}
|
|
|
|
//update frame controllers
|
|
unsigned int numFrameControllers = GetNumberOfFrameControllers();
|
|
for ( i = 0; i < numFrameControllers; i++ )
|
|
{
|
|
FrameControllerData fcData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
|
|
|
|
//if we need to update
|
|
if ( fcData.minFrame != fcData.maxFrame )
|
|
{
|
|
tFrameController* fc = GetFrameControllerByIndex( i );
|
|
|
|
//if the min frame is greater than the max frame then reverse the update
|
|
if ( fcData.minFrame > fcData.maxFrame )
|
|
{
|
|
fc->Advance( -dt , false );
|
|
}
|
|
else
|
|
{
|
|
fc->Advance( dt , false );
|
|
}
|
|
|
|
if ( fcData.isCyclic && fcData.numberOfCycles > 0 )
|
|
{
|
|
unsigned int currentNumberOfCycles = fc->LastFrameReached();
|
|
if ( currentNumberOfCycles >= fcData.numberOfCycles )
|
|
{
|
|
fc->SetCycleMode( FORCE_NON_CYCLIC );
|
|
fc->SetFrame( fcData.maxFrame );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStateProp::Render()
|
|
{
|
|
p3d::stack->Push();
|
|
p3d::stack->Multiply( m_Transform );
|
|
|
|
m_AnimatedObject->Display();
|
|
|
|
p3d::stack->Pop();
|
|
}
|
|
|
|
void CStateProp::UpdateFrameControllersForRender()
|
|
{
|
|
unsigned int numFrameControllers = GetNumberOfFrameControllers();
|
|
for ( unsigned int i = 0; i < numFrameControllers; i++ )
|
|
{
|
|
GetFrameControllerByIndex( i )->Advance( 0.f , true );
|
|
}
|
|
}
|
|
|
|
unsigned int CStateProp::GetState()
|
|
{
|
|
return m_CurrentState;
|
|
}
|
|
|
|
void CStateProp::NextState()
|
|
{
|
|
if ( m_CurrentState + 1 >= m_StatePropData->GetNumberOfStates() )
|
|
{
|
|
SetState( 0 );
|
|
}
|
|
else
|
|
{
|
|
SetState( m_CurrentState + 1 );
|
|
}
|
|
}
|
|
|
|
void CStateProp::PrevState()
|
|
{
|
|
if ( m_CurrentState - 1 < 0 )
|
|
{
|
|
SetState( m_StatePropData->GetNumberOfStates() - 1 );
|
|
}
|
|
else
|
|
{
|
|
SetState( m_CurrentState - 1 );
|
|
}
|
|
}
|
|
|
|
void CStateProp::SetState( unsigned int state )
|
|
{
|
|
if ( state < m_StatePropData->GetNumberOfStates() && state >= 0 )
|
|
{
|
|
m_CurrentState = state;
|
|
}
|
|
|
|
m_BaseFrameController->SetFrame(0.f);
|
|
|
|
unsigned int i;
|
|
|
|
//reset the FC for new state
|
|
unsigned int numFrameControllers = GetNumberOfFrameControllers();
|
|
for ( i = 0; i < numFrameControllers; i++ )
|
|
{
|
|
FrameControllerData frameControllerData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
|
|
tFrameController* fc = GetFrameControllerByIndex(i);
|
|
|
|
//if we are holding a frame over from last state dont reset
|
|
if ( !frameControllerData.holdFrame )
|
|
{
|
|
//Reset() MUST come first or it will trounce frame ranges etc...
|
|
fc->Reset();
|
|
}
|
|
fc->SetRelativeSpeed( frameControllerData.relativeSpeed );
|
|
fc->SetCycleMode( (frameControllerData.isCyclic == 1) ? FORCE_CYCLIC : FORCE_NON_CYCLIC );
|
|
if ( frameControllerData.minFrame > frameControllerData.maxFrame )
|
|
{
|
|
fc->SetFrameRange( frameControllerData.maxFrame , frameControllerData.minFrame );
|
|
}
|
|
else
|
|
{
|
|
fc->SetFrameRange( frameControllerData.minFrame , frameControllerData.maxFrame );
|
|
}
|
|
|
|
if ( !frameControllerData.holdFrame )
|
|
{
|
|
fc->SetFrame( frameControllerData.minFrame );
|
|
}
|
|
}
|
|
|
|
//Set visibility for new state
|
|
unsigned int numElements = m_AnimatedObject->GetBaseObject()->GetNumDrawableElement();
|
|
for ( i = 0; i < numElements; i++ )
|
|
{
|
|
tCompositeDrawable::DrawableElement* de = GetDrawableElement(i);
|
|
|
|
de->SetLockVisibility(false);
|
|
VisibilityData visibilityData = m_StatePropData->GetVisibilityData( m_CurrentState , i );
|
|
bool visible = visibilityData.isVisible == 1;
|
|
de->SetVisibility( visible );
|
|
|
|
//lock visibility if visiblility if false
|
|
de->SetLockVisibility(!visible);
|
|
}
|
|
}
|
|
|
|
void CStateProp::OnEvent( unsigned int eventID )
|
|
{
|
|
unsigned int i;
|
|
unsigned int numEvents = m_StatePropData->GetNumberOfEvents( m_CurrentState );
|
|
for ( i = 0; i < numEvents; i++ )
|
|
{
|
|
EventData eventData = m_StatePropData->GetEventData( m_CurrentState , i );
|
|
if ( eventData.eventID == eventID )
|
|
{
|
|
SetState( eventData.toState );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStateProp::UpdateOnDataEdit()
|
|
{
|
|
//Update without reseting the current frame or current state info
|
|
unsigned int i;
|
|
|
|
//update frame controllers
|
|
unsigned int numFrameControllers = GetNumberOfFrameControllers();
|
|
for ( i = 0; i < numFrameControllers; i++ )
|
|
{
|
|
FrameControllerData frameControllerData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
|
|
tFrameController* fc = GetFrameControllerByIndex(i);
|
|
float frame = fc->GetFrame();
|
|
fc->Reset();
|
|
fc->SetRelativeSpeed( frameControllerData.relativeSpeed );
|
|
fc->SetCycleMode( (frameControllerData.isCyclic == 1) ? FORCE_CYCLIC : FORCE_NON_CYCLIC );
|
|
if ( frameControllerData.minFrame > frameControllerData.maxFrame )
|
|
{
|
|
fc->SetFrameRange( frameControllerData.maxFrame , frameControllerData.minFrame );
|
|
}
|
|
else
|
|
{
|
|
fc->SetFrameRange( frameControllerData.minFrame , frameControllerData.maxFrame );
|
|
}
|
|
|
|
fc->SetFrame( frame );
|
|
}
|
|
|
|
//set visibilites
|
|
unsigned int numDrawableElements = GetNumberOfDrawableElements();
|
|
for ( i = 0; i < numDrawableElements; i++ )
|
|
{
|
|
tCompositeDrawable::DrawableElement* de = GetDrawableElement(i);
|
|
|
|
de->SetLockVisibility(false);
|
|
VisibilityData visibilityData = m_StatePropData->GetVisibilityData( m_CurrentState , i );
|
|
bool visible = visibilityData.isVisible == 1;
|
|
de->SetVisibility( visible );
|
|
|
|
//lock visibility if visiblility if false
|
|
de->SetLockVisibility(!visible);
|
|
}
|
|
}
|
|
|
|
float CStateProp::GetBaseFrameControllerFrame()
|
|
{
|
|
return m_BaseFrameController->GetFrame();
|
|
}
|
|
|
|
CStatePropData* CStateProp::GetCStatePropData()
|
|
{
|
|
return m_StatePropData;
|
|
}
|
|
|
|
unsigned int CStateProp::GetNumberOfFrameControllers()
|
|
{
|
|
return m_AnimatedObject->GetCurrentAnimation()->GetNumFrameControllers();
|
|
}
|
|
|
|
tFrameController* CStateProp::GetFrameControllerByIndex( unsigned int i )
|
|
{
|
|
return m_AnimatedObject->GetCurrentAnimation()->GetFrameControllerByIndex(i);
|
|
}
|
|
|
|
unsigned int CStateProp::GetNumberOfDrawableElements()
|
|
{
|
|
return m_AnimatedObject->GetBaseObject()->GetNumDrawableElement();
|
|
}
|
|
|
|
tCompositeDrawable::DrawableElement* CStateProp::GetDrawableElement( unsigned int i )
|
|
{
|
|
return m_AnimatedObject->GetBaseObject()->GetDrawableElement( i );
|
|
}
|
|
|
|
const char* CStateProp::GetDrawableName( unsigned int i )
|
|
{
|
|
return m_AnimatedObject->GetBaseObject()->GetDrawableElement( i )->GetDrawable()->GetName();
|
|
}
|
|
|
|
const char* CStateProp::GetPropName( )
|
|
{
|
|
return GetName();
|
|
}
|
|
|
|
//Export the CStatePropData
|
|
void CStateProp::ExportChunk( const char* filename )
|
|
{
|
|
//create the outchunk data chunk
|
|
tlDataChunk* outchunk = new tlDataChunk;
|
|
|
|
//create smart prop chunk
|
|
char buf[256];
|
|
tlStatePropChunk* statepropchunk = new tlStatePropChunk;
|
|
|
|
//version one has extra floats and ints
|
|
statepropchunk->SetVersion( 1 );
|
|
|
|
statepropchunk->SetName( m_StatePropData->GetName() );
|
|
statepropchunk->SetObjectFactoryName( m_StatePropData->GetName() );
|
|
statepropchunk->SetNumStates( m_StatePropData->GetNumberOfStates() );
|
|
|
|
unsigned int state;
|
|
int j;
|
|
//create state subchunks
|
|
for ( state = 0; state < m_StatePropData->GetNumberOfStates(); state++ )
|
|
{
|
|
tlStatePropStateDataChunk* statechunk = new tlStatePropStateDataChunk;
|
|
sprintf(buf, "state%i", state );
|
|
statechunk->SetName( buf );
|
|
TransitionData tData = m_StatePropData->GetTransitionData( state );
|
|
statechunk->SetAutoTransition( tData.autoTransition );
|
|
statechunk->SetOutFrame( tData.onFrame );
|
|
statechunk->SetOutState( tData.toState );
|
|
|
|
int numDrawables = GetNumberOfDrawableElements();
|
|
statechunk->SetNumDrawables( numDrawables );
|
|
for ( j = 0; j < numDrawables; j++ )
|
|
{
|
|
tlStatePropVisibilitiesDataChunk* visibilitychunk = new tlStatePropVisibilitiesDataChunk;
|
|
VisibilityData vData = m_StatePropData->GetVisibilityData( state , j );
|
|
visibilitychunk->SetName( GetDrawableElement(j)->GetDrawable()->GetName() );
|
|
visibilitychunk->SetVisible( vData.isVisible );
|
|
statechunk->AppendSubChunk( visibilitychunk );
|
|
}
|
|
|
|
int numFrameControllers = GetNumberOfFrameControllers();
|
|
statechunk->SetNumFrameControllers( numFrameControllers );
|
|
for ( j = 0; j < numFrameControllers; j++ )
|
|
{
|
|
tlStatePropFrameControllerDataChunk* framecontrollerchunk = new tlStatePropFrameControllerDataChunk;
|
|
FrameControllerData fData = m_StatePropData->GetFrameControllerData( state , j );
|
|
framecontrollerchunk->SetName( GetFrameControllerByIndex(j)->GetName() );
|
|
framecontrollerchunk->SetCyclic( fData.isCyclic );
|
|
framecontrollerchunk->SetMinFrame( fData.minFrame );
|
|
framecontrollerchunk->SetMaxFrame( fData.maxFrame );
|
|
framecontrollerchunk->SetRelativeSpeed( fData.relativeSpeed );
|
|
framecontrollerchunk->SetHoldFrame( fData.holdFrame );
|
|
framecontrollerchunk->SetNumberOfCycles( fData.numberOfCycles );
|
|
statechunk->AppendSubChunk( framecontrollerchunk );
|
|
}
|
|
|
|
int numEvents = m_StatePropData->GetNumberOfEvents( state );
|
|
statechunk->SetNumEvents( numEvents );
|
|
for ( j = 0; j < numEvents; j++ )
|
|
{
|
|
tlStatePropEventDataChunk* eventdatachunk = new tlStatePropEventDataChunk;
|
|
EventData eData = m_StatePropData->GetEventData( state , j );
|
|
eventdatachunk->SetName( eData.eventName );
|
|
eventdatachunk->SetState( eData.toState );
|
|
eventdatachunk->SetEventEnum( eData.eventID );
|
|
statechunk->AppendSubChunk( eventdatachunk );
|
|
}
|
|
|
|
int numCallbacks = m_StatePropData->GetNumberOfCallbacks( state );
|
|
statechunk->SetNumCallbacks( numCallbacks );
|
|
for ( j = 0; j < numCallbacks; j++ )
|
|
{
|
|
tlStatePropCallbackDataChunk* callbackChunk = new tlStatePropCallbackDataChunk;
|
|
CallbackData cData = m_StatePropData->GetCallbackData( state , j );
|
|
callbackChunk->SetName( cData.callbackName );
|
|
callbackChunk->SetOnFrame( cData.onFrame );
|
|
callbackChunk->SetEventEnum( cData.callbackID );
|
|
statechunk->AppendSubChunk( callbackChunk );
|
|
}
|
|
|
|
//append the sate chunk
|
|
statepropchunk->AppendSubChunk( statechunk );
|
|
}
|
|
|
|
outchunk->AppendSubChunk( statepropchunk );
|
|
|
|
// create the new output file
|
|
tlFile output(new tlFileByteStream(filename,omWRITE), tlFile::CHUNK32);
|
|
|
|
if(!output.IsOpen())
|
|
{
|
|
printf("Could not open %s for writing\n", filename);
|
|
return ;
|
|
}
|
|
|
|
outchunk->Write(&output);
|
|
output.Close();
|
|
} |