turning off gravity for certain entities

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
00se7en
Posts: 9
Joined: Tue Dec 18, 2007 1:19 am

turning off gravity for certain entities

Post by 00se7en »

thanks, so much for this physics engine. so far it has been very straight forward to use in my simple marble rolling game (and im a beginner to game programming).

my question is, is there a way to have some objects affected by gravity and others not in the same space?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: turning off gravity for certain entities

Post by Norbo »

Technically there is no boolean 'affectedByGravity' flag, but you could use a position tracking (non rotation tracking) force that directly counteracts gravity. Something like:

Code: Select all

                    Force f = new Force((Entity).getPosition(), new Vector3(0, 9.81f, 0));
                    (Entity).addForce(f);
                    f.isTrackingTarget = true;
                    f.isChangingDirectionWhileTracking = false;
If this is insufficient, let me know and I'll see what I can do. I'm torn between adding an extra property to PhysicallySimulated objects that would accomplish this relatively specific functionality versus just letting forces take care of it. Admittedly, the force method for counteracting gravity isn't particularly elegant/simple.

EDIT for future readers:
In v0.5.0, there is an isAffectedByGravity flag.
00se7en
Posts: 9
Joined: Tue Dec 18, 2007 1:19 am

Re: turning off gravity for certain entities

Post by 00se7en »

i actually considered trying something like that, but thought i'd make sure there was no property that i missed first. so i just tried it and it seems to work fine.
00se7en
Posts: 9
Joined: Tue Dec 18, 2007 1:19 am

Re: turning off gravity for certain entities

Post by 00se7en »

So after playing with this some more, I noticed that objects tend to drift. I have a ball that defies gravity using the method above and bounces back and forth between two cubes. I don't think that gravity is the problem because I tried turning it off and sill got the drift. Is this an inaccuracy of floating point math or is there some damping constant, etc that I could adjust?

Here is a simple "game" that shows the drift:

Code: Select all

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

using BEPUphysics;

namespace PhysicsTest
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        ContentManager content;

        Space space = new Space();

        StaticConvexPolyhedron box1;
        StaticConvexPolyhedron box2;
        PhysSphere ball;

        List<DisplayObject> displayObjects = new List<DisplayObject>();


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            content = new ContentManager(Services);
        }


        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            space.gravity = new Vector3(0f, -9f, 0f);

            Vector3 ballStart = new Vector3(0f, -30f, -150f);

            box1 = PrimitiveToolbox.constructCubeStaticConvexPolyhedron(new Vector3(0f, -30f, -100f), 12f);
            box2 = PrimitiveToolbox.constructCubeStaticConvexPolyhedron(new Vector3(0f, -30f, -220f), 12f);
            ball = PrimitiveToolbox.constructPhysSphere(ballStart, 2f, 1f);
            ball.bounciness = 2f;
            ball.angularDamping = 1f;
            space.addEntity(box1);
            space.addEntity(box2);
            space.addEntity(ball);

            Force antiGravityForce = new Force(ballStart, 1f * new Vector3(0f, 9f, 0f));
            antiGravityForce.target = ball;
            antiGravityForce.isTrackingTarget = true;
            antiGravityForce.changingDirectionWhileTracking = false;
            ball.applyForce(antiGravityForce);

            ball.applyImpulse(ballStart, new Vector3(0f, 0f, -100f));

            displayObjects.Add(new DisplayPolyhedron(box1, graphics));
            displayObjects.Add(new DisplayPolyhedron(box2, graphics));
            displayObjects.Add(new DisplaySphere(ball, graphics));

            base.Initialize();
        }


        /// <summary>
        /// Load your graphics content.  If loadAllContent is true, you should
        /// load content from both ResourceManagementMode pools.  Otherwise, just
        /// load ResourceManagementMode.Manual content.
        /// </summary>
        /// <param name="loadAllContent">Which type of content to load.</param>
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                // TODO: Load any ResourceManagementMode.Automatic content
            }

            // TODO: Load any ResourceManagementMode.Manual content
        }


        /// <summary>
        /// Unload your graphics content.  If unloadAllContent is true, you should
        /// unload content from both ResourceManagementMode pools.  Otherwise, just
        /// unload ResourceManagementMode.Manual content.  Manual content will get
        /// Disposed by the GraphicsDevice during a Reset.
        /// </summary>
        /// <param name="unloadAllContent">Which type of content to unload.</param>
        protected override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent)
            {
                // TODO: Unload any ResourceManagementMode.Automatic content
                content.Unload();
            }

            // TODO: Unload any ResourceManagementMode.Manual content
        }


        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();

            // TODO: Add your update logic here
            space.update(gameTime);

            base.Update(gameTime);
        }


        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            foreach (DisplayObject o in displayObjects)
            {
                o.draw(Matrix.CreateLookAt(new Vector3(0f, 0f, 0f), -Vector3.UnitZ, Vector3.Up),
                    Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), (float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height, .1f, 10000.0f));
            }

            base.Draw(gameTime);
        }
    }
}
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: turning off gravity for certain entities

Post by Norbo »

After a little messing around, it does seem to be a floating point problem- but not just from one source. The collision detection system is probably detecting contacts barely off center which is then compounded by position correction and probably deseperation to some extent as well. Judging by the fact that shrinking and slowing the involved objects down still generates drift, it is likely mostly the collision detection.

It looks like the best bet for a simulation like this is adding in a slider-type constraint for the ball to move on which could be broken when desired. Unfortunately the engine doesn't currently support slider constraints, but I am working on improved joint/constraints for v0.3.0.

Depending on your needs for a setup like this, it could be possible to use a StaticSphere with a nonzero velocity to simulate an unstoppable obstacle. I haven't tested movable static objects in quite some time though, so there could be nasty side effects.
User avatar
Zukarakox
Not a Site Admin
Posts: 426
Joined: Mon Jul 10, 2006 4:28 am

Re: turning off gravity for certain entities

Post by Zukarakox »

just make the boxes 1000x bigger, then even if there is a small drift, you wont be able 2 tell! :D


Edit: Ok I ran the gamethingy and I wouldnt really worry about it, enless you game is based on bounces like that that must be 100% accurate, then you might want to worry. All games basically have things like that that do happen from time to time and whenever you see them you just go 'whoa wtf happened' no 'HOLY CRAP THOSE FISIX SUX LOLOZLOZLOZLZ.'
i has multiple toes
00se7en
Posts: 9
Joined: Tue Dec 18, 2007 1:19 am

Re: turning off gravity for certain entities

Post by 00se7en »

Its not a big deal that it doesnt work, i'm just playing around with different physics driven features that i could add to my game. I was thinking of having orbs kind of like the ones in Portal (if you've played that). Those seem to bounce pretty accurately, but I have no idea if those are physics engine driven or have their own separate interactions. So yes accuracy would be important for what I wanted, but I might try other ideas if I keep after the flying orb feature.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: turning off gravity for certain entities

Post by Norbo »

Yeah that precisely the thing I was thinking about myself- I'm guessing they've devised a separate sphere case in Havok other than a GJK-based method which deals with numerical error better, which is very possible given the relative ease of sphere cases. It would become rather messy to add in such special cases though- there is a definite appeal to a one size fits all method.

Then again, given the way which those spheres act (essentially constant high speed and whathaveyou), they could be working under a slightly different method than even other spheres; specifically, some implementation of continuous collision detection is probably used. They might even be non-rotating frictionless particles, which is a whole different issue.
Post Reply