i personally wouldn't mind a revamp of the submodel animation system. so far it only supports a hand full of actions and only supports on and off animations that reset themselves after some time. i think bobs original plan was to have more animation triggers and animation types. like linked animations which would couple an animation to a variable. at some point it was possible to add a lua based animation right in a ships table entry which would be auto-applied to every ship of that class, but i dont think that was ever commited. id like to see those features revised and added to the engine. but i have no problem using scripting, as ive solved most of the problems associated with it (namely the ability to store metadata on a ship by ship basis), i just need to bring everything together.
to script animations for every ship would require

of work and probably my ship meta data system from the freespace rts (to track animation status from ship to ship). to do something simple which requires no metadata, by using a value thats part of the ship object and its children objects (subsystems, ship.physics, etc) , such as desired velocity, shield strength, hit points and so on. take your value that you want to use, crunch some numbers so that it represents the amount of some motion, build a matrix and apply it to an object. as the value changes, the object animates. heres an example:
if ship:isValid() then
--set vars for animations and input
--determine the input axes in -1 to 1 scaler format
local rotx = ship.Physics.RotationalVelocityDesired.x / ship.Physics.RotationalVelocityMax.x --yaw
local roty = ship.Physics.RotationalVelocityDesired.y / ship.Physics.RotationalVelocityMax.y --pitch
local rotz = ship.Physics.RotationalVelocityDesired.z / ship.Physics.RotationalVelocityMax.z --roll
local gox = ship.Physics.SideThrust --lateral
local goy = ship.Physics.VerticalThrust --vertical
local goz = ship.Physics.ForwardThrust --longitudinal
local msx, msy = mousejoy() --mouse axes
as you can see i took every axis (including the mouse position), abstracted it down to a -1 to 1 value and stored it in a bunch ov vars. continuing:
--control animation
if ship.Class:isValid() then --had to idiot proof this
if ship.Class.Name == "PB Sepulture" then
--get submodels
local psub = ship["stick_pitch"]
local rsub = ship["pilot_stick"]
local rsub2 = ship["copilot_stick"]
local tsub = ship["throttle"]
--yoke pitch
if psub:isValid() then
local Angs = psub.Orientation
Angs.p = rotx * 0.03
psub.Orientation = Angs
end
--yoke roll
if rsub:isValid() then
local Angs = rsub.Orientation
Angs.b = rotz * 2
rsub.Orientation = Angs
if rsub2:isValid() then rsub2.Orientation = Angs end
end
--throttle stick
if tsub:isValid() then
if goz >= 0 then goz = goz * 1.2 else goz = goz / 15 end
local Angs = tsub.Orientation
Angs.p = goz - 1.1
tsub.Orientation = Angs
end
if ship.Class.Name == "some other ship" then
--do the next ships animations
end
end
end
what ive done first is get handles for all the subobjects i wish to animate, in this case some flight controls in the cockpit. then for each i have a few lines of code to handle the animation. basicly all im doing is taking the objects old orientation, modifying it (my editing p,b,h values or by matrix multiply). more complicated animations, like a rotation on an arbitrary axis, would require a better understanding of matrix math.
a crash course in matrix ops for those that need it:
matrices represent the rotation of an object. the reason they are used is because it sort of streamlines the math involved in transformations. they are easy to combine using matrix multiply, the * operator. to apply to vectors you use ori:unrotateVector(vec) and ori:rotateVector(vec), one is essentially the inverse of the other. to apply a matrix to a ship or subobject, you can apply it directly, which would set an absolute orientation in world or model space, respectively. if you want to rotate something relative to how it is currently oriented, get its current matrix from its .orientation, and multiply it by the matrix that represents the orientation you want to add to it.
matrix multiply is how you combine rotations. its important to note that with matrix multiplication that a*b != b*a. so if matrix a stores a 90 degree rotation on the y axis, and matrix b represents a 90 degree rotation on the x axis, and assuming you have a ship in local space. a*b would make a matrix that when applied to the object would rotate it so that it points up and is rolled 90 degrees, while b*a would rotate the object so its pointed to a side and rolled 90 degrees.
fortunately scripting has most of the matrix ops needed pre coded for you, so you dont need to directly concern yourself with how to do it, rather how to use it. you can create a rotation from euler angles (rotations about primary axes in radians), and from a vector (though this doesnt give you any control over roll) about the only thing not in there is arbitrary axis rotation, which could be done with this function:
arbrot = function(a, r)
local s = math.sin(r)
local c = math.cos(r)
local t = 1 - c
local m = ba.createOrientation()
m[1] = t * a.x^2 + c
m[2] = t * a.x * a.y + s * a.z
m[3] = t * a.x * a.z - s * a.y
m[4] = t * a.x * a.y - s * a.z
m[5] = t * a.y^2 + c
m[6] = t * a.y * a.z + s * a.x
m[7] = t * a.x * a.z + s * a.y
m[8] = t * a.y * a.z - s * a.x
m[9] = t * a.z^2 + c
return m
end
another way to deal with animations is to interpolate between two orientations. using a:getInterpolated(b, 0.5) would come up with a matrix thats in the middle of a and b, seting the last argument to zero would return a and setting it to 1 would return b. i haven't used this yet but its probably gonna be key to making good animations in lua.