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:
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:
and here is my GameConnection::setCameraObject:
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:
and change it to
In GameConnection::writePacket, find this block of code:
and change it to:
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:
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:
We'll need to clean it up after the client leaves the game, so add this to GameConnection::onClientLeaveGame
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:
And we'll want to unhook it when the player dies. Insert this at the beginning of GameConnection::onDeath:
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
Remember to comment out the mouse commands for the player movement, as these are overwritten by the orbit camera controls
Script API
To use the different camera modes you can use the following API
Selecting the camera mode is done with e.g.:
Prior to calling the above modes you have to set the PlayerObject using
To use the 3rd person target mode you also need to set a TargetObject using
To use the static or tracking camera you need to set the position the camera should be placed suing
To use the follow terrain mode in 3rd person you give a bool to
To use the vertical freedom mode in 3rd person you give a bool to
The offset values in the datablock can be changed for the camera object via script using
The orbit camera can be manipulated from script using
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.
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.
#342
any hint and help please?
Edit: Ok the crash was due to my player model. not necessarily specific to the camera.
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
Try commenting out the flag right before the server sends position info so it alway sends it and see if it works.
Like this:
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
Thanks!
Dan
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
any idea?
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
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!
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
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
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
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
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
Dan
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
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.
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
And many others like these above.
Any help for a newby in C++ ???
Thanks.
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
"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
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
Some help with this problem would be greatly appriciated
*problem solved*
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
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.
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.
#360
starter.fps/server/scripts/camera.cs (0): Unable to instantiate non-conobject class AdvancedCameraData.
Has anyone had this problem before.
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.

Torque 3D Owner Entr0py
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:
-----
In gameConnectionMoves.cpp:
in const Move NullMove under
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
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:
in void AdvancedCamera::readPacketData(GameConnection *connection, BitStream *bstream)
add this line:
and this line:
in U32 AdvancedCamera::packUpdate(NetConnection *con, U32 mask, BitStream *bstream)
add these lines:
and these lines:
That's it!