The Matrix 4 - How Neo Got His Groove Back.

BlitzMax Forums/OpenGL Module/The Matrix 4 - How Neo Got His Groove Back.

AntonyWells(Posted 2005) [#1]
Having some wierd issues with using matrixes in gl rather than it's usual rotatef funcs,

This code, embeded into v2's camera bind for testing,

  glRotatef 0,1,0,0
  glRotatef 1,0,Angle,0


Works as expected. The box arcing around the scene(As the camera is position 250 units away from it)

But, when I try to use the entities local(or global, it has both) matrix to define the rotation of the camera, something very wierd happens.
Instead of an arcing box I get a black screen, except for a brief full screen of white.

Which to me indicates something in matrix code(Which does work, tested as I was doing it 2dally.) isn't reallying conforming to the gl matrix layout..

Here's the matrix code I'm using,



Type Matrix
	
	Method New()
	
		Mat=New Double[16]
			
	End Method
	
	Method Delete()
	
	'	Release Mat
		Mat=Null
	
	End Method
	
	Method Identity()
	
		Local Index:Int
		
		Mat[ 0 ] = 1
		For Index=1 To 15
			Mat[ Index ]=0
		Next
	
	End Method
	
	Method Pitch( nPitch:Double )
	
		Self.Identity()
		mat[5]=Cos( nPitch )
		mat[6]=Sin( nPitch )
		mat[9]=-Sin( nPitch )
	    mat[10]=Cos( nPitch )
	    mat[15]=1
	
	End Method
	
	Method Yaw( nYaw:Double )
	
	   Self.Identity()
		mat[0]=Cos( nYaw )
		mat[2]=-Sin( nYaw )
		mat[5]=1
		mat[8]=Sin( nYaw )
		Mat[10]=Cos( nYaw )
	
	End Method
	
	Method Roll( nRoll:Double )
	
	   Self.Identity()
		mat[0]=Cos( nRoll )
		mat[1]=Sin( nRoll )
		mat[4]=-Sin( nRoll )
		mat[5]=Cos( nRoll )
	
	End Method
		
	Method Position( nX:Double,nY:Double,nZ:Double )
	
		Self.Identity()
		mat[0] = 1
		mat[3] = nX
		mat[5] = 1
		mat[7] = nY
		mat[11] = nZ
		mat[15] = 1
	
	End Method
	
	Method Copy( IN:Matrix)
	
	   Local Index:Int,Val:Double
	
	   For Index=0 To 15
		Mat[Index]=IN.Mat[Index]
	   Next	
	
	End Method
	
	Method Rotate( nPitch:Double,nYaw:Double,nRoll:Double,X:Double=0,Y:Double=0,Z:Double=0 )
		
		Self.identity()
		Local Temp:Matrix = New Matrix
				
		Self.Pitch( nPitch )
		Temp.Copy( Self )
		Self.Yaw( nYaw ) 
		Temp.Multiply( Self )
		Self.Roll( nRoll )
		Temp.Multiply( Self )
		Self.Position( X,Y,Z )
		Temp.Multiply( Self )
		
		Self.Copy( Temp )
		
	End Method
		
	Method TForm_Point( X:Double,Y:Double,Z:Double )
	
		tFormX = (mat[0] * X) + (mat[1] * Y) + (mat[2] * Z) + mat[3]
		tFormY = (mat[4] * X) + (mat[5] * Y) + (mat[6] * Z) + mat[7]
		tFormZ = (mat[8] * X) + (mat[9] * Y) + (Mat[10] * Z) + mat[11]
	
	End Method
	
	Method TForm_Point2D( X:Double,Y:Double )
		
		Local Z=0
		tFormX = (mat[0] * X) + (mat[1] * Y) + (mat[2] * Z) + mat[3]
		tFormY = (mat[4] * X) + (mat[5] * Y) + (mat[6] * Z) + mat[7]
		
	End Method
	
	
	
	Method Multiply( With:Matrix )
	
		Local Temp:Matrix = New Matrix
		Local M:Int,m1:Int,m2:Int
	
		For m=0 To 3
			For m1=0 To 3
				Temp.Mat[ m1*4+m]=0
				For m2=0 To 3
					Temp.Mat[ m1*4+m]:+With.Mat[m2*4+m]*Mat[m1*4+m2]
				Next
			Next
	   Next
	
	   Local Index:Int,Val:Double 
	
	   For Val:Double =EachIn Temp.mat
		Mat[Index]=Val
		Index:+1
	   Next
	   'Release Temp
	
	End Method
	
	Method Debug( PrintFunc:Int(Out:String) )
		
		For Local J=0 To 15
			
			printFunc (J+1)+":"+Mat[J]
			
		Next
			
	End Method
	
	Field Mat:Double[]
	Field tFormX:Double,tFormY:Double,tFormZ:Double,tW:Double
End Type



This is the code from the entity class that generates the 'correct' matrix for rotations.

Method Rotate( Pitch:Double,Yaw:Double,Roll:Double,GlobalRotation = True )
	
		If GlobalRotation
			
			Rotation.Rotate( Pitch,Yaw,Roll )
			LocalRot.Copy( Rotation )
			
			If Parent<>Null
				
				Rotation.Multiply( Parent.Rotation )
			'	Self.UpdateSubs()
						
			Else
			
				LocalRot.Rotate( 0,0,0 )
			
			EndIf
			
			Self.UpdateSubs()
						
		Else
			
			If Parent<>Null
			
				Local Temp:Matrix = New Matrix
				Temp.Rotate( Pitch,Yaw,Roll )
				Rotation.Copy( Parent.Rotation )
				Rotation.Multiply( Temp )
				Self.UpdateSubs()
			Else
				
				Rotation.Rotate( Pitch,Yaw,Roll )
				LocalRot.Rotate( 0,0,0 )
				Self.UpdateSubs()
				
			EndIf
			
		EndIf
	End Method



Any ideas would be nice, I've hit a brick wall, but don't really want to switch back to glrotatef etc...


AntonyWells(Posted 2005) [#2]
This is how I pass the matrix to gl,

glmultmatrixd(Double Ptr(Varptr rotation.mat[0]) )
or same par, with glLoadMatrixD depending on situration. 
Wierd thing is I get identical results whichever one I use to define the camera's rotation. Which is the first rotation, and only in the simple test.



AntonyWells(Posted 2005) [#3]
Well fixed it already. Shock horror it's actually alot faster now too.

Method Rotate( nPitch:Double,nYaw:Double,nRoll:Double )
	
	   Local A!,B!,C!,D!,E!,F!,AD!,BD!
	   A   = Cos( npitch)
   	   B   = Sin( npitch)
   	   C       = Cos(nyaw)
   	   D       = Sin(nyaw)
   	   E       = Cos(nroll)
       F       = Sin(nroll)
	   AD      =   A * D
   	   BD      =   B * D
	   mat[0]  =   C * E
	   mat[1]  =  -C * F
	   mat[2]  =   D
	   mat[4]  =  BD * E + A * F
	   mat[5]  = -BD * F + A * E
	   mat[6]  =  -B * C
	   mat[8]  = -AD * E + B * F
	   mat[9]  =  AD * F + B * E
	   mat[10] =   A * C
   	   mat[3]  =  mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0
   	   mat[15] =  1
	
	End Method



Damien Sturdy(Posted 2005) [#4]

mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0



*confused......
Does that set mat[3] to 0 or -1 depending on if they all match 0 or not?!


AntonyWells(Posted 2005) [#5]
I just converted it from some C++ code tbh.

And it's not working after all, for some reason it clips half the screen now(-320 displays fine)..can't manually adjust the viewport to compensate either.

Quats here we come...


Damien Sturdy(Posted 2005) [#6]
it's amazing what you can figure out without using IF :)


AntonyWells(Posted 2005) [#7]
Yes, I invented the IFless optimization over at blitzcoder.
Or to be more accurate, I discovered it and ignored the fact it's been used for years and claimed it as my own. American Style.

:)


Damien Sturdy(Posted 2005) [#8]
The rr...um... AO..? Technique?


AntonyWells(Posted 2005) [#9]
The what now? But yeah, if it's good I invented it...


gman(Posted 2005) [#10]
just an FYI, i recently converted code using the same type of syntax:


mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0


and while it compiles, it does not work. a simple test:
Framework BRL.Blitz

Local a:Int,b:Int,c:Int

a = b = c = 3

DebugLog(a)
DebugLog(b)
DebugLog(c)



AntonyWells(Posted 2005) [#11]
ah, any suggestions how to get the above code working then? Might explain why it's producing a ton of visual problems when using it. (Same code works fine using glRotatef with quats, so it's not a gl problem)


Damien Sturdy(Posted 2005) [#12]
I duno- I made it up... Antony Optimisation? :/


AntonyWells(Posted 2005) [#13]
Let's walk away from thie conversation before it gets anymore surreal :)


N(Posted 2005) [#14]
Here's my math code just in the case that it might help...



Edit: And don't forget to transpose matrices before doing glLoadMatrixf( YourMatrix.GetPtr( ) )


AntonyWells(Posted 2005) [#15]
Thanks Noel, my matrix rotation code is now working fine thankfully so i'm halt tempted to stay with it rather than try yours,
Though I do have a problem, tform on points is producing wierd results when both pitch and yaw is involved, resulting in sub-entities arcing when they should only pivot..my vector/mult code is the same as yours, technically, so I'm stomped again. One of these days i'll have to learn some maths for real...

But anyway, did your code work fine for such things? I.e, if I tformed a vector of 100,0,0 on a rotation matrix consisting of 45,90,0, would the resultant vector properly only be affected by the yaw as the pitch shouldn't affect anything that has a z value of 0.

?


N(Posted 2005) [#16]
Nope, smae 'problem'.


AntonyWells(Posted 2005) [#17]
<Bleep>.


dmoc(Posted 2005) [#18]

if I tformed a vector of 100,0,0 on a rotation matrix consisting of 45,90,0, would the resultant vector properly only be affected by the yaw as the pitch shouldn't affect anything that has a z value of 0.



Antony, what do you expect to happen here? If I visualise the transform as rotating the reference axis, wouldn't 100,0,0 => 0,-50,-50? (quick guess, could be wrong)


AntonyWells(Posted 2005) [#19]
Shouldn't do. I mean consider a player character.

Facing forward.

Roll it 90 degrees. Now in b3d if you MoveEntity Man,0,0,5
It'll only move..wait..are you right? Is this guy right?

Have I been going nuts over something that is not even a bug?

Can we get a confirmation? ANYONE! :)


Chris C(Posted 2005) [#20]
just a thought

mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0


doesnt zero anything. as it does in C, I guess thats where you copied the code from...


AntonyWells(Posted 2005) [#21]
Yeah, I fixed that a while back.

Just had to zero them individually.

I'm really no good at maths...(Shocker!)


Chris C(Posted 2005) [#22]
wait till you look at doing a rotation on any axis using quats... urrgh, its not nice!

Dont suppose you know an easy way to work out up, side and forward vectors from eular angles do you?


AntonyWells(Posted 2005) [#23]
The way I'd do it is, transform the euler angles into a rotation matrix, then,

to get the up vector tform a vector of 0,1,0 by the rotation matrix, side -1 or 1,0,0 and for forward, 0,0,1

It should then be rotated correctly.

As is I'm almost certainly stopping developing vivid2.0 now, in favour of ogre/vc. At least until max3d is out. Too much work :)


Warren(Posted 2005) [#24]
Awesome.


AntonyWells(Posted 2005) [#25]
/\ Bored man typing, we've got a bored man typing here./\


Chris C(Posted 2005) [#26]
antony any danger of you sending me what you have on vivid2.0 so I can develop it further?


AntonyWells(Posted 2005) [#27]
Can do, although if you make millions out of it I want a nice car out of it :)

I'll send it later this morning. just woke up.


Chris C(Posted 2005) [#28]
oh, thought it was open source?


AntonyWells(Posted 2005) [#29]
Well, it's upto you really. You can upload it as an open source project or just keep it for yourself.


Chris C(Posted 2005) [#30]
well I could if you sent it... >:)


AntonyWells(Posted 2005) [#31]
Oh don't worry, I will. I'm just the world's most least motivated man. :)


Chris C(Posted 2005) [#32]
ether that or vivid's just vapour-ware :))


AntonyWells(Posted 2005) [#33]
Well check your inbox mr suspecious :)