Well that's what I did revenant chaos, but it didn't seem the best way to me. So I thought there must be a better way. I know I could do it with Vector/Quaternions, Eular would be a joke, shouldn't be that hard to make a class. To work out the direction vectors you could do this:
null=make matrix4(1)
null=make matrix4(2)
null=make matrix4(3)
null=make vector3(4)
rotate x matrix4 1,-wrapvalue( "x angle here" )/57.3
rotate y matrix4 2,-wrapvalue( "y angle here" )/57.3
rotate z matrix4 3,-wrapvalue( "z angle here" )/57.3
multiply matrix4 1,1,2:multiply matrix4 1,1,3
set vector3 4,0,0,1
transform normals vector3 4,4,2
dirx#=x vector3(4)
diry#=y vector3(4)
dirz#=z vector3(4)
Or how I did it:
function getUpVector( ang as vector3 )
local pitch as float
local yaw as float
local roll as float
local x as float
local y as float
local z as float
local mag as float
pitch = ang.x
yaw = ang.y
roll = ang.z
x = -sin(roll) * cos(pitch) + cos(roll) * sin(yaw) * sin(pitch)
y = cos(roll) * cos(pitch) + sin(roll) * sin(yaw) * sin(pitch)
z = cos(yaw) * sin(pitch)
mag = sqrt(x*x + y*y + z*z)
_vector3.x = x/mag
_vector3.y = y/mag
_vector3.z = z/mag
endfunction
function getRightVector( ang as vector3 )
local pitch as float
local yaw as float
local roll as float
local x as float
local y as float
local z as float
local mag as float
pitch = ang.x
yaw = ang.y
roll = ang.z
x = cos(roll) * cos(yaw)
y = sin(roll) * cos(yaw)
z = -sin(yaw)
mag = sqrt(x*x + y*y + z*z)
_vector3.x = x/mag
_vector3.y = y/mag
_vector3.z = z/mag
endfunction
function getForwardVector( ang as vector3 )
local pitch as float
local yaw as float
local roll as float
local x as float
local y as float
local z as float
local mag as float
pitch = ang.x
yaw = ang.y
roll = ang.z
x = sin(roll) * sin(pitch) + cos(roll) * sin(yaw) * cos(pitch)
y = -cos(roll) * sin(pitch) + sin(roll) * sin(yaw) * cos(pitch)
z = cos(yaw) * cos(pitch)
mag = sqrt(x*x + y*y + z*z)
_vector3.x = x/mag
_vector3.y = y/mag
_vector3.z = z/mag
endfunction
I was playing around with them, got stuck when it came to combined rotation of the source to it's super, example:
type vector3
x as float
y as float
z as float
endtype
global _vector3 as vector3
type emitter
position as vector3
orientation as vector3
rightVector as vector3
upVector as vector3
forwardVector as vector3
mesh as integer
endtype
global _superEmitter as emitter
global _sourceEmitter as emitter
sync on : sync rate 60
color backdrop rgb(72,72,72)
autocam off
position camera 0,0,-12
// set up root (super) emitter
make object cube 1,1
set object diffuse 1, rgb(0, 255, 255)
set object emissive 1, rgb(0, 255, 255)
set object wireframe 1, 1
_superEmitter.mesh = 1
setVector3(0,0,0) : _superEmitter.position = _vector3
setVector3(0,0,0) : _superEmitter.orientation = _vector3
getRightVector( _superEmitter.orientation ) : _superEmitter.rightVector = _vector3
getUpVector( _superEmitter.orientation ) : _superEmitter.upVector = _vector3
getForwardVector( _superEmitter.orientation ) : _superEmitter.forwardVector = _vector3
positionObject( 1, _superEmitter.position )
rotateObject( 1, _superEmitter.orientation )
// set up root (super) emitter
make object plain 2,1,1,1
set object diffuse 2, rgb(255, 255, 255)
set object emissive 2, rgb(255, 255, 255)
set object wireframe 2, 1
_sourceEmitter.mesh = 1
setVector3(0,3,0) : _sourceEmitter.position = _vector3
setVector3(0,0,0) : _sourceEmitter.orientation = _vector3
while false <> 1
// rotate super emitter
_superEmitter.orientation.x = wrapvalue(_superEmitter.orientation.x+0.2)
_superEmitter.orientation.y = wrapvalue(_superEmitter.orientation.y+0.5)
rotateObject( 1, _superEmitter.orientation )
// update vectors
getRightVector( _superEmitter.orientation ) : _superEmitter.rightVector = _vector3
getUpVector( _superEmitter.orientation ) : _superEmitter.upVector = _vector3
getForwardVector( _superEmitter.orientation ) : _superEmitter.forwardVector = _vector3
// update source emitter position/rotation offset from super emitter
x# = _superEmitter.position.x + _superEmitter.rightVector.x * _sourceEmitter.position.x
y# = _superEmitter.position.y + _superEmitter.rightVector.y * _sourceEmitter.position.x
z# = _superEmitter.position.z + _superEmitter.rightVector.z * _sourceEmitter.position.x
x# = x# + _superEmitter.upVector.x * _sourceEmitter.position.y
y# = y# + _superEmitter.upVector.y * _sourceEmitter.position.y
z# = z# + _superEmitter.upVector.z * _sourceEmitter.position.y
_vector3.x = x# + _superEmitter.forwardVector.x * _sourceEmitter.position.z
_vector3.y = y# + _superEmitter.forwardVector.y * _sourceEmitter.position.z
_vector3.z = z# + _superEmitter.forwardVector.z * _sourceEmitter.position.z
positionObject( 2, _vector3 )
// rotate super emitter
_sourceEmitter.orientation.y = wrapvalue(_sourceEmitter.orientation.y+2.0)
// to do the source rotation, I need to switch to quaternions cause this method won't work
rotateObject( 2, _superEmitter.orientation )
pitch object up 2,_sourceEmitter.orientation.z
turn object right 2,_sourceEmitter.orientation.y
roll object right 2,_sourceEmitter.orientation.x
sync
endwhile
function setVector3( x as float, y as float, z as float )
_vector3.x = x : _vector3.y = y : _vector3.z = z
endfunction
function getUpVector( ang as vector3 )
local pitch as float
local yaw as float
local roll as float
local x as float
local y as float
local z as float
local mag as float
pitch = ang.x
yaw = ang.y
roll = ang.z
x = -sin(roll) * cos(pitch) + cos(roll) * sin(yaw) * sin(pitch)
y = cos(roll) * cos(pitch) + sin(roll) * sin(yaw) * sin(pitch)
z = cos(yaw) * sin(pitch)
mag = sqrt(x*x + y*y + z*z)
_vector3.x = x/mag
_vector3.y = y/mag
_vector3.z = z/mag
endfunction
function getRightVector( ang as vector3 )
local pitch as float
local yaw as float
local roll as float
local x as float
local y as float
local z as float
local mag as float
pitch = ang.x
yaw = ang.y
roll = ang.z
x = cos(roll) * cos(yaw)
y = sin(roll) * cos(yaw)
z = -sin(yaw)
mag = sqrt(x*x + y*y + z*z)
_vector3.x = x/mag
_vector3.y = y/mag
_vector3.z = z/mag
endfunction
function getForwardVector( ang as vector3 )
local pitch as float
local yaw as float
local roll as float
local x as float
local y as float
local z as float
local mag as float
pitch = ang.x
yaw = ang.y
roll = ang.z
x = sin(roll) * sin(pitch) + cos(roll) * sin(yaw) * cos(pitch)
y = -cos(roll) * sin(pitch) + sin(roll) * sin(yaw) * cos(pitch)
z = cos(yaw) * cos(pitch)
mag = sqrt(x*x + y*y + z*z)
_vector3.x = x/mag
_vector3.y = y/mag
_vector3.z = z/mag
endfunction
// objectTransformWappers
function positionObject( obj, vector as vector3 )
position object obj, vector.x, vector.y, vector.z
endfunction
function rotateObject( obj, vector as vector3 )
rotate object obj, vector.x, vector.y, vector.z
endfunction