summaryrefslogtreecommitdiffstats
path: root/tools/statepropbuilder/src/stateprop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/statepropbuilder/src/stateprop.cpp')
-rw-r--r--tools/statepropbuilder/src/stateprop.cpp299
1 files changed, 299 insertions, 0 deletions
diff --git a/tools/statepropbuilder/src/stateprop.cpp b/tools/statepropbuilder/src/stateprop.cpp
new file mode 100644
index 0000000..fed8204
--- /dev/null
+++ b/tools/statepropbuilder/src/stateprop.cpp
@@ -0,0 +1,299 @@
+#include <p3d/utility.hpp>
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/anim/compositedrawable.hpp>
+#include <p3d/anim/animatedobject.hpp>
+#include <p3d/anim/animate.hpp>
+
+#include "stateprop/stateprop.hpp"
+#include "stateprop/statepropdata.hpp"
+
+CStateProp* CStateProp::CreateStateProp( CStatePropData* statePropData , unsigned int state )
+{
+ tAnimatedObjectFactory* objectFactory = statePropData->GetAnimatedObjectFactory();
+
+ P3DASSERT( objectFactory );
+
+ if ( objectFactory )
+ {
+ tAnimatedObject* animatedObject = objectFactory->CreateObject(NULL);
+ CStateProp* stateProp = new CStateProp( animatedObject , statePropData , state );
+ stateProp->SetName( statePropData->GetName() );
+ return stateProp;
+ }
+
+ return NULL;
+}
+
+CStateProp::CStateProp( tAnimatedObject* animatedObject , CStatePropData* statePropData , unsigned int state ) :
+ m_StatePropData( NULL ),
+ m_AnimatedObject( NULL ),
+ m_BaseFrameController( NULL ),
+ m_CurrentState( state ),
+ m_NumStatePropListeners( 0 )
+{
+ //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();
+
+ //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_NumStatePropListeners > 0 )
+ {
+ 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)
+ {
+ unsigned int i;
+ for ( i = 0; i < m_NumStatePropListeners; i++ )
+ {
+ m_StatePropListener[i]->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::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);
+ }
+
+ //notify listeners of a state change
+ for ( i = 0; i < m_NumStatePropListeners; i++ )
+ {
+ m_StatePropListener[i]->RecieveEvent( STATEPROP_CHANGE_STATE_EVENT , this );
+ }
+}
+
+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::AddStatePropListener( CStatePropListener* statePropListener )
+{
+ if ( m_NumStatePropListeners < MAX_LISTENERS )
+ {
+ m_StatePropListener[m_NumStatePropListeners] = statePropListener;
+ m_NumStatePropListeners++;
+ }
+}
+void CStateProp::RemoveStatePropListener( CStatePropListener* statePropListener )
+{
+ unsigned int i = 0;
+ //find this entry
+ for ( i = 0; i < m_NumStatePropListeners; i++ )
+ {
+ if ( m_StatePropListener[i] == statePropListener )
+ {
+ m_NumStatePropListeners--;
+ break;
+ }
+ }
+
+ //copy other entries back over
+ for ( i; i < m_NumStatePropListeners; i++ )
+ {
+ m_StatePropListener[i] = m_StatePropListener[i+1];
+ }
+}
+
+tDrawable* CStateProp::GetDrawable()
+{
+ return m_AnimatedObject->GetBaseObject();
+}
+
+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 );
+}