Game Development Community

Vehicle Camera Effects

by Chris Haigler · in Torque Game Engine · 07/30/2007 (12:12 pm) · 2 replies

I'm having some trouble getting the CameraFXManager to work while piloting a vehicle. Specifically, explosions which are setup to shake the screen (via shakeCamera = true; in the datablock) don't work if the control object is a vehicle. A bit of debugging shows the camera effect is initialized and updated correctly but the update isn't seen.

After some digging, I discovered the Player class applies camera effects inside of interpolateTick() (around line 1173):

void Player::interpolateTick(F32 dt)
{
   if (mControlObject)
      mControlObject->interpolateTick(dt);

   // Client side interpolation
   Parent::interpolateTick(dt);
   if(dt != 0.0f)
   {
      Point3F pos = delta.pos + delta.posVec * dt;
      Point3F rot = delta.rot + delta.rotVec * dt;

      mHead = delta.head + delta.headVec * dt;
      setRenderPosition(pos,rot,dt);

[b]
      // apply camera effects - is this the best place? - bramage
      GameConnection* connection = GameConnection::getConnectionToServer();
      if( connection->isFirstPerson() )
      {
         ShapeBase *obj = connection->getControlObject();
         if( obj == this )
         {
            MatrixF curTrans = getRenderTransform();
            curTrans.mul( gCamFXMgr.getTrans() );
            Parent::setRenderTransform( curTrans );
         }
      }
[/b]
   }
   else
   {
      mHead = delta.head;
      setRenderPosition(delta.pos, delta.rot, 0);
   }
   updateLookAnimation();
   delta.dt = dt;
}

From what I can tell, it looks as though the render transform is modified based on the camera effect transformations. Unfortunately, Player seems to be the only class to actually do this and the bolded section of code has no effect if copied/pasted to Vehicle::interpolateTick().

Has anyone managed to implement the CameraFXManager for vehicles?

#1
07/30/2007 (10:17 pm)
D'oh! I've got it working. Forgot all about having to update the CameraFXManager from within whatever object was implementing it.

Getting camera effects working from within vehicles is a pretty simple matter. Make the following changes to get it to work [note: this is built on TGE 1.4.2 with TLK]:

(1). Add #include "game/fx/cameraFXMgr.h" to the include list at the top of vehicle.cc.

(2). Change void Vehicle::advanceTime(F32 dt) from:

void Vehicle::advanceTime(F32 dt)
{
   Parent::advanceTime(dt);

   updateLiftoffDust( dt );
   updateDamageSmoke( dt );
   updateFroth(dt);

   // Update 3rd person camera offset.  Camera update is done
   // here as it's a client side only animation.
   mCameraOffset -=
      (mCameraOffset * mDataBlock->cameraDecay +
      mRigid.linVelocity * mDataBlock->cameraLag) * dt;
}

to:

void Vehicle::advanceTime(F32 dt)
{
   Parent::advanceTime(dt);

   updateLiftoffDust( dt );
   updateDamageSmoke( dt );
   updateFroth(dt);

   // Update 3rd person camera offset.  Camera update is done
   // here as it's a client side only animation.
   mCameraOffset -=
      (mCameraOffset * mDataBlock->cameraDecay +
      mRigid.linVelocity * mDataBlock->cameraLag) * dt;

   // Update camera effects here.
   GameConnection *con = GameConnection::getConnectionToServer();
   ShapeBase *obj = con->getControlObject();
   if( obj == this)
   {
      if( mDamageState == Disabled || mDamageState == Destroyed )
      {
         // clear out all camera effects being applied to player if dead
         gCamFXMgr.clear();
      }
      gCamFXMgr.update( dt );
   }
}

(3). Change void Vehicle::interpolateTick(F32 dt) from:

void Vehicle::interpolateTick(F32 dt)
{
   Parent::interpolateTick(dt);

   if(dt == 0.0f)
      setRenderPosition(mDelta.pos, mDelta.rot[1]);
   else
   {
      QuatF rot;
      rot.interpolate(mDelta.rot[1], mDelta.rot[0], dt);
      Point3F pos = mDelta.pos + mDelta.posVec * dt;
      setRenderPosition(pos,rot);
   }
   mDelta.dt = dt;
}

to:

void Vehicle::interpolateTick(F32 dt)
{
   Parent::interpolateTick(dt);

   if(dt == 0.0f)
      setRenderPosition(mDelta.pos, mDelta.rot[1]);
   else
   {
      QuatF rot;
      rot.interpolate(mDelta.rot[1], mDelta.rot[0], dt);
      Point3F pos = mDelta.pos + mDelta.posVec * dt;
      setRenderPosition(pos,rot);

      // apply camera effects 
      GameConnection* connection = GameConnection::getConnectionToServer();
      ShapeBase *obj = connection->getControlObject();
      if( obj == this )
      {
		 MatrixF curTrans = getRenderTransform();
         curTrans.mul( gCamFXMgr.getTrans() );

		 Parent::setRenderTransform( curTrans );
      }
   }

   mDelta.dt = dt;
}

(4). Recompile and the camera effects should be seen when piloting vehicles. :]
#2
07/31/2007 (5:51 pm)
Nice find. thanks for sharing