How to 'Point' a matrix?
BlitzMax Forums/BlitzMax Programming/How to 'Point' a matrix?
| ||
I've nicked some of trinity's matrix stuff for the basis of v2's entity system. It's working fine, with sub-entities etc, but I really need to figure out how to point a matrix towards a point in 3d space. Any links or tutorials or even code that cover this or anyone here know? Here's the matrix code as is, fairly simple, but works. 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 how DirectX's MatrixLookat function works...zaxis = normal(At - Eye) xaxis = normal(cross(Up, zaxis)) yaxis = cross(zaxis, xaxis) xaxis.x yaxis.x zaxis.x 0 xaxis.y yaxis.y zaxis.y 0 xaxis.z yaxis.z zaxis.z 0 -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1 |
| ||
Thanks. I'm a little bit confused tbh..never used directx code before. Would still be grateful for any help people have on this. |
| ||
zaxis, xaxis and yaxis are three vectors. At is a vector defining the lookat/target position. Up is a vector defining what axis is considered to be "Up". Eye is a vector defining what position you are looking from. zaxis = differencevector(At - Eye) normalized. xaxis = Normalized crossproduct of Up and zaxis yaxis = crossproduct of zaxis and xaxis. Then put the resulting x,y & z values from these vectors in the matrix(as above). -dot(xaxis,eye) = dotproduct of xaxis and eye -dot(yaxis,eye) = dotproduct of yaxis and eye -dot(zaxis,eye) = dotproduct of zaxis and eye I believe a DirectX Transformmatrix looks different from an OpenGL matrix. Is the OpenGL transformmatrix a Transposed DirectX Matrix? |
| ||
Or if you could get your hands on the sourcecode for the gluLookAt() function. |
| ||
Thanks again, it makes sense now. Not sure on any differences between gl/directx matrixes tbh. I'll post up my function based on the above to this thread for anyone interested, and to make sure i've not made any mistakes which i no doubt will. |
| ||
The big difference you need to worry about between DirectX and OpenGL is Left hand coordinate systems or right Hand. That will affect the signs in your matrixs. Off top of my head I dont remember what changes but know that causes issues with the Z Axis. Direct X help files actually go into detail on how to move between the different coordinate systems. Doug Stastny |
| ||
According to the Dx-helpfile, to make the above MatrixLookat function "Right-Handed?" you just switch zaxis = normal(At-Eye) to zaxis = normal(Eye-At). Almost sounds too easy, but on the other hand, it might just be that easy. |
| ||
I'm a bit confused why you're using all this matrix stuff like this anthony, Opengl has a great builtin matrix system that you must be using all the time anyway, why not use that. I'm just wondering, because my gl engine is coming on fine (cameras,entitys,meshs,lights,textures,materials ect) and it only uses the gl matrixs. For example pointing a matrix would be done with glRotatef(). |
| ||
Yeah well, I'm kind of using it to some extent. I use the local rotational matrixes and use glLoad/MultiMat to create the rotation needed. In theory this should allow easier shader-centricisity as you can pass matrices directly to Shaders. Btw, how would glRotatef help with point exactly? You'd still need to do the underlying maths unless you use gluLookAt..which is pretty limiting. - As for left-right hand coords, it can be fixed(at least visually) by scaling everything 1,1,-1 |
| ||
In theory this should allow easier shader-centricisity as you can pass matrices directly to Shaders You can use glGetFloatv(GL_MODELVIEW_MATRIX, Varptr(afMatrix[0])) to get a matrix. Btw, how would glRotatef help with point exactly? Yes you would need to do the math :) *EDIT* just checked my entity code and it turns out I used gluLookAt *EDIT* |
| ||
Opengl has a great builtin matrix system Wha? not really... more like passing 12 floats to ogl. I'd have a matrix class if I was making an engine. I suppose you've got the glrotate/move/etc, but there is really so much more you could add to a matrix class. |
| ||
Opengl has a great built-in matrix system Yeah "great" is a bit over the top lol, should read "Opengl has a built-in matrix system" :) Don't get me wrong, I'm sure Antony knows what he's doing, I'm not saying that using the gl matrix is any better than Antonys class, I was being more inquisitive as to why a matrix class would be needed, what are the advantages? I'm only just learning this stuff myself, and it seems a bit strange to use a matrix class when your already using gl matrix anyway. |
| ||
No worries Papa, I actually did it your way for my last two engines so I'm not even dismissing the idea. Just trying it a new way this time around :) |