DanielChappuis / reactphysics3d

Open source C++ physics engine library in 3D
http://www.reactphysics3d.com
zlib License
1.55k stars 224 forks source link

Inverted rotation using "setAngularVelocity" #270

Closed gennariarmando closed 2 years ago

gennariarmando commented 2 years ago

Using "setAngularVelocity" to rotate a body inverts the velocity applied if the body's angle is under 0.0f or above 6.2f radians, Means that negative velocity will be applied as positive and vice versa. Is this supposed to happen? Thank you.

DanielChappuis commented 2 years ago

Hello,

Means that negative velocity will be applied as positive and vice versa.

I am not sure what you mean by this. What is negative velocity in 3D?

The rule is the following. If the angular velocity vector is pointing toward you, the body will appear to rotate in counter-clockwise. If it's pointing in the opposite direction, it will rotate clockwise as you can see in this picture from Wikipedia. That's what should happen.

gennariarmando commented 2 years ago

I'll try to be more specific of what I'm trying to achieve.

I am not sure what you mean by this. What is negative velocity in 3D?

I meant that if I set a value of 1.0 to the z axis it'll rotate clockwise, -1.0 will rotate it counterclockwise, this seems to me the right behaviour. But if the z axis value goes under 0.0 or above 6.2 as mentioned before it'll be the opposite, 1.0 will rotate it counterclockwise and -1.0 clockwise, until it reaches again 0.0 or 6.2 then it'll change direction again and again. What I'm trying to achieve is a continuous rotation in one way or other.

If that's the right behaviour then please close this issue, thanks for reply.

DanielChappuis commented 2 years ago

I am not sure I understand. You mean that if you do this, it rotates:

body->setAngularVelocity(Vector3(0, 0, 2));

but if you do it with a value greather than 6.2 it rotates in the other direction?

body->setAngularVelocity(Vector3(0, 0, 7));

gennariarmando commented 2 years ago

I use this to rotate body clockwise: body->setAngularVelocity(Vector3(0, 0, 1));

Then this to rotate body counterclockwise: body->setAngularVelocity(Vector3(0, 0, -1));

Then I print out the current body velocity using this: body->getAngularVelocity();

And I get the orientation using this: body->getTransform().getOrientation().getRotationAngleAxis(angle, axis);

If body is rotating clockwise and the z axis reaches 6,28319 radians, the body starts rotating in the other direction until it reaches 0.0. Same happens if body rotates counterclockwise, and it reaches 0.0f.

What I suppose should happen is that once it rotates 360 degrees it goes directly to 0 instead of rotating slowly back to 0.

Don't know how to explain it better, sorry. :(

DanielChappuis commented 2 years ago

Sorry for my late reply.

I think that I understand the issue. You are using the Quaternion::getRotationAngleAxis() method that returns the quaternion angle in range [0, pi] because it is computed as follows:

angle = std::acos(w) * decimal(2.0);

Therefore if you are expecting an angle between [0, 2*pi], it will not work and that's probably why you have the feeling that the body moves backward but that's not the case.

If you want to get an angle in range [0, 2*pi], you will probably need to compute something like that:

image

Reference: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation

You should really try to use quaternions directly instead of converting to angles as much as possible.