0 votes

There has already been a similar question, yet no answer: Lerp rotation above 180 degrees

By default 360 degrees are from -180 to +180. For example, when I am rotating with tweens interpolate_property from -160 to +160 (which in theory is 40deg difference) instead the engine chooses to go all the way around and rotate 320 degrees. Is there any method that could help me rotate by shortest path?

This is my current code:

func turn_to_smooth(target_direction: Vector3):
    dummy_direction.turn_to(target_direction)
    var from = rotation_degrees
    var to = dummy_direction.rotation_degrees

    TweenNode.interpolate_property(
        self,
        "rotation_degrees",
        from,
        to,
        1,
        Tween.TRANS_LINEAR, 
        Tween.EASE_IN_OUT
    )

    TweenNode.start()
in Engine by (12 points)

See this article in the docs for help:
https://docs.godotengine.org/en/3.1/tutorials/3d/using_transforms.html

The solution for your problem should be "Interpolation with quaternions":
https://docs.godotengine.org/en/3.1/tutorials/3d/using_transforms.html#interpolating-with-quaternions

The question you are citing says that you should use radians instead of degrees, if you want to allow values greater than 180 (=PI). Have you tried with radians? If you can have values greater or lower than PI, you can check which way to move by using min(angledifa, angledifb), where angledifb would be 40, and a 320.
I think this has a similar solution (look for zylann's answer)
https://godotengine.org/qa/5770/how-to-lerp-between-two-angles

Yes I have tried it with Radians - in a nutshell it does completely the same thing.
My tween interpolate_property still goes the longer path.

"you can check which way to move by using min(angledifa, angledifb),"
How does that help me? What method should I use to move that path?
What would happen next time? because if I move from -340 to -400 the original rotation is already ruined

After insight of wombatstampede
Not yet sure how this is working - tho it solved my problem. I will do my research but this is my current solution:

func turn_to_smooth(target_direction: Vector3):
    dummy_direction.turn_to(target_direction)


func _physics_process(delta):
    var from = Quat(transform.basis)
    var to = Quat(dummy_direction.transform.basis)

    # find halfway point between a and b
    var c = from.slerp(to, 0.1) 
    transform.basis = Basis(c)

1 Answer

+2 votes

I'm just copying my comment here to indicate that there's been an answer to your question which led to a solution (by you).
My comment:

See this article in the docs for help:
https://docs.godotengine.org/en/3.1/tutorials/3d/using_transforms.html

The solution for your problem should be "Interpolation with
quaternions":
https://docs.godotengine.org/en/3.1/tutorials/3d/using_transforms.html#interpolating-with-quaternions

Please see the comment for Ankeris above for the specific solution.

by (3,248 points)

Quat resets scaling of my object, but I could just put a Spatial element as a parent and have a script on it

Github issue

Ok, obviously you solved it somehow that way. :-)

I just did a short test. And the scale is reflected as a factor (somehow) in transform.basis. It seems that Quat normalizes the vectors (to 0..1) and therefore resets the implicit scale back to (1,1,1).

Personally I find it a bit misleading that this isn't visibly shown in the "Matrix" in the Spatial Inspektor which seems always normalized.

Probably you can re-apply the scale in each assignment. I didn't test it but the changed assignment might look like this:

transform.basis = Basis(c).scaled(scale)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.