The Matrix 4 - How Neo Got His Groove Back.
BlitzMax Forums/OpenGL Module/The Matrix 4 - How Neo Got His Groove Back.
| ||
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... |
| ||
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. |
| ||
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 |
| ||
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?! |
| ||
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... |
| ||
it's amazing what you can figure out without using IF :) |
| ||
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. :) |
| ||
The rr...um... AO..? Technique? |
| ||
The what now? But yeah, if it's good I invented it... |
| ||
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) |
| ||
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) |
| ||
I duno- I made it up... Antony Optimisation? :/ |
| ||
Let's walk away from thie conversation before it gets anymore surreal :) |
| ||
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( ) ) |
| ||
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. ? |
| ||
Nope, smae 'problem'. |
| ||
<Bleep>. |
| ||
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) |
| ||
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! :) |
| ||
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... |
| ||
Yeah, I fixed that a while back. Just had to zero them individually. I'm really no good at maths...(Shocker!) |
| ||
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? |
| ||
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 :) |
| ||
Awesome. |
| ||
/\ Bored man typing, we've got a bored man typing here./\ |
| ||
antony any danger of you sending me what you have on vivid2.0 so I can develop it further? |
| ||
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. |
| ||
oh, thought it was open source? |
| ||
Well, it's upto you really. You can upload it as an open source project or just keep it for yourself. |
| ||
well I could if you sent it... >:) |
| ||
Oh don't worry, I will. I'm just the world's most least motivated man. :) |
| ||
ether that or vivid's just vapour-ware :)) |
| ||
Well check your inbox mr suspecious :) |