Jump to content
gamecreator

SetRotation Pitch Bug

Recommended Posts

I'm trying to rotate a model slowly 360 degrees. While yaw and roll worked as expected, pitch was glitchy. After 90 degrees it started turning in reverse for a bit, then at 120 it jumped ahead and went back to rotating the original. Then at the other end (I forget the angle) it glitched up again.

 

I'm using:

model->SetRotation(rot,0,0,true);

 

As I said, if I change it to rotate the yaw or roll, it works perfectly:

model->SetRotation(0,rot,0,true);

model->SetRotation(0,0,rot,true);

 

This is on the release branch (not beta).

Share this post


Link to post

Some of this I am sure is the results of avoiding

, but what is interesting is that it doesn't cause the reverse rotation if you use local coordinates in SetRotation(). That in itself seems weird to me because I thought LE3 was the same as LE2 in regards to if an object doesn't have a parent then local = global. Perhaps the problem is due to all the objects are now a child of the scene root in LE3?

 

But in any case, to see the effects of avoiding gimbal lock, rotate the model in 'local' coordinates and show the rotation value you are setting versus the actual entity's rotation. When rotating just the X-axis, the Y&Z will need to auto adjust from -180 to -0/+0 to +180 to avoid gimbal lock. When rotating on just the Y or Z axis, the other axis only need to change from a +0 to -0 to avoid gimbal lock. I assume its due to the order in which eular rotations are being applied.

 

function Script:UpdateWorld()
  self.rot = self.rot + 1
  if self.rot == 360 then self.rot = 0 end
  self.entity:SetRotation(self.rot,0,0)
end

function Script:PostRender(context)
  context:SetBlendMode(Blend.Alpha)
  context:DrawText("self.rot: "..self.rot, 0, 450)
  context:DrawText("entity rot: "..self.entity:GetRotation(true):ToString(), 0, 470)
  context:SetBlendMode(Blend.Solid)
end

Share this post


Link to post

Thank you. I have zero familiarity with gimbal lock but that might also explain why GetRotation returns wacky numbers.

circle.jpg

 

As opposed to 0 to 360. So setting an angle at 270 returns -90 with GetRotation.

Share this post


Link to post

That doesn't fix the problem. Is it really too much to ask that:

 

1. SetRotation(100,0,0,true) set the pitch to 100 no matter what? Is there a situation where it's helpful that it sets it to 80 or whatever instead? I'd even be fine with an undocumented function SetRotationTrue or whatever that does this properly.

2. GetRotation() returns 270 when the angle is 270

 

I know you often try to appease beginners to have things make sense to them right from the beginning. Isn't stuff like this confusing to them too? Does it break the engine to do what's intuitive as opposed to some complex rules only you and two other people know about?

 

Sorry if I seem a bit frustrated but from my perspective this is very basic: you set an angle, you expect an angle. Why complicate things? And maybe it's harder to fix than I think and if that's the case then so be it. Do what you think is best.

Share this post


Link to post

I agree it seems confusing as it was something that stymied me on LE2 at one time as well. What I was alluding to above but somehow forgot to point out directly, was to use the local coordinates for setting and getting the rotation. This way when you set a rotation to (100,0,0), then the local 'get' will return (100,0,0) whereas the global 'get' will return (80,-0,0). Why the global cannot return in the same format - I do not know but the same situation existed in LE2.

Share this post


Link to post

It appears that only when the global flag is set to true, entity:SetRotation() flips the sign of the pitch.

Share this post


Link to post

It appears that only when the global flag is set to true, entity:SetRotation() flips the sign of the pitch.

 

yep - was that way in LE2 as well. Also, the global flag set to true for entity:GetRotation() will return an angle based on a flipped sign.

Share this post


Link to post

I believe it is working correctly now:

window = Window:Create()
context = Context:Create(window)
world = World:Create()
camera = Camera:Create()
camera:SetRotation(35,0,0)
camera:Move(0,0,-3)
local light = DirectionalLight:Create() 
light:SetRotation(35,35,0) 

local model = Model:Cone() 

local pitch=0

while true do

	pitch=pitch + 0.1

	model:SetRotation(pitch,0,0,true)

	if window:Closed() or window:KeyHit(Key.Escape) then return false end

	Time:Update()
	world:Update()
	world:Render()

	context:SetBlendMode(1)
	context:DrawText(pitch,0,0)	
	context:DrawText(model:GetRotation(true).x,0,20)

	context:Sync()

end

Are we talking about numbers not matching what you expect them to be, or are we talking about a visual glitch?

Share this post


Link to post

Okay, that is correct behavior then. I hope that is clear why.

Share this post


Link to post

When you call SetRotation() with the global flag, the euler is converted to a quaternion, transformed to local space, then converted to a euler.

When you call GetRotation() with the global flag, the reverse happens.

Share this post


Link to post
Guest
This topic is now closed to further replies.
×
×
  • Create New...