# Writing my own camera class... Problems

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

## Recommended Posts

I have a problem when translating, im trying to make my class similer to that of the "Quaternion Camera Class", but it seems that there is somthing wrong with the way i am calculating the ypos... Bellow is my equivalent to the setPerspective function in the Quaternion Camera Class.
void positionWorld()
{

glRotatef(pitch,1.0f,0,0);

if ((velocity > 0) || (velocity < 0))
{
ypos -= (float)sin(pitch*piover180)* velocity;
}

glTranslatef(-xpos, -ypos, -zpos);
}


-Nathan

##### Share on other sites
Could you describe what happens and what should happen?

##### Share on other sites
pitching up or down 180o feels like you traviling backwards and everything is inverted... I also noticed this a little as i approach 180, it just doesnt have the same feel as the "Quaternion Camera Class".

##### Share on other sites
camera motions are hard, you need to fiddle with them.

xb = forward velocity
yb = up/down velocity
zb = strafe velocity
t = timestep

I use these in my engine to move the camera(and it's not pretty)
xv=(sin(-rx/(180/3.1415))*(xb*t))-(sin(+(rx+90)/(180/3.1415))*(zb*t));
yv=(sin(ry/(180/3.1415))*(xb*t))+(yb*t);
zv=(-(cos(-rx/(180/3.1415))*(xb*t)))-(cos(+(rx+90)/(180/3.1415))*(zb*t));

x=x+xv;
z=z+zv;
y=y+yv;

I use these to find out the current heading vector(and it's pretty mutch the same as yours only different).

v[0]=(sin(-rx/(180/3.1415))*(1));
v[1]=(sin(ry/(180/3.1415))*(1));
v[2]=(-(cos(-rx/(180/3.1415))*(1)));

Use these if you like, otherwise, just start fiddeling with them until it works.

##### Share on other sites
yeah thanks for that, but it sorta translates to exactly what i already have... lol...

##### Share on other sites
lc_overlord:

That's one ugly piece of code!
First the realtime cos and sin funtions(big performance no-no), then the realtime divisions(performance no-no), and best for last =), the absolutely cryptic huge lines of code.

*G*
lax=px+(tcos[anglex]*tncos[angley]);laz=pz+(tsin[anglex]*tncos[angley]);lay=py+tsin[angley];

Woudln't something like this be prettier?
Of course with this one there is no velocity control, but you get the picture. =)

##### Share on other sites
I know it's not pretty, it's only temoprary code, infact my entire update/input fuction is one big horrific mess, Only 50% of all the stuff in it actuarly does something and it uses a spiderwebb of different variabls.
Just look at this mess.

Globals:
GL_Window*	g_window;Keys*		g_keys;double x=0,y=0,z=0,rx=0,ry=0,rz=0,xb=0,yb=0,zb=0,acc=60,yg=0;double g[3],op[3],fpsf[5];int fpsi=0,fpsit=0,textpos,textpos2,blurmethod=1;int lastm_y=0;int filter[2][10];float p[5000][3],tc=0,df=10,blurlength=0,bmhold=0;int llist[256];unsigned int b,b2,s,s2;unsigned int ptex;shader tx;screen sx;sky skyx;camera cam;light lx;CFsound sn;CFlog lg;CFdraw dm;CFgsv gsv;CFhud hud;

Update func:
void Update (DWORD milliseconds)								// Perform Motion Updates Here{	double t2,xv,yv,zv,lp[3],fo;	t2=(double)milliseconds/1000;	double t,gpoint[3],mvec[4];	float f[2];	int done=0,i=0;	if (g_keys->keyDown [VK_ESCAPE] == TRUE)					// Is ESC Being Pressed?	{		TerminateApplication (g_window);						// Terminate The Program	}		//	mousefilter	filter[0][0]=filter[0][1];	filter[0][1]=filter[0][2];	filter[0][2]=filter[0][3];	filter[0][3]=filter[0][4];	filter[0][4]=filter[0][5];	filter[0][5]=filter[0][6];	filter[0][6]=filter[0][7];	filter[0][7]=filter[0][8];	filter[0][8]=filter[0][9];	filter[0][0]=mouse_x-300;	f[0]=filter[0][0]+filter[0][1]+filter[0][2]+filter[0][3]+filter[0][4]+filter[0][5]+filter[0][6]+filter[0][7]+filter[0][8]+filter[0][9];	filter[1][0]=filter[1][1];	filter[1][1]=filter[1][2];	filter[1][2]=filter[1][3];	filter[1][3]=filter[1][4];	filter[1][4]=filter[1][5];	filter[1][5]=filter[1][6];	filter[1][6]=filter[1][7];	filter[1][7]=filter[1][8];	filter[1][8]=filter[1][9];	filter[1][0]=mouse_y-300;	f[1]=filter[1][0]+filter[1][1]+filter[1][2]+filter[1][3]+filter[1][4]+filter[1][5]+filter[1][6]+filter[1][7]+filter[1][8]+filter[1][9];	fpsf[0]=fpsf[1];	fpsf[1]=fpsf[2];	fpsf[2]=fpsf[3];	fpsf[3]=fpsf[4];	fpsf[4]=t2;		t=((fpsf[0]+fpsf[1]+fpsf[2]+fpsf[3]+fpsf[4])/5);	tc+=t2;	fpsit++;	if (tc>1){tc-=1; fpsi=fpsit; fpsit=0;}//	fpsi=(int)(1/t);		rx -= (f[0]*10*t);	ry -= (f[1]*10*t);	SetCursorPos(300,300);	if (rx<0) rx=rx+360;	if (rx>360) rx=rx-360;	if (xb>0) xb-=(acc*t);	else if (xb<-0) xb+=(acc*t);	if ((xb>-acc*t/2) && (xb<acc*t/2)) xb=0;	if (GetAsyncKeyState(VK_HOME)) xb=xb+(acc*t*2);	if (GetAsyncKeyState(VK_END)) xb=xb-(acc*t*2);	if (xb>30) xb=30;	if (xb<-30) xb=-30;			if (zb>0) zb-=(acc*t);	else if (zb<-0) zb+=(acc*t);	if ((zb>-acc*t/2) && (zb<acc*t/2)) zb=0;	if (GetAsyncKeyState(VK_DELETE)) zb=zb+(acc*t*2);	if (GetAsyncKeyState(VK_NEXT)) zb=zb-(acc*t*2);	if (zb>30) zb=30;	if (zb<-30) zb=-30;	if (yb>0) yb-=(acc*t);	else if (yb<-0) yb+=(acc*t);	if ((yb>-acc*t/2) && (yb<acc*t/2)) yb=0;	if (GetAsyncKeyState(VK_RETURN)) yb=yb+(acc*t*2);	if (GetAsyncKeyState(VK_INSERT)) yb=yb-(acc*t*2);	if (yb>15) yb=15;	if (yb<-15) yb=-15;	lx.setLight(llist[1]);	lp[0]=lx.getPos(0);	lp[1]=lx.getPos(1);	lp[2]=lx.getPos(2);//	fo=lx.getFalloff();		bmhold+=t;	if ((g_keys->keyDown ['B']) && (bmhold>0.1))	{		if (blurmethod==0) blurmethod=1;		else blurmethod=0;		bmhold=0;	}			if (g_keys->keyDown ['A']) blurlength+=0.3;	if (g_keys->keyDown ['Z']) blurlength-=0.3;	if (blurlength<0) blurlength=0;	if (blurlength>40) blurlength=40;	if (g_keys->keyDown [VK_UP]) lp[0]+=1;	if (g_keys->keyDown [VK_ADD]) lp[1]+=1;	if (g_keys->keyDown [VK_RIGHT]) lp[2]+=1;	if (g_keys->keyDown [VK_DOWN]) lp[0]-=1;	if (g_keys->keyDown [VK_SUBTRACT]) lp[1]-=1;	if (g_keys->keyDown [VK_LEFT]) lp[2]-=1;		if (g_keys->keyDown [VK_MULTIPLY]) df+=0.1;	if (g_keys->keyDown [VK_DIVIDE]) df-=0.1;	lx.setPos(lp[0],lp[1],lp[2]);	lx.setDifuse(df,df,df,1);	//lx.setFalloff(fo);//	yg -=(0.5*t);		double v[3];	xv=(sin(-rx/(180/3.1415))*(xb*t))-(sin(+(rx+90)/(180/3.1415))*(zb*t));	yv=(sin(ry/(180/3.1415))*(xb*t))+(yb*t);	zv=(-(cos(-rx/(180/3.1415))*(xb*t)))-(cos(+(rx+90)/(180/3.1415))*(zb*t));	v[0]=(sin(-rx/(180/3.1415))*(1));	v[1]=(sin(ry/(180/3.1415))*(1));	v[2]=(-(cos(-rx/(180/3.1415))*(1)));	normalize(v,1);	cam.setCameraPos(x,y,z);	cam.setCameraAngle(rx,ry,rz);	cam.setCameraVector(v);//	sn.setListnerCamv(x,y,z,rx,ry,rz,xb);		op[0]=x; 	op[1]=y;	op[2]=z;	x=x+xv; 	z=z+zv; 	y=y+yv;	dm.setTime(t);			if (g_keys->keyDown [VK_F1] == TRUE)						// Is F1 Being Pressed?	{		ToggleFullscreen (g_window);							// Toggle Fullscreen Mode	}}

But as i said it's only temps, it will be rewritten eventualy(allthough probobly sometime 2007)

##### Share on other sites
Yeah i realise the performance hits, but at the momment im only concerned with get it to actualy work...

i still havent solved the problem...

-Nathan

##### Share on other sites
@xor : Hmmm I'm not sure lookup tables are still a good idea for sin and cos functions :
- your solution will only give an approximation of sin and cos (at least, you should interpolate to get a decent value) ;
- some processors now have sin/cos functions and I'm not sure they are much slower than reading tables in memory ; for processors that don't there are approximations for those functions that are more cache-friendly that a LUT.

BTW, the "ugly division" in his code is not a division. Any decent compiler will calculate 1/(180/pi) statically and generate a product instead.

Just my 0.02 €

[Edited by - rodzilla on October 24, 2004 11:31:11 PM]

##### Share on other sites
rodzilla:

Why do you say something like that? It SO obvious that the code is poorly written that even the author admits it.
Have you ever tried booth ways? Using trignometric instructions instead of a table. Because i have, and i _know_ it's better.

Quote:
 your solution will only give an approximation of sin and cos (at least, you should interpolate to get a decent value) ;

Actually it won't. It will give me a value with the precision of a double for the exact angle i'm asking for. I only need, in this case in particular, 2048 angle positions. They are all stored in a table.

Quote:
 some processors now have sin/cos functions and I'm not sure they are much slower than reading tables in memory ; for processors that don't there are approximations for those functions that are more cache-friendly that a LUT.

Some processor NOW have sin/cos?! Processor have sin/cos and more trignometric funtions since the introduction of FPU's wich remounts to the age of the 386!
As for the speed, have you checked recently any latency tables for cpu/fpu operations? An addition takes a cycle to compute, a multiplication 10, and a division over 50 IRC. Sin and cos operations take between 160 and 280 cycles, some other trignometric operations can go up to 300 cycles. There is a big diference.

Quote:
 BTW, the "ugly division" in his code is not a division. Any decent compiler will calculate 1/(180/pi) statically and generate a product instead.

(rx+90)/(180/3.1415))
This first division won't be compiled statically,
(-rx/(180/3.1415))
And this first one won't either. It's ugly enough.

--edit--
I should note those cycles are for Pentium 4 processors.
--edit--

[Edited by - xor on October 25, 2004 8:14:30 AM]

1. 1
Rutin
32
2. 2
3. 3
4. 4
5. 5

• 13
• 57
• 11
• 10
• 14
• ### Forum Statistics

• Total Topics
632967
• Total Posts
3009557
• ### Who's Online (See full list)

There are no registered users currently online

×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!