Screen rotation

BlitzMax Forums/BlitzMax Programming/Screen rotation

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

This might be of use to somebody.
Although DX only I'm sure the OGL equivalent is very similar.
If anybody wants to clean it up, add to it or comment feel free.
I haven't put it in the Code Archives yet as I'm not too sure how much use it is in a real situation. I haven't put too much thought into it either.
Thanks to Noel for his Math3D lib in the Code Archives.
Import Brl.Math

Strict

Const RAD_TO_DEGREE! = 180!/Pi
Const DEGREE_TO_RAD! = Pi / 180!
Const gw:Float = 800.0
Const gh:Float=600.0
Graphics gw , gh
SetViewport -(gw/2),-(gh/2),gw*2,gh*2
Local depth:Float = 2.0
Local scale :Float = 1.0
Local angle:Float=5.0
Local image1:timage = LoadImage("ground.png")
Local image2:timage=LoadImage("max.png")
Local backup_matrix:matrix=matrix.create(2.0/gw,0.0,0.0,0.0,..
									0.0,( - 2.0 / gh) , 0.0 , 0.0 , ..
									0.0,0.0,(2.0/2.0),0.0,..
		 							 - 1.0 - (1.0 / gw) , 1.0 + (1.0 / gh) , 1.0 , 1.0)
Local world_matrix:matrix=matrix.create(2.0/gw,0.0,0.0,0.0,..
									0.0,( - 2.0 / gh) , 0.0 , 0.0 , ..
									0.0,0.0,(2.0/2.0),0.0,..
		 							 - 1.0 - (1.0 / gw) , 1.0 + (1.0 / gh) , 1.0 , 1.0)

Local transform_z_left:matrix = matrix.create(Cos(angle) , Sin(angle), 0.0 , 0.0 , ..
									-Sin(angle), Cos(angle), 0.0 , 0.0 , ..
									0.0 , 0.0 , 1.0 , 0.0 , .. 
									0.0 , 0.0 , 0.0 , 1.0)
									
Local transform_z_right:matrix = transform_z_left.transpose()
										
setmatrix(world_matrix)		
While Not KeyHit(KEY_ESCAPE)
	Cls
	If KeyDown(KEY_SPACE)
		world_matrix = backup_matrix
		SetScale 1.0,1.0
		setmatrix(world_matrix)
	EndIf
	TileImage image1 , 0 , 0
	DrawImage image2 , mousex(),mousey()
	If KeyDown(KEY_LEFT) 
		world_matrix = world_matrix.transformmat(transform_z_left) 
		setmatrix(world_matrix)
	EndIf
	If KeyDown(KEY_RIGHT)
		world_matrix = world_matrix.transformmat(transform_z_right) 
		setmatrix(world_matrix)
	EndIf
	If KeyDown(KEY_UP)
		SetScale 2.0 , 2.0
	EndIf
	If KeyDown(key_down)
		SetScale 0.5 , 0.5
	EndIf
	Flip
Wend

Function setmatrix(in:matrix)
		Local change_matrix:Float[]
		change_matrix=[in.m00,in.m01,in.m02,in.m03,in.m10,in.m11,in.m12,in.m13,in.m20,in.m21,in.m22,in.m23,in.m30,in.m31,in.m32,in.m33]
		D3D7GraphicsDriver().Direct3DDevice7().SetTransform(D3DTS_PROJECTION , change_matrix)
End Function

Function DegreeToRad:Float( d:Float )
	Return d*DEGREE_TO_RAD
End Function

Function RadToDegree!( r! )
	Return r*RAD_TO_DEGREE
End Function

' 4x4 Matrix
Type Matrix
	Field m00# = 1, m01# = 0, m02# = 0, m03# = 0
	Field m10# = 0, m11# = 1, m12# = 0, m13# = 0
	Field m20# = 0, m21# = 0, m22# = 1, m23# = 0
	Field m30# = 0, m31# = 0, m32# = 0, m33# = 1
	Function Create:matrix(in00# , in01# , in02# , in03# , in10# , in11# , in12# , in13# , in20# , in21# , in22# , in23# , ..
		in30#,in31# , in32# , in33#)
		Local temp_matrix:matrix = New matrix
			temp_matrix.m00=in00
			temp_matrix.m01=in01
			temp_matrix.m02=in02
			temp_matrix.m03=in03
			temp_matrix.m10=in10
			temp_matrix.m11=in11
			temp_matrix.m12=in12
			temp_matrix.m13=in13
			temp_matrix.m20=in20
			temp_matrix.m21=in21
			temp_matrix.m22=in22
			temp_matrix.m23=in23
			temp_matrix.m30=in30
			temp_matrix.m31=in31
			temp_matrix.m32=in32
			temp_matrix.m33 = in33
		Return temp_matrix
	End Function
	
	Method Copy:Matrix( )
		Local i:Matrix = New Matrix
		MemCopy( Varptr i.m00, Varptr m00, 64 )
		Return i
	End Method
	
	Method Translate( x#, y#, z# )
		m03 = x
		m13 = y
		m23 = z
	End Method
	
	Method Scale( x#, y#, z# )
		m00 :* x
		m10 :* x
		m20 :* x
		
		m01 :* y
		m11 :* y
		m21 :* y
		
		m02 :* z
		m12 :* z
		m22 :* z
	End Method
	
	Method TransformMat:Matrix( i:Matrix )
		Local r:Matrix = New Matrix
		
		r.m00 = m00 * i.m00 + m01 * i.m10 + m02 * i.m20 + m03 * i.m30
		r.m01 = m00 * i.m01 + m01 * i.m11 + m02 * i.m21 + m03 * i.m31
		r.m02 = m00 * i.m02 + m01 * i.m12 + m02 * i.m22 + m03 * i.m32
		r.m03 = m00 * i.m03 + m01 * i.m13 + m02 * i.m23 + m03 * i.m33
		
		r.m10 = m10 * i.m00 + m11 * i.m10 + m12 * i.m20 + m13 * i.m30
		r.m11 = m10 * i.m01 + m11 * i.m11 + m12 * i.m21 + m13 * i.m31
		r.m12 = m10 * i.m02 + m11 * i.m12 + m12 * i.m22 + m13 * i.m32
		r.m13 = m10 * i.m03 + m11 * i.m13 + m12 * i.m23 + m13 * i.m33
		
		r.m20 = m20 * i.m00 + m21 * i.m10 + m22 * i.m20 + m23 * i.m30
		r.m21 = m20 * i.m01 + m21 * i.m11 + m22 * i.m21 + m23 * i.m31
		r.m22 = m20 * i.m02 + m21 * i.m12 + m22 * i.m22 + m23 * i.m32
		r.m23 = m20 * i.m03 + m21 * i.m13 + m22 * i.m23 + m23 * i.m33
		
		r.m30 = m30 * i.m00 + m31 * i.m10 + m32 * i.m20 + m33 * i.m30
		r.m31 = m30 * i.m01 + m31 * i.m11 + m32 * i.m21 + m33 * i.m31
		r.m32 = m30 * i.m02 + m31 * i.m12 + m32 * i.m22 + m33 * i.m32
		r.m33 = m30 * i.m03 + m31 * i.m13 + m32 * i.m23 + m33 * i.m33
		
		Return r
	End Method
		
	Method Add:Matrix( i:Matrix )
		Local a:Float Ptr = GetPtr( )
		Local b:Float Ptr = GetPtr( )
		Local r:Matrix = New Matrix
		Local c:Float Ptr = r.GetPtr( )
		For Local n:Int = 0 To 15
			c[n]=a[n]+b[n]
		Next
		Return r
	End Method
	
	Method Subtract:Matrix( i:Matrix )
	 Local a:Float Ptr = GetPtr( )
		Local b:Float Ptr = GetPtr( )
		Local r:Matrix = New Matrix
		Local c:Float Ptr = r.GetPtr( )
		For Local n:Int = 0 To 15
			c[n]=a[n]-b[n]
		Next
		Return r
	End Method
	
	
	Method Transpose:Matrix( )
	 Local x:Int,y:Int
	 Local r:Matrix = New Matrix
	 Local a:Float Ptr = GetPtr( )
	 Local b:Float Ptr = r.GetPtr( )
	 For x = 0 To 3
		 For y = 0 To 3
			 b[x*4+y] = a[y*4+x]
		 Next
	 Next
	 Return r
	End Method
	
	Method GetPtr:Float Ptr( )
		Return Varptr m00
	End Method
	
	Method ToArray:Float[]( )
		Local r:Float[16]
		MemCopy( Varptr r[0], GetPtr( ), 64 )
		Return r
	End Method
	
	Function FromArray:Matrix( arr:Float[] )
		Return FromPtr( Varptr arr[0] )
	End Function
	
	Function FromPtr:Matrix( arr:Float Ptr )
		Local r:Matrix = New Matrix
		Local p:Float Ptr = r.GetPtr( )
		MemCopy( p, arr, 64 )
		Return r
	End Function
End Type



<edit> The viewport and setscale could be slicker plus mouse movement would need adjusting. However, it's the screen rotation I was most interested in doing.