Collision of Cylinder isn't precisely

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
amumu
Posts: 2
Joined: Thu May 10, 2012 10:05 am

Collision of Cylinder isn't precisely

Post by amumu »

I was developing a game based on the platform of BEPUphysics.
In this game, golden coins will drop from high to a platform.

I created a Cylinder and rleased it from a flat Box, Cylinder is the modle for golden coins while Box for the Platform,But I found the second when the Cylinder hit the box,Cylinder will fall into Box and gradually rebound.

But I didn't find this when I tried to drop Sphere and some smaller Box onto this flat Box.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Collision of Cylinder isn't precisely

Post by Norbo »

If the objects are very large relative to the usual scale of objects (0.5 to 10 units is regular for the default settings), an object which overlaps another object will seem to depenetrate slowly because the amount of overlap is large relative to the CollisionResponseSettings.MaximumPositionCorrectionSpeed (CollisionResponseSettings.MaximumPenetrationCorrectionSpeed in v1.2).

Scales excessively larger than the the engine is tuned for can cause issues which may lead to penetration to begin with. Spheres and boxes have special cases with each other, so this effect wouldn't be so apparent. Cylinders, however, use the general case collision detection system which relies on these tuning factors. If this is the problem, consider using something like the BEPUphysicsDemos ConfigurationHelper.ApplyScale method to change the various tuning factors in the engine to compensate for the scale. Another option is to reduce the scale of the simulation to match the default scale- this option may work better in the long term for numerical reasons.

If it's not just a scale issue, I could take a look at the configuration if you can isolate the problem for me to debug (e.g. in a BEPUphysicsDemos demo/code snippet).
amumu
Posts: 2
Joined: Thu May 10, 2012 10:05 am

Re: Collision of Cylinder isn't precisely

Post by amumu »

Norbo wrote: If it's not just a scale issue, I could take a look at the configuration if you can isolate the problem for me to debug (e.g. in a BEPUphysicsDemos demo/code snippet).
I did some changes to BEPUphysicsDemos to demonstrate this problem:

Code: Select all

namespace BEPUphysicsDemos.Demos
{
    /// <summary>
    /// Demo showing a wall of blocks stacked up.
    /// </summary>
    public class WallDemo : StandardDemo
    {
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public WallDemo(DemosGame game)
            : base(game)
        {
            int width = 3;
            int height = 2;
            //float blockWidth = 2f;
            float blockHeight = 1f;
            float blockRadius = 3f;
            //float blockLength = 1f;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    var toAdd =
                        new Cylinder (
                            new Vector3 (
                            i * blockRadius * 2 + blockRadius * (j % 2) - width * blockRadius,
                                blockHeight * .5f + j * (blockHeight) + 60,
                                0),
                                blockHeight, blockRadius, 10);
                        //new Box(
                        //    new Vector3(
                        //        i * blockWidth + .5f * blockWidth * (j % 2) - width * blockWidth * .5f,
                        //        blockHeight * .5f + j * (blockHeight),
                        //        0),
                        //    blockWidth, blockHeight, blockLength, 10);
                    Space.Add(toAdd);
                }
            }

            Box ground = new Box(new Vector3(0, -.5f, 0), 50, 1, 50);
            Space.Add(ground);
            game.Camera.Position = new Vector3(0, 6, 15);
        }

        /// <summary>
        /// Gets the name of the simulation.
        /// </summary>
        public override string Name
        {
            get { return "Wall"; }
        }
    }
}
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Collision of Cylinder isn't precisely

Post by Norbo »

That is indeed caused by the cylinders being quite large relative to the correction speed. Since they hit the ground so fast, they penetrate quite a bit. The default maximum correction speed is small relative to the size of those shapes, so it doesn't depenetrate quickly.

To address this, do at least one of the following:
-Increase the CollisionResponseSettings.MaximumPositionCorrectionSpeed.
-Shrink the objects to fit the default position correction speed better.
-Perform more frequent, shorter time steps by setting the Space.TimeStepSettings.TimeStepDuration to a smaller value and calling Space.Update() more frequently or by using Space.Update(dt) to use internal time stepping. If there's sufficient time for it, this is a good way to improve simulation quality overall.
-Enable continuous collision detection by setting the objects' PositionUpdateMode to continuous. This will avoid some of the penetration, though combining this with one of the other options will help more.
cjhazard
Posts: 35
Joined: Mon Aug 01, 2011 8:05 pm

Re: Collision of Cylinder isn't precisely

Post by cjhazard »

Hi Norbo. I too am having problems with penetration. I've tried adjusting the scale, settings, time step etc. to no avail (actually setting the time-step to something very small e.g. 1/300 seems to improve things somewhat but that seems too small a setting to me). The problem seems to occur when an object falls from a height (and not a particularly great height) and then hits the "ground" (i.e. a static mesh or immoveable box). It's not a huge amount of penetration but enough to make a jumping character look a bit amateur.

However, I'm not sure if it's just my eyes but I don't notice the problem when I'm not fixing all 3 axes (I'm using a capsule for the character physics meshes) by setting the inverse inertia tensor to zeros. Could that be affecting things at all?

Any advice you can give is greatly appreciated.

Thanks.
CJ.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Collision of Cylinder isn't precisely

Post by Norbo »

I've tried adjusting the scale, settings, time step etc. to no avail (actually setting the time-step to something very small e.g. 1/300 seems to improve things somewhat but that seems too small a setting to me)
1/300f should eliminate pretty much any nasty effect related to penetration unless things are moving extremely fast. If it only improved 'somewhat' then there's probably something besides the usual expected behavior in play. Given that you've already tried fiddling with settings a bunch, it's probably best if we just skip to the next step: try reproducing the issue in a simplified BEPUphysicsDemos demo for me to debug. :)
However, I'm not sure if it's just my eyes but I don't notice the problem when I'm not fixing all 3 axes (I'm using a capsule for the character physics meshes) by setting the inverse inertia tensor to zeros. Could that be affecting things at all?
Locking the rotation of an object reduces the ways in which the object can react. So, a fast impact that would otherwise introduce primarily angular motion will introduce only linear motion. That could be why it's more obvious with locking. Angular motion locking is not the core issue, though.
cjhazard
Posts: 35
Joined: Mon Aug 01, 2011 8:05 pm

Re: Collision of Cylinder isn't precisely

Post by cjhazard »

Thanks Norbo... I should have thought to try it with the demos first! I'm sure it's probably something dumb I'm doing... or not doing!

I'll let you know how I get on.
cjhazard
Posts: 35
Joined: Mon Aug 01, 2011 8:05 pm

Re: Collision of Cylinder isn't precisely

Post by cjhazard »

Hi again Norbo. I modified the PyramidDemo (I'm using v1.1 of BEPU physics by the way) to include a cylinder which I can make 'jump' by pressing the 'J' key. If the jump is large enough (although it's not MASSIVE) I can still observe the penetration behaviour.

This is the new code for the pyramid demo...

Code: Select all

    public class PyramidDemo : StandardDemo
    {
        Capsule _capsule;
        Vector3 _jumpForce = new Vector3(0, 25, 0);
        KeyboardState _prevState;

        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public PyramidDemo(DemosGame game)
            : base(game)
        {
            float boxSize = 2f;
            int boxCount = 20;
            float platformLength = Math.Min(50, boxCount * boxSize + 10);
            Space.Add(new Box(new Vector3(0, -.5f, 0), boxCount * boxSize + 20, 1,
                              platformLength));

            for (int i = 0; i < boxCount; i++)
            {
                for (int j = 0; j < boxCount - i; j++)
                {
                    Space.Add(new Box(
                                  new Vector3(
                                      -boxCount * boxSize / 2 + boxSize / 2 * i + j * (boxSize),
                                      (boxSize / 2) + i * boxSize,
                                      0),
                                  boxSize, boxSize, boxSize, 20));
                }
            }

            _capsule = new Capsule(new Vector3(0, 2, platformLength / 4),
                new Vector3(0, 4, platformLength / 4), 1.0f, 50.0f);
            _capsule.LocalInertiaTensorInverse = new Matrix3X3();

            Space.Add(_capsule);

            game.Camera.Position = new Vector3(-boxCount * boxSize, 2, boxCount * boxSize);
            game.Camera.Yaw = (float)Math.PI / -4f;
            game.Camera.Pitch = (float)Math.PI / 9f;
        }

        public override void Update(float dt)
        {
            KeyboardState keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.J) && _prevState.IsKeyUp(Keys.J)) {
                _capsule.LinearVelocity += _jumpForce;
            }

            _prevState = keyState;

            base.Update(dt);
        }

        /// <summary>
        /// Gets the name of the simulation.
        /// </summary>
        public override string Name
        {
            get { return "Pyramid"; }
        }
    }
And here's a video illustrating the issue. It's right at the point it hits the floor... I know it's not a huge thing but it just looks a bit naff when my player keeps sinking into the floor after a jump.



Maybe I'm just being picky. LOL! :D

Thanks again.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Collision of Cylinder isn't precisely

Post by Norbo »

That's actually pretty hard to resolve fully. Fundamentally, it's caused by discrete updates. Unfortunately, turning on continuous collision detection won't help much because the CCD is designed to stop tunnelling and similarly severe issues, not tiny impacts.

(Attempting to stop for every tiny impact using a motion clamping CCD approach results in significant unacceptable halting. This can be fought against by using a different form of CCD- frequently, speculative contacts. The engine already uses speculative contacts for certain things but does not use them for CCD since doing so can cause a different form of artifacts unless more complicated tricks are implemented. These additional tricks have floated around on my todo list for a while, but they haven't yet had high enough priority to pursue.)

After the object integrates into penetration, corrective impulses are applied. This adds energy and can make the object 'jump' since contacts are incapable of pulling objects together. The jump can be reduced by lowering the CollisionResponseSettings.MaximumPenetrationCorrectionSpeed or PenetrationRecoveryStiffness, but then objects will be in penetration longer. Reducing the time step duration proportionally reduces the penetration amount.

For now, the easiest solution is probably to play a little animation of some kind on impact for whatever object is following the physics entity. It would not take much to hide a little penetration or bounce.
<--- how do I use the embed youtube feature???
It is a bit picky; it requires the full regular URL.
cjhazard
Posts: 35
Joined: Mon Aug 01, 2011 8:05 pm

Re: Collision of Cylinder isn't precisely

Post by cjhazard »

Thanks for the highly informative answer. It helps just to know that this is not unexpected behaviour (I can work with that) and not simply something I'm doing wrong. By fiddling around with settings (I tried out the DefaultMargin one) a bit more I've managed to virtually eliminate it, but I like the idea of hiding it with a little animation or dust effect for larger falls. Excellent idea! :D

Cheers!
Post Reply