pombreda / bullet

Automatically exported from code.google.com/p/bullet
Other
0 stars 0 forks source link

Rigid body on top of another rigid body doesnt fall when scaling the shape (video explanation attached) #721

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create 2 btRigidBody and place one on top of another one
2. use setLocalScaling of the one in bottom, and reduce the X and Z parts of 
it, leaving Y intact, after placing the second btRigidBody on a position where 
it should fall
3. Check how the btRigidBody who is on top of the other one doesn't fall. If 
you translate or apply a velocity to the said one, check how it falls.

What is the expected output? What do you see instead?
The expected output should be that the rigid body who is on top of the other 
one should fall. Here is a video demonstration: 
http://www.youtube.com/watch?v=wwNJ3gM8-Bo

What version of the product are you using? On what operating system?
2.81 revision 2613, Windows 7. Ogre for rendering-related stuff

Please provide any additional information below.
Scaling snippet:

void MovablePlatform::scaleUpdate(const FrameEvent& evt)
{
    btScalar toScale = getScaleFrequency() * evt.timeSinceLastFrame;
    btVector3 scale = getBox()->getBody()->getCollisionShape()->getLocalScaling();
    if (
        (mScaleFlags.x() == 1 && scale.x() <= mScaleLimit + 0.0001) ||
        (mScaleFlags.y() != 0 && scale.y() <= mScaleLimit + 0.0001) ||
        (mScaleFlags.z() != 0 && scale.z() <= mScaleLimit + 0.0001))
    {
        mIncreaseScaleFlag = true;
    }
    else if (
        (mScaleFlags.x() == 1 && scale.x() >= 1) ||
        (mScaleFlags.y() != 0 && scale.y() >= 1) ||
        (mScaleFlags.z() != 0 && scale.z() >= 1))
    {
        mIncreaseScaleFlag = false;
    }

    btVector3 scaleFactor = mScaleFlags;
    if (!mIncreaseScaleFlag)
    {
        toScale *= -1;
    }

    if (Math::Abs(toScale) >= 0.0001)
    {
        scaleFactor.setX(scaleFactor.x() * (toScale / getBox()->getBoundingBox().x()));
        scaleFactor.setY(scaleFactor.y() * (toScale / getBox()->getBoundingBox().y()));
        scaleFactor.setZ(scaleFactor.z() * (toScale / getBox()->getBoundingBox().z()));
    }
    static bool scalingPlatformFix = false;
    if (scalingPlatformFix)
    {
        if (scaleFactor.y() == 0)
        {
            scaleFactor.setY(0.001);
        }
    }
    else
    {
        if (scaleFactor.y() == 0)
        {
            scaleFactor.setY(-0.001);
        }
    }
    scalingPlatformFix = !scalingPlatformFix;

    getBox()->getBody()->getCollisionShape()->setLocalScaling(scale + scaleFactor);
}

Original issue reported on code.google.com by f.lebo...@gmail.com on 7 Jul 2013 at 2:55

GoogleCodeExporter commented 9 years ago
Note: the part that assigns a small value to Y was used to check if fixed it, 
but it doesn't. Forgot to remove it.

Original comment by f.lebo...@gmail.com on 7 Jul 2013 at 2:58

GoogleCodeExporter commented 9 years ago

Before you make any change to the collision shape (replace shape, resize etc) 
you need to 

1) remove the rigid body from the world
2) make the change (resize etc)
3) re-insert the body into the world

Alternatively you can flush the contact points manually for the object involved:

dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(b
ody->getBroadphaseHandle(), dynamicsWorld->getDispatcher());

Original comment by erwin.coumans on 9 Jul 2013 at 8:18