Harry wrote:This has been bothering me some time ago too, and I hadn't yet got around to find out how to do it. But your question made me look into this again:
This C++ code, copied from Observer::setTargetSpeed, is used to transform vectors (in this case in the line of sight instead of "up") by a quaternion:
Code: Select all
Vec3f(0, 0, -s) * getOrientation().toMatrix4();
The problem here is the "toMatrix4()"-conversion from a quaternion to a rotation matrix and the resulting multiplication between a vector and a matrix, which aren't available in Celx-scripting.
Thanks so far Harald.
Harry wrote:So I think you either have to implement this in Lua yourself,
I have no problem doing this in Lua myself, if only I knew how..
If I am correct, the formula to be applied (pseudo code) is
newUp = defaultUp * getOrientation()
where 'newUp' is [0,1,0] when the line of sight is [0,0,-1], ie looking along the z-axis.
I found this text on Internet:
Internet wrote:If a 3-vector is represented by a homogeneous quaternion, that is one whose scalar part is zero, then to rotate a vector <0, V> through an angle theta
about a unit axis vector A, do the following:
let Q = < -cos(theta/2), A * sin(theta/2) >
rotated vector = Q * <0, V> * COMP Q
and worked this out in Lua like this:
Code: Select all
function vector(x,y,z)
-- wrapper for celestia:newvector() function
return celestia:newvector(x,y,z)
end
function comp(q)
-- this functions calculates the complement of quaternion/orientation 'q'
return celestia:newrotation(-1 * vector(q.x,q.y,q.z),q.w)
end
function rotationToVector(rot)
-- convert a rotation to a vector, ie only use the vector part
return vector(rot.x,rot.y,rot.z)
end
function vectorRotate (v,a,theta)
-- quaternion implementation of rotation vector 'v' around axis 'a' by angle 'theta'
local q = celestia:newrotation( math.sin(theta/2)*a, -math.cos(theta/2))
local rv = rotationToVector(q * celestia:newrotation(v,0) * comp(q))
return rv:normalize()
end
and then tried using this to calculate the upvector from the current orientation:
Code: Select all
yaxis = vector(0,1,0)
obs = celestia:getobserver()
up = vectorRotate(yaxis,vector(obs.x,obs.y,obs.z),obs.w)
but this absolutely does not what I want.
It is unclear to me if the 'w' part of an orientation is the angle to be applied.
Or rather: I do not know what angle to use in my vectorRotate function.
Harry wrote:[]... or wait for the next Celestia-version (I will check in a rotation:transform(vector) which does this).
Must be cool to be able to put these functions in celx yourself
I appreciate the help Harald.
However, I'd like to go on with my script asap.
So if you, or someone else, can confirm that I am trying to do the right thing but in a wrong way, rather than doing the wrong thing in the right way, or even worse, trying to do the wrong thing in the wrong way....
Paul