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.
#22
%this.advCamera.delete();
(How the hell did that get there?!)
Very nice resource thanks a lot :)
06/26/2004 (4:22 am)
Ok I got it to work. In game.cs function GameConnection::createPlayer, I had to comment out this line:%this.advCamera.delete();
(How the hell did that get there?!)
Very nice resource thanks a lot :)
#23
06/26/2004 (11:00 pm)
Well Done!
#24
However, since I've added this code to the starter.racing mod, I've had two problems:
1. I cannot drop player at camera, drop camera at player, or toggle camera(so editing missions is a pain).
2. When I attempt to reset my car after a crash or roll-over, torque crashes :(
If anyone can offer any help/advice, I'd greatly appreciate it!
07/03/2004 (6:50 pm)
Awesome! This is just what I needed.However, since I've added this code to the starter.racing mod, I've had two problems:
1. I cannot drop player at camera, drop camera at player, or toggle camera(so editing missions is a pain).
2. When I attempt to reset my car after a crash or roll-over, torque crashes :(
If anyone can offer any help/advice, I'd greatly appreciate it!
#25
Brad
I was able to fix my own problem. It appears that I had to implement the key binds in two files. default.bind.cs and in defaults.cs.
07/07/2004 (6:10 pm)
Hey guys I have implemented this mod and so far it looks awesome. The only thing that appears not to be working is being able to orbit around the player. I've had problems with another in what appears where the keybinds are not working. Any help on how I would get them to work would be greatly appreciated.Brad
I was able to fix my own problem. It appears that I had to implement the key binds in two files. default.bind.cs and in defaults.cs.
#26
Great resource btw. Just what I needed :)
07/08/2004 (3:53 pm)
I've got a similiar problem. The bindings are working (pressing a key will hit a breakpoint in AdvancedCamera.cc), but the transformation is never applied to the camera.Great resource btw. Just what I needed :)
#27
07/15/2004 (6:31 am)
Great Resource!!
#28
Mapping string: CamZoomOut to index: 3
At processPlayerInput: direction is 6
Error:
x/server/scripts/game.cs (351): Unknown command setCameraObject.
Object LocalClientConnection(1443) GameConnection -> NetConnection -> SimGroup -> SimSet -> SimObject
Script(game.cs):
348- %this.advCamera.setPlayerObject(%player);
349- %this.advCamera.setThirdPersonMode();
350- %this.advCamera.setFollowTerrainMode(false);
351- %this.setCameraObject(%this.advCamera);
Any ideas!
07/20/2004 (3:03 am)
I'm getting the below error. All the buttons work but they do nothing...Mapping string: CamZoomOut to index: 3
At processPlayerInput: direction is 6
Error:
x/server/scripts/game.cs (351): Unknown command setCameraObject.
Object LocalClientConnection(1443) GameConnection -> NetConnection -> SimGroup -> SimSet -> SimObject
Script(game.cs):
348- %this.advCamera.setPlayerObject(%player);
349- %this.advCamera.setThirdPersonMode();
350- %this.advCamera.setFollowTerrainMode(false);
351- %this.setCameraObject(%this.advCamera);
Any ideas!
#29
07/20/2004 (4:33 am)
Did you make all of the changes to gameconnection.cc and recompile?
#30
Feelin stupid here... after reading your post, i just tried to recompile it (again???)...
Recompile fine. Ran demo. And it worked!!!
Hmmm!!! Thanks...
07/20/2004 (4:53 am)
Don,Feelin stupid here... after reading your post, i just tried to recompile it (again???)...
Recompile fine. Ran demo. And it worked!!!
Hmmm!!! Thanks...
#31
08/01/2004 (4:35 pm)
Edit: Fixed.
#32
*Rips out the orbit mode and adds it....
08/12/2004 (11:59 am)
Cool updates. I'll have to add some of this to my version of the adv camera. Did you ever get that tether movment working? I added something like that to my camera, and it stops when its too close to the player/follow object. Its more like a Zelda*Rips out the orbit mode and adds it....
#33
But I would very much love to add your "Zelda cam" into this resource (with proper credits naturally given). I really like the camera in Zelda Wind Waker, and it would be cool to have something like that.
08/12/2004 (12:06 pm)
I never got around to work on tether and/or RTS camera, and I havent heard from Stephen for weeks (*buzz* *buzz*) about his upgrade to the orbit cam (so it moves smoothly applying acceleration instead of fixed increments)But I would very much love to add your "Zelda cam" into this resource (with proper credits naturally given). I really like the camera in Zelda Wind Waker, and it would be cool to have something like that.
#34
08/12/2004 (12:21 pm)
im having some problems getting this implemented when i press one of the camera control buttoms i get an error :serverCmdCamZoomIn´: Unknown command. please help
#35
If (like me) you would like adjustable distance in 3rd person mode - do the following:
In game/advancedCamera.cc (line 221) add the following (addition in bold):
To use this, in your scripts add the following:
client/scripts/default.bind.cs: (note: i am using $pref::Camera::CameraMode to track which camera selection is active)
now in server/scripts/commands.cs add:
Hope it helps someone :D
09/11/2004 (11:35 pm)
Hi All,If (like me) you would like adjustable distance in 3rd person mode - do the following:
In game/advancedCamera.cc (line 221) add the following (addition in bold):
MatrixF objToWorld = playerObj->getRenderTransform(); [b]mCurrentThirdPersonOffset = mDataBlock->thirdPersonOffset; // update 3rd person camera offset[/b] objToWorld.mulP(mCurrentThirdPersonOffset, &cameraPosWorld);
To use this, in your scripts add the following:
client/scripts/default.bind.cs: (note: i am using $pref::Camera::CameraMode to track which camera selection is active)
function Zoom3rdPersonCamera(%val) {
if(%val) {
if($pref::Camera::CameraMode == 1) {
commandToServer('Camera_Zoom_3rd_Person', %val);
}
}
}
moveMap.bind(mouse, "zaxis", Zoom3rdPersonCamera);now in server/scripts/commands.cs add:
function serverCmdCamera_Zoom_3rd_Person(%client, %val) {
%client.advCamera.setPlayerObject(%client);
%x_pos = firstWord(AdvCameraData.thirdPersonOffset);
%y_pos = getWord(AdvCameraData.thirdPersonOffset,1);
%z_pos = getWord(AdvCameraData.thirdPersonOffset,2);
if(%val > 0) {
%y_pos += 1;
} else {
%y_pos -= 1;
}
AdvCameraData.thirdPersonOffset = %x_pos @ " " @ %y_pos @ " " @ %z_pos;
}Hope it helps someone :D
#36
I may be wrong but I think the problem is that I am not doing the same thing on the client side, in interpolateTick(). Unfortunately, I don't think I can do exactly the same thing, since a command from a key press should register directly with the server and not with the client (or at least I don't want to update the ghost camera directly). But by the time the server updates the client with new declination and azimuth values, the client has already called interpolateTick(), which doesn't move the camera when a key is being held down. I'm not sure that this is the problem, but all I know is that my camera movement is not completely smooth.
I'm not sure how I should approach this problem. Does anyone have an idea?
09/15/2004 (9:47 pm)
I would like to make the Orbit Mode Camera work with Dungeon Siege-like controls, so that when I hold down an arrow key, the camera will continually move accordingly. What I've done so far is make the declination/azimuth change every processTick() as long as a key is held down. Unfortunately, this results in a somewhat jerky camera.I may be wrong but I think the problem is that I am not doing the same thing on the client side, in interpolateTick(). Unfortunately, I don't think I can do exactly the same thing, since a command from a key press should register directly with the server and not with the client (or at least I don't want to update the ghost camera directly). But by the time the server updates the client with new declination and azimuth values, the client has already called interpolateTick(), which doesn't move the camera when a key is being held down. I'm not sure that this is the problem, but all I know is that my camera movement is not completely smooth.
I'm not sure how I should approach this problem. Does anyone have an idea?
#37
What you want to do is record a oldPosition and a currentPosition in each tick - and send that to the client.
The client can then interpolate between the 2 values. Basically you do something like this:
So you do (pseudo code)
I hope that is correct understood by me, and that doing soething like this gives you smooth movement.
Be more than welcome to post your resulting code - or mail it to me. I'll add it to the resource
09/16/2004 (12:18 am)
The interpolation code in the adv camera is basically non existant - so try to modify that to allow for more smooth movement. I havent done much work on interpolation at all (yet), so I hope someone can confirm what I'm about to say.What you want to do is record a oldPosition and a currentPosition in each tick - and send that to the client.
The client can then interpolate between the 2 values. Basically you do something like this:
Server side
Tick Tick
| |
v v
Pos old ----->------->------>------> New pos
^ ^ ^
| | |
Interpolate Ip Ip
Client sideSo you do (pseudo code)
interpolate() {
if (deltaTime == 0) {
currentPos = newPos;
} else {
currentPos = oldPos + deltaTime*movementVector;
}
}I hope that is correct understood by me, and that doing soething like this gives you smooth movement.
Be more than welcome to post your resulting code - or mail it to me. I'll add it to the resource
#38
I also wanted smoother movement for the Orbit Camera, and thought that it shouldn't have to wait for a delay for the server update. The original player 3rd person camera doesn't lag, so I looked into that and learned about control objects and the move manager. I looked at the resource for making another control object so the user can control the camera and player at the same time (Controlling a Seperate Camera, and while that looked good I didn't want to double my network traffic per move. So this is what I decided on:
I modified GameConnection::getNextMove() (which processes client moves) to send its Move struct data directly to the client version of Advanced Camera. Then, I re-wrote the Advanced Camera function processPlayerInput() to use the Move struct to come up with the azimuth and other values. Also, I told the server to stop overwriting the client's azimuth values in the AdvancedCamera::writePacketData() function (the function that handles control object updates as far as I can tell). Doing it this way, now on the client the orbit camera is really smooth and looks great.
However, the servers position of the orbit camera was wrong.
To fix that, I had to grab the move struct once it got to the server and pass it the server's version of Advanced Camera. I did that in Player::processTick() right before the player's move info is parsed.
All in all it seems to be working pretty well. The client orbit camera looks good and is smooth (oh by the way, I'm using the mouse to orbit the camera, as that's the kind of orbit camera I wanted), and the servers position of the camera is correct (as far as I can tell).
However, this is my first time trying this kind of thing, so I don't know if it's the best way to go about it. Please feel free to point out anything in my approach that doesn't work well for some reason or some other improvements that could be made.
I'd also like to play around with the interpolateTick() per Thomas's suggestion, especially for the zoom, which is still chunky. If I get a chance to and find something interesting I'll let you all know.
09/16/2004 (8:15 am)
Hi all,I also wanted smoother movement for the Orbit Camera, and thought that it shouldn't have to wait for a delay for the server update. The original player 3rd person camera doesn't lag, so I looked into that and learned about control objects and the move manager. I looked at the resource for making another control object so the user can control the camera and player at the same time (Controlling a Seperate Camera, and while that looked good I didn't want to double my network traffic per move. So this is what I decided on:
I modified GameConnection::getNextMove() (which processes client moves) to send its Move struct data directly to the client version of Advanced Camera. Then, I re-wrote the Advanced Camera function processPlayerInput() to use the Move struct to come up with the azimuth and other values. Also, I told the server to stop overwriting the client's azimuth values in the AdvancedCamera::writePacketData() function (the function that handles control object updates as far as I can tell). Doing it this way, now on the client the orbit camera is really smooth and looks great.
However, the servers position of the orbit camera was wrong.
To fix that, I had to grab the move struct once it got to the server and pass it the server's version of Advanced Camera. I did that in Player::processTick() right before the player's move info is parsed.
All in all it seems to be working pretty well. The client orbit camera looks good and is smooth (oh by the way, I'm using the mouse to orbit the camera, as that's the kind of orbit camera I wanted), and the servers position of the camera is correct (as far as I can tell).
However, this is my first time trying this kind of thing, so I don't know if it's the best way to go about it. Please feel free to point out anything in my approach that doesn't work well for some reason or some other improvements that could be made.
I'd also like to play around with the interpolateTick() per Thomas's suggestion, especially for the zoom, which is still chunky. If I get a chance to and find something interesting I'll let you all know.
#39
If you want, you can contact me and I'll put the code into the resource (same offer as I give everyone else)
I have looked somewhat at the interpolation code, and it seems to be fairly correct what I wrote. It seems to work by the processTick() setting the transform matrix, while the interpolate sets the rendertransform matrix. On each tick the server overwrites the client settings. Still go to play a little with this yet in a few tests
09/16/2004 (9:37 am)
Sounds great Drew!!! Thanks for sharing the info.If you want, you can contact me and I'll put the code into the resource (same offer as I give everyone else)
I have looked somewhat at the interpolation code, and it seems to be fairly correct what I wrote. It seems to work by the processTick() setting the transform matrix, while the interpolate sets the rendertransform matrix. On each tick the server overwrites the client settings. Still go to play a little with this yet in a few tests
#40
Awesome resource!!!
I was wondering... I need another mode, and would like you to help me pls...
How do i rotate the Camera on the Z-axis (but not the X/Y)? Let me explain. I want
the Height to always be the same distance from player/car, like in GodView mode... But i still want the camera to rotate the same way my vehicle is going/player is running....
Now... when you crash and roll your car, the camera would stay at that height, which
means no more cameras going underground and/or crazy etc...
That should give a player the camera mode like in GTA and other racing games... I'm sure people would want that ;)
Then lastly... Is there any reason for this not to be in HEAD?
Edit: Damnit... I forgot...
Edit: Oh Yes... Did anyone manage to get the reset fixed? Cause TGE crashes when my car lands on roof and I reset (Ctrl + R)... Rickardo Cleaver also posted that problem in this same thread...
09/20/2004 (12:24 am)
Hmmm... Wonder where my post went ... Anyway... here goes againAwesome resource!!!
I was wondering... I need another mode, and would like you to help me pls...
How do i rotate the Camera on the Z-axis (but not the X/Y)? Let me explain. I want
the Height to always be the same distance from player/car, like in GodView mode... But i still want the camera to rotate the same way my vehicle is going/player is running....
Now... when you crash and roll your car, the camera would stay at that height, which
means no more cameras going underground and/or crazy etc...
That should give a player the camera mode like in GTA and other racing games... I'm sure people would want that ;)
Then lastly... Is there any reason for this not to be in HEAD?
Edit: Damnit... I forgot...
Edit: Oh Yes... Did anyone manage to get the reset fixed? Cause TGE crashes when my car lands on roof and I reset (Ctrl + R)... Rickardo Cleaver also posted that problem in this same thread...

Torque 3D Owner Entr0py
Ghost Always objects received.
Mapping string: MissionStartPhase3 to index: 10
Client Replication Startup has Happened!
fxFoliageReplicator - Client Foliage Replication Startup is complete.
*** Phase 3: Mission Lighting
Successfully loaded mission lighting file: 'starter.fps/data/missions/stronghold_f4d4221.ml'
Mission lighting done
Mapping string: MissionStartPhase3Ack to index: 2
Mapping string: MissionStart to index: 11
Mapping string: SyncClock to index: 12