Jump to content
  • Advertisement
judeclarke

Updating when a rigid body has two collisions

Recommended Posts

For my test case I have a sphere sliding across a horizontal plane that will eventually come in contact with a vertical plane. I have figured out the correct way to deal with a moving sphere to plane for either sliding to resting contact or bouncing off of it. However, it was always with only one rigid body object to one static collision. Now there are two static collision objects. The way the static collisions are added are 1) Vertical plane 2) Horizontal plane. As a result it find the collision with the horizontal plane to slide across it (index 1) but it will find collision with the vertical plane (index 0) once it reaches it. With the logic I have below, it will never consider the collision with the vertical plane. How should I ensure that it will respond to collision with it?

 

    float fAccumulator = 0.0f;

    while(fAccumulator < fElapsedTime && mRigidBodyObjects.size() > 0)
    {
        F32 left_time = fElapsedTime - fAccumulator;

        for(unsigned int i = 0; i < mRigidBodyObjects.size(); ++i)
        {
            int j1 = -1;
            RigidBodyCollisionResult crFirstCollisionResult;
            crFirstCollisionResult.fCollisionTime = FLT_MAX;

            RigidBodyCollisionResult crCollisionResult;

            for(unsigned int j = 0; j < mStaticObjects.size(); ++j)
            {
                crCollisionResult = mRigidBodySolver.Collide(mRigidBodyObjects[i], mStaticObjects[j], left_time);

                if(crCollisionResult.enCollisionState == WILL_COLLIDE)
                {
                    if(crCollisionResult.fCollisionTime <= crFirstCollisionResult.fCollisionTime)
                    {
                        crFirstCollisionResult = crCollisionResult;
                        j1 = j;
                    }
                }
                else if(crCollisionResult.enCollisionState == HAS_COLLISION || crCollisionResult.enCollisionState == RESTING_CONTACT)
                {
                    crFirstCollisionResult = crCollisionResult;
                    j1 = j;
                }
            }

            if(crCollisionResult.enCollisionState == WILL_COLLIDE || crCollisionResult.enCollisionState == NO_COLLISION) {
                mRigidBodyObjects[i]->ApplyGravity();
            }

            if(j1 != -1)
            {
                if(crFirstCollisionResult.enCollisionState == WILL_COLLIDE && crFirstCollisionResult.fCollisionTime <= fElapsedTime)
                {
                    mRigidBodyObjects[i]->Update(crFirstCollisionResult.fCollisionTime);

                    mRigidBodySolver.HandleCollisionReponse(mRigidBodyObjects[i], mStaticObjects[j1], crFirstCollisionResult, crFirstCollisionResult.fCollisionTime);
                    fAccumulator += crFirstCollisionResult.fCollisionTime;
                }
                else if(crFirstCollisionResult.enCollisionState == HAS_COLLISION || crFirstCollisionResult.enCollisionState == RESTING_CONTACT)
                {
                    mRigidBodySolver.HandleCollisionReponse(mRigidBodyObjects[i], mStaticObjects[j1], crFirstCollisionResult, left_time);

                    mRigidBodyObjects[i]->Update(left_time);

                    fAccumulator += left_time;
                }
                else
                {
                    mRigidBodySolver.HandleCollisionReponse(mRigidBodyObjects[i], mStaticObjects[j1], crFirstCollisionResult, left_time);

                    mRigidBodyObjects[i]->Update(left_time);

                    fAccumulator += left_time;
                }
            }
            else
            {
                mRigidBodyObjects[i]->Update(left_time);
                fAccumulator = fElapsedTime;
            }
        }
    }

 

Edited by judeclarke

Share this post


Link to post
Share on other sites
Advertisement

Hi judeclarke,

I am going to describe my understanding of the problem to make sure there is no confusion. On the frame the sphere is sliding along the horizontal frame and about to collide with the vertical plane, this is what happens:

  • i = 0, testing vertical plane returns WILL_COLLIDE.
  • i = 1, testing horizontal plane returns HAS_COLLISION as the sphere is currently touching the plane.

This HAS_COLLISION overwrites the firstCollisionResult stored by the vertical plane, throwing it away.

The issue here is that you still need to test that vertical collision result. After you apply resolution to the first collision (horizontal plane) you need to do it for the next one. After resolving the first, you can no longer be certain that the sphere will hit the vertical plane. The most straightforward approach would be to test for the next collision after each resolution, while ignoring the horizontal plane, and any other static objects that have already been resolved. This way you resolve collision in order of time of impact, and will ensure each pair of objects is resolved eventually.

This could be very expensive if you have a lot of static objects, or if you do this for a lot of rigidbodies. This method is continuous collision resolution, as every collision is resolved in order. To increase performance, you could avoid recomputing the collisions, or use something like speculative contacts and ignore the order of resolution of these collisions.

I don't know of any good resources on completely continuous physics, but here are some links on continuous detection between two objects, and speculative contacts. These speculative contacts are implemented through constraints, so might be a tad confusing, but the ideas there may be useful.

https://www.gdcvault.com/play/1015856/A-Different-Approach-for-Continuous

http://twvideo01.ubm-us.net/o1/vault/gdc2013/slides/824737Catto_Erin_PhysicsForGame.pdf

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!