Controllers and Forces

I have seen a number of questions regarding controllers and forces in the Forums, since I am working through many of the same basic issues, I thought I would add what I learn as I learn it here. Please edit and fix whatever is incorrect!

Controllers

The way the JigLibX engine is set up, all forces that are applied directly to a body are cleared prior to beginning a new iteration calculation. This is presumably so that the engine can decide when to apply which forces, rather then the users "update" code. In order to apply forces to a body, you must create a controller object to handle this for you. A controller object inherits from the abstract class "Controller" in the JigLibX.Physics library, and must do a few things.

First, in order to affect an object, the controller must have an reference to it, so passing in the body objects (or references to them) you want it to affect is a good idea. Also, before it will function it must activate itself, this is handled simply by a call to EnableController(), after the controller has been initialized. This function is exposed as part of the inherited class.

The bulk of the work of the Controller is accomplished in the UpdateController method, which you must overload in your child class in order for it to do anything. This is where you actually apply forces and torques to the bodys that you have passed in (through the use of AddBodyForce/Torque, AddWorldForce/Torque.

One other trick is that applying a force to a body does not automatically make it active. So a body that has been set inactive (i.e. "timed out") and a force is applied to, will not move. To fix this, you should probably check the IsActive flag, and if it isn't set, the body.SetActive();

So here is a very basic example of the minimum a controller would need:

using JigLibX.Physics;
using JigLibX.Geometry;
using JigLibX.Math;
using JigLibX.Utils;

namespace GameNamespace
{
    public class physController : Controller
    {
        private Body body0;
        public Vector3 force0 = new Vector3();
        public Vector3 torque0 = new Vector3();

        public physController()
        {
        }

        public void Initialize(Body body0)
        {
            EnableController();
            this.body0 = body0;
        }

        public override void UpdateController(float dt)
        {
            if (body0 == null)
                return;

            if (force0 != null && force0 != Vector3.Zero)
            {
                body0.AddBodyForce(force0);
                if (!body0.IsActive)
                    body0.SetActive();
            }
            if (torque0 != null && torque0 != Vector3.Zero)
            {
                body0.AddBodyTorque(torque0);
                if (!body0.IsActive)
                    body0.SetActive();
            }

        }

    }
}

Note that here force0 and torque0 are public, which is clearly a poor design choice, and also EnableController() is called directly on the created object.

Forces

The types of forces we can apply in our controller are generally limited to "body force", "world force", "body torque", and "world torque". The only difference between applying a force to using "body" or "world" is the coordinate system used for the force direction. AddBodyForce applies the force based on the Bodys coordinates.. so Vector3.Forward is directly forward from the orientation that the body is currently facing. If you want absolute coordinates, you apply the force using AddWorldForce. The force still is affecting only the body that you apply it to, but the coordinate system is that of the world (so the same direction, irrespective of the facing of the body itself). The same is true for torques.

When applying forces we also have the option to apply the force to a position on the object other then the center of mass. This is simply given as a position vector to the location the force is being applied from its center of mass. Torques, however are always applied about the center of mass. To create a more complex torque like a wrench (force at one end, about a "connection" at the other), you would need to apply a body force to a position on the end of the wrench, with the other end attached with a constrained joint.

There are several other methods that can be used to add forces to a body, however their usage is more specific. AddExternalForce is a virtual class, which in its default usage does nothing more then "apply gravity". This is seemingly here to allow a place for constant global force to be added by overriding the method. In its default state, it doesn't really do anything.

Impulses are instant changes in the velocity (or angular velocity) of the body. Rather then applying a force which causes an acceleration, applying an impulse immediately increases to the new velocity. This would be the same as directly affecting the exposed velocity of a body with += impulse / mass. Applying a "negative impulse" would be subtracting from the current velocity.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License