flight class using native quaternions?

@Andrew_Stacey i would like to apply your (and @ignatz’s) Flight class to the craft entity quaternions. I would really appreciate if you could find the time to modify it to be compatible with the new craft framework.

@LoopSpace in my program i fly a submarine inside a deep sea neutrino telescope.

I use the Flight class developed by you and ignatz in https://gist.github.com/dermotbalson/8876478

I could not figure out how to convert the self.y and self.pr rotations of the flight class to the craft.entity.rotation used by codeacraft. Ideally we would need an updated flight class based on the native quaternions and your matExt (or vecExt) class.

Surely, Codea should fully incorporate your matExt class?

Could you link to the code that you want to adapt. There’s quite a lot of code that came out of the various discussions with Ignatz at that time. The underlying quaternion extensions have been adapted to the new quat type and can be found on github as the file VecExt.lua. For specifics, it would be useful to know what exactly you are trying to do.

got the submarine flight stuff working, uses forces and torques, includes the laggy camera and auto levelling from @ignatz and @loopspace flight class.


Very impressive!

The latest vecext code (https://github.com/loopspace/Codea-Library-Maths) contains extensions to the native quaternions so that anything written with the old code can be adapted to the new. It’s just a matter of replacing the vec4s with quats.

But it might be easier to start afresh. I wrote the low-level code in that project and Ignatz wrote the higher level stuff, so while I could help with the quaternions, I’ve no particular insight as to how the Flight class uses them (indeed, Ignatz an I used to - politely - disagree on such matters so it isn’t how I would have written it). As you’re using craft, maybe starting with clean code would be easier than adapting old stuff.

@LoopSpace, so i decided to use the craft 3d physics to control the flight instead. i apply forces and torques to control the speed and direction. this seems to work okay.

i would like to also implement the camera following scheme that @ignatz used, in which the camera follows the plane, but with a time lag.

the old code (https://gist.github.com/dermotbalson/8876478 in flight class) has this line in it:

self.cam.avel = (myq * cq^“”):log()

myq and cq are quaternions…can you explain to me what the ^”” means and also what the log() is doing? i think they are extensions that you add in your vecext class?

Hi @piinthesky

That’s sounding like you’re making progress.

The ^"" and log are extensions that I added. Incidentally, I’ve ported all of my extensions to the new quaternion class at https://github.com/loopspace/Codea-Library-Maths/blob/master/VecExt.lua.

  • q^"" is the conjugate of q. In terms of rotations, this is the inverse rotation. Formally, the conjugate of t + x i + y j + z k is t - x i - y j - z k.

  • q:log() is the logarithm of q. This is a little trickier to explain as it’s something from differential geometry. It’s a little easier to explain one dimension down. Imagine standing at the north pole and looking along the lines of longitude. You can get to anywhere on the earth by travelling along a line of longitude for a given distance, so if I specify a direction and a distance you get to a place (there’s a little issue about the south pole, but we’ll ignore that for now). This map is known as an exponential map. The reverse map is the logarithm. This takes a place on the earth and returns the direction and distance needed to get there.

    There’s a similar map which takes a quaternion and returns a vec3. It can be used to provide a path of rotations from the identity rotation to the given quaternion.

thanks, i confess i don’t understand how this laggy camera code works, it seems rather complicated!

i find the vecext class crashes when multiplying these two quaternions (1,0,0,0)*(0,0,0,-1), should it! these are the initial values for myq and the conjugate of cq above.

I don’t guarantee bug-free code!

Can you provide some code that I can cut-and-paste to try it out? Just so that I know I’m testing exactly what you’re trying. Thanks.

investigating further, it seems if myq is a vec4 then it behaves. when myq is a craft quaternion then multiplying it with cq, a vec4, it crashes. so multiplying a quaternion with a vec4 does not work. so it seems vec4 and quaternion are not equivalent.

They are equivalent but not interchangeable. Originally, there was no native quaternion so I extended the vec4 class to a quaternion class. Now that there are native quaternions, I figured that it wouldn’t make sense to use vec4s any more. I left the code for legacy reasons, but the intention was to make a complete switch from vec4s to quaternions. So you should replace both myq and cq by quaternions throughout the code and not mix the two types.


unless i missed it, in craft there does not appear to be a convenient way to set the 4 components of a quaternion i.e. myq=quart(w,x,y,z). instead one has to make a quart.eulerAngles, then set each component explicitly. or is there a better way?

I think this is fixed in the latest beta, but in the meantime what I’ve used is:

local function __quat(a,b,c,d)
    local q = quat()
    q.w = a
    q.x = b
    q.y = c
    q.z = d
    return q