Hi everyone!
I'm trying to write a function that will rotate my object in a pitch, yaw and roll format, which I kind of have.. (for a better description my previous thread: Lua Local Rotation - Kaine
Basically, I'm getting the rotation via this:
local yaw_rotation = Quaternion(Vector3.up(), math.rad(roll)) local pitch_rotation = Quaternion(Vector3.forward(), math.rad(pitch)) local roll_rotation = Quaternion(Vector3.right(), math.rad(yaw)) local new_rotation = Quaternion.multiply(Quaternion.multiply(yaw_rotation, pitch_rotation), roll_rotation)
The issue with this is that when I roll my object (a spaceship) and then pitch, it technically should pitch in it's new local axis. At the moment, as it just defines the axis for pitch_rotation as Vector3.forward() (which is (0,1,0)) then no matter what the roll is, it always pitches upwards in the direction of world axis... I have no idea where to go from here and I'm having trouble finding any information regarding this. Any help is greatly appreciated!
Cheers,
Kaine
I apologise for all the self answering posts..
I just figured that:
local pitch_rotation = Quaternion(Vector3(0, math.cos(math.rad(roll)), math.sin(math.rad(roll)))
Will rotate the pitch on the correct axis.. however I'm not sure if this is the correct way to do so? It definitely works. Please correct me if this is incorrect!
Cheers,
Kaine
Update: So I kind of having it working however in certain cases I'm still recieving unwanted rotations.
So far my function is now (roughly):
local yaw_rotation = Quaternion(Vector3.up(), math.rad(yaw)) local pitch_rotation = Quaternion(Vector3(0, math.cos(math.rad(roll)), math.sin(math.rad(roll))), math.rad(yaw)) local roll_rotation = Quaternion(Vector3(1,0,0), math.rad(roll)) return Quaternion.multiply(Quaternion.multiply(yaw_rotation, pitch_rotation), roll_rotation)
What happens now, if I roll say 45 degrees, then I pitch, the ship pitch up in new direction resulting from roll as the pitch axis is defined as:
Vector3(0, math.cos(math.rad(roll)), math.sin(math.rad(roll)))
This works fine until for example you do the same as before, where you roll say 45 degrees, then pitch up say 20 degrees.. then if you try to roll again, this affects both the roll AND the pitch axis as it is dependent on the roll; i.e. the ship is rolling, while at the same time it's pitch axis is changing which also changes the orientation of the ship..For the life of my I can't figure out the formula to get the ship rotating correctly for all orientations... I know this is kind of confusing to understand so if needed I can provide more info or a video demonstrating my issue. Help is greatly appreciated (and very much needed!) Thank you!
Cheers,
Kaine
quick question: in your first post, for yaw_rotation you're using "roll" as the input and roll_rotation is using "yaw", is this intentional?
Hey guys!
Dan I'll post a video tomorrow, I've found that this can be quite difficult to explain so I think it'll help clear things up 🙂
KenPayne, uh yes that's a mistake! Oops. However that mistake isn't in my actual program as I typed it out again for the forums as I have a large section of accompanying code that wasn't needed for my question. Refer to my third post for a more current/correct version and check back soon for a video of what I mean!
Cheers everyone,
Kaine
I think the problem is that I don't have is I don't have axis to that local axis though, so I have to calculate that axis, which is where I think I'm running into problems, I have to convert from a world coordinate system to local.. I think it's more often done through matrices rather than so directly through quaternions but I haven't done this before so I have no idea.. Maybe you could elaborate a little?
Thanks!
Hi Kaine!
This example appears to work:
local function compute_rotation(self, input, dt) local q_original = Unit.local_rotation(self.unit, 1) local m_original = Matrix4x4.from_quaternion(q_original) local q_yaw = Quaternion(Vector3(0,0,1), -Vector3.x(input.move) * self.yaw_speed * dt * 15) local q_pitch = Quaternion(Matrix4x4.x(m_original), Vector3.y(input.move) * self.pitch_speed * dt * 15) local q_frame = Quaternion.normalize(Quaternion.multiply(q_yaw, q_pitch)) local q_roll = Quaternion(Matrix4x4.y(m_original), Vector3.x(input.pan) * self.roll_speed * dt) q_frame = Quaternion.normalize(Quaternion.multiply(q_frame, q_roll)) local q_new = Quaternion.normalize(Quaternion.multiply(q_frame, q_original)) return q_new end
Hey t_livee!
Thanks for the example! It's definitely much closer than what I had! The roll now works, however, it still yaws around the world z axis no matter what the pitch of the object is. Any ideas?
Cheers,
Kaine
Edit:
I think this might have done the trick:
local q_original = Unit.local_rotation(self.unit, 1) local m_original = Matrix4x4.from_quaternion(q_original) local q_yaw = Quaternion(Matrix4x4.z(m_original), math.rad(frame_ypr_velocity.x)) local q_pitch = Quaternion(Matrix4x4.x(m_original), math.rad(frame_ypr_velocity.y)) local q_roll = Quaternion(Matrix4x4.y(m_original), math.rad(frame_ypr_velocity.z)) local q_local = Quaternion.multiply(Quaternion.multiply(q_yaw, q_pitch), q_roll) local q_new = Quaternion.multiply(q_local, q_original) return q_new
I'll test it thoroughly and if it doesn't work I'll be back haha. Thanks again!
Can't find what you're looking for? Ask the community or share your knowledge.