Finally got a decent camera ported over. The only real problem I'm having is the orientation. I set the initial camera y position to 5 and it puts it at -5 in the world.
Can you guys check this out and see why the Y axis is inverted. Btw, the vector.bmx is below in it's own codebox.
The problem may lie here:
The z component of ViewDir was originally set to -1 and that made positioning the camera on the z axis be in reverse. Soon as I get the bugs worked out I'll put this in the archives.
Controls: Arrow Keys to move and strafe - Mouse to look around.
Camera.bmx
Vector.bmx
Can you guys check this out and see why the Y axis is inverted. Btw, the vector.bmx is below in it's own codebox.
The problem may lie here:
cam.ViewDir.Set(0.0, 0.0, 1.0) cam.UpVector.Set(0.0, 1.0, 0.0) cam.RightVector.Set(1.0, 0.0, 0.0)
The z component of ViewDir was originally set to -1 and that made positioning the camera on the z axis be in reverse. Soon as I get the bugs worked out I'll put this in the archives.
Controls: Arrow Keys to move and strafe - Mouse to look around.
Camera.bmx
'Advanced Camera 'converted by Chroma from a site I can't remember atm cuz my brain is fried now... Global width = 1024 Global height = 768 GLGraphics(width,height,32,85,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER) 'glClear(GL_COLOR_BUFFER_BIT) 'glLoadIdentity(); Include "vector.bmx" Const PIdiv180:Double = (Pi/180.0) ReShape(width,height) CenterX = GraphicsWidth()/2 CenterY = GraphicsHeight()/2 'Init Camera Global cam:Camera = Camera.Create() cam.Position.Set(0.0, 0.0, 0.0) cam.ViewDir.Set(0.0, 0.0, -1.0) cam.UpVector.Set(0.0, 1.0, 0.0) cam.RightVector.Set(1.0, 0.0, 0.0) cam.RotatedX = 0.0 cam.RotatedY = 0.0 cam.RotatedZ = 0.0 MoveMouse CenterX,CenterY cam.position.set(0,5,20) 'Main Loop While Not KeyHit(KEY_ESCAPE) glClear(GL_COLOR_BUFFER_BIT) glLoadIdentity(); 'Keyboard Controls If KeyDown(KEY_UP) Then cam.moveforward(-0.1) If KeyDown(KEY_DOWN) Then cam.moveforward(0.1) If KeyDown(KEY_LEFT) Then cam.straferight(-0.1) If KeyDown(KEY_RIGHT) Then cam.straferight(0.1) 'Mouselook Controls cam.rotatex( -(MouseY()-CenterY) * 3.0 ) cam.rotatey( -(MouseX()-CenterX) * 3.0 ) cam.rotatez(cam.RotatedZ) 'Render Camera cam.render() 'Render the DisplayList Display() 'Reset Mouse MoveMouse CenterX,CenterY Flip Wend 'Draw Some Cool Stuff To Look At Function Display() glTranslatef(0.0,-0.5,-6.0) glScalef(3.0,1.0,3.0) size! = 2.0 LinesX = 30 LinesZ = 30 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 xc = 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 zc = 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 Function ReShape(x:Int, y:Int) If y = 0 And x = 0 Return glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45.0,x/y,0.5,2000.0) glMatrixMode(GL_MODELVIEW) glViewport(0,0,x,y) End Function Type Camera Field Position:Vector Field ViewDir:Vector Field UpVector:Vector Field RightVector:Vector Field RotatedX:Float Field RotatedY:Float Field RotatedZ:Float Function Create:Camera( xpos:Float=0, ypos:Float=0, zpos:Float=0 ) Local c:Camera = New Camera c.Position:Vector = Vector.Create(xpos,ypos,zpos) c.ViewDir:Vector = Vector.Create() c.UpVector:Vector = Vector.Create() c.RightVector:Vector = Vector.Create() Return c End Function Method Render() Local ViewPoint:Vector = New Vector ViewPoint.Add( Position, ViewDir ) gluLookAt( Position.x,Position.y,Position.z,ViewPoint.x,ViewPoint.y,ViewPoint.z,UpVector.x,UpVector.y,UpVector.z) End Method ' Method Rotate(p:Float,y:Float,r:Float) ' End Method ' Method Turn(pr:Float,yr:Float,rr:Float) ' End Method ' Method Move(xd:Float,yd:Float,zd:Float) ' End Method ' Method Point(entity:Int) ' End Method ' Method AlignTo(x:Float,y:Float,z:Float) ' End Method ' Method Zoom(zm:Float) ' End Method Method RotateX( Angle:Float ) self.RotatedX :+ Angle Local temp1:Vector = Vector.Create( ViewDir.x, ViewDir.y, ViewDir.z ) Local temp2:Vector = Vector.Create( UpVector.x, UpVector.y, UpVector.z ) Local temp3:Vector = Vector.Create() temp1.MulScalar( Cos(Angle * PIdiv180) ) temp2.MulScalar( Sin(Angle * PIdiv180) ) temp3.Add(temp1,temp2) temp3.Normalize() self.ViewDir.Set( temp3.x, temp3.y, temp3.z ) UpVector.CrossProduct(ViewDir,RightVector) UpVector.MulScalar(-1) End Method Method RotateY( Angle:Float ) self.RotatedY :+ Angle Local temp4:Vector = Vector.Create( ViewDir.x, ViewDir.y, ViewDir.z ) Local temp5:Vector = Vector.Create( RightVector.x, RightVector.y, RightVector.z ) Local temp6:Vector = Vector.Create() temp4.MulScalar( Cos(Angle * PIdiv180) ) temp5.MulScalar( Sin(Angle * PIdiv180) ) temp6.Sub(temp4,temp5) temp6.Normalize() self.ViewDir.Set( temp6.x, temp6.y, temp6.z ) RightVector.CrossProduct(ViewDir,UpVector) End Method Method RotateZ( Angle:Float ) self.RotatedZ :+ Angle Local temp7:Vector = Vector.Create( RightVector.x, RightVector.y, RightVector.z ) Local temp8:Vector = Vector.Create( UpVector.x, UpVector.y, UpVector.z ) Local temp9:Vector = Vector.Create() temp7.MulScalar( Cos(Angle * PIdiv180) ) temp8.MulScalar( Sin(Angle * PIdiv180) ) temp9.Add(temp7,temp8) temp9.Normalize() RightVector.set( temp9.x, temp9.y, temp9.z ) UpVector.CrossProduct(ViewDir, RightVector) UpVector.MulScalar(-1) End Method Method MoveForward( Distance:Float ) Local temp:Vector = Vector.Create(ViewDir.x,ViewDir.y,ViewDir.z) temp.MulScalar(-Distance) Position.Add( Position, temp ) End Method Method StrafeRight( Distance:Float ) Local temp:Vector = Vector.Create(RightVector.x,RightVector.y,RightVector.z) temp.MulScalar(Distance) Position.Add( Position, temp ) End Method Method MoveUpward( Distance:Float ) Position.Add( Position, UpVector.MulScalar(Distance) ) End Method End Type
Vector.bmx
'// Vector Math Library v2.0 '// BlitzMAX Edition '// by Chroma Type Vector Field x:Float Field y:Float Field z:Float Const Tol:Float = 0.001 Function Create:Vector( x:Float = 0, y:Float = 0, z:Float = 0 ) Local v:Vector = New Vector v.x = x v.y = y v.z = z Return v End Function Method Set( x:Float = 0, y:Float = 0, z:Float = 0 ) self.x = x self.y = y self.z = z End Method Method Add( v1:Vector, v2:Vector ) self.x = v1.x + v2.x self.y = v1.y + v2.y self.z = v1.z + v2.z End Method Method Sub( v1:Vector, v2:Vector ) self.x = v1.x - v2.x self.y = v1.y - v2.y self.z = v1.z - v2.z End Method Method Mul( v1:Vector, v2:Vector ) self.x = v1.x * v2.x self.y = v1.y * v2.y self.z = v1.z * v2.z End Method Method Div( v1:Vector, v2:Vector ) self.x = v1.x / v2.x self.y = v1.y / v2.y self.z = v1.z / v2.z End Method Method AddScalar( s:Float ) self.x :+ s self.y :+ s self.z :+ s End Method Method SubScalar( s:Float ) self.x :- s self.y :- s self.z :- s End Method Method MulScalar( s:Float ) self.x :* s self.y :* s self.z :* s End Method Method DivScalar( s:Float ) self.x :/ s self.y :/ s self.z :/ s End Method Method Magnitude:Float() Return Sqr(self.x * self.x + self.y * self.y + self.z * self.z) End Method Method Normalize() Local mag:Float = self.Magnitude() If mag = 0.0 Then self.Set(0.0,0.0,0.0);Return self.x :/ mag self.y :/ mag self.z :/ mag 'If ( Abs( self.x ) < Tol ) self.x = 0.0 'If ( Abs( self.y ) < Tol ) self.y = 0.0 'If ( Abs( self.z ) < Tol ) self.z = 0.0 End Method Method CrossProduct( v1:Vector, v2:Vector) self.x = v1.y * v2.z - v1.z * v2.y self.y = -v1.x * v2.z + v1.z * v2.x self.z = v1.x * v2.y - v1.y * v2.x EndMethod Method DotProduct:Float(v:Vector) Return self.x * v.x + self.y * v.y + self.z * v.z EndMethod Method AddTimeStep( v:Vector, time_step:Float ) self.x :+ v.x * time_step self.y :+ v.y * time_step self.z :+ v.z * time_step End Method Method Show( xpos:Int, ypos:Int, label:String ) DrawText label+"_X: "+self.x, xpos, ypos DrawText label+"_Y: "+self.y, xpos, ypos + 20 DrawText label+"_Z: "+self.z, xpos, ypos + 40 End Method ' Method QuatToVec(q:Quat) ' self.x = q.x ' self.y = q.y ' self.z = q.z ' End Method End Type '// Degrees To Radians Conversion Function DegreesToRadians:Float(deg:Float) Return deg * Pi / 180.0 End Function '// Radians To Degrees Conversion Function RadiansToDegrees:Float(rad:Float) Return rad * 180.0 / Pi End Function