//=========================================================================== // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // Component: AnimDynaPhysLoader // // Description: Loader for instanced, animated, dynaphys DSG objects // // Authors: Michael Riegger // //=========================================================================== //--------------------------------------------------------------------------- // Includes //=========================================================================== #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
#include #ifndef RAD_RELEASE #include #endif //=========================================================================== // Local Constants, Typedefs, and Macros //=========================================================================== Map< tUID, tUID > AnimDynaPhysLoader::s_ShadowList; //=========================================================================== // Global Data, Local Data, Local Classes //=========================================================================== //=========================================================================== // Member Functions //=========================================================================== //=========================================================================== // AnimDynaPhysLoader::AnimDynaPhysLoader //=========================================================================== // Description: // AnimDynaPhysLoader ctor // // Constraints: // // Parameters: // // // Return: // //=========================================================================== AnimDynaPhysLoader::AnimDynaPhysLoader() : tSimpleChunkHandler(SRR2::ChunkID::INSTA_ANIM_DYNA_PHYS_DSG) { mpListenerCB = NULL; mUserData = -1; if ( s_ShadowList.capacity() == 0 ) { s_ShadowList.reserve( 20 ); } } //=========================================================================== // AnimDynaPhysLoader::~AnimDynaPhysLoader //=========================================================================== // Description: // AnimDynaPhysLoader dtor // // Constraints: // // Parameters: // // // Return: // //=========================================================================== AnimDynaPhysLoader::~AnimDynaPhysLoader() { } //=========================================================================== // AnimDynaPhysLoader::LoadObject //=========================================================================== // Description: // Loads an InstAnimDynaPhysDSG chunk and creates all the instances // // Constraints: // Expecting file format to be: // string name (max size 255) // long version // long hasalpha flag // // // Parameters: // Chunk file, and store // // Return: // NULL, no final chunk going specifically into the inventory via return // //=========================================================================== tEntity* AnimDynaPhysLoader::LoadObject(tChunkFile* file, tEntityStore* store) { IEntityDSG::msDeletionsSafe=true; // Grab the name char typeName[255]; file->GetPString(typeName); // Quick test to see if we are dealing with an animated BV object int simAnimJoint = -1; if ( strstr ( typeName, "crate" ) != NULL ) simAnimJoint = 3; else if ( strstr ( typeName, "vending" ) != NULL ) simAnimJoint = 1; else if ( strstr ( typeName, "l2_monkiesgag" ) != NULL ) simAnimJoint = 1; else if ( strstr ( typeName, "l7_spider" ) != NULL ) simAnimJoint = 1; #ifndef RAD_RELEASE PropStats::StartTracking(typeName); #endif int instanceCount = 0; // Grab version info int version = file->GetLong(); // Grab the flag that tell us whether or not the object has alpha or not int hasAlpha = file->GetLong(); // Does this chunk contain a subchunk for instances bool foundInstances = false; bool persistance = true; // Is this object a global entity (i.e. is it loaded once at level startup and // all subsequent instances are cloned off this thing?) StatePropDSG* globalStatepropEntity = static_cast(GetAllWrappers()->GetGlobalEntity(tName::MakeUID(typeName))); if(strstr(typeName, "phonestop_Shape")) { persistance = false; } bool haveGlobal = globalStatepropEntity != 0; #ifndef RAD_RELEASE if ( haveGlobal ) { rAssert( dynamic_cast< StatePropDSG* >( globalStatepropEntity ) != NULL ); } #endif CollisionAttributes* pCollAttr = NULL; AnimDynaPhysWrapper* pWrappedObject = NULL; // Is this a mission prop? bool isMissionProp = IsMissionProp( typeName ); while( file->ChunksRemaining() ) { file->BeginChunk(); switch(file->GetCurrentID()) { case SRR2::ChunkID::ANIM_OBJ_DSG_WRAPPER: // We are loading a stateprop { if(!haveGlobal) { HeapMgr()->PushHeap( GMA_TEMP ); AnimObjDSGWrapperLoader* pObjWrapperLoader = new AnimObjDSGWrapperLoader; HeapMgr()->PopHeap( GMA_TEMP ); pWrappedObject = (AnimDynaPhysWrapper*) pObjWrapperLoader->LoadObject( file, store ); pWrappedObject->AddRef (); pObjWrapperLoader->ReleaseVerified(); } m_IsStateProp = true; } break; case SRR2::ChunkID::ANIM_DSG_WRAPPER: { if(!haveGlobal) { // This is the wrapped object and contains a whole load of crap, meshes, comp drawables, billboards // load them all // Format of the wrapped object is // string name // ULONG version // ULONG hasalpha // pWrappedObject = new (GMA_TEMP ) WrappedObject; // LoadAnimWrapper( file, store, pWrappedObject ); HeapMgr()->PushHeap( GMA_TEMP ); AnimDynaPhysWrapperLoader* pWrapperLoader = new AnimDynaPhysWrapperLoader; HeapMgr()->PopHeap( GMA_TEMP ); pWrappedObject = (AnimDynaPhysWrapper*) pWrapperLoader->LoadObject( file, store ); pWrappedObject->AddRef (); pWrapperLoader->Release(); } m_IsStateProp = false; } break; // Relies on ObjectAttributes and the Wrapped DSG object being loaded first case SRR2::ChunkID::OBJECT_ATTRIBUTES: { if(!haveGlobal) { rAssert( pWrappedObject != NULL ); // Relies on the Wrapped Object being loaded first int classType = file->GetLong(); int physPropID = file->GetLong(); char tempsound [64]; file->GetString(tempsound); //Chuck: Reading the new sound properties since we dont use the sound returned from the ATC manager. float volume; if ( classType == PROP_MOVEABLE || classType == PROP_BREAKABLE || classType == PROP_ONETIME_MOVEABLE || classType == 8 ) { volume = pWrappedObject->GetVolume(); } else { volume = 0.0f; } pCollAttr = GetATCManager()->CreateCollisionAttributes(classType, physPropID, volume); pCollAttr->AddRef (); pCollAttr->SetSound(tempsound); //Chuck: Setting the CollAttr to use the correct sound from the OTC chunk. } } break; case SRR2::ChunkID::INSTANCES: { foundInstances = true; //Instances >> Scenegraph file->BeginChunk(); //Scenegraph >> ScenegraphRoot file->BeginChunk(); //ScenegraphRoot >> ScenegraphBranch file->BeginChunk(); //ScenegraphBranch >> ScenegraphTransform file->BeginChunk(); //ScenegraphTransform >> real ScenegraphTransform //f->BeginChunk(); while( file->ChunksRemaining() ) { instanceCount++; file->BeginChunk(); char name[256]; file->GetPString(name); int numChild = file->GetLong(); rmt::Matrix matrix; file->GetData( &matrix,16, tFile::DWORD ); if ( m_IsStateProp ) { short persistentID = -1; if(persistance && ((haveGlobal && globalStatepropEntity->GetCollisionAttributes()->GetClasstypeid()) || (!haveGlobal && ((pCollAttr->GetClasstypeid() == PROP_BREAKABLE) || (pCollAttr->GetClasstypeid() == PROP_MOVEABLE))))) { if ( isMissionProp == false ) persistentID = GetPersistentWorldManager()->GetPersistentObjectID( tEntity::MakeUID( file->GetFilename() ),tEntity::MakeUID(typeName) ); else persistentID = -1; } if( persistentID >= -1 ) { StatePropDSG* pStatePropDSG = NULL; // Should we clone off the global entity (if it exists?) if (haveGlobal) { pStatePropDSG = globalStatepropEntity->Clone( name, matrix ); } else { rAssert( pCollAttr != NULL ); rAssert( pWrappedObject != NULL ); bool useSharedtPose = pWrappedObject->HasAnimation() ? false : true; pStatePropDSG = new StatePropDSG(); pStatePropDSG->LoadSetup( pWrappedObject->GetStatePropData(), 0, matrix, pCollAttr, true, store, useSharedtPose, pWrappedObject->GetCollisionObject(), pWrappedObject->GetPhysicsObject() ); pStatePropDSG->SetName( name ); pStatePropDSG->SetSimJoint( simAnimJoint ); } #ifndef FINAL if( !haveGlobal && (pWrappedObject->GetStatePropData() == NULL)) { char outbuffer [255]; sprintf(outbuffer,"Error: %s is missing a StateProp Chunk \n",pWrappedObject->GetName()); rTuneAssertMsg( 0,outbuffer ); } #endif mpListenerCB->OnChunkLoaded( pStatePropDSG, mUserData, _id ); pStatePropDSG->mPersistentObjectID = persistentID; // Check to see if there is a shadow associated with this object tUID compDrawUID = pStatePropDSG->GetDrawableUID(); tUID shadowElementName = GetShadowElement( compDrawUID ); if ( shadowElementName != static_cast< tUID >( 0 ) ) { pStatePropDSG->SetShadowElement( shadowElementName ); } // place it into the inventory so that locators can access it by name bool collision = store->TestCollision( pStatePropDSG->GetUID(), pStatePropDSG ); if( !collision ) { store->Store( pStatePropDSG ); } else { HandleCollision( pStatePropDSG ); } // Lets offset the animation so that every crate or vending machine // instance isn't jumping together // Make the stateprop instances each start at a different point in time static rmt::Randomizer randomizer( Game::GetRandomSeed () ); const float RANDOM_TIME_MS = 10000.0f; // Advance animations by 0 - 10 seconds float randomUpdateTime = randomizer.Float() * RANDOM_TIME_MS; pStatePropDSG->AdvanceAnimation( randomUpdateTime ); } } else { InstAnimDynaPhysDSG* pAnimDSG = new InstAnimDynaPhysDSG(); // Make sure that each name is unique // things like the powerboxes are set via lookup pAnimDSG->SetName( name ); if( hasAlpha || pWrappedObject->HasAlpha() ) { pAnimDSG->mTranslucent = true; } else { pAnimDSG->mTranslucent = false; } rAssert( pCollAttr != NULL ); pAnimDSG->LoadSetUp( pCollAttr, matrix, pWrappedObject->GetDrawable(), pWrappedObject->GetController(), store ); mpListenerCB->OnChunkLoaded( static_cast< InstDynaPhysDSG*> (pAnimDSG), mUserData, _id ); // place it into the inventory so that locators can access it by name store->Store( pAnimDSG ); } file->EndChunk(); #ifndef RAD_RELEASE if ( instanceCount == 1 ) { PropStats::StopTracking( typeName, 1 ); PropStats::StartTracking( typeName ); instanceCount = 0; } #endif } //ScenegraphBranch >> ScenegraphTransform file->EndChunk(); //ScenegraphRoot >> ScenegraphBranch file->EndChunk(); //Scenegraph >> ScenegraphRoot file->EndChunk(); //Instances >> Scenegraph file->EndChunk(); } break; default: rAssertMsg( false, "Unknown chunk in AnimatedDynaPhysDSG file"); break; }; file->EndChunk(); } if(0&&!foundInstances && !haveGlobal ) { // No instance chunk! // Therefore this MUST be a global entity // Dump it into the global entity list // so that subsequent instances of this type // will get cloned off the global entity instead of loading all this crap again //This must be a global entity. StatePropDSG* globalEntityStateProp = new StatePropDSG(); rAssert(globalEntityStateProp); // Give this thing the name of the type bool useSharedtPose = pWrappedObject->HasAnimation() ? false : true; rmt::Matrix identity; identity.Identity(); globalEntityStateProp->LoadSetup( pWrappedObject->GetStatePropData(), 0, identity, pCollAttr, false, NULL, useSharedtPose, pWrappedObject->GetCollisionObject(), pWrappedObject->GetPhysicsObject() ); globalEntityStateProp->SetName( typeName ); GetAllWrappers()->AddGlobalEntity( globalEntityStateProp ); globalEntityStateProp->SetSimJoint( simAnimJoint ); instanceCount++; } if( pWrappedObject != NULL) { pWrappedObject->ReleaseVerified (); } if ( pCollAttr != NULL ) { pCollAttr->Release (); } #ifndef RAD_RELEASE PropStats::StopTracking( typeName, instanceCount ); #endif IEntityDSG::msDeletionsSafe=false; return NULL; } //=========================================================================== // AnimDynaPhysLoader::SetRegdListener //=========================================================================== // Description: // Informs the loader its listener is. // // Constraints: // // Parameters: // Pointer to the new listener. Integer for the data it sends to it OnChunkLoaded() // // Return: // //=========================================================================== void AnimDynaPhysLoader::SetRegdListener( ChunkListenerCallback* pListenerCB, int iUserData ) { // // Follow protocol; notify old Listener, that it has been // "disconnected". // if( mpListenerCB != NULL ) { mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 ); } mpListenerCB = pListenerCB; mUserData = iUserData; } //=========================================================================== // AnimDynaPhysLoader::ModRegdListener //=========================================================================== // Description: // Changes the data that gets sent to the listener // // Constraints: // Listener must have been set already via SetRegdListener // // Parameters: // Pointer to the listener. Integer holding the new data // // Return: // //=========================================================================== void AnimDynaPhysLoader::ModRegdListener( ChunkListenerCallback* pListenerCB, int iUserData ) { rAssert( pListenerCB == mpListenerCB ); mUserData = iUserData; } void AnimDynaPhysLoader::SetShadowElement( const char* compDrawName, const char* drawableElementName ) { s_ShadowList.insert( tName::MakeUID( compDrawName ), tName::MakeUID( drawableElementName ) ); } void AnimDynaPhysLoader::ClearShadowList() { s_ShadowList.clear(); } tUID AnimDynaPhysLoader::GetShadowElement( tUID compDrawName ) { tUID elementName; Map< tUID, tUID >::const_iterator it; it = s_ShadowList.find( compDrawName ); if ( it != s_ShadowList.end() ) elementName = it->second; else elementName = 0; return elementName; } /////////////////////////////////////////////////////////// // AnimDyaPhysWrapperLoader methods /////////////////////////////////////////////////////////// AnimDynaPhysWrapperLoader::AnimDynaPhysWrapperLoader() : tSimpleChunkHandler(SRR2::ChunkID::ANIM_DSG_WRAPPER) { mpListenerCB = NULL; mUserData = -1; mpCompDLoader = new tCompositeDrawableLoader; mpCompDLoader->AddRef(); mpMCLoader = new tMultiControllerLoader; mpMCLoader->AddRef(); mpSkelLoader = new tSkeletonLoader; mpSkelLoader->AddRef(); mpAnimationLoader = new tAnimationLoader; mpAnimationLoader->AddRef(); mpCollObjLoader = new sim::CollisionObjectLoader; mpCollObjLoader->AddRef(); mpPhysObjLoader = new sim::PhysicsObjectLoader; mpPhysObjLoader->AddRef(); mpFCLoader = new tFrameControllerLoader; mpFCLoader->AddRef(); } AnimDynaPhysWrapperLoader::~AnimDynaPhysWrapperLoader() { mpCollObjLoader->ReleaseVerified(); mpPhysObjLoader->ReleaseVerified(); mpCompDLoader->ReleaseVerified(); mpMCLoader->ReleaseVerified(); mpSkelLoader->ReleaseVerified(); mpAnimationLoader->ReleaseVerified(); mpFCLoader->ReleaseVerified(); } tEntity* AnimDynaPhysWrapperLoader::LoadObject( tChunkFile* file, tEntityStore* store ) { HeapMgr()->PushHeap( GMA_LEVEL_OTHER ); AnimDynaPhysWrapper* wrapper = new AnimDynaPhysWrapper; HeapMgr()->PopHeap( GMA_LEVEL_OTHER ); rAssert( file != NULL ); rAssert( store != NULL ); // Grab the name char buffer[256]; file->GetPString( buffer ); wrapper->SetName( buffer ); // Grab version info int version = file->GetLong(); // Grab the flag that tell us whether or not the object has alpha or not int hasAlpha = file->GetLong(); wrapper->mHasAlpha = ( hasAlpha != 0x00000000 ); bool collisionObjectFound = false; while( file->ChunksRemaining() ) { file->BeginChunk(); switch( file->GetCurrentID() ) { case P3D_COMPOSITE_DRAWABLE: { // We will save the composite drawable since we need it // for our DSG objects rAssertMsg( wrapper->mCompDraw == NULL, "There must only be one composite drawable in the wrapper!" ); wrapper->mCompDraw = (tCompositeDrawable*)mpCompDLoader->LoadObject( file, store ); wrapper->mCompDraw->AddRef(); store->Store( wrapper->mCompDraw ); rAssert( wrapper->mCompDraw != NULL ); } break; case P3D_MULTI_CONTROLLER: { rAssert( wrapper->mMultiController == NULL ); wrapper->mMultiController = (tMultiController*)mpMCLoader->LoadObject( file, store ); rAssert( wrapper->mMultiController != NULL ); // This should be inserted into the list of world render multicontrollers that // get advanced every frame wrapper->mMultiController->SetCycleMode( FORCE_CYCLIC ); wrapper->mMultiController->AddRef(); bool collision = store->TestCollision( wrapper->mMultiController->GetUID(), wrapper->mMultiController ); if( !collision ) { store->Store( wrapper->mMultiController ); } else { HandleCollision( wrapper->mMultiController ); } } break; case Pure3D::Animation::FrameControllerData::FRAME_CONTROLLER: { tFrameController* pFC = static_cast< tFrameController* >( mpFCLoader->LoadObject( file, store ) ); rAssert( pFC != NULL ); store->Store( pFC ); } break; case Simulation::Collision::OBJECT: { collisionObjectFound = true; rAssert( wrapper->mCollisionObject == NULL ); wrapper->mCollisionObject = static_cast< sim::CollisionObject* > (mpCollObjLoader->LoadObject( file, store )); rAssert( wrapper->mCollisionObject != NULL ); wrapper->mCollisionObject->AddRef(); store->Store( wrapper->mCollisionObject ); } break; case Pure3D::BillboardObject::QUAD_GROUP: { // Remember that we have our own billboard loader // make sure that these don't get dumped into the DSG, override first // Grab the loader BillboardWrappedLoader::OverrideLoader( true ); BillboardWrappedLoader* pBBQLoader = static_cast(AllWrappers::GetInstance()->mpLoader(AllWrappers::msBillboard)); tBillboardQuadGroup* pGroup = static_cast( pBBQLoader->LoadObject( file, store ) ); rAssert( pGroup != NULL ); store->Store( pGroup ); // Set the loader back to its normal state BillboardWrappedLoader::OverrideLoader( false ); } break; case Pure3D::Mesh::MESH: { GeometryWrappedLoader* pGeoLoader = (GeometryWrappedLoader*)AllWrappers::GetInstance()->mpLoader( AllWrappers::msGeometry ); tGeometry* pGeo = static_cast(pGeoLoader->LoadObject( file, store ) ); rAssert( pGeo != NULL ); store->Store( pGeo ); } break; case Pure3D::Animation::AnimationData::ANIMATION: { tAnimation* pAnimation = static_cast< tAnimation*> ( mpAnimationLoader->LoadObject( file, store ) ); rAssert( pAnimation != NULL ); store->Store( pAnimation ); wrapper->SetHasAnimation( true ); } break; case Simulation::Physics::OBJECT: rAssert( wrapper->mPhysicsObject == NULL ); wrapper->mPhysicsObject = (sim::PhysicsObject*)mpPhysObjLoader->LoadObject( file,store ); rAssert( wrapper->mPhysicsObject != NULL ); store->Store( wrapper->mPhysicsObject ); wrapper->mPhysicsObject->AddRef (); break; case P3D_SKELETON: { tSkeleton* pSkeleton = static_cast< tSkeleton* > (mpSkelLoader->LoadObject( file, store ) ); rAssert( pSkeleton != NULL ); store->Store( pSkeleton ); } break; default: rAssertMsg( false, "Unknown chunk in animated wrapper chunk file"); break; }; file->EndChunk(); } if ( collisionObjectFound == false ) { rReleasePrintf("WARNING - Stateprop %s is missing a collision volume!\n", buffer ); } return wrapper; } //=========================================================================== // AnimDynaPhysWrapperLoader::SetRegdListener //=========================================================================== // Description: // Informs the loader its listener is. // // Constraints: // // Parameters: // Pointer to the new listener. Integer for the data it sends to it OnChunkLoaded() // // Return: // //=========================================================================== void AnimDynaPhysWrapperLoader::SetRegdListener( ChunkListenerCallback* pListenerCB, int iUserData ) { // // Follow protocol; notify old Listener, that it has been // "disconnected". // if( mpListenerCB != NULL ) { mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 ); } mpListenerCB = pListenerCB; mUserData = iUserData; } //=========================================================================== // AnimDynaPhysWrapperLoader::ModRegdListener //=========================================================================== // Description: // Changes the data that gets sent to the listener // // Constraints: // Listener must have been set already via SetRegdListener // // Parameters: // Pointer to the listener. Integer holding the new data // // Return: // //=========================================================================== void AnimDynaPhysWrapperLoader::ModRegdListener( ChunkListenerCallback* pListenerCB, int iUserData ) { rAssert( pListenerCB == mpListenerCB ); mUserData = iUserData; } /////////////////////////////////////////////////////////// // ANIM_OBJ_DSG_WRAPPER methods /////////////////////////////////////////////////////////// AnimObjDSGWrapperLoader::AnimObjDSGWrapperLoader() : tSimpleChunkHandler(SRR2::ChunkID::ANIM_OBJ_DSG_WRAPPER) { mpListenerCB = NULL; mUserData = -1; mpCompDLoader = new tCompositeDrawableLoader; mpCompDLoader->AddRef(); mpMCLoader = new tMultiControllerLoader; mpMCLoader->AddRef(); mpSkelLoader = new tSkeletonLoader; mpSkelLoader->AddRef(); mpAnimationLoader = new tAnimationLoader; mpAnimationLoader->AddRef(); mpCollObjLoader = new sim::CollisionObjectLoader; mpCollObjLoader->AddRef(); mpPhysObjLoader = new sim::PhysicsObjectLoader; mpPhysObjLoader->AddRef(); mpFCLoader = new tFrameControllerLoader; mpFCLoader->AddRef(); mpStatePropLoader = new CStatePropDataLoader; mpStatePropLoader->AddRef(); mpFactoryLoader = new tAnimatedObjectFactoryLoader; mpAnimObjectLoader = new tAnimatedObjectLoader; } AnimObjDSGWrapperLoader::~AnimObjDSGWrapperLoader() { mpCollObjLoader->ReleaseVerified(); mpPhysObjLoader->ReleaseVerified(); mpCompDLoader->ReleaseVerified(); mpMCLoader->ReleaseVerified(); mpSkelLoader->ReleaseVerified(); mpAnimationLoader->ReleaseVerified(); mpFCLoader->ReleaseVerified(); mpStatePropLoader->ReleaseVerified(); mpFactoryLoader->ReleaseVerified(); mpAnimObjectLoader->ReleaseVerified(); } tEntity* AnimObjDSGWrapperLoader::LoadObject( tChunkFile* file, tEntityStore* store ) { HeapMgr()->PushHeap( GMA_LEVEL_OTHER ); AnimDynaPhysWrapper* wrapper = new AnimDynaPhysWrapper; HeapMgr()->PopHeap( GMA_LEVEL_OTHER ); rAssert( file != NULL ); rAssert( store != NULL ); // Grab the name char buffer[256]; file->GetPString( buffer ); wrapper->SetName( buffer ); // Grab version info int version = file->GetUChar(); // Grab the flag that tell us whether or not the object has alpha or not int hasAlpha = file->GetUChar(); wrapper->mHasAlpha = ( hasAlpha != 0x00000000 ); while( file->ChunksRemaining() ) { file->BeginChunk(); unsigned int id = file->GetCurrentID(); switch( id ) { case P3D_COMPOSITE_DRAWABLE: { // We will save the composite drawable since we need it // for our DSG objects rAssertMsg( wrapper->mCompDraw == NULL, "There must only be one composite drawable in the wrapper!" ); wrapper->mCompDraw = (tCompositeDrawable*)mpCompDLoader->LoadObject( file, store ); wrapper->mCompDraw->AddRef(); store->Store( wrapper->mCompDraw ); rAssert( wrapper->mCompDraw != NULL ); } break; case P3D_MULTI_CONTROLLER: { rAssert( wrapper->mMultiController == NULL ); wrapper->mMultiController = (tMultiController*)mpMCLoader->LoadObject( file, store ); rAssert( wrapper->mMultiController != NULL ); // This should be inserted into the list of world render multicontrollers that // get advanced every frame wrapper->mMultiController->SetCycleMode( FORCE_CYCLIC ); wrapper->mMultiController->AddRef(); bool collision = store->TestCollision( wrapper->mMultiController->GetUID(), wrapper->mMultiController ); if( !collision ) { store->Store( wrapper->mMultiController ); } else { HandleCollision( wrapper->mMultiController ); } } break; case Pure3D::Animation::FrameControllerData::FRAME_CONTROLLER: { tFrameController* pFC = static_cast< tFrameController* >( mpFCLoader->LoadObject( file, store ) ); rAssert( pFC != NULL ); store->Store( pFC ); } break; case Simulation::Collision::OBJECT: { rAssert( wrapper->mCollisionObject == NULL ); wrapper->mCollisionObject = static_cast< sim::CollisionObject* > (mpCollObjLoader->LoadObject( file, store )); rAssert( wrapper->mCollisionObject != NULL ); wrapper->mCollisionObject->AddRef(); store->Store( wrapper->mCollisionObject ); //wrapper->mCollisionObject->AddRef (); } break; case Pure3D::BillboardObject::QUAD_GROUP: { // Remember that we have our own billboard loader // make sure that these don't get dumped into the DSG, override first // Grab the loader BillboardWrappedLoader::OverrideLoader( true ); BillboardWrappedLoader* pBBQLoader = static_cast(AllWrappers::GetInstance()->mpLoader(AllWrappers::msBillboard)); tBillboardQuadGroup* pGroup = static_cast( pBBQLoader->LoadObject( file, store ) ); rAssert( pGroup != NULL ); store->Store( pGroup ); // Set the loader back to its normal state BillboardWrappedLoader::OverrideLoader( false ); } break; case Pure3D::Mesh::MESH: { GeometryWrappedLoader* pGeoLoader = (GeometryWrappedLoader*)AllWrappers::GetInstance()->mpLoader( AllWrappers::msGeometry ); tGeometry* pGeo = static_cast(pGeoLoader->LoadObject( file, store ) ); rAssert( pGeo != NULL ); store->Store( pGeo ); } break; case Pure3D::Animation::AnimationData::ANIMATION: { tAnimation* pAnimation = static_cast< tAnimation*> ( mpAnimationLoader->LoadObject( file, store ) ); rAssert( pAnimation != NULL ); store->Store( pAnimation ); } break; case Simulation::Physics::OBJECT: rAssert( wrapper->mPhysicsObject == NULL ); wrapper->mPhysicsObject = (sim::PhysicsObject*)mpPhysObjLoader->LoadObject( file,store ); rAssert( wrapper->mPhysicsObject != NULL ); store->Store( wrapper->mPhysicsObject ); wrapper->mPhysicsObject->AddRef (); break; case P3D_SKELETON: { tSkeleton* pSkeleton = static_cast< tSkeleton* > (mpSkelLoader->LoadObject( file, store ) ); rAssert( pSkeleton != NULL ); store->Store( pSkeleton ); } break; case StateProp::STATEPROP: { CStatePropData* pPropData = static_cast< CStatePropData* > (mpStatePropLoader->LoadObject( file, store ) ); rAssert( dynamic_cast< CStatePropData* >( pPropData ) != NULL ); rAssert( pPropData != NULL ); tRefCounted::Assign(wrapper->mStatePropData, pPropData); store->Store( pPropData ); } break; case Pure3D::AnimatedObject::FACTORY: { tEntity* entity = mpFactoryLoader->LoadObject( file, store ); rAssert( dynamic_cast< tAnimatedObjectFactory* >(entity) != NULL ); store->Store( entity ); } break; case Pure3D::AnimatedObject::OBJECT: { tEntity* pEntity = mpAnimObjectLoader->LoadObject( file, store ); rAssert( pEntity != NULL ); store->Store( pEntity ); } break; default: rAssertMsg( false, "Unknown chunk in animated wrapper chunk file"); break; }; file->EndChunk(); } return wrapper; } //=========================================================================== // AnimObjDSGWrapperLoader::SetRegdListener //=========================================================================== // Description: // Informs the loader its listener is. // // Constraints: // // Parameters: // Pointer to the new listener. Integer for the data it sends to it OnChunkLoaded() // // Return: // //=========================================================================== void AnimObjDSGWrapperLoader::SetRegdListener( ChunkListenerCallback* pListenerCB, int iUserData ) { // // Follow protocol; notify old Listener, that it has been // "disconnected". // if( mpListenerCB != NULL ) { mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 ); } mpListenerCB = pListenerCB; mUserData = iUserData; } //=========================================================================== // AnimObjDSGWrapperLoader::ModRegdListener //=========================================================================== // Description: // Changes the data that gets sent to the listener // // Constraints: // Listener must have been set already via SetRegdListener // // Parameters: // Pointer to the listener. Integer holding the new data // // Return: // //=========================================================================== void AnimObjDSGWrapperLoader::ModRegdListener( ChunkListenerCallback* pListenerCB, int iUserData ) { rAssert( pListenerCB == mpListenerCB ); mUserData = iUserData; } //=========================================================================== // AnimObjDSGWrapperLoader::IsMissionProp //=========================================================================== // Description: // Returns boolean indicating if the prop is used in a mission // // Constraints: // Only one stateprop mission prop - the powerbox // // Parameters: // none // // Return: // bool indicating if this prop is used in a mission // //=========================================================================== bool AnimDynaPhysLoader::IsMissionProp( const char* name )const { if ( strcmp( name, "l1z6_powerbox_Shape" ) == 0 ) return true; else return false; }