879 lines
22 KiB
C++
879 lines
22 KiB
C++
/*===========================================================================
|
|
Workspace.cpp - Pure3D testbed
|
|
|
|
|
|
Copyright (c) 1995-1999 Radical Entertainment, Inc.
|
|
All rights reserved.
|
|
===========================================================================*/
|
|
#include <windows.h>
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <typeinfo.h>
|
|
#include <ctype.h> //for isdigit
|
|
#include <stdlib.h> //for atoi
|
|
|
|
#include <p3d/pure3d.hpp>
|
|
#include <p3d/anim/animatedobject.hpp>
|
|
#include <p3d/anim/poseanimation.hpp>
|
|
#include <p3d/anim/skeleton.hpp>
|
|
#include <p3d/geometry.hpp>
|
|
#include <p3d/anim/polyskin.hpp>
|
|
#include <p3d/utility.hpp>
|
|
#include <p3d/drawable.hpp>
|
|
|
|
#include <simcommon/simutility.hpp>
|
|
#include <simcommon/simenvironment.hpp> // for SimUnits
|
|
#include <simcommon/simulatedobject.hpp>
|
|
#include <simcollision/collisionmanager.hpp>
|
|
#include <simcollision/collisiondisplay.hpp>
|
|
#include <simcollision/proximitydetection.hpp>
|
|
|
|
#include <sp/interface.hpp>
|
|
#include "workspace.hpp"
|
|
|
|
#include "stateprop.hpp"
|
|
#include "statepropdata.hpp"
|
|
|
|
void RegisterExtraChunks(void)
|
|
{ //do nothing
|
|
}
|
|
|
|
bool g_DrawCollision = true;
|
|
bool g_IsPaused = false;
|
|
bool g_DebugPhysicsDisplay = false;
|
|
float g_TotalTime_sec = 0.f;
|
|
|
|
const char c_StatePropExtension[] = "_spdata.p3d";
|
|
|
|
|
|
Workspace* g_Workspace = NULL;
|
|
CStateProp* g_CStateProp = NULL;
|
|
|
|
template <class T> class TemplateIterator : public ViewerIterator
|
|
{
|
|
public:
|
|
TemplateIterator(T* t)
|
|
{
|
|
iterator = t;
|
|
current = iterator->First();
|
|
}
|
|
|
|
~TemplateIterator()
|
|
{
|
|
delete iterator;
|
|
}
|
|
|
|
tEntity* First(void)
|
|
{
|
|
current = iterator->First();
|
|
|
|
return current;
|
|
}
|
|
|
|
tEntity* Current(void)
|
|
{
|
|
if(!current)
|
|
current = iterator->First();
|
|
|
|
return current;
|
|
}
|
|
|
|
tEntity* Next(bool loop = false)
|
|
{
|
|
current = iterator->Next();
|
|
if(loop && !current)
|
|
current = iterator->First();
|
|
return current;
|
|
}
|
|
|
|
tEntity* Prev(void)
|
|
{
|
|
current = iterator->Prev();
|
|
if(!current)
|
|
current = iterator->Last();
|
|
return current;
|
|
|
|
}
|
|
|
|
private:
|
|
T* iterator;
|
|
tEntity* current;
|
|
};
|
|
|
|
class DrawIterator : public tInventory::Iterator<tDrawable> {};
|
|
class ObjectFactoryIterator : public tInventory::Iterator<tAnimatedObjectFactory> {};
|
|
class CStatePropDataIterator : public tInventory::Iterator<CStatePropData> {};
|
|
|
|
|
|
//Get allocated memory
|
|
unsigned int GetAllocatedMemory()
|
|
{
|
|
// on windows can't rely on the total physical memory so we must walk over
|
|
// each heap and accumulate all the memory allocated in it. there is stack
|
|
// overhead too but that should be minimal.
|
|
HANDLE heaps[128];
|
|
|
|
int numHeaps = GetProcessHeaps(sizeof(heaps)/sizeof(heaps[0]), heaps);
|
|
if(numHeaps > sizeof(heaps)/sizeof(heaps[0]))
|
|
{
|
|
numHeaps = sizeof(heaps)/sizeof(heaps[0]);
|
|
}
|
|
|
|
unsigned int total = 0;
|
|
int i;
|
|
for(i=0; i<numHeaps; i++)
|
|
{
|
|
PROCESS_HEAP_ENTRY heapEntry;
|
|
|
|
heapEntry.lpData = NULL;
|
|
if(!HeapLock(heaps[i]))
|
|
{
|
|
//HC_DEBUGPRINT(("could not lock heap %d", i));
|
|
continue;
|
|
}
|
|
while(HeapWalk(heaps[i], &heapEntry))
|
|
{
|
|
if(heapEntry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
|
|
{
|
|
// don't count non-committed pages as some of pure3d seems to
|
|
// mmap or allocate large ranges that never actually get paged
|
|
// in
|
|
//total += heapEntry.cbData;
|
|
}
|
|
else
|
|
{
|
|
total += heapEntry.cbData;
|
|
}
|
|
}
|
|
HeapUnlock(heaps[i]);
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Workspace class
|
|
// derive from Testbed.
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
Workspace::Workspace() :
|
|
m_CStateProp(NULL),
|
|
m_CollisionManager(NULL),
|
|
m_CollisionSolver(NULL),
|
|
m_DrawableFloor(NULL),
|
|
m_SimStateFloor(NULL)
|
|
{
|
|
sim::InstallSimLoaders();
|
|
|
|
//draw outlines for debug render
|
|
sim::SetDrawVolumeMethod( sim::DrawVolumeShape );
|
|
|
|
Init();
|
|
}
|
|
|
|
|
|
Workspace::~Workspace()
|
|
{
|
|
ResetAll();
|
|
|
|
if ( m_CStateProp )
|
|
m_CStateProp->Release();
|
|
|
|
p3d::loadManager->RemoveAllHandlers(); // should be in testbed
|
|
}
|
|
|
|
void Workspace::Init()
|
|
{
|
|
// get path to exe
|
|
GetModuleFileName(NULL, m_Path, sizeof(m_Path) - 1);
|
|
m_Path[ strlen(m_Path) - 13 ] = '\0';
|
|
|
|
m_DrawableIterator = new TemplateIterator<DrawIterator>(new DrawIterator);
|
|
m_ObjectFactoryIterator = new TemplateIterator<ObjectFactoryIterator>(new ObjectFactoryIterator);
|
|
m_CStatePropDataIterator = new TemplateIterator<CStatePropDataIterator>(new CStatePropDataIterator);
|
|
|
|
// install loader for Prop
|
|
tP3DFileHandler* p3d = p3d::loadManager->GetP3DHandler();
|
|
if(p3d)
|
|
{
|
|
p3d->AddHandler( new CStatePropDataLoader );
|
|
}
|
|
|
|
if (!sim::SimUnits::UnitSet())
|
|
{
|
|
sim::InitializeSimulation( sim::MetersUnits );
|
|
}
|
|
|
|
if (!m_CollisionManager)
|
|
{
|
|
float MAX_UPDATEAI_TIME_ms = 1000.0f*1.0f/30.0f; // 30 fps
|
|
//sim::SimulatedObject::SetMaxTimeStep(MAX_UPDATEAI_TIME_ms/1000.0f);
|
|
float collisionDistanceCGS = 2.0f; // cm
|
|
m_CollisionManager = sim::CollisionManager::GetInstance();
|
|
m_CollisionManager->AddRef();
|
|
sim::SimEnvironment* simEnvironment = sim::SimEnvironment::GetDefaultSimEnvironment();
|
|
simEnvironment->SetCollisionDistanceCGS(collisionDistanceCGS);
|
|
m_CollisionManager->SetCollisionManagerAttributes( sim::CM_DetectAll | sim::CM_SolveAll );
|
|
|
|
P3DASSERT(m_CollisionSolver == NULL);
|
|
m_CollisionSolver = new AICollisionSolverAgent();
|
|
m_CollisionSolver->AddRef();
|
|
m_CollisionManager->GetImpulseBasedCollisionSolver()->SetCollisionSolverAgent(m_CollisionSolver);
|
|
}
|
|
}
|
|
|
|
void Workspace::LoadFloor( const char* p3dfilename )
|
|
{
|
|
if ( m_DrawableFloor )
|
|
m_DrawableFloor->Release();
|
|
|
|
if ( m_SimStateFloor )
|
|
m_SimStateFloor->Release();
|
|
|
|
//check that a data file exist
|
|
FILE* p = fopen( p3dfilename , "r" );
|
|
if ( p )
|
|
{
|
|
p3d::inventory->RemoveAllElements();
|
|
|
|
(void) p3d::load(p3dfilename);
|
|
|
|
m_DrawableFloor = p3d::find<tDrawable>("floorShape");
|
|
if ( m_DrawableFloor )
|
|
m_DrawableFloor->AddRef();
|
|
|
|
fclose(p);
|
|
}
|
|
}
|
|
|
|
void Workspace::ResetAll(bool emptyInventory)
|
|
{
|
|
if (emptyInventory)
|
|
{
|
|
delete m_DrawableIterator;
|
|
delete m_ObjectFactoryIterator;
|
|
delete m_CStatePropDataIterator;
|
|
|
|
p3d::inventory->RemoveAllElements();
|
|
}
|
|
|
|
ResetProp();
|
|
|
|
|
|
if ( m_CollisionSolver )
|
|
{
|
|
m_CollisionSolver->Release();
|
|
m_CollisionSolver = NULL;
|
|
}
|
|
|
|
if ( m_CollisionManager )
|
|
{
|
|
m_CollisionManager->ResetAll();
|
|
m_CollisionManager->Release();
|
|
m_CollisionManager = NULL;
|
|
}
|
|
|
|
this->Init();
|
|
}
|
|
|
|
void Workspace::Advance(float dt_ms)
|
|
{
|
|
g_TotalTime_sec += dt_ms / 1000.f;
|
|
float inDt_Sec = dt_ms / 1000.f;
|
|
|
|
if ( !g_IsPaused )
|
|
{
|
|
if ( m_CStateProp )
|
|
{
|
|
m_CStateProp->Update(dt_ms);
|
|
}
|
|
if ( m_CollisionManager )
|
|
{
|
|
m_CollisionManager->Update( inDt_Sec , g_TotalTime_sec );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Workspace::Display(tContext* context)
|
|
{
|
|
if ( m_DrawableFloor )
|
|
{
|
|
m_DrawableFloor->Display();
|
|
}
|
|
|
|
if ( m_CStateProp )
|
|
{
|
|
m_CStateProp->UpdateFrameControllersForRender();
|
|
m_CStateProp->Render();
|
|
}
|
|
|
|
if ( g_DrawCollision )
|
|
{
|
|
sim::DisplayCollisionObjects(sim::CollisionManager::GetInstance());
|
|
}
|
|
}
|
|
|
|
void Workspace::ResetProp()
|
|
{
|
|
if ( m_CStateProp )
|
|
{
|
|
m_CStateProp->Release();
|
|
}
|
|
|
|
m_CStateProp = NULL;
|
|
g_CStateProp = NULL;
|
|
}
|
|
|
|
int Workspace::Load( const char* name )
|
|
{
|
|
ResetAll();
|
|
|
|
(void) p3d::load(name);
|
|
|
|
//Search for object factories
|
|
m_ObjectFactoryIterator->First();
|
|
m_CStatePropDataIterator->First();
|
|
|
|
if ( m_ObjectFactoryIterator->Current() && m_CStatePropDataIterator->Current() )
|
|
{
|
|
//if we have an objectfactory and a prop we are good (1 file with all chunks)
|
|
CStatePropData* statePropData = ((CStatePropData*)m_CStatePropDataIterator->Current());
|
|
m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
|
|
m_CStateProp->AddRef();
|
|
}
|
|
else if( m_ObjectFactoryIterator->Current() )
|
|
{
|
|
//if we just have the factory we need the file with the prop data so load it
|
|
char buf[256];
|
|
memcpy( buf , name , strlen(name) - strlen(".p3d") );
|
|
buf[strlen(name) - strlen(".p3d")] = '\0';
|
|
strcat(buf , c_StatePropExtension );
|
|
|
|
//check that a data file exist
|
|
FILE* p = fopen( buf , "r" );
|
|
if ( p )
|
|
{
|
|
(void) p3d::load(buf);
|
|
|
|
m_CStatePropDataIterator->First();
|
|
if ( m_CStatePropDataIterator->Current() )
|
|
{
|
|
//if we have an objectfactory and a prop we are good (1 file with all chunks)
|
|
CStatePropData* statePropData = ((CStatePropData*)m_CStatePropDataIterator->Current());
|
|
m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
|
|
m_CStateProp->AddRef();
|
|
}
|
|
fclose(p);
|
|
}
|
|
else
|
|
{
|
|
//Create a new prop
|
|
CStatePropData* statePropData = new CStatePropData( (tAnimatedObjectFactory*)m_ObjectFactoryIterator->Current() );
|
|
if ( statePropData )
|
|
{
|
|
m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
|
|
m_CStateProp->AddRef();
|
|
}
|
|
}
|
|
}
|
|
else if( m_CStatePropDataIterator->Current() )
|
|
{
|
|
//if we just have the prop we need the file with the factory
|
|
char buf[256];
|
|
memcpy( buf , name , strlen(name) - strlen(c_StatePropExtension) );
|
|
buf[strlen(name) - strlen(c_StatePropExtension)] = '\0';
|
|
strcat(buf , ".p3d");
|
|
|
|
//check that a data file exist
|
|
FILE* p = fopen( buf , "r" );
|
|
if ( p )
|
|
{
|
|
(void) p3d::load(buf);
|
|
|
|
m_ObjectFactoryIterator->First();
|
|
if ( m_ObjectFactoryIterator->Current() )
|
|
{
|
|
CStatePropData* statePropData = ((CStatePropData*)m_CStatePropDataIterator->Current());
|
|
m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
|
|
m_CStateProp->AddRef();
|
|
}
|
|
fclose(p);
|
|
}
|
|
else
|
|
{
|
|
//no file associated with this prop data...
|
|
ResetAll();
|
|
}
|
|
}
|
|
|
|
if ( m_CStateProp )
|
|
{
|
|
g_CStateProp = m_CStateProp;
|
|
}
|
|
else
|
|
{
|
|
g_CStateProp = NULL;
|
|
}
|
|
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// CStateProp - DLL interface
|
|
//=============================================================================
|
|
//Load a pure3D file with art for the background===============================
|
|
int SP_CALLCONV SPLoadBackground( const char* filename )
|
|
{
|
|
if ( g_Workspace )
|
|
{
|
|
g_Workspace->LoadFloor( filename );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Load pure3D file ============================================================
|
|
int SP_CALLCONV SPLoad( const char* filename )
|
|
{
|
|
if ( g_Workspace )
|
|
{
|
|
g_Workspace->Load( filename );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Export the SmartPropData ====================================================
|
|
int SP_CALLCONV SPExportStatePropData( const char* filename )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
char buf[256];
|
|
memcpy( buf , filename , strlen(filename) - strlen(".p3d") );
|
|
buf[strlen(filename) - strlen(".p3d")] = '\0';
|
|
strcat( buf , c_StatePropExtension );
|
|
g_CStateProp->ExportChunk( buf );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Display collision ==========================================================
|
|
int SP_CALLCONV SPShowCollision( int show )
|
|
{
|
|
g_DrawCollision = ( show == 1 );
|
|
return 1;
|
|
}
|
|
|
|
//Prop name ===================================================================
|
|
const char* SP_CALLCONV SPGetPropName()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetCStatePropData()->GetName();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//advance ====================================================================
|
|
int SP_CALLCONV SPPause( bool b )
|
|
{
|
|
g_IsPaused = b;
|
|
return 1;
|
|
}
|
|
int SP_CALLCONV SPAdvanceOneFrame()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->Update( 100.f );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPBackOneFrame()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->Update( -100.f );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// State Data =================================================================
|
|
unsigned int SP_CALLCONV SPGetNumberOfStates()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetCStatePropData()->GetNumberOfStates();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int SP_CALLCONV SPInsertState( unsigned int state )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->InsertState( state );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPDeleteState( unsigned int state )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->DeleteState( state );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int SP_CALLCONV SPGetCurrentState()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetState();
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPNextState()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->NextState();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPPrevState()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->PrevState();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetState( unsigned int state )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->SetState( state );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Transition Data =============================================================
|
|
bool SP_CALLCONV SPGetTransitionData( int state , TransitionData* transitionData )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
transitionData->autoTransition = g_CStateProp->GetCStatePropData()->GetTransitionData( state ).autoTransition;
|
|
transitionData->onFrame = g_CStateProp->GetCStatePropData()->GetTransitionData( state ).onFrame;
|
|
transitionData->toState = g_CStateProp->GetCStatePropData()->GetTransitionData( state ).toState;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
int SP_CALLCONV SPSetAutoTransition( int state, bool b )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetAutoTransition( state , b );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetAutoTransitionOnFrame( int state, float onFrame )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetAutoTransitionOnFrame( state , onFrame );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetAutoTransitionToState( int state, int toState )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetAutoTransitionToState( state , toState );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Visibility Data =============================================================
|
|
bool SP_CALLCONV SPGetVisibilityData( int state , int index , VisibilityData* visibilityData )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
visibilityData->isVisible = g_CStateProp->GetCStatePropData()->GetVisibilityData( state , index ).isVisible;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
int SP_CALLCONV SPSetVisible( int state , int index , bool b )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetVisible( state , index , b );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetAllVisibilities( int state , bool b )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetAllVisibilities( state , b );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPShowAll(int state)
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->ShowAll( state );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPHideAll(int state)
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->HideAll( state );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
SP_IMPORT int SP_CALLCONV SPGetNumDrawables()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetNumberOfDrawableElements();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char* SP_CALLCONV SPGetDrawableName( int index )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetDrawableName( index );
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//Frame Controller Data =======================================================
|
|
bool SPGetFrameControllerData( int state, int fc , FrameControllerData* fcData )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
fcData->holdFrame = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).holdFrame;
|
|
fcData->isCyclic = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).isCyclic;
|
|
fcData->maxFrame = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).maxFrame;
|
|
fcData->minFrame = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).minFrame;
|
|
fcData->numberOfCycles = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).numberOfCycles;
|
|
fcData->relativeSpeed = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).relativeSpeed;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
int SP_CALLCONV SPSetCyclic( int state ,int fc, bool isCyclic )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetCyclic( state , fc , isCyclic );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetRelativeSpeed( int state ,int fc, float speed )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetRelativeSpeed( state , fc , speed );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetFrameRange( int state ,int fc, float min, float max )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetFrameRange( state , fc , min , max );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetHoldFrame( int state , int fc , bool holdFrame )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetHoldFrame( state , fc , holdFrame );
|
|
g_CStateProp->UpdateOnDataEdit();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPSetNumberOfCycles( int state , int fc , unsigned int numberOfCycles )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->SetNumberOfCycles( state , fc , numberOfCycles );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int SP_CALLCONV SPGetNumFrameControllers()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetNumberOfFrameControllers();
|
|
}
|
|
return 0;
|
|
}
|
|
float SP_CALLCONV SPGetBaseFrameControllerFrame()
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetBaseFrameControllerFrame();
|
|
}
|
|
return 0.f;
|
|
}
|
|
float SP_CALLCONV SPGetFrameControllerFrame( int index )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetFrameControllerByIndex( index )->GetFrame();
|
|
}
|
|
return 0.f;
|
|
}
|
|
const char* SP_CALLCONV SPGetFrameControllerName( int index )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetFrameControllerByIndex( index )->GetName();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//Event Data ==================================================================
|
|
unsigned int SP_CALLCONV SPGetNumberOfEvents( int state )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetCStatePropData()->GetNumberOfEvents( state );
|
|
}
|
|
return 0;
|
|
}
|
|
bool SP_CALLCONV SPGetEventData( int state , int eventindex , EventData *eventData)
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
EventData ed = g_CStateProp->GetCStatePropData()->GetEventData( state , eventindex );
|
|
eventData->eventID = ed.eventID;
|
|
strcpy( eventData->eventName , ed.eventName );
|
|
eventData->toState = ed.toState;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
int SP_CALLCONV SPAddEvent( const char* event , int eventEnum , int toState , int fromState )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->AddEvent( event , eventEnum , toState , fromState );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPEditEvent( int state, int EventIndex, char* eventName, int eventEnum , int toState )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->EditEvent( state , EventIndex , eventName , eventEnum , toState );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPDeleteEvent( int fromState , int index )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->DeleteEvent( fromState , index );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Callback Data ===============================================================
|
|
unsigned int SP_CALLCONV SPGetNumberOfCallbacks( int state )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
return g_CStateProp->GetCStatePropData()->GetNumberOfCallbacks( state );
|
|
}
|
|
return 0;
|
|
}
|
|
bool SP_CALLCONV SPGetCallbackData( int state , int index , CallbackData* callbackData )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
callbackData->callbackID = g_CStateProp->GetCStatePropData()->GetCallbackData( state , index ).callbackID;
|
|
strcpy( callbackData->callbackName , g_CStateProp->GetCStatePropData()->GetCallbackData( state , index ).callbackName );
|
|
callbackData->onFrame = g_CStateProp->GetCStatePropData()->GetCallbackData( state , index ).onFrame;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
int SP_CALLCONV SPAddCallback( int state , const char* event , int eventEnum , float frame )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->AddCallback( state , event , eventEnum , frame );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPEditCallback( int state, int CBIndex, char* eventname, int eventEnum , float frame )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->EditCallback( state , CBIndex , eventname , eventEnum , frame );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int SP_CALLCONV SPDeleteCallback( int state , int index )
|
|
{
|
|
if ( g_CStateProp )
|
|
{
|
|
g_CStateProp->GetCStatePropData()->DeleteCallback( state , index );
|
|
return 1;
|
|
}
|
|
return 0;
|
|
} |