Game Development Community

dev|Pro Game Development Curriculum

Advanced Camera

by Thomas \"Man of Ice\" Lund · 04/03/2008 (11:57 am) · 480 comments

Download Code File

Description
Over time a lot of people have released camera resources, but some do not work anymore, others are hard to implement etc.

I've tried to assemble a single class to add to the engine that implements them all in one go using the same basic architecture. This enables minimum code bloat and makes it way easier to keep the code up to date.

Change log
March 3rd, 2005
Manoel made some changes to the orbit camera. Works in multiplayer now and is much nicer by using console variables

February 3rd, 2005
Fixed small big in interpolation.

February 2nd, 2005
Major changes in this one with various contributors.
* Static camera mode
* Smooth interpolation and transition between modes
* Smooth orbit camera!!!
* Vertical freedom mode when in 3rd person
* Better collision check with terrain and interiors
* Mouse control of orbit camera
* Totally reworked codebase and lots of cleanups. Much more readable now

Manoel Neto contributed the new orbit camera and the interpolation
Zik Saleeba contributed the vertical freedom mode and better collision check

Thanks a lot!!!!

I have marked changes with a New in the text below for those who upgrade

January 23rd, 2005
Minor changes. Larger update soon with new functionality
* Now takes GameBase objects as target + player
* Removed debug message in orbit camera
* Added getters for player and target object

June 25th, 2004
Updated the bindings for orbit camera. Switched left+right.

June 23rd, 2004
A big thanks to Stephen Zepp for contributing with an orbit camera mode. Its added to the resource, and is perfect for RTS games and action adventures. It allows for a camera to rotate around a user as if placed on a sphere. The user can zoom in/out, rotate and tilt the camera.

June 9th, 2004
Added getter/setter for the 3 offset values accessible from script
Added a "follow terrain" mode for the third person camera, so the camera follows the terrain slope - doesnt work perfectly

April 5th, 2004
All camera modes now use a raycast to not get hidden behind terrain or interiors

April 3rd, 2004
This release is the first release, and might not be as "advanced" as the author would like, but its time to release it and get some feedback to further enhance it down the road.

Camera Modes Implemented
The resource currently implements the following camera systems:
* Track Mode
This is the same as the tracking camera resource posted by Cory Osborn. A stationary camera tracks the player and keeps him in focus.

* New Static Mode
Camera stays in its position and rotation. Useful for e.g. scene based adventures where the camera doesnt move with the players

* Third Person Mode
The camera is placed at an offset behind the player and rotates with the player. The camera itself is not controllable

* Third Person Track Mode
The camera is placed in third person mode but rotated so it always looks at a specified object, but with the player in full view

* God View
Camera is placed at an offset from the player and does not rotate with the player. This is your typical "Diablo" kind of camera.

* New Orbit Mode
Camera is placed on a sphere looking at the player, and can rotate/tilt and zoom controlled by the player. There are bindings to the mouse when in single player game (server and client on same machine)

Movie
Here is a small movie displaying the different camera modes (3 MB)
www.codejar.com/advancedcamerademo.wmv

How to Add
First off all you need to take the attached advancedCamera.cc/h files and add to engine\game and add them to the project.

Then you need to expose the camera object in GameConnection as described in Cory's resource www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4720

I took the liberty to paste the relevant parts in here too

Exposing mCameraObject
The first thing you want to do is add console method's to access the GameConnection setCameraObject/getCameraObject methods. I added these to GameConnection.cc right after the console method for getControlObject:

ConsoleMethod( GameConnection, setCameraObject, bool, 3, 3, "(ShapeBase object)")
{
   ShapeBase *gb;
   if(!Sim::findObject(argv[2], gb))
      return false;

   object->setCameraObject(gb);
   return true;
}

ConsoleMethod( GameConnection, getCameraObject, S32, 2, 2, "")
{
   argv;
   SimObject* cp = object->getCameraObject();
   return cp ? cp->getId(): 0;
}

ConsoleMethod( GameConnection, clearCameraObject, void, 2, 2, "")
{
   object->setCameraObject(NULL);
}

After playing around with it, I also found you need some adjustments to the setCameraObject and setControlObject methods - otherwise the client connection can screw things up if you bounce the same object from your connection's control to camera or vice versa. Here is my GameConnection::setControlObject:

void GameConnection::setControlObject(ShapeBase *obj)
{
   if(mControlObject == obj)
      return;

   if(mControlObject && mControlObject != mCameraObject) 
      mControlObject->setControllingClient(0);
   
   if(obj)
   {
      // Nothing else is permitted to control this object.
      if (ShapeBase* coo = obj->getControllingObject())
         coo->setControlObject(0);
      if (GameConnection *con = obj->getControllingClient()) 
      {
         if (this != con) 
         {
            // was it controlled via camera or control?
            if (con->getControlObject() == obj)
               con->setControlObject(0);
            else
               con->setCameraObject(0);
         }
      }

      // We are now the controlling client of this object.
      obj->setControllingClient(this);
   }

   // Okay, set our control object.
   mControlObject = obj;
   if (mCameraObject.isNull())
      setScopeObject(mControlObject);
}


and here is my GameConnection::setCameraObject:

void GameConnection::setCameraObject(ShapeBase *obj)
{
   if(mCameraObject == obj)
      return;

   if(mCameraObject && mCameraObject != mControlObject) 
      mCameraObject->setControllingClient(0);
   
   if (obj) {
      // Nothing else is permitted to control this object.
      if (ShapeBase* coo = obj->getControllingObject())
         coo->setControlObject(0);
      if (GameConnection *con = obj->getControllingClient()) 
      {
         if (this != con) 
         {
            // was it controlled via camera or control?
            if (con->getControlObject() == obj)
               con->setControlObject(0);
            else
               con->setCameraObject(0);
         }
      }

      // We are now the controlling client of this object.
      obj->setControllingClient(this);
   }

   // Okay, set our camera object.

   mCameraObject = obj;

   if (mCameraObject.isNull()) {
      setScopeObject(mControlObject);
   } else {
      setScopeObject(mCameraObject);
      // if this is a client then set the fov and active image
      if(isServerConnection())
      {
         F32 fov = mCameraObject->getDefaultCameraFov();
         GameSetCameraFov(fov);
      }
   }
}

Camera read/write packets
None of this will work unless the client copy of the camera object gets packets updated. Here we're going to modify GameConnection::readPacket and GameConnection::writePacket.

In GameConnection::readPacket, find this block of code:

if (bstream->readFlag())
      {
         S32 gIndex = bstream->readInt(10);
         ShapeBase* obj = static_cast<ShapeBase*>(resolveGhost(gIndex));
         setCameraObject(obj);
      }
      else
         setCameraObject(0);

and change it to

if (bstream->readFlag()) 
      {
         S32 gIndex = bstream->readInt(NetConnection::GhostIdBitSize);
         ShapeBase* obj = static_cast<ShapeBase*>(resolveGhost(gIndex));
         setCameraObject(obj);
         obj->readPacketData(this, bstream);
      }
      else
         setCameraObject(0);


In GameConnection::writePacket, find this block of code:

if (!mCameraObject.isNull() && mCameraObject != mControlObject)
      {
         gIndex = getGhostIndex(mCameraObject);
         if (bstream->writeFlag(gIndex != -1))
            bstream->writeInt(gIndex, 10);
      }
      else
         bstream->writeFlag( false );

and change it to:

if (!mCameraObject.isNull() && mCameraObject != mControlObject) 
      {
         gIndex = getGhostIndex(mCameraObject);
         if (bstream->writeFlag(gIndex != -1)) {
            bstream->writeInt(gIndex, NetConnection::GhostIdBitSize);
            mCameraObject->writePacketData(this, bstream);
         }
      }
      else
         bstream->writeFlag( false );

Recompile it all and the engine is ready to go.

Script

To use the camera you need to follow some of Corys resource, but with some modifications. Datablock and naming has changed

First, add a datablock for the tracking camera to /fps/server/scripts/camera.cs:

...
datablock AdvancedCameraData(AdvCameraData)
{
   lookAtOffset = "0 0 2";
   thirdPersonOffset = "0 -3 3";
   godViewOffset = "0 -20 20";
   maxTerrainDiff = 2;
   orbitMinMaxZoom = "5 100";
   orbitMinMaxDeclination = "10 80";
   damping = 0.25;

};
...

Next, add it to the connection just like is currently done with the base camera class. Add this inside GameConnection::onClientEnterGame (/fps/server/scripts/game.cs), right after %this.camera is set up:

...
   // create advanced camera
      %this.advCamera = new AdvancedCamera() {
      dataBlock = AdvCameraData;
   };
   MissionCleanup.add(%this.advCamera);
   %this.advCamera.scopeToClient(%this);
...


We'll need to clean it up after the client leaves the game, so add this to GameConnection::onClientLeaveGame

...
   if (isObject(%this.advCamera))

      %this.advCamera.delete();
...


We need to tell it what to do when added and assign the connection's camera object, so add this to the end of GameConnection::createPlayer:

...
  // We set the camera system to run in 3rd person mode around the %player
  %this.advCamera.setPlayerObject(%player);
  %this.advCamera.setThirdPersonMode();
  %this.advCamera.setFollowTerrainMode(false);
  %this.advCamera.setVerticalFreedomMode(false);
  %this.setCameraObject(%this.advCamera);
...


And we'll want to unhook it when the player dies. Insert this at the beginning of GameConnection::onDeath:

...
   // clear connections camera
   %this.advCamera.clearPlayerObject();
   %this.advCamera.clearTargetObject();
   %this.clearCameraObject();
...

The last thing to know, is if you're in first-person mode, GameConnection automatically uses the control object to render the engine rather than the camera object. So if you don't see this working when you first enter a mission, toggle out of first-person.

Orbit mode
To use the orbit camera, one needs to add some key binds to manipulating the camera.

All you need to do, is add the following to your client\config.cs or better to your client\scripts\default.bind.cs

//------------------------------------------------------------------------------
// Advanced Camera Movement
//------------------------------------------------------------------------------

$cameraYawSpeed = -100.0;
$cameraPitchSpeed = -50.0;
$cameraZoomSpeed = -5.0;

function rotateCameraHorizontal(%val)
{
     $advCamera::Yaw = getMouseAdjustAmount(%val)*$cameraYawSpeed ;
}

function rotateCameraVertical(%val)
{
     $advCamera::Pitch = getMouseAdjustAmount(%val)*$cameraPitchSpeed;
}

function zoomCamera(%val)
{
     $advCamera::Zoom = getMouseAdjustAmount(%val)*$cameraZoomSpeed;
}

moveMap.bind( mouse, xaxis, rotateCameraHorizontal);
moveMap.bind( mouse, yaxis, rotateCameraVertical );
moveMap.bind( mouse, zaxis, zoomCamera );

Remember to comment out the mouse commands for the player movement, as these are overwritten by the orbit camera controls
//moveMap.bind( mouse, xaxis, yaw );
//moveMap.bind( mouse, yaxis, pitch );

Script API
To use the different camera modes you can use the following API
Selecting the camera mode is done with e.g.:
%this.advCamera.setTrackMode();
  %this.advCamera.setThirdPersonMode();
  %this.advCamera.setThirdPersonTargetMode();
  %this.advCamera.setGodViewMode();
  %this.advCamera.setOrbitMode();
  %this.advCamera.setStaticMode();

Prior to calling the above modes you have to set the PlayerObject using
setPlayerObject();

To use the 3rd person target mode you also need to set a TargetObject using
setTargetObject();

To use the static or tracking camera you need to set the position the camera should be placed suing
setCameraPosition(Point3F pos);

To use the follow terrain mode in 3rd person you give a bool to
setFollowTerrainMode(true/false);

To use the vertical freedom mode in 3rd person you give a bool to
setVerticalFreedomMode(true/false);
This only works if the player object is a Player, because it uses the head movement.

The offset values in the datablock can be changed for the camera object via script using
get/setLookAtOffset();
get/setThirdPersonOffset();
get/setGodViewOffset();
The setters take a Point3F as argument.

The orbit camera can be manipulated from script using
get/setOrbitMinMaxZoom()
get/setOrbitMinMaxDeclination()
The min/max take a Point2F

You can also manipulate the orbit camera directly by assigning values to the following variables
[code]
$advCamera::Yaw
$advCamera::Pitch
$advCamera::Zoom
$advCamera::azimuth
$advCamera::declination
$advCamera::zoomDistance
[code]

All camera modes coexist, so you can set the position, player object and target object once and then switch camera modes around as you see fit. Switching mode will not clear the old objects/positions.
#341
02/06/2007 (10:49 pm)
Ok here's the code I promised. These changes cause the server to update the camera's position rather than the camera being completely clientside.

BUGS
--The camera is jerky because it needs interpolation. I tried for days to get it to work but frankly I got sick of it. I am no math wiz, so perhaps one of you guys might be able to fix it.

--I have only tested this in orbit mode, so other modes may or may not work.

NOTES

-- There is a lot of code that could probably be removed since the client no longer uses it. For the sake of brevity I am only going to post the stuff that needs to be changed to get it to work (based on the original unmodified resource)

-- I am working with TGEA so the only difference between TGEA and non-TGEA is commenting out the include to dgl.h in advancedCamera.cc for TGEA. Also I will refer to files as .cpp files, but in TGE I believe they are still .cc files.

-- I have highlighted changed lines in bold

-- Edited on Feb 08, 2007 20:42 - Removed "interpolation" code from advancedCamera::setPosition, it was interfering with the server position of the camera.



----------------------------------------------------------

First we need to alter the move struct to allow for Yaw Pitch and Zoom variables to be passed to the server. This will allow us to have camera controls seperate from the controlobject's.

-----
In moveManager.h:

F32 yaw, pitch, roll; // 0-2PI
[b]
   F32 cyaw, cpitch, czoom; // camera controls
[/b]

-----
In gameConnectionMoves.cpp:

in const Move NullMove under
0,0,0,   // Yaw, pitch, roll,
[b]
   0,0,0,   // cyaw, cpitch, czoom camera controls
[/b]

in void Move::pack(BitStream *stream)
if(stream->writeFlag(proll != 0))
       stream->writeInt(proll, 16);
[b]
   if(stream->writeFlag(cyaw != 0))
      stream->write(cyaw);
   if(stream->writeFlag(cpitch != 0))
      stream->write(cpitch);
   if(stream->writeFlag(czoom != 0))
      stream->write(czoom);
[/b]

In void Move::unpack(BitStream *stream)
proll = stream->readInt(16);
    else
       proll = 0;
[b]

   if(stream->readFlag())
       stream->read(&cyaw);
   else
      cyaw = 0;
   if(stream->readFlag())
       stream->read(&cpitch);
   else
      cpitch = 0;
   if(stream->readFlag())
       stream->read(&czoom);
   else
      czoom = 0;

[/b]

In bool GameConnection::getNextMove(Move &curMove)
curMove.yaw = MoveManager::mYaw + yawAdd;
    curMove.roll = MoveManager::mRoll + rollAdd;

[b]
   curMove.cyaw    = Con::getFloatVariable( "$advCamera::Yaw",   0.0 );
   curMove.cpitch   = Con::getFloatVariable( "$advCamera::Pitch",  0.0 ); 
   curMove.czoom  = Con::getFloatVariable( "$advCamera::Zoom", 0.0 );

[/b]

-----

Now the server camera object needs access to the servers move struct:

In gameProcess.cpp:

In the includes, add an include for advancedCamera.h
[b]
#include "game/advancedCamera.h"
[/b]

In void ProcessList::advanceObjects():
// with objects being deleted from within the process method.
    GameBase list;
    GameBase* obj;
[b]
   AdvancedCamera * cam;
[/b]

Farther down (don't forget the else!):
con->getMoveList(&movePtr, &numMoves);
 
[b]		    if(SimObject *camera = con->getCameraObject())
 			   if (camera->getClassName()=="AdvancedCamera")
			   cam = static_cast<AdvancedCamera *>(camera);
[/b]
                     for (m = 0; m < numMoves && pGB->getControllingClient() == con; )
[b]			{
				if(cam)
				   cam->processTick(&movePtr[m]);
[/b]                          obj->processTick(&movePtr[m++]);
[b]			}
 [/b]              con->clearMoves(m);

             continue;
          }
       }
[b]	  if(obj->getClassName() == "AdvancedCamera" && obj->isServerObject())
		  continue;
      else [/b]if (obj->mProcessTick)
          obj->processTick(0);

-----

Now we need the server to properly update ticks:

In advancedCamera.cpp

We need to remove almost everything in void AdvancedCamera::advanceTime(F32 dt) so it looks liek this:
// Update camera position every time time is advanced
void AdvancedCamera::advanceTime(F32 dt) {

	Parent::advanceTime(dt);
}

and put it all in void AdvancedCamera::processTick(const Move* move) (with some other stuff) so that it looks like this:
void AdvancedCamera::processTick(const Move* move) {
	Parent::processTick(move);
[b]

   if(move)
   {
      mYaw=move->cyaw;
      mPitch=move->cpitch;
      mZoom=move->czoom;
   }
		updateMovementValues(1);

	// This will hold the new position of the camera
	Point3F	cameraPosWorld;

	// Grab the player and target object used in most modes
	GameBase *castObj = mPlayerObject;
	ShapeBase* playerObj = dynamic_cast<ShapeBase*>(castObj);
	castObj = mTargetObject;
	ShapeBase* targetObj = dynamic_cast<ShapeBase*>(castObj);

	// Update position based on which mode the camera is in
	switch (mMode)
	{
	case TrackMode :
	case StaticMode :
		{
			// Set the camera to its fixed position
			cameraPosWorld = mCameraPos;
			break;
		}

	case ThirdPersonMode :
		{
			// Move camera to third person offset position			
			if(	playerObj != NULL )	{
				MatrixF	objToWorld;
				// If the vertical freedom mode is on, and the player object is a player
				// then we can adjust the tilt of the camera using the head rotation
				Player*	playerObjAsPlayer =	dynamic_cast<Player*>(playerObj);
				if (mVerticalFreedom &&	playerObjAsPlayer != NULL) {

					Point3F	DistanceBehindHead(0, mCurrentThirdPersonOffset.y, 0);
					Point3F	DistanceAboveGround(0, 0, mCurrentThirdPersonOffset.z);

					objToWorld = playerObjAsPlayer->getRenderTransform();
					Point3F	HeadRotation = playerObjAsPlayer->getHeadRotation();
					F32	HeadPitch =	HeadRotation.x;
					MatrixF	HeadPitchMatrix( EulerF( HeadPitch,	0, 0 ) );
					objToWorld.mul(HeadPitchMatrix);

					objToWorld.mulP(DistanceBehindHead,	&cameraPosWorld);
					cameraPosWorld += DistanceAboveGround;
				}
				else {
					objToWorld = playerObj->getRenderTransform();
					objToWorld.mulP(mCurrentThirdPersonOffset, &cameraPosWorld);
				}
			}
			break;
		}  
	case ThirdPersonTargetMode :
		{
			// Calculate vector from player to target, and move camera to offset
			if( playerObj != NULL && targetObj != NULL) {
				MatrixF objToWorld = playerObj->getRenderTransform();
				VectorF dirVec = targetObj->getPosition() - playerObj->getPosition();
				dirVec.normalize();
				objToWorld.setColumn(1, dirVec);			
				objToWorld.mulP(mCurrentThirdPersonOffset, &cameraPosWorld);
			}
			break;
		}
	case GodViewMode :
		{
			// Move camera to track object position
			// and add the offset
			if( playerObj != NULL ) {
				playerObj->getRenderTransform().getColumn(3, &cameraPosWorld);
				cameraPosWorld += mCurrentGodViewOffset;
			}
			break;
		}
	case OrbitMode :
		{
			if ( playerObj != NULL)
			{
				Point3F mConvertedOrbitOffset;
				F32 mOffsetX;
				F32 mOffsetY;
				F32 mOffsetZ;

				MatrixF objToWorld = playerObj->getRenderTransform();
				objToWorld.mulP(mCurrentOrbitOffset, &cameraPosWorld);

				// use spherical to cartesian coord transforms to calculate offset
				mOffsetX = mZoomDistance * sin(mDeclination) * cos(mAzimuth);
				mOffsetY = mZoomDistance * sin(mDeclination) * sin(mAzimuth);
				mOffsetZ = mZoomDistance * cos(mDeclination);
				mConvertedOrbitOffset.set(mOffsetX, mOffsetY, mOffsetZ);
				cameraPosWorld += mConvertedOrbitOffset;
			}
			break;
		}
	default :
		{
			// Somehow we ended up here. Should not happen ever
			Con::errorf("process tick with no mode");
			break;
		}
	}

	// Attempt to follow the terrain if enabled
	if (mFollowTerrain == true && playerObj != NULL) {
		cameraPosWorld = adjustCameraToTerrain(playerObj->getRenderPosition(), cameraPosWorld);
	}

	// Adjust camera position if it collides with "stuff"
	// for all modes except track mode
	if (mMode && mMode != TrackMode && playerObj != NULL) {
		cameraPosWorld = runCameraCollisionCheck(playerObj->getRenderPosition(), cameraPosWorld);
	}

	// Place camera into its final position	
	if(isServerObject());
	setPosition(cameraPosWorld);

	// If on the client, calc delta for backstepping
	if (isClientObject()) {
		setPosition(delta.posVec);
// FIX ME - need interpolation
//		delta.pos = getPosition();
//		delta.rot = getRotation();
//		delta.posVec = delta.posVec - delta.pos;
//		delta.rotVec = delta.rotVec - delta.rot
	}

	if (getControllingClient() && mContainer)
		updateContainer();
[/b]
}

replace void AdvancedCamera::setPosition(const Point3F& pos) with this:
[b]
// Sets the position and calculates rotation
void AdvancedCamera::setPosition(const Point3F& pos) {

	// Set rotation to point at the tracked object
	MatrixF transMat;
	ShapeBase* obj = dynamic_cast<ShapeBase*>(static_cast<SimObject*>(mPlayerObject));
	if (obj && mMode != StaticMode && isServerObject()) {
		Point3F objPos;
		getLookAtPos(&objPos);

		VectorF dirVec = objPos - pos;
		dirVec.normalize();

		MathUtils::getAnglesFromVector(dirVec, mRot.z, mRot.x);
		mRot.x = 0 - mRot.x;

		transMat = MathUtils::createOrientFromDir(dirVec);
	    transMat.setColumn(3, pos);

	} else {
		MatrixF xRot, zRot;
		xRot.set(EulerF(mRot.x, 0, 0));
		zRot.set(EulerF(0, 0, mRot.z));
		transMat.mul(zRot, xRot);
		transMat.setColumn(3, pos);
	}

	Parent::setTransform(transMat);
}
[/b]

in void AdvancedCamera::writePacketData(GameConnection *connection, BitStream *bstream)

Add this line:
mObjToWorld.getColumn(3,&pos);
 	bstream->setCompressionPoint(pos);
 	mathWrite(*bstream, pos);
[b]	mathWrite(*bstream, mRot);[/b]
 	mathWrite(*bstream, mCameraPos);
 	mathWrite(*bstream, mCurrentLookAtOffset);
 	mathWrite(*bstream, mCurrentThirdPersonOffset);

in void AdvancedCamera::readPacketData(GameConnection *connection, BitStream *bstream)

add this line:
Point3F pos;
	mathRead(*bstream, &pos);
	[b]mathRead(*bstream, &mRot);[/b]
	bstream->setCompressionPoint(pos);
	mathRead(*bstream, &mCameraPos);
	mathRead(*bstream, &mCurrentLookAtOffset);

and this line:
deleteNotify(mTargetObject);
 		}
 	}
[b]	delta.posVec=pos;[/b]
 }
in U32 AdvancedCamera::packUpdate(NetConnection *con, U32 mask, BitStream *bstream)

add these lines:
bstream->write(pos.x);
 		bstream->write(pos.y);
 		bstream->write(pos.z);
[b]		bstream->write(mRot.x);
		bstream->write(mRot.y);
		bstream->write(mRot.z);[/b]

and these lines:
bstream->read(&pos.x);
 		bstream->read(&pos.y);
 		bstream->read(&pos.z);
[b]		bstream->read(&mRot.x);
		bstream->read(&mRot.y);
		bstream->read(&mRot.z);
	    setPosition(pos);[/b]

That's it!
#342
02/14/2007 (6:01 pm)
I am running in a networked enviornment where remote player 1's advCamera sets target on remote player2. I am getting random crashes 1 out of 5/6 times when I join the server. It seems very random yet happens consistently every 5th time when I join server and sets this player's camera to view a remote client's player.
any hint and help please?

Edit: Ok the crash was due to my player model. not necessarily specific to the camera.
#343
02/15/2007 (2:25 pm)
I implemented Shannon and Pisal Setthawong's code to save network bandwidth, but now the mouse and zoom won't work in orbital mode, any idea?
#344
02/17/2007 (4:32 pm)
Gamer:

Try commenting out the flag right before the server sends position info so it alway sends it and see if it works.

Like this:

//	bstream->writeFlag(bCameraPos);
//	if (bCameraPos)
		mathWrite(*bstream, mCameraPos);
//	bCameraPos = false;
#345
02/18/2007 (7:07 pm)
in 1.5....the camera works fine with the default player. as soon as i change it to anything else ( a simple cube with no animations) then things dont work. the first person view is fine, but as soon as i switch to the tab view (god mode in my case, but ive tried all the others) i get a gray screen and i dont see anything else. the cube model looks normal as i can see the kork player cube running around...i have the nodes set for cam and eye....what do i need to call script wise to see what's going on / where things are going wrong...any help would be greatly appreciated.
Thanks!

Dan
#346
02/24/2007 (7:23 pm)
I am unable to see any players(aiplayer or regular player) unless I set the advanced camera on them, in which case I would just see the target player, but noone else.
any idea?
#347
02/24/2007 (7:33 pm)
Ok found the cause of my problem of why other players were not visible. the visibleDistance for sky in mission map must be set big enough( it was 200, then I changed to 1500) now i can see the other players from the advanced camera.
#348
03/03/2007 (7:01 am)
Sorry to post something so basic, but i'm having trouble getting the camera to move. It looks like the code is unable to find the AdvancedCameraData. Here are the two errors i'm getting:

server/scripts/camera.cs(27) -- Unable to instantiate AdvancedCameraData

and

server/scripts/game.cs(220) -- Unable to instantiate AdvancedCamera

i'd say the C++ code isn't implemented properly by me, but i've followed instructions and even compiled the code a second time, but nothing happened.

I'm using Torque 1.5, and i'm a bit bummed out because i've managed to get it in 1.4 and 1.3 before. What am i forgetting, cause i don't see it at the moment.

Thanks in advance.

>> EDIT: Sorry for being an idiot. I compiled Torque in Debug mode, not release. So i kept starting up the wrong .exe Works fine now!!! Thanks!
#349
03/27/2007 (1:11 pm)
Problem:

I am using the AdvancedCamera, and everything works great, except when in Static Mode, I cannot point the camera down.

%this.advCamera.setLookAtOffset( %dir );

works fine, as long as the z component of %dir is positive. Otherwise, the world seems to disappear.

Thanks in advance for any advice
#350
03/27/2007 (5:51 pm)
has anyone been able to get the camera working with a dts other than original?
what do i need to change? i can get the mod working but once i change the player.dts i cannot get the camera to work properly (the scene renders all grey as if im inside the model or really far away).
how can i tell where the camera is relative to the player?
thanks for any help!

Dan
#351
03/28/2007 (1:45 am)
I think there's a script function to get the camera's position. I dont know because i heavily changed this code. The way i used it is just by printing out the Point3F cameraPosWorld in AdvancedCamera::interpolateTick (or ProcessTick, if you didnt change it) to the console. Con::printf("%f %f %f", cameraPosWorld.x, cameraPosWorld.y, cameraPosWorld.z);. This spams the console a load but you can allways read it back in console.log.
#352
03/31/2007 (5:50 pm)
im a little new to torque...im having difficulty knowing what i can print out from the console by default and when i need to add something to the engine to print some variables...any good tutorials/books/resources on debugging/getting around in the code? thanks again!

Dan
#353
04/01/2007 (6:38 am)
Well most is basic c++ knowledge but like i said, adding

Con::printf("%f %f %f", cameraPosWorld.x, cameraPosWorld.y, cameraPosWorld.z);

to AdvancedCamera::ProcessTick at the bottom then it will show them in the console.. or spam them is a better word :) . I'm not some advanced torque coder either, but with basic c++ knowledge and help of intellisense (it's in visual studio 2005, very usefull) you can find a lot of functions in torque. If you dont have intellisense you can look in the doxygen documentation from torque which does basicly the same thing only on a website.
#354
04/03/2007 (7:48 am)
I'm trying to compile the 1.5 version and got some errors.

error C3861: 'isServerConnection': identifier not found, even with argument-dependent lookup

error C2556: 'S32 cGameConnectionsetCameraObject(GameConnection *,S32,const char ** )' : overloaded function differs only by return type from 'bool cGameConnectionsetCameraObject(GameConnection *,S32,const char ** )'
        c:\Torque-SDK-1-5-0-AdvCam\engine\game\gameConnection.cc(1265) : see declaration of 'cGameConnectionsetCameraObject'

error C2371: 'cGameConnectionsetCameraObject' : redefinition; different basic types
        c:\Torque-SDK-1-5-0-AdvCam\engine\game\gameConnection.cc(1265) : see declaration of 'cGameConnectionsetCameraObject'

And many others like these above.

Any help for a newby in C++ ???

Thanks.
#355
04/03/2007 (8:05 am)
If you read the comments then it says:

"Just adding to a recent CVS and notice
the bool isServerConnection()
is now
isConnectionToServer()"

and if you're getting loads more errors, dont forget to include those advancedcamera files to your project
#356
04/09/2007 (5:53 am)
I'm trying to use this in TGEA , i get the camera to work fine but i can not view from it witout it being the controllable object. The camera works if i have it as controllable object so it seems like it could be the setCameraObject that is not working.

Some help with this problem would be greatly appriciated

*problem solved*
#357
04/11/2007 (1:10 am)
@Entr0py: Have you added this changes to the "original" advancedCamera.cc and .h?

I have implement your changes, but then the game crashs, probably at the first frame ingame. I have used a clean TGEA and startet with the old camera, so it muss be something in your modifikation. Only with the original advancedCamera-files (without dgl.h ;) ) i have no errors and no crashes.
#358
04/12/2007 (12:30 pm)
This works fine in TGE 1.5.1; just merged it in to the new build.
#359
04/12/2007 (3:24 pm)
Thanks for help @Robin.

Works fine now =D
#360
04/16/2007 (12:13 pm)
Am get this error:
starter.fps/server/scripts/camera.cs (0): Unable to instantiate non-conobject class AdvancedCameraData.

Has anyone had this problem before.