Blitz3D Style Camera Type

BlitzMax Forums/BlitzMax Programming/Blitz3D Style Camera Type

Chroma(Posted 2005) [#1]
I'm looking into creating a Camera Type for the archives that imitates the Blitz3D camera system.

I knocked up some basic code and some comments on what each command would do. I'm at work at the moment but plan on working on this when i get home. I'm still not very familiar with OpenGL but I assume this would help a lot of people immensely.

If you want to contribute then by all means let 'er rip.

'Blitz3D style camera control
'This is Pseudo Code!!

'Camera commands would go something like:

Global cam:Camera = Camera.Create()

cam.position(0,20,-20)
cam.rotate(30,0,0)
cam.turn(0,0,0.5)
cam.point(My_Entity)
cam.alignto(50,20,100)

Type camera
	Field x:Float
	Field y:Float
	Field z:Float
	Field pitch:Float
	Field yaw:Float
	Field roll:Float
	Field pitch_rate:Float
	Field yaw_rate:Float
	Field roll_rate:Float
	
	Function Create:Camera(x:Float = 0,y:Float = 0,z:Float = 0)
		Local c:Camera = New Camera
		c.x = x
		c.y = y
		c.z = z
		Return c
	End Function

	Method Position(x:Float,y:Float,z:Float)
	'position the camera at x,y,z
	End Method
	
	Method Rotate(p:Float,y:Float,r:Float)
	'rotate the camera to p,y,r in Euler angles
	End Method
	
	Method Turn(pr:Float,yr:Float,rr:Float)
	'turn the camera pr,ya,rr 
	End Method
	
	Method Point(entity:Int)
	'find the xyz position of 'entity' and align the camera to it
	End Method
	
	Method AlignTo(x:Float,y:Float,z:Float)
	'point the camera at position xyz
	End Method
End Type



Oddball(Posted 2005) [#2]
I would recommend using Quaternions for storing rotations and only convert to Euler when rotating the modelview matrix. Or if you're feeling really brave just use matrices for it all. Using Euler for it all makes arbitrary rotations difficult. There's plenty of Quaternion code in the archive to get you started.


Chroma(Posted 2005) [#3]
The user would define what angle he wanted to turn the camera to in Euler angles but the rotations would be done by Quaternion. Sorry I didn't specify that. Avoids gimbal lock that way.

I have a full quat library I wrote so it's already working here. Just have to wait till I get home to start messing about with it.


Chroma(Posted 2005) [#4]
If I'm reading correctly, it appears the camera never leaves 0,0,0. That totally rocks because I think that pretty much eliminates the camera from shaking.


Chroma(Posted 2005) [#5]
Well this is where I'm at so far. It's getting there.

'Blitz3D style camera control
'This is becoming unlike Pseudo Code!! =P


Global width = 800
Global height = 600

GLGraphics(width,height,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER)

glViewport(0,0,width,height)	'Reset The Current Viewport
glMatrixMode(GL_PROJECTION)		'Select The Projection Matrix
glLoadIdentity()				'Reset The Projection Matrix

'	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0,width/height,0.1,100.0)

glMatrixMode(GL_MODELVIEW)		'// Select The Modelview Matrix
glLoadIdentity()				'// Reset The Modelview Matrix


'Set Background Color
glClearColor(glColor(150), glColor(200), glColor(255), 0.0)

DrawGLScene()

'Camera commands would go something like:
Global z:Int = -100
While Not KeyHit(KEY_ESCAPE)

'glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

If KeyDown(KEY_UP)
	glrotatef(10,0,0,0)
EndIf


'GLDrawText "Camera X: "+cam.x,5,5
'GLDrawText "Camera Y: "+cam.y,5,25
'GLDrawText "Camera Z: "+cam.z,5,50

Flip
Wend

Function GLColor:Float(RGB:Int)
	Return RGB / 255.0
End Function

Function DrawGLScene()
	'Clear Screen And Depth Buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    'Reset The Current Modelview Matrix
    glLoadIdentity()
    glTranslatef(0.0, 0.0,-10.0)		'// Translate Into The Screen
    glBegin(GL_TRIANGLES)			'// Start Drawing A Triangle
	glColor3f( 1.0,0.0,0.0)			'// Red Color
	glVertex3f(0.0, 1.0, 0.0)		'// Top Color
	glColor3f(0.0,1.0,0.0)			'// Green
	glVertex3f(-1.0,-1.0, 0.0)		'// Bottom Left Vertex
	glColor3f(0.0,0.0,1.0)			'// Blue Color
	glVertex3f( 1.0,-1.0, 0.0)		'// Bottom Right Vertex
    glEnd()							'// Finished Drawing The Triangle
End Function

'cam.position(0,20,-20)
'cam.rotate(30,0,0)
'cam.turn(0,0,0.5)
'cam.point(My_Entity)
'cam.alignto(50,20,100)

Type camera
	Field x:Float
	Field y:Float
	Field z:Float
	Field pitch:Float
	Field yaw:Float
	Field roll:Float
	Field pitch_rate:Float
	Field yaw_rate:Float
	Field roll_rate:Float
	
	Function Create:Camera(x:Float = 0,y:Float = 0,z:Float = 0)
		Local c:Camera = New Camera
		c.x = x
		c.y = y
		c.z = z
		Return c
	End Function

	Method Position(x:Float,y:Float,z:Float)
	'position the camera at x,y,z
	End Method
	
	Method Rotate(p:Float,y:Float,r:Float)
	'rotate the camera to p,y,r in Euler angles
	End Method
	
	Method Turn(pr:Float,yr:Float,rr:Float)
	'turn the camera pr,ya,rr 
	End Method
	
	Method Point(entity:Int)
	'find the xyz position of 'entity' and align the camera to it
	End Method
	
	Method AlignTo(x:Float,y:Float,z:Float)
	'point the camera at position xyz
	End Method
End Type


'Command  Description  
'glLoadIdentity  Reset your world To ``flatness''  
'glMatrixMode  Move control To camera Or model  
'gluLookAt  Use this To position your camera in your scene  
'glRotatef  Rotates everything after the call by an amount  
'glTranslatef  Moves things in x,y,z  
'glScalef  Increases the size of things 
'glPushMatrix  Saves your current camera 
'glPopMatrix  Restores the previous camera.