In case all above fails and FYI in general, it's probably good to know how exactly angles are defined in mohaa.
Say you have some set of angles A = (p y r); with p, y, r pitch, yaw and roll angles.
Also define I to be the set of unrotated coordinate vectors "fwd", "lf" and "up". Because I is unrotated these are aligned to the world axes x,y,z.
I = {fwd,lf,up} = { (1 0 0) , (0 1 0) , (0 0 1) }
Now what mohaa does with the value of angles you give it, is rotate the model's coordinate system. As a result, the vertex locations move as well (relative to the world's coordinate system) and the object looks rotated.
The way this rotation is accomplished is somewhat arbitrary and hence inconvenient, but here is how it is done anyway.
(note: all subsequent rotations are right-handed, which means that for instance in a 2D coordinate system, the x-axis would rotate towards the positive y-axis, and the y-axis towards the negative x-axis. For a left-handed rotation this is the other way around.)
First, the coordinate system I is rotated around the world z axes by the amount y (the yaw). This results in a new sytem, say C, with the up vector still aligned with the world z-axis but with new forward and left vectors.
Next, the pitch rotation is applied by rotating the new coordinate system C around
its left vector by p (the pitch). Again we get a new coordinate system, D, which has the same left vector as C but new forward and up vectors.
We've almost established the final coordinate system now, we only have to add the roll next. This is done by rotating the entire system D around
its forward vector by r (the roll), leading to system E with the same forwardvector as D but new left and up vectors.
E is the final rotated coordinate system, which depends only on the values given for p, y and r.
Now I am aware this 'explanation' may produce more clouds than it dissolves, and I would be quite amazed if you'd understand it all at once. However I'm hoping that at least some of it makes sense, and after some trial and error more will... maybe eventually you'll get it all and notice it doesn't in any way help you solve your problem. But hey by then you've learned a lot anyway
Assuming that you have learned a lot and not wanting to take all fun / challenge away, I'll present you with a simple method to transform any set of 2 vectors (forward and left, up is defined as fwd x lf) into angles that can be used to rotate your plane entity. Finding out what should be the new forward / left vectors depending on the player's input and plane roll angle I'll leave up to you for now, but you know where to go if you need help in the future
Code: Select all
level.PI = 3.1415926
// transforms vectors to angles (pitch,yaw,roll)
// unlike vector_toangles this also includes roll
vectors_toangles local.vec_fwd local.vec_lf:
local.base_angles = vector_toangles local.vec_fwd
local.base_fwd = local.vec_fwd
local.base_lf = -1.0 * (angles_toleft local.base_angles)
local.base_up = vector_cross local.base_fwd local.base_lf
local.cos = local.vec_lf * local.base_lf
if(abs local.cos < 0.8)
{
local.roll_angle = waitthread arccos local.cos
if(local.vec_lf * local.base_up < 0.0)
{
local.roll_angle = -local.roll_angle
}
}
else
{
// arccos inaccurate here
// so just use arcsin instead
// (far more sensitive in this region)
local.sin = local.vec_lf * local.base_up
local.roll_angle = waitthread arcsin local.sin
if(local.cos < 0.0)
{
local.roll_angle = level.PI - local.roll_angle
}
}
// convert to degrees
local.roll_angle = local.roll_angle / level.PI * 180.0
local.angles = local.base_angles
local.angles[2] = local.roll_angle
end local.angles
// inverse sin
// somewhat inaccurate near +-0.5PI
arcsin local.x:
if(local.x < -0.857 || local.x > 0.857)
{
// some 9th order approximation
local.x3 = local.x * local.x * local.x
local.x9 = local.x3 * local.x3 * local.x3
local.out = local.x + (0.5 * level.PI - 1.0) * local.x9
}
else
{
local.x2 = local.x * local.x
local.x3 = local.x2 * local.x
local.x5 = local.x3 * local.x2
// Taylor series expansion
local.out = local.x + 0.1667 * local.x3 + 0.075 * local.x5
}
end local.out
// inverse cos
arccos local.rad:
local.result = 0.5 * level.PI - (waitthread arcsin local.rad)
end local.result