Stingray Forum (Read Only)
Welcome to Autodesk’s Stingray Forums. Share your knowledge, ask questions, and explore popular Stingray topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lua - Rotating along custom axis with Quarternions

11 REPLIES 11
Reply
Message 1 of 12
Anonymous
723 Views, 11 Replies

Lua - Rotating along custom axis with Quarternions

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

11 REPLIES 11
Message 2 of 12
Anonymous
in reply to: Anonymous

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

Message 3 of 12
Anonymous
in reply to: Anonymous

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

Message 4 of 12
dan.matlack
in reply to: Anonymous

A video would be helpful 🙂 or maybe a diagram? just see what your intended behavior is -- then we can go from there to work on the scripting for input.
______________________________________
Dan Matlack
Senior Content Manager || Games Solutions
Autodesk, Inc.
Message 5 of 12
Anonymous
in reply to: Anonymous

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?

Message 6 of 12
Anonymous
in reply to: Anonymous

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

Message 7 of 12
Anonymous
in reply to: dan.matlack

Hey Dan!

 

Here is a video describing the issue I'm having:

 

 

Cheers!

Kaine

Message 8 of 12
dan.matlack
in reply to: Anonymous

Great vid. Thanks! It looks like you just want to make sure your pitch is adjusted every tick so that after you roll, it starts the pitch on the local axis from the new pitch values that were changed when you were in your roll. Does that make sense? Basically every tick after your pitch values have changed, reset them to 0 on the local axis. That will allow the pitch controls to always start correctly, like it did the first time you pitched.
______________________________________
Dan Matlack
Senior Content Manager || Games Solutions
Autodesk, Inc.
Message 9 of 12
Anonymous
in reply to: dan.matlack

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!

 

Message 10 of 12
dan.matlack
in reply to: Anonymous

Hi Kaine,

I'm going to see about getting some sample script for you to get that local axis for pitch. Will get back to you shortly. Thanks!
______________________________________
Dan Matlack
Senior Content Manager || Games Solutions
Autodesk, Inc.
Message 11 of 12
t_livee
in reply to: Anonymous

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
Message 12 of 12
Anonymous
in reply to: t_livee

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.

Post to forums  

Autodesk Design & Make Report