//============================================================================= // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // File: animcollisionentitydsg.cpp // // Description: Implementation of class AnimCollisionEntityDSG // // History: 05/07/2002 + Created -- NAME // //============================================================================= //======================================== // System Includes //======================================== // Foundation Tech #include #include #include #include #include #include #include #include //======================================== // Project Includes //======================================== #include #include #include #include #include #include #include #include #include #include #include #include #include #include //****************************************************************************** // // Global Data, Local Data, Local Classes // //****************************************************************************** // // Table of objects with sounds (but no sound in CollisionAttributes) // struct AnimEntitySoundData { radInt64 animEntityUID; const char* soundName; unsigned int jointNumber; const char* settingName; }; static const AnimEntitySoundData s_animSoundTable[] = { { tEntity::MakeUID( "Splatform2Trans" ), "platform_02", 1, "platform_settings" }, { tEntity::MakeUID( "Aplatform1Trans" ), "platform_01", 1, "platform_settings" }, { tEntity::MakeUID( "Aplatform2Trans" ), "platform_01", 1, "platform_settings" }, { tEntity::MakeUID( "trapdoor1Trans" ), "platform_01", 1, "platform_settings" }, { tEntity::MakeUID( "crane" ), "platform_02", 3, "crane_settings" }, { tEntity::MakeUID( "roboarm" ), "robo_arm", 1, "platform_settings" } }; static unsigned int s_animSoundTableSize = sizeof( s_animSoundTable ) / sizeof( AnimEntitySoundData ); //****************************************************************************** // // Public Member Functions // //****************************************************************************** //============================================================================== // AnimCollisionEntityDSG::AnimCollisionEntityDSG //============================================================================== // Description: Constructor. // // Parameters: None. // // Return: N/A. // //============================================================================== AnimCollisionEntityDSG::AnimCollisionEntityDSG() : mfDirection( 1.0f ), mpActionButton( 0 ) { } //============================================================================== // AnimCollisionEntityDSG::~AnimCollisionEntityDSG //============================================================================== // Description: Destructor. // // Parameters: None. // // Return: N/A. // //============================================================================== AnimCollisionEntityDSG::~AnimCollisionEntityDSG() { BEGIN_PROFILE( "AnimColl Destroy" ); tRefCounted::Release( mpDrawable ); tRefCounted::Release( mpPoseEngine ); tRefCounted::Release( mpRootMatrixDriver ); tRefCounted::Release( mpSimStateArticulated ); tRefCounted::Release( mpAnimController ); if ( mpActionButton ) { mpActionButton->Destroy( ); tRefCounted::Release( mpActionButton ); } GetEventManager()->TriggerEvent( EVENT_STOP_ANIM_ENTITY_DSG_SOUND, this ); END_PROFILE( "AnimColl Destroy" ); } /* ============================================================================== AnimCollisionEntityDSG::Create ============================================================================== Description: Comment Parameters: ( const char* objectName, const char* animName ) Return: bool ============================================================================= */ bool AnimCollisionEntityDSG::Create( const char* objectName, const char* animName ) { rAssert( false ); return false; } //======================================================================== // animcollisionentitydsg:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== void AnimCollisionEntityDSG::LoadSetUp ( tCompositeDrawable* ipCompD, tMultiController* ipAnimFC, sim::CollisionObject* ipCollObject, tEntityStore* ipStore ) { mpDrawable = ipCompD; mpAnimController = ipAnimFC; rAssert( mpDrawable ); rAssert(mpAnimController); rAssert( ipCollObject ); if(mpDrawable && mpAnimController && ipCollObject ) { mpDrawable->AddRef(); mpAnimController->AddRef(); mTransform.Identity( ); tPose* p3dPose = mpDrawable->GetPose(); p3dPose->Evaluate(); mTransform = p3dPose->GetJoint( 0 )->worldMatrix; mpPoseEngine = new poser::PoseEngine( p3dPose, 1, p3dPose->GetNumJoint() ); mpPoseEngine->AddRef(); mpRootMatrixDriver = new RootMatrixDriver(&(mTransform)); mpRootMatrixDriver->AddRef(); // TODO - not really doing proper cleanup on this shit mpPoseEngine->AddPoseDriver(0, mpRootMatrixDriver ); // The section stuff here is a hack. // Tracked to ATG as bug 1259. // p3d::inventory->PushSection (); p3d::inventory->AddSection (SKELCACHE); p3d::inventory->SelectSection (SKELCACHE); mpSimStateArticulated = sim::SimStateArticulated::CreateSimStateArticulated( mpPoseEngine->GetPose(), ipCollObject, (sim::SimulatedObject*)0 ); p3d::inventory->PopSection (); rAssert( mpSimStateArticulated ); mpSimStateArticulated->AddRef(); mpSimStateArticulated->mAIRefIndex = PhysicsAIRef::redBrickPhizMoveableAnim; mpSimStateArticulated->mAIRefPointer = (void*)this; // Manually set this because physics seems to be pretty confused. // // TODO: fix this, because now physics system will generate collision pairs // for this object with other animcollentity. // // TBJ [8/28/2002] // mpSimStateArticulated->GetCollisionObject()->SetIsStatic( false ); // This will init the pose, and set the bounding boxes. // UpdatePose( 0.0f ); } mpDrawable->ProcessShaders(*this); // // Now that we're set up, see if we're supposed to play a sound -- Esan // findSoundName(); } /* ============================================================================== AnimCollisionEntityDSG::SetAction ============================================================================== Description: Comment Parameters: ( ActionButton::AnimSwitch* pActionButton ) Return: void ============================================================================= */ void AnimCollisionEntityDSG::SetAction( ActionButton::AnimSwitch* pActionButton ) { tRefCounted::Assign( mpActionButton, pActionButton ); } //======================================================================== // animcollisionentitydsg:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== void AnimCollisionEntityDSG::GetBoundingBox(rmt::Box3D* box) { *box = mBoundingBox; } //======================================================================== // animcollisionentitydsg:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== void AnimCollisionEntityDSG::GetBoundingSphere(rmt::Sphere* sphere) { *sphere = mBoundingSphere; } /* ============================================================================== AnimCollisionEntityDSG::Display ============================================================================== Description: Comment Parameters: () Return: void ============================================================================= */ void AnimCollisionEntityDSG::Display() { if(IS_DRAW_LONG) return; #ifdef PROFILER_ENABLED char profileName[] = " AnimCollisionEntityDSG Display"; #endif DSG_BEGIN_PROFILE(profileName) mpDrawable->Display(); DSG_END_PROFILE(profileName) } /* ============================================================================== AnimCollisionEntityDSG::pPosition ============================================================================== Description: Comment Parameters: () Return: rmt ============================================================================= */ rmt::Vector* AnimCollisionEntityDSG::pPosition() { return (rmt::Vector*)(mTransform.m[3]); } /* ============================================================================== AnimCollisionEntityDSG::rPosition ============================================================================== Description: Comment Parameters: () Return: const ============================================================================= */ const rmt::Vector& AnimCollisionEntityDSG::rPosition() { return mTransform.Row( 3 ); } /* ============================================================================== AnimCollisionEntityDSG::GetPosition ============================================================================== Description: Comment Parameters: ( rmt::Vector* ipPosn ) Return: void ============================================================================= */ void AnimCollisionEntityDSG::GetPosition( rmt::Vector* ipPosn ) { *ipPosn = mTransform.Row(3); } void AnimCollisionEntityDSG::AdvanceAnimation( float timeins ) { mpAnimController->Advance( timeins * 1000.0f * mfDirection ); } /* ============================================================================== AnimCollisionEntityDSG::Update ============================================================================== Description: Comment Parameters: ( float timeins ) Return: void ============================================================================= */ void AnimCollisionEntityDSG::Update( float timeins ) { if ( mpActionButton ) { mpActionButton->Update( timeins ); } // Store this before we update the transform so the scenegraph can // find 'this'. // rmt::Box3D oldBox; GetBoundingBox( &oldBox ); // We only need to update when the animation is actually playing. // if ( mfDirection != 0 ) { UpdatePose( timeins ); } // Move the object in the scenegraph. // WorldRenderLayer* pWorldRenderLayer = static_cast< WorldRenderLayer* > (GetRenderManager()->mpLayer( mRenderLayer )); // Sanity check rAssert( dynamic_cast(pWorldRenderLayer) != NULL ); pWorldRenderLayer->pWorldScene()->Move( oldBox, this ); } /* ============================================================================== AnimCollisionEntityDSG::UpdatePose ============================================================================== Description: Comment Parameters: ( float timeins ) Return: void ============================================================================= */ void AnimCollisionEntityDSG::UpdatePose( float timeins ) { // advance the animation and update transform! // //mpAnimController->Advance( timeins * 1000.0f * mfDirection ); this->mTransform = mpDrawable->GetPose()->GetJoint( 0 )->worldMatrix;//objectMatrix; mpSimStateArticulated->StoreJointState( timeins ); mpPoseEngine->Begin(false); int i; for (i = 0; i < mpPoseEngine->GetPassCount(); i++) { mpPoseEngine->Advance(i, timeins ); mpPoseEngine->Update(i); } mpPoseEngine->End(); // copy over what we're gonna render mpSimStateArticulated->UpdateJointState( timeins ); sim::CollisionObject* pObject = mpSimStateArticulated->GetCollisionObject(); pObject->Update(); UpdateBBox( pObject->GetCollisionVolume( ) ); } /* ============================================================================== AnimCollisionEntityDSG::UpdateBBox ============================================================================== Description: Comment Parameters: ( sim::CollisionVolume* pVolume ) Return: void ============================================================================= */ void AnimCollisionEntityDSG::UpdateBBox( sim::CollisionVolume* pVolume ) { // Use the BBox and BSphere from the CollisionVolume to // update the drawable BBOX and BSphere. // mBoundingSphere.centre = pVolume->mPosition; mBoundingSphere.radius = pVolume->mSphereRadius; rmt::Vector position = pVolume->mPosition; rmt::Vector size = pVolume->mBoxSize; mBoundingBox.high.Add( position, size ); size.Scale( -1.0f ); mBoundingBox.low.Add( position, size ); } /* ============================================================================== AnimCollisionEntityDSG::UpdateVisibility ============================================================================== Description: Comment Parameters: ( void ) Return: void ============================================================================= */ void AnimCollisionEntityDSG::UpdateVisibility( void ) { mpSimStateArticulated->GetCollisionObject( )->SetVisibility( mpDrawable ); } /* ============================================================================== AnimCollisionEntityDSG::PreReactToCollision ============================================================================== Description: Comment Parameters: ( sim::SimState* pCollidedObj, sim::Collision& inCollision ) Return: bool ============================================================================= */ sim::Solving_Answer AnimCollisionEntityDSG::PreReactToCollision( sim::SimState* pCollidedObj, sim::Collision& inCollision ) { return sim::Solving_Continue; } //============================================================================= // AnimCollisionEntityDSG::PostReactToCollision //============================================================================= // Description: Comment // // Parameters: ( sim::SimState* pCollidedObj, sim::Collision& inCollision ) // // Return: sim // //============================================================================= sim::Solving_Answer AnimCollisionEntityDSG::PostReactToCollision(rmt::Vector& impulse, sim::Collision& inCollision) { // subclass-specific shit here return CollisionEntityDSG::PostReactToCollision(impulse, inCollision); } /* ============================================================================== AnimCollisionEntityDSG::GetPoseJoint ============================================================================== Description: Comment Parameters: ( int jointIndex, bool bAttachToJoint ) Return: tPose ============================================================================= */ tPose::Joint* AnimCollisionEntityDSG::GetPoseJoint( int jointIndex, bool bAttachToJoint ) { tPose::Joint* pJoint = 0; if ( jointIndex >= 0 ) { pJoint = mpPoseEngine->GetP3DPose( )->GetJoint( jointIndex );// GetPose( )->GetJoint( jointIndex ); } // If not found, try the root. // if ( pJoint == (tPose::Joint*)0 && !bAttachToJoint ) { pJoint = mpPoseEngine->GetP3DPose( )->GetJoint( 0 );// mpPoseEngine->GetPose( )->GetJoint( 0 ); } rAssert( pJoint ); return pJoint; } //****************************************************************************** // // Private Member Functions // //****************************************************************************** void AnimCollisionEntityDSG::OnSetSimState( sim::SimState* ipCollObj ) { } //============================================================================= // AnimCollisionEntityDSG::findSoundName //============================================================================= // Description: Platforms messed up the usual sound drill. Because they don't // have entries in the art DB, we need to search a table to find // out whether this anim entity has a sound that the sound system // needs to know about. // // Parameters: None // // Return: void // //============================================================================= void AnimCollisionEntityDSG::findSoundName() { unsigned int i; const char* soundName; tUID myName = GetUID(); soundName = NULL; for( i = 0; i < s_animSoundTableSize; i++ ) { if( myName == static_cast< tUID >( s_animSoundTable[i].animEntityUID ) ) { soundName = s_animSoundTable[i].soundName; break; } } if( soundName != NULL ) { // // We've got sound, tell the sound system // AnimSoundDSGData data( soundName, this, GetPoseJoint( s_animSoundTable[i].jointNumber, false ), s_animSoundTable[i].settingName ); GetEventManager()->TriggerEvent( EVENT_START_ANIM_ENTITY_DSG_SOUND, &data ); } }