OpenGL Camera almost done

BlitzMax Forums/BlitzMax OpenGL Programming/OpenGL Camera almost done

found some code that uses quats (no nasty glulook at vectors :D ) to do local camera rotations

but that too has the same "feature" rotate the mouse
and you end up with a local z axis rotation too...

so I really dont understand whats going on if anyone could explain I'd be most greatful

heres the code for what its worth:
SuperStrict 
Type point
	Field x#,y#,z#,w#

	Method Sub:point( v1:point, v2:point )
		Local t:point=New point
		t.x = v1.x - v2.x
		t.y = v1.y - v2.y
		t.z = v1.z - v2.z
		Return t
	End Method
	
	Method add:Point(v1:point,v2:point)
		Local t:point=New point
		t.x=v1.x+v2.x
		t.y=v1.y+v2.y
		t.z=v1.z+v2.z
		Return t
	EndMethod
	
	Method getlength:Float()
		Return Float(Sqr( x*x + y*y + z*z ))
	End Method
	
	Method cross:point(p1:point,p2:point)
		Local t:point=New point
		t.x = ((p1.y * p2.z) - (p1.z * p2.y))
   		t.y = ((p1.z * p2.x) - (p1.x * p2.z))
   		t.z = ((p1.x * p2.y) - (p1.y * p2.x))
		Return t
	EndMethod
	
	Method Normal:point()
		Local length:Float = getlength()

		If length = 0.0 Then length = 1.0
		
		x = x/length
		y = y/length
		z = z/length
		w = w/length
	EndMethod
	
	Method mult:point(f:Float)
		x:*f ; y:*f ; z:*f
	EndMethod
	
	Method QuatFromAxis:point(a:point, phi:Float)
			Local t:point=New point
            Local sine:Float
            
            phi = phi * 0.5
            sine = Float(Sin(phi))
            
            a.Normal()

            t.x = a.x
			t.y = a.y
			t.z = a.z

            t.x:*sine
            t.y:*sine
            t.z:*sine
            t.w = Float(Cos(phi))
			Return t
	EndMethod
	
	Method quatadd:point(q:point)
		Local result:point=New point
		Local v1:point=New point,v2:point=New point,crossp:point=New point,v3:point=New point
		v1.x=x ; v1.y=y ; v1.z=z
		v2.x=q.x ; v2.y=q.y ; v2.z=q.z
		
		crossp=Cross(v2, v1)

		v1.mult(q.w)
		v2.mult(w)
            
        v3 = v3.add(v1,v2)
        v3 = v3.add(crossp,v3)

		v3.w = w * q.w - (x * q.x + y * q.y + z * q.z)
            
		result.x = v3.x; result.y = v3.y; result.z = v3.z; result.w = v3.w

        Return result;
	EndMethod
	
	Method CreateMatrix(pMatrix:Float[] Var)
'	         // Calculate the first row.
	         pMatrix[0]  = 1.0 - 2.0 * (y * y + z * z); 
	         pMatrix[1]  = 2.0 * (x * y - z * w);
	         pMatrix[2]  = 2.0 * (z * x + y * w);
	         pMatrix[3]  = 0.0  

'	         // Calculate the second row.
	         pMatrix[4]  = 2.0 * (x * y + z * w)  
	         pMatrix[5]  = 1.0 - 2.0 * (z * z + x * x) 
	         pMatrix[6]  = 2.0 * (y * z - x * w)  
	         pMatrix[7]  = 0.0  

'	         // Calculate the third row.
	         pMatrix[8]  = 2.0 * (z * x - y * w)
	         pMatrix[9]  = 2.0 * (y * z + x * w)
	         pMatrix[10] = 1.0 - 2.0 * (y * y + x * x)
	         pMatrix[11] = 0.0;  

'	         // Calculate the fourth row.
	         pMatrix[12] = 0  
	         pMatrix[13] = 0  
	         pMatrix[14] = 0  
	         pMatrix[15] = 1.0
	EndMethod
EndType

GLGraphics(640,480,0,0,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER)

Global CenterX:Int = GraphicsWidth()/2
Global CenterY:Int = GraphicsHeight()/2

glMatrixMode(GL_PROJECTION)  
glLoadIdentity()
gluPerspective(45.0,GraphicsWidth()/GraphicsHeight(),0.5,1000.0)
glMatrixMode(GL_MODELVIEW)
glViewport(0,0,GraphicsWidth(),GraphicsHeight())
Global oldquat:Point=New point,newquat:point=New point
oldquat.w=1;newquat.w=1	
Global mx:Int,my:Int

	
While Not KeyHit(KEY_ESCAPE)
	glClear(GL_COLOR_BUFFER_BIT)
	
	mx=MouseX();my=MouseY()
	MoveMouse centerx,centery
	oldquat=calcrot((2.0 * centerx - centerx*2) / centerx,(2.0 * centery - centery*2) / centery,(2.0 * mx - centerx*2) / centerx,(2.0 * my - centery*2) / centery)
	newquat=oldquat.quatadd(newquat)
	
	glloadidentity()
	Local m:Float[16]
	newquat.CreateMatrix(m)
	glMultMatrixf(m)

	display()

	Flip

Wend

Const TRACKBALL_SIZE:Float=0.5

Function calcrot:point(x1:Float,y1:Float,x2:Float,y2:Float)
	Local axis:point=New point
	Local p1:point=New point, p2:point=New point, difference:point=New point
	Local phi:Float
	Local length:Float
	Local q:point=New point
	
	p1.x = x1
	p1.y = y1
	p1.z = ProjectPointToSphere(TRACKBALL_SIZE, x1, y1)
	p2.x = x2
	p2.y = y2
	p2.z = ProjectPointToSphere(TRACKBALL_SIZE, x2, y2)
	difference = difference.sub(p1,p2)
	length = difference.getlength() / (2.0 * TRACKBALL_SIZE)
	If length > 1.0 Then length = 1.0
	If length < -1.0 Then length = -1.0
	phi = 2.0 * Float(ASin(length))
	axis=axis.Cross(p2, p1)
	q=q.QuatFromAxis(axis, phi)
	Return q
	
EndFunction

Function ProjectPointToSphere:Float(radius:Float,x:Float,y:Float)
	Local z#,length#
	length = Float(Sqr(x * x + y * y))
	If length < radius * 0.70710678118654752440 Then 
		z = Float(Sqr(radius * radius - length * length))
	Else
		radius = radius / 1.41421356237309504880
        z = radius * radius / length
	EndIf
	Return z
EndFunction

'Draw Some Cool Stuff To Look At
Function Display()
'	glTranslatef(0.0,-0.5,-6.0)

	glScalef(3.0,1.0,3.0)
	
	Local size# = 2.0
	Local LinesX# = 30
	Local LinesZ# = 30

	Local halfsize# = size / 2.0
	glColor3f(1.0,1.0,1.0)
	glPushMatrix()
		glTranslatef(0.0,-halfsize ,0.0)
		DrawNet(size,LinesX,LinesZ)
		glTranslatef(0.0,size,0.0)
		DrawNet(size,LinesX,LinesZ)
	glPopMatrix()
	glColor3f(0.0,0.0,1.0)
	glPushMatrix()
		glTranslatef(-halfsize,0.0,0.0);
		glRotatef(90.0,0.0,0.0,halfsize)
		DrawNet(size,LinesX,LinesZ)
		glTranslatef(0.0,-size,0.0)
		DrawNet(size,LinesX,LinesZ)
	glPopMatrix()
	glColor3f(1.0,0.0,0.0)
	glPushMatrix()
		glTranslatef(0.0,0.0,-halfsize)	
		glRotatef(90.0,halfsize,0.0,0.0)
		DrawNet(size,LinesX,LinesZ)
		glTranslatef(0.0,size,0.0)
		DrawNet(size,LinesX,LinesZ)
	glPopMatrix()
	glFlush()
EndFunction


Function DrawNet(size:Float, LinesX:Int, LinesZ:Int)
	glBegin(GL_LINES)
	For Local xc:Int = 0 To LinesX-1 
	
		glVertex3f(	-size / 2.0 + xc / Float(LinesX-1)*size,0.0,size / 2.0)
		glVertex3f(	-size / 2.0 + xc / Float(LinesX-1)*size,0.0,size / -2.0)
	Next
	For Local zc:Int = 0 To LinesX-1
	
		glVertex3f(	size / 2.0,0.0,-size / 2.0 + zc / Float(LinesZ-1)*size)
		glVertex3f(	size / -2.0,0.0,-size / 2.0 + zc / Float(LinesZ-1)*size);
	Next
	glEnd()
End Function