//======================================================================== // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // File: DynaPhysLoader.cpp // // Description: Implementation for DynaPhysLoader class. // // History: Implemented --Devin [5/27/2002] //======================================================================== //======================================== // System Includes //======================================== #include #include #include //======================================== // Project Includes //======================================== #include #include #include #include #include #include #include #include #include #ifndef RAD_RELEASE #include #endif //************************************************************************ // // Global Data, Local Data, Local Classes // //************************************************************************ //************************************************************************ // // Public Member Functions : DynaPhysLoader Interface // //************************************************************************ //======================================================================== // DynaPhysLoader:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== DynaPhysLoader::DynaPhysLoader() : tSimpleChunkHandler(SRR2::ChunkID::DYNA_PHYS_DSG) { HeapMgr()->PushHeap( GMA_PERSISTENT ); mpCollObjLoader = new sim::CollisionObjectLoader(); mpCollObjLoader->AddRef(); mpPhysObjLoader = new sim::PhysicsObjectLoader(); mpPhysObjLoader->AddRef(); mpCompDLoader = new tCompositeDrawableLoader; mpCompDLoader->AddRef(); HeapMgr()->PopHeap(GMA_PERSISTENT); mpListenerCB = NULL; mUserData = -1; } //======================================================================== // DynaPhysLoader:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== DynaPhysLoader::~DynaPhysLoader() { mpCollObjLoader->Release(); mpPhysObjLoader->Release(); mpCompDLoader->Release(); } /////////////////////////////////////////////////////////////////////// // tSimpleChunkHandler /////////////////////////////////////////////////////////////////////// //======================================================================== // DynaPhysLoader:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== tEntity* DynaPhysLoader::LoadObject(tChunkFile* f, tEntityStore* store) { IEntityDSG::msDeletionsSafe=true; char objName[128]; char name[128]; f->GetPString(objName); #ifndef RAD_RELEASE PropStats::StartTracking( objName ); #endif bool test = tName::MakeUID(objName) == tName::MakeUID("l1_streetlamp_Shape"); static bool doTestOnce = true; // Lets see if theis object has a shadow associated with it const char* pShadowName = BlobbyShadowNames::FindShadowName( objName ); tDrawable* pShadow; if ( pShadowName != NULL ) { pShadow = p3d::find< tDrawable > ( pShadowName ); } else { pShadow = NULL; } int instanceCount = 0; int version = f->GetLong(); int HasAlpha = f->GetLong(); //pDynaPhysDSG->SetName(name); sim::CollisionObject* pCollObj = NULL; sim::PhysicsObject* pPhysObj = NULL; tDrawable* pDrawable = NULL; sim::SimState* pSimState = NULL; CollisionAttributes* pCollAttr = NULL; bool foundInstances = false; InstDynaPhysDSG* pCurDynaPhysDSG = static_cast(GetAllWrappers()->GetGlobalEntity(tName::MakeUID(objName))); //new InstDynaPhysDSG; while(f->ChunksRemaining()) { f->BeginChunk(); switch(f->GetCurrentID()) { case SRR2::ChunkID::INSTANCES: { //Instances >> Scenegraph f->BeginChunk(); //Scenegraph >> ScenegraphRoot f->BeginChunk(); //ScenegraphRoot >> ScenegraphBranch f->BeginChunk(); //ScenegraphBranch >> ScenegraphTransform f->BeginChunk(); foundInstances = true; //ScenegraphTransform >> real ScenegraphTransform //f->BeginChunk(); for(;f->ChunksRemaining();) { instanceCount++; f->BeginChunk(); f->GetPString(name); int numChild = f->GetLong(); rmt::Matrix matrix; f->GetData(&matrix,16,tFile::DWORD); if(pCurDynaPhysDSG == 0) { pCurDynaPhysDSG = new InstDynaPhysDSG(); rAssert(pCurDynaPhysDSG); pCurDynaPhysDSG->SetName(name); pCurDynaPhysDSG->mTranslucent = ( HasAlpha != 0 ) || pShadow; pSimState = sim::SimState::CreateSimState(pCollObj,pPhysObj); // I suppose this could have just as easily gone into LoadSetUp pSimState->SetControl(sim::simAICtrl); pSimState->SetTransform(matrix); pCurDynaPhysDSG->LoadSetUp(pSimState, pCollAttr, matrix, pDrawable, pShadow ); mpListenerCB->OnChunkLoaded( pCurDynaPhysDSG, mUserData, _id ); pCurDynaPhysDSG = 0; } else { InstDynaPhysDSG* clone = pCurDynaPhysDSG->Clone(name, matrix); mpListenerCB->OnChunkLoaded(clone, mUserData, _id); } f->EndChunk(); } //ScenegraphBranch >> ScenegraphTransform f->EndChunk(); //ScenegraphRoot >> ScenegraphBranch f->EndChunk(); //Scenegraph >> ScenegraphRoot f->EndChunk(); //Instances >> Scenegraph f->EndChunk(); } break; case Pure3D::Mesh::MESH: { if(pCurDynaPhysDSG == 0) { tGeometry* pGeo = (tGeometry*)((GeometryWrappedLoader*)GetAllWrappers()->mpLoader(AllWrappers::msGeometry))->LoadObject(f,store); if( pGeo ) { tRefCounted::Assign(pDrawable,(tDrawable*)pGeo); } } } break; case P3D_COMPOSITE_DRAWABLE: { if(pCurDynaPhysDSG == 0) { tCompositeDrawable* pCompD = static_cast( mpCompDLoader->LoadObject( f, store ) ); if( store->TestCollision( pCompD->GetUID(), pCompD ) ) { HandleCollision( pCompD ); pCompD = NULL; } else { store->Store( pCompD ); tRefCounted::Assign(pDrawable,(tDrawable*)pCompD); } } } break; case Simulation::Physics::OBJECT: { if(pCurDynaPhysDSG == 0) { tRefCounted::Assign(pPhysObj,(sim::PhysicsObject*)mpPhysObjLoader->LoadObject(f,store)); } } break; case Simulation::Collision::OBJECT: { if(pCurDynaPhysDSG == 0) { tRefCounted::Assign(pCollObj,(sim::CollisionObject*)mpCollObjLoader->LoadObject(f, store)); // TBJ [7/9/2002] // Added this to store collision objects in the inventory. // A normal loader stores the top level chunk, in this case the StaticPhysDSG. // Since we want the Collision Object in the inventory, we have to store it here. // if ( pCollObj ) { if( store->TestCollision( pCollObj->GetUID(), pCollObj ) ) { HandleCollision(pCollObj); // TBJ [7/9/2002] // Don't know what to do with this code? Doesn't seem right to assign to NULL if // the collObj does in fact exist. // I'll take it out for now. // //pCollObj = NULL; //return LOAD_ERROR; } else { store->Store(pCollObj); } } } } break; case SRR2::ChunkID::OBJECT_ATTRIBUTES: { if(pCurDynaPhysDSG == 0) { int classType = f->GetLong(); int physPropID = f->GetLong(); char tempsound [64]; f->GetString(tempsound); // MS10 GREG TODO: This isn't even being used and calling it is leaking memory. // // we need to pass in volume for this thing to be able to set the mass properly in the PhysicsProperties rAssert(pPhysObj); float volume = pPhysObj->GetVolume(); tRefCounted::Assign(pCollAttr,GetATCManager()->CreateCollisionAttributes(classType, physPropID, volume)); pCollAttr->SetSound(tempsound); } } break; default: break; } // switch f->EndChunk(); } // while if( foundInstances == false || (test && doTestOnce) ) { doTestOnce = false; //This must be a global entity. rmt::Matrix matrix; matrix.Identity(); pCurDynaPhysDSG = new InstDynaPhysDSG(); rAssert(pCurDynaPhysDSG); pCurDynaPhysDSG->SetName(objName); pCurDynaPhysDSG->mTranslucent = HasAlpha != 0; pSimState = sim::SimState::CreateSimState(pCollObj, pPhysObj); pSimState->SetControl(sim::simAICtrl); pSimState->SetTransform(matrix); pCurDynaPhysDSG->LoadSetUp(pSimState, pCollAttr, matrix, pDrawable, pShadow ); GetAllWrappers()->AddGlobalEntity(pCurDynaPhysDSG); instanceCount++; } // // Spin Pure3D async loading. // ///p3d::loadManager->SwitchTask(); tRefCounted::Release(pCollObj); tRefCounted::Release(pPhysObj); tRefCounted::Release(pDrawable); tRefCounted::Release(pCollAttr); #ifndef RAD_RELEASE PropStats::StopTracking( objName, instanceCount ); #endif IEntityDSG::msDeletionsSafe=false; return NULL; } /////////////////////////////////////////////////////////////////////// // IWrappedLoader /////////////////////////////////////////////////////////////////////// //======================================================================== // DynaPhysLoader::SetRegdListener //======================================================================== // // Description: Register a new listener/caretaker, notify old listener of // severed connection. // // Parameters: pListenerCB: Callback to call OnChunkLoaded // pUserData: Data to pass along for filtering, etc // // Return: None. // // Constraints: None. // //======================================================================== void DynaPhysLoader::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; } //======================================================================== // DynaPhysLoader::ModRegdListener //======================================================================== // // Description: Just fuck with the current pUserData // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== void DynaPhysLoader::ModRegdListener ( ChunkListenerCallback* pListenerCB, int iUserData ) { #if 0 char DebugBuf[255]; sprintf( DebugBuf, "GeometryWrappedLoader::ModRegdListener: pListenerCB %X vs mpListenerCB %X\n", pListenerCB, mpListenerCB ); rDebugString( DebugBuf ); #endif rAssert( pListenerCB == mpListenerCB ); mUserData = iUserData; } //************************************************************************ // // Protected Member Functions : DynaPhysLoader // //************************************************************************ //************************************************************************ // // Private Member Functions : DynaPhysLoader // //************************************************************************