Transformation matrix

Blitz3D Forums/Blitz3D Programming/Transformation matrix

Dabbede(Posted 2003) [#1]
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


puki(Posted 2003) [#2]
Is this a question or are you announcing this fact?


(tu) sinu(Posted 2003) [#3]
he just typed it wrong, he was asking, didn't you see the '?' :)


Ricky Smith(Posted 2003) [#4]
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.


Dabbede(Posted 2003) [#5]
Thanks for the tip! anyway... I'm sorry for my bad english :)


Dabbede(Posted 2003) [#6]
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?


Ricky Smith(Posted 2003) [#7]
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 ?


Dabbede(Posted 2003) [#8]
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!


Ricky Smith(Posted 2003) [#9]
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




Ricky Smith(Posted 2003) [#10]
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.


Dabbede(Posted 2004) [#11]
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...)


Ricky Smith(Posted 2004) [#12]
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.


Dabbede(Posted 2004) [#13]
Ok! Here you are! Hope this can help...


RayTracer(Posted 2004) [#14]
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


Dabbede(Posted 2004) [#15]
I know! But untill this bug remains unsolved my work will be useless! PLEASE HELP ME!!!!!!!!!!


RayTracer(Posted 2004) [#16]
I'd love to help but my knoledge on quaternions is very limited


koekjesbaby(Posted 2004) [#17]
maybe this guy can help: http://www.blitzbasic.com/logs/userlog.php?user=285


Ricky Smith(Posted 2004) [#18]
@Dabbede - that zip file you posted seems empty..........