This project is read-only.

Body Gravity

May 16, 2008 at 11:24 AM
Hi

I have disabled the main gravity, and now want to apply gravity to a box. enough gravity to draw boxes torwards it etc..

I tried the following;

 

StaticBox mainBox = new StaticBox(new Vector3(0, 0, 0));
mainBox.Scale =
new Vector3(8, 8, 8);
mainBox.Mass = 100.0f;
mainBox.Body.AddBodyForce(
new Vector3(80, 50, 20));
mainBox.Body.AddExternalForces(200.0f);
mainBox.Body.ApplyGravity =
true;
mainBox.Body.AddWorldForce(
new Vector3(5, 5, 5));
mainBox.Body.AddGravityToExternalForce();

Can someone please point me in the right direction?

Thanks
Q

 

May 27, 2008 at 9:16 AM

Managed to make a working sample. Can upload the whole sample screen (working in the RoeEngine)

Here's the method I created, currently called from my game loop.. Busy refactoring and moving it to a GravityManager

 

 

        public void UpdateGravity()
        {
            #region Variables
            Cube c;
            double dist, grav, length, xd, xGrav, yd, yGrav;
            #endregion

            for (int i = 0; i < cubes.Length; i++)
            {
                c = cubes[i];

                // Only perform if Gravity force is stil Enabled.
                if (c.Gravity.Enabled)
                {
                    xd = mainBox.Body.Position.X - c.b.Body.Position.X;

                    yd = mainBox.Body.Position.Y - c.b.Body.Position.Y;

                    dist = Math.Sqrt((xd * xd) + (yd * yd));
                   
                    length = RoeEngine2.Helpers.Calc.length(mainBox.Scale);

                    if (dist < length)
                    {
                        dist = length;
                    }

                    grav = ((c.b.Mass * mainBox.Mass) / (dist * dist)) * 5;

                    xGrav = grav * (xd / dist);
                    yGrav = grav * (yd / dist);

                    if (dist > 0)
                    {
                        c.Gravity.Accel.X = (float)xGrav / c.b.Mass;
                        c.Gravity.Accel.Y = (float)yGrav / c.b.Mass;
                    }
                    else
                    {
                        c.Gravity.Accel.X = 0;
                        c.Gravity.Accel.Y = 0;
                    }
                    c.Gravity.Accel.Z = 0;
                }
            }

Here's the code for the Cube class

 

    class Cube
    {
        public Box b;
        public GravityController Gravity;
        public Cube(Vector3 position)
        {
            b = new Box(position, new Vector3(3, 3, 3), Matrix.Identity);
            b.Mass = 0.8f;

            Gravity = new GravityController(b.Body);

            PhysicsSystem.CurrentPhysicsSystem.AddController(Gravity);

            b.Body.CollisionSkin.callbackFn += new CollisionCallbackFn(CollisionSkin_callbackFn);
        }
        bool CollisionSkin_callbackFn(CollisionSkin skin0, CollisionSkin skin1)
        {
          //  b.Body.AllowFreezing = true;
            b.Body.Immovable = true;
          //  g.Enabled = false;
           // b.Body.DisableBody();
            return true;
        }
    }

And then lastly the Gravity Controler, this is just used to send the increments in position to the physics engine.

    class GravityController : Controller
    {
        public Vector3 Accel = new Vector3(0, 0, 0);

        public bool Enabled = true;

        Body MoveableBody;

        public GravityController(Body moveableBody)
        {
            MoveableBody = moveableBody;
        }
       
        public override void UpdateController(float dt)
        {
            if (Enabled)
            {
                MoveableBody.ApplyWorldImpulse(Accel);
            }
        }
    }