chasecam problems. springs?

Started by
13 comments, last by suliman 16 years, 4 months ago
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
Advertisement
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 );
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
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.
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 :)!







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.
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

here is one. Best seen after 2 min. This cam is pretty firmly attached to the craft, just little "chase-effect".

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.
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?

This topic is closed to new replies.

Advertisement