Sign in to follow this  

chasecam problems. springs?

This topic is 3664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Im fiddling with a airplane game in irrlicht 3d engine. I have a chasecam that follows the plane around like in freelancer, darkstar one etc. Problem is the cam is moving jiggely unless i just attach it to a static distance from the plane (which i dont want since that makes the cam really boring). 1. I set the cameras target (where it looks at) to the plane 2. I define a spot behind the ship that is the goal for the cameras position 3. As the plane moves and changes speed, the cams movement-speed is affect with the distance between where it is and the cam-goal (behind the ship) 4. The cam rocks back and forth and never comes to rest at the goal-position (another version i tried it didnt rock but it stayed further back from the ship if the ship moves faster, which i don't want) Ive got a lot of suggestions but they end up with the same problem. Someone suggested using springs. Would that work? I dont find any good tutorials on that and im really clueless on how to make them work. Any pointers? Erik

Share this post


Link to post
Share on other sites
You could try using a 'dragged' camera, where essentially your camera is on a leash and gets dragged around behind the plane/ship.

To do this you essentially just get the vector between the camera last frame and the object and then move the camera along that vector to always maintain a constant seperation from the ship. You can make this more 'springy' by lerping the camera from its last position to this new desired position, something like this.


static const float CAMERA_DISTANCE = 3.f;
static const float LERP_SPEED = 0.4f;

Vector3 toPlayerFromCamera = shipPosition - m_CameraPosition;
toPlayerFromCamera.Normalise();

Vector3 desiredCameraPosition = shipPosition - ( toPlayerFromCamera * CAMERA_DISTANCE );

m_CameraPosition = Lerp( m_CameraPosition, desiredCameraPosition, LERP_SPEED );

Share this post


Link to post
Share on other sites
are those irrlicht functions?
so lerp is some kind of interpolation? Would this feel like a chasecam or a "dragged cam" (if i call what they have in those games for chasecam).

I want the cam to be slighlty left behind when acceleration but get back to its original disatance from the plane.

E

Share this post


Link to post
Share on other sites
Sounds to me like in step number three you are taking the vector to the target position and adding to your velocity so it's building up, travelling past the target and then doing the same thing in the return direction.

For springy behaviour I simply determine the vector to the target position and set the camera velocity to that multiplied by something like 0.35 (or something like that). That'll make it slide into position easing in as it reaches the target position (albeit technically never actually getting there but you shouldn't be able to notice). The lower the number the looser the spring with 1.0 being rock solid.

Doing this will of course lead to the camera being left behind as the craft moves faster so you could simply treat the camera position on that relative axis seperately and make that a much tighter spring.

Share this post


Link to post
Share on other sites
Sorry no, those were not irrlicht functions, its was more pseudo code..let me try and explain it a bit better however.

The first thing we do is get the vector from the camera to the player.
Vector3 toPlayerFromCamera = shipPosition - m_CameraPosition;


We then normalise this vector to make it unit length.
toPlayerFromCamera.Normalise(); 


If we then subtract this vector from the shipPosition (vector holding the ships world xyz coordinates), we can find the point along the toPlayerFromCamera vector which is our CAMERA_DISTANCE away from the ship.

So basically we draw a line between the camera last frame and the ship this frame, we then find where on that line is 3meters away (in the example above) from the ship, and set this as our desiredPosition.

 Vector3 desiredCameraPosition = shipPosition - ( toPlayerFromCamera * CAMERA_DISTANCE ); 


This would give us a 'dragged' camera but with no springyness as yet.


The Lerp() function is basically interpolating yes, this is where you get your springy feel. Im sure you can write your own lerp function pretty easily, basically take the first parameter which is our current position xyz, second parameter which is our destination xyz find the difference between them (x difference, y difference , z difference ), multiply the differences by our time step (third paramter) and add them to our initial position.

As we are providing a fixed step, and lerping from our new camera position each frame, you will get a nice sence of acceleration and deceleration on the camera as it approaches.
The lerp is completley idependant of your ships speed also, so the camera doesnt need to care about the ship speed, and as you go faster it will hang futher back as you wanted.

Sorry if the last two paragraphs dont make much sence, got to rush out now, but hopefully that clears things up a bit :)!







Share this post


Link to post
Share on other sites
thanks.
you misunderstood me, i DONT want it to be further back when ship is going faster. I simply mean that like all chasecams, it should be temporaliry "left behind" when the plane acc and the cam should then quickly "catch up" with its original position behind the craft. This also makes you see more of the side of the ship when turning etc.

Share this post


Link to post
Share on other sites
Trust me, the code above will do exactally what you want :)
If you dont want it to be left behind too much, you can set the LERP value to 1.f or not even do the lerp step at all, if you just want a springy feel and to be able to see the sides when you turn then again, the dragged camera method i mentioned above is perfect!

Draw it out on paper, and draw a few frames to see what the code above does, its pretty simple.

Ill see if i can find a youtube video that has the same method implemented, so you can see if its what you want or not

Share this post


Link to post
Share on other sites
i might do something like that (or i misunderstood).

This code produce a smooth result. Only problem is that the distance between ship and camera gets longer as the ship goes faster.

//camPos == the goal-position for the camera slightly behind the craft

vect3d camNow = camera->getPosition();
float camSpeed=0.02f;

float disX=(abs(camPos.X-camNow.X));
float disY=(abs(camPos.Y-camNow.Y));
float disZ=(abs(camPos.Z-camNow.Z));

//move-distance this tick
float deltaX=camSpeed*disX;
float deltaY=camSpeed*disY;
float deltaZ=camSpeed*disZ;


//apply move-distance to camPos
if(camPos.X>camNow.X)
camNow.X+=deltaX;
if(camPos.X<camNow.X)
camNow.X-=deltaX;

if(camPos.Y>camNow.Y)
camNow.Y+=deltaY;
if(camPos.Y<camNow.Y)
camNow.Y-=deltaY;

if(camPos.Z>camNow.Z)
camNow.Z+=deltaZ;
if(camPos.Z<camNow.Z)
camNow.Z-=deltaZ;


camera->setPosition(camNow);

//set camera target (where it looks at)
vect3d camAim=pos;
camAim.Y+=height;
camera->setTarget(camAim);





If i instead do

deltaX=camSpeed*disX*disX //square of distance




the cam accelerates up to the target-position when ship changes speed (this is good), but instead the cam rocks back and forth when turning! So both versions are non-working. There is no interpolation here though. But i dont see where to put that and how it can help.

Share this post


Link to post
Share on other sites
Can I ask why your not using vectors when stepping your cameras position? That would make your life so much easier, you only seem to be using them when dealing with Engine vectors? Are you not comfortable using them?

Share this post


Link to post
Share on other sites
im new to them so i do it manually when running into problem to know that im not doing a mistake with the syntax and easier follow whats happening :)
But how about my problem. What am I missing?

[Edited by - suliman on November 27, 2007 3:21:42 PM]

Share this post


Link to post
Share on other sites
I've also tried stuff like this

float camSpeed=0.03*(vel); //multiply with ship-velocity



And this version stays at the right distance even though ship changes speed, it doesn't rock back and forth BUT relative to the increase in speed, the cam gets more and more static to its target-position behind the ship (of course). Thusly removing the "chase-effect" totally at higher speeds...
Plz?

[Edited by - suliman on November 28, 2007 2:29:08 AM]

Share this post


Link to post
Share on other sites
I think you need to make your interpolation number variable with speed. If the camera is farther back than it should be, slowly increase it each frame until the distance is correct. Then if the camera is too close (like when the target slows down), slowly decrease it. Imagine the camera is it's own ship. When it sees the ship infront of it speed up, it needs to speed up, but in this case you're 'speeding up' the interpolation between current position and desired position.

[Edited by - ItsDan on November 29, 2007 10:41:21 AM]

Share this post


Link to post
Share on other sites
finally solved!

I simply move the cam closer to the goalPos (using ship-speed and direction of ship before appplying this ticks turning) before calculating on camera movement using my original code. Voila!

This makes cam soft and nice and dont change camera behavior due to ship speed.
E

Share this post


Link to post
Share on other sites

This topic is 3664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this