Page 1 of 1

Most efficient rotation method for an entity?

Posted: Thu May 31, 2018 10:20 pm
by D646
Evening all,

I am creating a game and decided to migrate my code and use BepuPhysics.
The engine is really easy to use and works just amazing, however, Ithink I am overcomplicating my rotation method for players and game objects.
Basically, I am using something like:

Code: Select all

Public void RotateOnYAxis(float radiants)
{
Body.OrientationMatrix = Matrix3x3.CreateFromAxisAngle(Vector3.Up, radiants);
 }
Where Body is an entity (a box or whatever).
This way, I can get my entities orientation vector from Body.OrientationMatrix.Forward.

Is there a better way (or more efficient) to make an entity rotate around a given axis? BepuPhysics seems very advanced and I have the impresion that I am doing it the wrong way, but I cannot find any method or property to apply a rotation in a more straightforward maner.

Just two apretiations:
-I am blind, so perhaps my method is not working so well, but it's hard to perform tests like that without a visual representation.
-And english is not my native language, so excuse me if it doesn't make sense at all...

Thanks in advance!

Re: Most efficient rotation method for an entity?

Posted: Thu May 31, 2018 10:50 pm
by Norbo
Directly setting the orientation of an entity is pretty cheap and can work just fine. There are a few things to keep in mind:
1) Directly changing orientation is equivalent to teleportation. The physics engine can't stop it from entering collision because there is no velocity associated with the movement.
2) OrientationMatrix is a wrapper around the Orientation quaternion, so you could skip a step by setting the Orientation property instead.
3) Directly setting any of the orientation properties forces the entity awake, so it won't go into a low cost sleeping state.

There are a couple of other options. First, you can compute an angular velocity that approaches your orientation goal and set that to the entity's AngularVelocity property. An example of how to do this can be found in the EntityRotator source: https://github.com/bepu/bepuphysics1/bl ... tor.cs#L83

The other option for dynamic entities is to use an angular motor. Motor constraints work within the solver, so they can be a little more stable (and expensive) than directly setting angular velocity on a dynamic entity in difficult situations.

You might want to just use the EntityRotator; it uses the direct velocity approach for kinematics and motors for dynamics.

Re: Most efficient rotation method for an entity?

Posted: Fri Jun 01, 2018 8:13 am
by D646
Morning,

Thanks for your answer.
I tried to apply what you suggested, however, I am missing something.
Before integrating the useful EntityRotator, I modified my Rotate method like that, just for testing the "teleporting" aproach.

Code: Select all

public void Rotate(float radiants)
{
Body.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Up, radiants);
}
If I understood right, this should rotate the body around its Y axis, (a vertical axis just in the center of the body), however, the value of Body.OrientationMatrix.Forward always returns (0, 0, 0).
Then, I tried to use the entity rotator like that:

Code: Select all

public void Rotate(float radiants)
{
EntityRotator rotator = new EntityRotator(Body);
PhysicsEngine.Add(rotator);
Quaternion quat = Quaternion.CreateFromAxisAngle(Vector3.Up, radiants);
rotator.TargetOrientation = quat;
 }
.. and get the same results.

Thanks again for your time, I am sure I am missing something very basic...

Re: Most efficient rotation method for an entity?

Posted: Fri Jun 01, 2018 5:49 pm
by Norbo
Since the OrientationMatrix is constructed from the Orientation quaternion, and the Orientation is forced to be normalized, the OrientationMatrix.Forward should always be a unit length direction. (Or NaNs if something has gone badly wrong.)

For example:

Code: Select all

body.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver4);
var forward = body.OrientationMatrix.Forward;
Forward should be (-0.7071068, 0, -0.7071067).

If you're seeing all zeroes, I would recommend confirming that there isn't some kind of intermediate issue interfering with the output.

With regard to the entity rotator, I should mention that since it operates only on velocities, at least one physics time step must pass in order for it to have any effect on the orientation. (Also, you'll want to create one rotator and reuse it across multiple calls, otherwise you'll end up with a bunch of EntityRotators in the Space fighting each other.)

Re: Most efficient rotation method for an entity?

Posted: Sun Jun 03, 2018 10:00 pm
by D646
Thanks for your help, @Norbo.
It worked prety well. For some reason, quaternion.ToString() were returning something like: 0, 0, 0, 1, and I concluded that any rotation were happening.
Talking about EntityRotator, after diving into the source code, it seems that setting EntityRotator.TargetOrientation = any vector3 is enought to make it starts rotating. Is there any property or whatever to set a fixed time for the total rotation? My aproach is as follows (in pseudocode):

(TargetOrientationInradiants - CurrentOrientationInRadiants) / TotalTargetTime * elapsedTimeSinzeLastUpdate = radiants to be added in this update to reach TargetOrientation in given time.

Is it possible to make it automatically? There isn't any property like velocity, or Time in the EntityRotator class.

Thanks again for your time.

Re: Most efficient rotation method for an entity?

Posted: Sun Jun 03, 2018 10:48 pm
by Norbo
The EntityRotator doesn't support a 'time to meet goal' explicitly, but for dynamics, you can modify the underlying motor to behave in different ways. For example, you could mess with the rotator.AngularMotor.Servo.MaxCorrectiveVelocity, rotator.AngularMotor.Servo.BaseCorrectiveSpeed, or spring settings to change how fast the motor tries to reach the goal.

Kinematics don't use the motor, so that option isn't available and external orientation interpolation will still be needed.