Rotate an entity (possibly using offset)

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
al9191
Posts: 68
Joined: Wed Nov 16, 2011 11:19 pm

Rotate an entity (possibly using offset)

Post by al9191 »

I am in process of writing a game using the BEPU engine, but have got stuck trying to rotate my entity.

The entity is a convex hull representation of a model.

When I click left I want to rotate the entity to the left and when I click right rotate it right. (Around the Y axis.)

I have managed to rotate it by working out the rotation matrix and then just setting the OrientationMatrix as it:

Code: Select all

ConvexHull Body;
float totalRotation;

public void rotate(float angle) {
totalRotation += angle; //keeps track of total rotation of object so far
float cosRotate = (float)Math.Cos(angle);
float sinRotate = (float)Math.Sin(angle);
Matrix3X3 orientation = new Matrix3X3(cosRotate, 0f, sinRotate, 0f, 1f, 0f, -sinRotate, 0, cosRotate);
Body.OrientationMatrix = orientation;
}
However, I found that when the entity collides with another entity then this turns the entity around. This means that when I then try to carry on rotating the entity as I was before, it doesn't know about any rotation the physics engine has applied to it because of the collision.

I therefore, tried to use the Orientation matrix of the entity and add a rotation to that but I just can't get it to work.

How would you therefore go about rotating an entity so that you always know the orientation of the entity and can then rotate that when arrows are pressed?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Rotate an entity (possibly using offset)

Post by Norbo »

1) Some general information about entities.
It sounds like your entity is dynamic. This means it responds to collisions like a regular familiar physical object.

Dynamic entities are created when an entity's constructor is given a mass value, or the entity's BecomeDynamic function is called later.

Entities can also be kinematic. This kind of entity behaves as though it has infinite mass and inertia. It will not respond to collisions or constraints. The only way to change its velocity is to do so directly with the entity's properties. Kinematic entities are created when an entity's constructor is not given a mass value, or the entity's BecomeKinematic function is called later.

So if you want complete control over the entity, use a kinematic entity instead of a dynamic entity.

2) Avoid teleportation
Setting the orientation or position of an entity directly constitutes a teleportation. There is no velocity involved; the entity simply ceases to be in one location, and appears in another. Collision response cannot handle this rigidly. Dynamic entities touching a teleporting entity will still undergo a partial, squishy response thanks to the penetration correction component of collision response.

To maintain good collision response, use velocities to control entities.

If you desire position-level control over entities, you can use convenience classes like the EntityMover and EntityRotator to handle the computation of velocities to reach desired position goals. Those work on both dynamic entities and kinematic entities, though they are more rigid when used with kinematic entities since kinematics do not respond to collisions.

If you just want to make an object rotate around the world up axis, you could also accelerate the angular velocity. The AngularVelocity property is a Vector3 representing the axis of rotation with speed equal to the vector's magnitude. So, an AngularVelocity of (0,5,0) would make the entity rotate around the Y axis at 5 radians per second. You could apply incremental angular accelerations to spin up an object (entity.AngularVelocity += angularAcceleration * dt).

If you want to figure out how fast the entity is rotating around an axis, you can dot the AngularVelocity against the normalized axis. This information can be used to implement a speed limit. For example, apply an acceleration every frame without exceeding a max speed.

3) In general, use helper methods
Matrix3X3 has a bunch of static helper methods to create rotation matrices and stuff like that. Very rarely does a matrix have to be constructed from components. If the Matrix3X3 lacks a helper method you need, consider using the XNA Quaternion or Matrix classes which have even more options. There are conversions between all the types.
al9191
Posts: 68
Joined: Wed Nov 16, 2011 11:19 pm

Re: Rotate an entity (possibly using offset)

Post by al9191 »

Thanks very much for the help have it working using velocities now.

The only thing is that to say move it forward, if I update the X of the LinearVelocity vector3, this moves it in the X direction with respect to the world.
I want to move it forwards with respect to the entity itself, so if it is positioned at an angle, when up is pressed to apply a velocity to move the entity forwards would mean moving at the angle it is placed at.

I would do this with trigonometry, but that requires me to know the angle it is placed at which just goes back to the problem I had before. How do you go about moving and entity using velocity with respect to the direction it is currently facing?


*EDIT* I found a method on another forum post that can get the angle rotated from a Quaternion. I will try and get my head around the maths of how a Quaternion works and use that :).
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Rotate an entity (possibly using offset)

Post by Norbo »

You could also use the entity.OrientationMatrix.Forward. This and other tricks can be found in this thread: http://bepu.nfshost.com/forum/viewtopic.php?f=4&t=1442
Post Reply