Okay, doing the math on paper this makes sense:
1. Work out the Right/Up/Look vectors for the current angle Pitch/Yaw/Roll(XYZ)
2. Build a rotation matrix from them
3. Work out the Right/Up/Look vectors only for the Roll(Z) angle
4. Build a rotation matrix from them
5. Multiply them in reverse order and the result matrix is the final rotation
6. Convert the rotation matrix to Eular
After doing testing it finally worked! Thank GOD!!!!
So I made this function to work with whatever eular angle and can rotate every axis PitchYawRoll:
global _rotVec as integer = 1
global _rotMat1 as integer = 2
global _rotMat2 as integer = 3
make vector3 _rotVec
make matrix4 _rotMat1
make matrix4 _rotMat2
sync on : sync rate 60
autocam off : move camera -10
make object cube 1,1
move object left 1,1
make object cube 2,1
move object right 2,1
color object 2,rgb(255,0,0)
do
angle# = wrapvalue(angle#+0.5)
rotate object 1,0,angle#,0
roll object left 1,angle#
rotate object 2,0,angle#,0
rotate_PitchYawRoll( 2, 0, 0, 1, angle# )
sync
loop
/////////////////////////////////////////////////////////////////////////////////
// rotate_PitchYawRoll( id, xAxis, yAxis, zAxis, angle as float )
/////////////////////////////////////////////////////////////////////////////////
// id - of the object your rotating
// axis - the (unit) axis your rotating about
// pitch(1,0,0) : yaw(0,1,0) : roll(0,0,1)
// angle - the amount your rotating about the choosen axis
/////////////////////////////////////////////////////////////////////////////////
function rotate_PitchYawRoll( id, xAxis, yAxis, zAxis, angle as float )
local pitch as float : local yaw as float : local roll as float
local m11 as float : local m12 as float : local m13 as float : local m14 as float
local m21 as float : local m22 as float : local m23 as float : local m24 as float
local m31 as float : local m32 as float : local m33 as float : local m34 as float
local m41 as float : local m42 as float : local m43 as float : local m44 as float
// build rotation matrix on current object angle
pitch = object angle x(id)
yaw = object angle y(id)
roll = object angle z(id)
// right vector
m11 = cos(roll) * cos(yaw)
m12 = sin(roll) * cos(yaw)
m13 = -sin(yaw)
m14 = 0.0
// up vector
m21 = -sin(roll) * cos(pitch) + cos(roll) * sin(yaw) * sin(pitch)
m22 = cos(roll) * cos(pitch) + sin(roll) * sin(yaw) * sin(pitch)
m23 = cos(yaw) * sin(pitch)
m24 = 0.0
// look vector
m31 = sin(roll) * sin(pitch) + cos(roll) * sin(yaw) * cos(pitch)
m32 = -cos(roll) * sin(pitch) + sin(roll) * sin(yaw) * cos(pitch)
m33 = cos(yaw) * cos(pitch)
m34 = 0.0
m41 = 0 : m42 = 0 : m43 = 0 : m44 = 1
set matrix4 _rotMat1, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44
// build rotation matrix on desired axis angle
pitch = (xAxis*angle)
yaw = (yAxis*angle)
roll = (zAxis*angle)
// right vector
m11 = cos(roll) * cos(yaw)
m12 = sin(roll) * cos(yaw)
m13 = -sin(yaw)
m14 = 0.0
// up vector
m21 = -sin(roll) * cos(pitch) + cos(roll) * sin(yaw) * sin(pitch)
m22 = cos(roll) * cos(pitch) + sin(roll) * sin(yaw) * sin(pitch)
m23 = cos(yaw) * sin(pitch)
m24 = 0.0
// look vector
m31 = sin(roll) * sin(pitch) + cos(roll) * sin(yaw) * cos(pitch)
m32 = -cos(roll) * sin(pitch) + sin(roll) * sin(yaw) * cos(pitch)
m33 = cos(yaw) * cos(pitch)
m34 = 0.0
m41 = 0 : m42 = 0 : m43 = 0 : m44 = 1
set matrix4 _rotMat2, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44
// multiply rotation matrices together and apply rotation to object
multiply matrix4 _rotMat1,_rotMat2,_rotMat1
set vector3 to matrix4 rotation _rotVec, _rotMat1
rotate object id, x vector3(_rotVec), y vector3(_rotVec), z vector3(_rotVec)
endfunction
What I would do now is change the function so it doesn't use objects and just outputs the resulting vector based on my given values: rotate_PitchYawRoll( axisVector, angleVector, amount )
Thou, for most object based rotations that requires this type of rotation I'll just used a dummy object cause it's 5 times quicker (just tested)
"Get in the Van!" - Van B