strange chasecam movement...

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

strange chasecam movement...

Post by suliman »

hi
My chasecam is following my ship nicely. But there is two problems:
1. The distance between cam and ship is relative to the speed of the ship, it shouldnt be (it should be "normal" space-chase-cam)
2. The cam moves a bit jittery.

Here is the code and a compiled example.
http://epagames.cabspace.com/islands.rar

Code: Select all

float lenght=40;
float height=20;
float camSpeed=0.003;
		
m.setRotationDegrees(rot);
vector3df dirBack(-1,0,0);
m.rotateVect(dirBack);

camPos =pos;
camPos+=dirBack*lenght;
camPos.Y+=height;

static long last_update = GetTickCount();
long ms_elapsed = GetTickCount() - last_update;
last_update = GetTickCount();

vect3d camNow = camera->getPosition();
const float MILLISECONDS_TO_EQUILIBRIUM = 600.0f;
float lambda = static_cast<float> (ms_elapsed) / MILLISECONDS_TO_EQUILIBRIUM;
if(lambda>1.0f)
	lambda=1.0;
camNow.X = (lambda * camPos.X) + ((1.0f - lambda) * camNow.X);
camNow.Y = (lambda * camPos.Y) + ((1.0f - lambda) * camNow.Y);
camNow.Z = (lambda * camPos.Z) + ((1.0f - lambda) * camNow.Z);

camera->setPosition(camNow);

jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

after
camera->SetPosition(camNow);

add the line:

camera->updateAbsolutePosition();

i think that will solve problem 2 and maybe problem 1
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

thanks, but it didnt solve any of them :)

Any other ideas?
jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

try this link


http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=12529

look for the code post for WoWcamera(...)

it is originally thought as a 360 degree rotating camera, with zoom but you can pass your ship's getRotation() angles to it each frame to recenter camera behind ship.
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

that wouldnt be a chasecam. A chasecam is not always at the exact same distance.
jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

Sorry, I misunderstood the problem 1 and thought that constant distance was the goal.

this camera follows smoothly and will roll with the target
it can be altered to not roll (uncomment the "setUpVector()" line near the end)

it follows target rotation changes instantly, but distance changes take time and the time can be set with internal variable "moveSpeed" (between 0.0 and 1.0 float)

Code: Select all

//I3rdPersonCam.h                          3rd Person chase camera for Irrlicht 3D 1.1   
// version 0.2

#include <irrlicht.h>
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
// 1.  create I3rdPersonCam object;
// 2.  attach a CameraSceneNode with attachCamera()
// 3.  Set a target with setTarget()
// 4.  call modOrientation(pan, tilt, zoom) or setOrientation(pan, tilt, zoom) to set relative position camera
// 5.  call updatePosition() to apply new Position data
// 6.  repeat 4 and 5 as needed

// you might be better off reading the code for information.

class I3rdPersonCam{

public:
	float camPan;
	float camTilt;
	float camZoom;
	float maxZoom;
	float moveSpeed;
	ICameraSceneNode* cam;
	ISceneNode* camTarget;
	vector3df offset;
	
	I3rdPersonCam(){
		camPan=0;
		camTilt=45;
		camZoom=14;
		maxZoom=250;
		moveSpeed=0.06;     //should be less than or equal to 1
		}

	void setTarget(ISceneNode *newTarget){
		camTarget=newTarget;
		}

	void setOffset(vector3df newOffset){
		offset=newOffset;
		}

	void attachCamera(ICameraSceneNode *camtoattach){
		cam=camtoattach;
		}

	void modOrientation(float pan1,float tilt1,float zoom1){
		camPan=camPan+pan1;
		camTilt=camTilt+tilt1;
		camZoom=camZoom+zoom1;
		if(camPan>360)camPan=camPan-360;
		if(camPan<-360)camPan=camPan+360;
		if(camTilt>89)camTilt=89;
		if(camTilt<-89)camTilt=-89;
		if(camZoom>maxZoom)camZoom=maxZoom;
		if(camZoom<0)camZoom=0;
		}

	void setOrientation(float pan1,float tilt1,float zoom1){
		camPan=pan1;
		camTilt=tilt1;
		camZoom=zoom1;
		}


void updatePosition()
{
vector3df CPosVector;
vector3df NewCamLocation;
vector3df Target1;
vector3df CPos;
CPos=cam->getPosition();


	matrix4 m1;
	vector3df campos;
	vector3df Upvect1=vector3df(0,1,0);
	m1.setRotationDegrees(camTarget->getRotation());
	m1.transformVect(Upvect1);
	cam->setUpVector(Upvect1);


//CamPan==0 places camera behind Model--- CamPan range 0-360
//camTilt inputs should be between -89 and +89
CPosVector.X=cos((camPan+180)*PI/180)*sin((camTilt+90)*PI/180);
CPosVector.Y=cos((camTilt+90)*PI/180);
CPosVector.Z=sin((camPan+180)*PI/180)*sin((camTilt+90)*PI/180);

matrix4 m2;
m2.setRotationDegrees(camTarget->getRotation());
m2.transformVect(CPosVector);

Target1=camTarget->getPosition()+offset;
NewCamLocation.X=Target1.X+CPosVector.X*camZoom;
NewCamLocation.Y=Target1.Y+CPosVector.Y*camZoom;
NewCamLocation.Z=Target1.Z+CPosVector.Z*camZoom;


vector3df diff1;

diff1=NewCamLocation-CPos;

NewCamLocation.X=CPos.X+diff1.X*moveSpeed;
NewCamLocation.Y=CPos.Y+diff1.Y*moveSpeed;
NewCamLocation.Z=CPos.Z+diff1.Z*moveSpeed;

cam->setPosition(NewCamLocation);
//cam->setUpVector(vector3df(0,1,0));  
cam->setTarget(vector3df(Target1));
cam->updateAbsolutePosition();
}

};

This camera follows a walking object very well and tries to stay a set distance and flies to that set distance at a speed based on how far from the distance it is so farther away = faster flight
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

thanks for the code.
i use cam.setOrientation(0,-10,30);

the cam is smoother so thats nice, BUT:
this cam has the same problem i described with my camera: if the velocity of the craft increases, so does the distance between cam and craft. The cam should "catch up" with its desired position" behind the craft. If i double the speed of the craft, the distance between cam and ship should NOT be double (as speed changes, this distance should temporalily change, but as stated the cam should catch up with its desired position).

This is a classic chasecam, but no code eve found or written manages to do this without pendelum movement.

Any inputs?

E
jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

In my test with this camera the camera does catch up with a walking model, as a ship is faster, you may need to adjust the move speed to a higher value maybe 0.5f so that the camera travels faster.

the move speed is not reay a speed at all but a fraction of the distance measured between camera location and desired location which is traveled each frame

if camera is 1000 units behind and needs to be 100 units behind then a moveSpeed of 0.5f will bring the camera 450 units closer to target position

but if the camera is closer to the target position it moves slower

you must reference the moveSpeed variable directly like this:


I3rdPersonCam My3rdCam1;

My3rdCam1.moveSpeed= 0.5f

if you haven't done this that may be why the camera lags so far back because the default is moveSpeed=0.06f which is very slow

moveSpeed=1.0f is the limit which makes the camera not chase but keeps it at the exact distance

note: this camera never reaches the exact target distance, but aproaches the target distance at a percentage of the distance between which is measured each frame
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

what you describe is what i want, but it doesnt work that way. i use

I3rdPersonCam(){
camPan=0;
camTilt=45;
camZoom=14;
maxZoom=250;
moveSpeed=0.02; //should be less than or equal to 1
}

and increasing the speed does only lower the scale of the difference in distance in different, the cam still change distance (it does NOT catch up with a fast plane). See a compiled version of it here:

http://epagames.cabspace.com/islands.rar

increase speed with left button and you will se the problem...
jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

My late night coding is getting the better of me.

[edit] incorrect solution removed

since this camera never really reaches the target distance (only approaches that distance) you may still get some lag at high speeds since acceleration must occur before high speed although if you constantly adjust the move speed with a ratio of (airspeed:maximum airspeed) you may alter this effect


this camera works really good with a stoppable object since it has time to catch up, but for constantly moving objects you may need to have a higher moveSpeed=0.5f
or adjust move speed based on airspeed
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

Im not following you. Did you see my demo?
I dont need to change speed for this cam to not work at constant distance. If i raise speed and keep it constant at high speed the distance is larger then if i hold a constant low speed.

i try things like

cam.moveSpeed=myCraft.vel/20+0.02;

but this doesnt work very well. It still makes the cam stay at different distance depending on speed, and changes the amount of "chase effect" at higher speeds. It seems if i let the moveSpeed increase enough to keep up with planes going at higher speed, it will be fast enough to remove the "chase effect", thus being a simple static behind camera.

So my question remains:
Is there no way to do a chasecam? I know they have it in a lot of games...

Thanks a lot for your input
E
jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

Try this in place of the original one.
It works with the same input so change moveSpeed to suit your needs.

<note> there may be some unused code lines, since it has ben edited so many times, but it works.

Code: Select all

//I3rdPersonCam.h                          3rd Person chase camera for Irrlicht 3D 1.1   
// version 0.3

#include <irrlicht.h>
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
// 1.  create I3rdPersonCam object;
// 2.  attach a CameraSceneNode with attachCamera()
// 3.  Set a target with setTarget()
// 4.  call modOrientation(pan, tilt, zoom) or setOrientation(pan, tilt, zoom) to set relative position camera
// 5.  call updatePosition() to apply new Position data
// 6.  repeat 4 and 5 as needed


class I3rdPersonCam{

public:
	float camPan;
	float camTilt;
	float camZoom;
	float maxZoom;
	vector3df momentum;
	vector3df TargetLastPosition;
	float moveSpeed;
	ICameraSceneNode* cam;
	ISceneNode* camTarget;
	vector3df offset;
	
	I3rdPersonCam(){
		camPan=0;
		camTilt=45;
		camZoom=14;
		maxZoom=250;
		moveSpeed=0.02;
		}
	void setTarget(ISceneNode *newTarget){
		camTarget=newTarget;
		}
	void setOffset(vector3df newOffset){
		offset=newOffset;
		}
	void attachCamera(ICameraSceneNode *camtoattach){
		cam=camtoattach;
		}
	void modOrientation(float pan1,float tilt1,float zoom1){
		camPan=camPan+pan1;
		camTilt=camTilt+tilt1;
		camZoom=camZoom+zoom1;
		if(camPan>360)camPan=camPan-360;
		if(camPan<-360)camPan=camPan+360;
		if(camTilt>89)camTilt=89;
		if(camTilt<-89)camTilt=-89;
		if(camZoom>maxZoom)camZoom=maxZoom;
		if(camZoom<0)camZoom=0;
		}
	void setOrientation(float pan1,float tilt1,float zoom1){
		camPan=pan1;
		camTilt=tilt1;
		camZoom=zoom1;
		}
vector3df OldTargetCamLocation;
void updatePosition()
{
vector3df TargetCamLocation;
vector3df CPosVector;
vector3df NewCamLocation;
vector3df Target1;
vector3df CPos;
CPos=cam->getPosition();
	matrix4 m1;
	vector3df campos;
	vector3df Upvect1=vector3df(0,1,0);
	m1.setRotationDegrees(camTarget->getRotation());
	m1.transformVect(Upvect1);
	cam->setUpVector(Upvect1);

//calculates desired location of orbital camera
CPosVector.X=cos((camPan+180)*PI/180)*sin((camTilt+90)*PI/180);
CPosVector.Y=cos((camTilt+90)*PI/180);
CPosVector.Z=sin((camPan+180)*PI/180)*sin((camTilt+90)*PI/180);

matrix4 m2;
m2.setRotationDegrees(camTarget->getRotation());
m2.transformVect(CPosVector);

Target1=camTarget->getPosition()+offset;

TargetCamLocation.X=Target1.X+CPosVector.X*(camZoom);
TargetCamLocation.Y=Target1.Y+CPosVector.Y*(camZoom);
TargetCamLocation.Z=Target1.Z+CPosVector.Z*(camZoom);

vector3df diff1;

diff1=TargetCamLocation-CPos;

NewCamLocation.X=TargetCamLocation.X-(diff1.X-diff1.X*moveSpeed);
NewCamLocation.Y=TargetCamLocation.Y-(diff1.Y-diff1.Y*moveSpeed);
NewCamLocation.Z=TargetCamLocation.Z-(diff1.Z-diff1.Z*moveSpeed);

vector3df oldmomentum;
oldmomentum=momentum;
momentum=momentum+diff1*moveSpeed;
vector3df redmomentum;
redmomentum=oldmomentum+diff1*moveSpeed*3;

redmomentum=TargetCamLocation-OldTargetCamLocation;  //leave out if you want momentum effect

if(oldmomentum.X-momentum.X>0)momentum.X=redmomentum.X;
if(oldmomentum.Y-momentum.Y>0)momentum.Y=redmomentum.Y;
if(oldmomentum.Z-momentum.Z>0)momentum.Z=redmomentum.Z;

NewCamLocation.X+=momentum.X;
NewCamLocation.Y+=momentum.Y;
NewCamLocation.Z+=momentum.Z;

OldTargetCamLocation=TargetCamLocation;

cam->setPosition(NewCamLocation);
CPos=cam->getPosition();

//cam->setUpVector(vector3df(0,1,0));  
cam->setTarget(vector3df(Target1));
cam->updateAbsolutePosition();
TargetLastPosition=Target1;
}
};




suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

did you try that camera on a moving object yourself? It doesnt work at all as intended. i use this

cam.setOrientation(0,0,30);
cam.updatePosition();
cam.moveSpeed=0.001;


and setup is

cam.attachCamera(smgr->addCameraSceneNode());
cam.setTarget(myCraft.node);


Im beginning to really loose my interest in 3d game making... Theres just to much hassle to do the most basic thing. And a lot of experienced 3d programmers cant do it either so it seems theres a lot of studying to do to even get enywhere... I might stick to my good old 2d games. Where i spend time coming up with ideas and implementating them instead of spending time asking people on the forums why stuff doesnt work the way they are supposed to.

Thanks alot anyway for all your help guys!
Erik
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

this is still not working. No ideas anyone? Se the demo for more vivid description of the problem.
Post Reply