Transformation matrix
Blitz3D Forums/Blitz3D Programming/Transformation matrix
| ||
Hello everybody! There is a way to access to the transformation matrix? Something like GetMatElement but where you can change the values of the matrix? Thanks |
| ||
Is this a question or are you announcing this fact? |
| ||
he just typed it wrong, he was asking, didn't you see the '?' :) |
| ||
You can't change the values of the transformation matrix - as Blitz uses this internally - you can only access the values - The documentation is extremely scant as usual. As an example the following code will convert the matrix values to a quaternion : Global Quat_W# Global Quat_X# Global Quat_Y# Global Quat_Z# Function Mat2Quat(entity) m00#=GetMatElement#(entity,0,0) m01#=GetMatElement#(entity,0,1) m02#=GetMatElement#(entity,0,2) m10#=GetMatElement#(entity,1,0) m11#=GetMatElement#(entity,1,1) m12#=GetMatElement#(entity,1,2) m20#=GetMatElement#(entity,2,0) m21#=GetMatElement#(entity,2,1) m22#=GetMatElement#(entity,2,2) Quat_W#= Sqr (1 + m00 + m11 + m22) /2 Quat_X# = (m21 - m12)/( 4 *Quat_W#) Quat_Y#= (m02 - m20)/( 4 *Quat_W#) Quat_Z# = (m10 - m01)/( 4 *Quat_W#) End Function Careful when using this with parented entities as it seems the matrix values are accumulative as you go through the hierarchy. More information on the transformation matrix would be great as this could be a very useful command. |
| ||
Thanks for the tip! anyway... I'm sorry for my bad english :) |
| ||
Well, is there a working algorithms to retrive pitch,yaw & roll from a rotation matrix? Actually I use this,yaw=-asin(R(2,0)) pitch=atan2(R(2,1) / cos(yaw),R(2,2) / cos(yaw)) roll=atan2(R(1,0) / cos(yaw),R(0,0) / cos(yaw)) but at some angles the entity seems to turn too quickly, jerkily... any idea? |
| ||
If you're working with rotations it may be better to use quaternion values - you can then interpolate smoothly between 2 quat values using a QuatSlerp function. What is it that you are trying to achieve ? |
| ||
I know very little about quaternions. I tried them only 1 time and I found them a little difficult because blitz uses only euler angles! I'm trying to write a dll to implement tokamak in blitz3d, but tokamak uses only quaternions or matrices for rotations... You posted the code to retrive a quat from a matrix...do you also know the algorithms to transform a quat into euler angles(pitch,yaw&roll)? or to transform an euler into quat? I already have those algs but they don't work correctly. I think the order of the axes that blitz use (y-x-z ...right??) it's different from the order that tokamak use to manage rotations! So, if you have those algs and they work correctly, please post them and I'll try! |
| ||
Here ya go !Global QuatLib_X# Global QuatLib_Y# Global QuatLib_Z# Global QuatLib_W# Global QuatLib_Pitch# Global QuatLib_Yaw# Global QuatLib_Roll# Function QuatToEuler(Qxx#, Qyy#, Qzz#, Qw#) Qx#=Qzz#*-1 Qy#=Qxx#*-1 Qz#=Qyy# Qx2# = Qx# * 2.0 Qy2# = Qy# * 2.0 Qz2# = Qz# * 2.0 Sin_T# = (Qy2# * Qw#) - (Qx2# * Qz#) Cos_T# = 1.0 - (Sin_T# * Sin_T#) If Abs(Cos_T#) > QuatToEuler_Epsilon# Cos_T# = Sqr(Cos_T#) Else Cos_T# = 0 EndIf If Abs(Cos_T#) > QuatToEuler_Epsilon# Sin_V# = ( (Qy2# * Qz#) + (Qx2# * Qw#)) / Cos_T# Cos_V# = (1.0 - (Qx2# * Qx#) - (Qy2# * Qy#)) / Cos_T# Sin_F# = ( (Qx2# * Qy#) + (Qz2# * Qw#)) / Cos_T# Cos_F# = (1.0 - (Qy2# * Qy#) - (Qz2# * Qz#)) / Cos_T# Else Sin_V# = (Qx2# * Qw#) - (Qy2# * Qz#) Cos_V# = 1.0 - (Qx2# * Qx#) - (Qz2# * Qz#) Sin_F# = 0 Cos_F# = 1.0 EndIf QuatLib_Pitch# = ATan2(Sin_T#, Cos_T#) QuatLib_Yaw# = ATan2(Sin_F#, Cos_F#) QuatLib_Roll# = ATan2(Sin_V#, Cos_V#) End Function Function EulerToQuat(Pitch#, Yaw#, Roll#) Pitch# = Pitch# / 2.0 Yaw# = Yaw# / 2.0 Roll# = Roll# / 2.0 Cos_Pitch# = Cos(Pitch#) Cos_Yaw# = Cos(Yaw#) Cos_Roll# = Cos(Roll#); Sin_Pitch# = Sin(Pitch#) Sin_Yaw# = Sin(Yaw#) Sin_Roll# = Sin(Roll#); CpCy# = Cos_Pitch# * Cos_Yaw# SpSy# = Sin_Pitch# * Sin_Yaw# SpCy# = Sin_Pitch# * Cos_Yaw# CpSy# = Cos_Pitch# * Sin_Yaw# QuatLib_Z# = ((Sin_Roll# * CpCy#) - (Cos_Roll# * SpSy#))*-1 QuatLib_X# = ((Cos_Roll# * SpCy#) + (Sin_Roll# * CpSy#))*-1 QuatLib_Y# = (Cos_Roll# * CpSy#) - (Sin_Roll# * SpCy#) QuatLib_W# = (Cos_Roll# * CpCy#) + (Sin_Roll# * SpSy#) End Function |
| ||
Here ya go !Global QuatLib_X# Global QuatLib_Y# Global QuatLib_Z# Global QuatLib_W# Global QuatLib_Pitch# Global QuatLib_Yaw# Global QuatLib_Roll# Function QuatToEuler(Qxx#, Qyy#, Qzz#, Qw#) Qx#=Qzz#*-1 Qy#=Qxx#*-1 Qz#=Qyy# Qx2# = Qx# * 2.0 Qy2# = Qy# * 2.0 Qz2# = Qz# * 2.0 Sin_T# = (Qy2# * Qw#) - (Qx2# * Qz#) Cos_T# = 1.0 - (Sin_T# * Sin_T#) If Abs(Cos_T#) > QuatToEuler_Epsilon# Cos_T# = Sqr(Cos_T#) Else Cos_T# = 0 EndIf If Abs(Cos_T#) > QuatToEuler_Epsilon# Sin_V# = ( (Qy2# * Qz#) + (Qx2# * Qw#)) / Cos_T# Cos_V# = (1.0 - (Qx2# * Qx#) - (Qy2# * Qy#)) / Cos_T# Sin_F# = ( (Qx2# * Qy#) + (Qz2# * Qw#)) / Cos_T# Cos_F# = (1.0 - (Qy2# * Qy#) - (Qz2# * Qz#)) / Cos_T# Else Sin_V# = (Qx2# * Qw#) - (Qy2# * Qz#) Cos_V# = 1.0 - (Qx2# * Qx#) - (Qz2# * Qz#) Sin_F# = 0 Cos_F# = 1.0 EndIf QuatLib_Pitch# = ATan2(Sin_T#, Cos_T#) QuatLib_Yaw# = ATan2(Sin_F#, Cos_F#) QuatLib_Roll# = ATan2(Sin_V#, Cos_V#) End Function Function EulerToQuat(Pitch#, Yaw#, Roll#) Pitch# = Pitch# / 2.0 Yaw# = Yaw# / 2.0 Roll# = Roll# / 2.0 Cos_Pitch# = Cos(Pitch#) Cos_Yaw# = Cos(Yaw#) Cos_Roll# = Cos(Roll#); Sin_Pitch# = Sin(Pitch#) Sin_Yaw# = Sin(Yaw#) Sin_Roll# = Sin(Roll#); CpCy# = Cos_Pitch# * Cos_Yaw# SpSy# = Sin_Pitch# * Sin_Yaw# SpCy# = Sin_Pitch# * Cos_Yaw# CpSy# = Cos_Pitch# * Sin_Yaw# QuatLib_Z# = ((Sin_Roll# * CpCy#) - (Cos_Roll# * SpSy#))*-1 QuatLib_X# = ((Cos_Roll# * SpCy#) + (Sin_Roll# * CpSy#))*-1 QuatLib_Y# = (Cos_Roll# * CpSy#) - (Sin_Roll# * SpCy#) QuatLib_W# = (Cos_Roll# * CpCy#) + (Sin_Roll# * SpSy#) End Function sorry for the double post ! These were originally by sswift I think - I've modified them so they give the correct axis rotation for Blitz3d. |
| ||
Douh! Nothing to do! Probably there's something I miss in tokamak... it's impossible that every QuatLib I tried (not only this) doesn't work! Is it possible that tokamak use different axes order? Or with quaternions this has no importance? In fact pitch & roll must be negate, from Smiff's QuatLib, (-pitch & -roll) to rotate in the right way. But always jerkily! Aaarghhhhh! (smoke from ears...) |
| ||
If you post/send an example of what you are trying to do I'll try to help - it would be great to have Tomakak wrapped ! If the fuction works for you inversing the pitch & roll then go with that - modify the function until it gives you what you want. Working with Quaternions can be a big headache initially ! To rotate from one quaternion value to another you need to interpolate between the values using a QuatSlerp function - this stops the rotation from being 'jerky'. You also need to be aware that to add a quaternion rotation to an existing value you need to multiply the quats using a MultiplyQuat function. Both these functions can be found in the code archives. |
| ||
Ok! Here you are! Hope this can help... |
| ||
tokamak would bring blitz to a new level...i think everyone should join hands and make this possible :) [edit]: the demo looks impressive ,really fast ,ive tested 500 cubes and it ran smooth |
| ||
I know! But untill this bug remains unsolved my work will be useless! PLEASE HELP ME!!!!!!!!!! |
| ||
I'd love to help but my knoledge on quaternions is very limited |
| ||
maybe this guy can help: http://www.blitzbasic.com/logs/userlog.php?user=285 |
| ||
@Dabbede - that zip file you posted seems empty.......... |