Game Development Community

Separate Camera Object... that moves

by Christian Boutin · in Torque Game Engine · 12/27/2005 (2:20 pm) · 10 replies

I've used Cory Osborn's excellent "Using a Separate Camera" to at last manage to detach the camera from the protagonist. Believing I could use this as a starting ground to finally get a camera I can control in the code (rather than one tied to the control character) I started to build on it. But I can't seem to be able to move it smoothly. If I move the target in the getLookAtPos, it's all smooth and fine. But if I change the position of the camera in processTick, then it becomes jittery and stutters alot. Maybe processTick isn't the right place to handle this? If not then where? Any idea would help. Thanks, and here's some code snippet:

I've renamed the class RailCamera (in the end I want it to follow a path (or rail)).

Here's my ProcessTick. At one point I change the delta.posVec, which creates alot of weird stuttering of the image.

void RailCamera::processTick(const Move* move) {
//Move* neo_move = (Move*)malloc(sizeof(Move));
//memcpy(neo_move, move, sizeof(Move));

Point3F tpos;

Parent::processTick(move);

// get pre-tick position
mObjToWorld.getColumn(3,&delta.posVec);

ShapeBase* obj = dynamic_cast(static_cast(mTrackObject));
if (obj != NULL){
obj->getRenderTransform().getColumn(3, &tpos);
delta.posVec.y += (tpos.y-delta.posVec.y)/100;// <- this will cause a stuttering problem as it moves the actual camera
delta.posVec.x += (tpos.x-delta.posVec.x)/100;


}else{
Con::printf("Camera Target is NULL");
}
//delta.pos = delta.posVec;



setPosition(delta.posVec);

// If on the client, calc delta for backstepping
if (isClientObject()) {
delta.posVec = delta.posVec - delta.pos;
}
setMaskBits(MoveMask);
if (getControllingClient() && mContainer)
updateContainer();
}

//This is my getLookAtPos, notice that in this one the lookatPos changes but that creates no stuttering

bool RailCamera::getLookAtPos(Point3F* lookAtPos) {
ShapeBase* obj = dynamic_cast(static_cast(mTrackObject));
if (obj == NULL)
return false;

obj->getRenderTransform().getColumn(3, lookAtPos);

targetPos.x += (lookAtPos->x-targetPos.x)/10;
targetPos.y += (lookAtPos->y-targetPos.y)/10;


lookAtPos->x = targetPos.x;
lookAtPos->y = targetPos.y;

return true;
}

#1
12/27/2005 (2:30 pm)
Why not just use the pathed camera resource? The demos, especially the WarZone demo put it to great use.
#2
12/27/2005 (3:00 pm)
I've tried integrating Object moving along path and Camera moving along path to my 1.4 build and I get tons of compilation errors. Are these resources supposed to work with 1.4?

Anyway I'd like it to eventually move along a path but I'd also like to have complete control over it so if I want to alter it's movement along the path (to simulate a hit or other events) I'd like to understand how to move it myself so I can do that.
#3
12/27/2005 (4:03 pm)
I think the problem with my code is that I update the SetPosition only with each ProcessTick, while the "lookAt" is handled at each interpolation. But the think is, if I put the

delta.posVec.x += (tpos.x-delta.posVec.x)/100;

near the end of the ProcessTick function, which should help InterpolateTick know what to do with the camera, then when I get back to ProcessTick the camera's position is reset. Which gives the effect that the camera is fighting against itself to move, but resets to it's previous position every few frames.

Anyone has any idea how to deal with this?
#4
12/31/2005 (6:44 pm)
Why not set the lookAt pos every interpolateTick from the renderPosition of the object..?
#5
01/01/2006 (7:50 pm)
I'm not sure I understand what you mean.

The lookAt behaves the way I want, Cory Osborn's resource is excellent for a stationary camera that changes it's "lookat" position every frame. However it's the camera's position itself that I need updated every frame, and both ways I've found to move it do not work.

Way 1: Calling a setPosition every ProcessTick means that the camera will only move every X frames which gives a very choppy feel to the camera's movement. I'm sure that's not the way to go.

Way 2 : Moving it during the InterpolateTick. This creates a fluid movement but for some reason once the ProcessTick is called, the progress the camera made during the InterpolateTick is forgotten and the camera snaps back to where it was at the last ProcessTick. Now I know that's because there's some value somewhere I don't update that I should. I just don't know what it is.

I can make the whole project available to anyone who'd want to take a look.
#6
01/02/2006 (3:31 am)
Are you sure you're updating the delta structure for the camera? Also, be aware that interpolateTick has some weird semantics associated with it. I'd suggest adding a print out in processTick and interpolateTick so you know when they're getting called in what order and with which parameters.
#7
01/02/2006 (9:34 pm)
I've returned to the original trackingcamera.cc (which I've renamed RailCamera) and started over but I'm going around in circle. I've made a few additionnal tests and the results want to make my head explode :

First thing I want to point out is that putting a breakpoint in the constructor of RailCamera will reveal that the class is build three times before the main menu even shows up. I found that a bit strange considering the script doesn't create a RailCamera until later, but I figure it's used for some kind of maintenance/initialization so I didn't mind it.

I created a new Point3F variable in the RailCamera class called "Point3F wanna_be_pos". After adding a breakpoint in the InterpolateTick method I discovered that every few (10/20) frames the values of wanna_be_pos would be completely lost but then (after another 10-20 frames) they would come back. I added a watch on "this" and this is when I started to bleed from the ears.

The value of "this" changes every 10-20 frames, and whenever it changes my "wanna_be_pos" variable is lost, but "this" will come back to it's original value after another 10-20 frames. I figured it must've been casted as something else as that happens sometimes in C++ (this changes because the class has been called as another type). I looked at the stack and it's called from the exact same line wether the "this" is the right or wrong value.

Now it's possible that this morphing of the value of "this" has something to do with value of the camera resetting every few frames, or it can be completely unrelated, I'm still completely puzzled as to what's going on with the value of "this" changing in such a way. If anyone has been through that and wants to share thoughts or ideas, believe me you're quite welcome :-D

Time to sleep on that.
#8
01/08/2006 (1:39 am)
Er... you're aware the game runs two copies of the object, one for client and one for server, right? And only the client gets interpolated?
#9
01/08/2006 (3:18 pm)
Yes I was aware of that, interpolation is when the client has to figure out where stuff is headed to compensate for latency.

Thanks for helping me, I managed to find Cory Osbourne's latest 2 resources and merged them with 1.4 and it seems to work.

However after much internal debate I've decided to move away from Torque for the time being. Ever since I started to work with Torque more than a year ago the very first thing I wanted to do is to have my own camera and be able to move it and aim it as I wished within the game. I've been swimming in quicksand ever since.

Although I recognize that Torque may be a great engine for first person and close-by third person games, it is not appropriate for what I wish to develop, which requires constant camera movement/adjustments.

I came back to Torque for 1.4 because I hoped the camera system had improved, but I still find myself knee-deep in third party resources trying to get what I believe should be a very basic camera system (be here, look there, move here, track that). And as these resources may not have been thoroughly tested or supported, I have no idea how well they'll react once the game is far enough in development or when I decided to implement multiplayer.

I'll keep an eye on the site and come back at the next major release, maybe then there will be a camera system appropriate for custom-camera games.

Thanks for trying to help.
#10
01/08/2006 (4:35 pm)
I'd say the camera system is pretty flexible - any object can be used as a camera, the "Camera" class is just for convenience & special features. But the important thing is getting your game done, and any tool that lets you do that is the right one. :)

Good luck with your game!