Jump to content
CrazyM

Best method for smooth rotation over time to a specific angle

Recommended Posts

Can anyone recommend the best method to rotate an entity in global space, over time, to a specific angle (90 degree increments)?

 

I wrote a bit that does this, but it feels like bloated attempt and has some issues when it comes to detecting when the rotation has arrived at it's destination due to float value variations.

 

In the example below, a button click sets the rotation in motion with (self.rotateX = true), and increments the first step in the rotation with (self.rotateSpeed). In the update function, the current global x rotation is compared to the target (self.rotAngle.x) rotation, and the rotation should continue until the global and target rotations match. At this point, the rotateX flag is disabled (self.rotateX = false).

 

function Script:UpdateWorld()
   -- Attempting to detect when the target rotation has been reached
   if Math:Round(self.selected:GetRotation(true).x) ~= self.rotAngle.x and self.rotateX == true then
    self.newRot = self.selected:GetRotation(true)
    self.newRot.x = Math:Inc(self.rotAngle.x, self.selected:GetRotation(true).x, self.rotateSpeed)
    self.selected:SetRotation(self.newRot, true)
    if Math:Round(self.selected:GetRotation(true).x) == self.rotAngle.x and self.rotateX == true then
	    self.rotateX = false
	    System:Print("X rotation complete")
    end
   end
end

function Script:ButtonClick(mPos)
   if self:IsInRect(mPos, self.upRect) == true then
    self.rotateX = true
    self.rotAngle = self.selected:GetRotation(true) + Vec3(90,0,0)
    self.newRot.x = Math:Inc(self.rotAngle.x, self.selected:GetRotation(true).x, self.rotateSpeed)
    self.selected:SetRotation(self.newRot, true)
   end
end

Share this post


Link to post

Math:CurveAngle seems to do the same thing as the Math:Inc method I'm currently using, but with a difference scale on the step value. I was hoping there might be a cleaner approach than the one I'm using already.

 

Thanks

Share this post


Link to post

The main issue is with detecting an entities arrival at its target rotation so the rotate flag can be disabled, because the rotation float values are usually something like 89.38285 instead of 90. I tried Math:Round, but this still seems like an unreliable solution.

Share this post


Link to post

Just replace

if Math:Round(self.selected:GetRotation(true).x) == self.rotAngle.x

By

if Math:Abs(self.selected:GetRotation(true).x - self.rotAngle.x) < threshold

 

Where you have to choose an acceptable threshold

Share this post


Link to post

@Rick - I will likely use the snapping idea with Ma-Shell's elegant proximity test to keep entities aligned.

 

@Ma-Shell - That's a great idea, very clean!

 

Thanks guys!

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...