Page 1 of 1

Disable slider constraint when limit is violated

Posted: Sun Oct 16, 2011 4:23 pm
by PaulMartz
Hi all -- I'm using a slider constraint to simulate a drawer in a cabinet. I'd like to disable the constraint when the user pulls the drawer all the way out. However, I'm unable to see how I can programmatically determine when the constrained body is at the limit of the constraint.

I'm currently able to work around this. The app starts up with the drawer completely closed (positioned at the upper limit of the constraint). So I get the origin of the constrained body world transform and save it off. Next, after each step, I obtain the origin of the body's current world transform, subtract it from the start origin, and compute the length of the result. If the length is greater than the distance between the two limits, I disable the constraint.

It works, but it seems like kind of a hack, so if there's a better way to do it, I'd appreciate any info. Thanks!
-Paul

Re: Disable slider constraint when limit is violated

Posted: Sun Oct 16, 2011 7:04 pm
by Dr.Shepherd
I suppose you can use the breakable constraint. Not for sure, because I didn't implement it by myself.

Re: Disable slider constraint when limit is violated

Posted: Sun Oct 16, 2011 8:42 pm
by PaulMartz
Thanks, but I only want to break the constraint when one of the slider limits -- in my case, the min limit -- is violated. The breakable constraint seems to allow breakage when an impulse in any direction exceeds the breakage threshold, so the constraint will break against either limit, or even if a force orthogonal to the slider axis is applied to the constrained body.
-Paul

Re: Disable slider constraint when limit is violated

Posted: Sun Oct 16, 2011 9:40 pm
by Dr.Shepherd
Then I suppose what you are doing is the most direct way. Actually the breakable constraint is accomplished by checking whether the internal force is greater than the limit.

Re: Disable slider constraint when limit is violated

Posted: Mon Oct 17, 2011 12:20 am
by jarno
There are probably a number of ways to do this. What I do is sub-class the btSequentialImpulseConstraintSolver and override the solveGroup() method like:

Code: Select all

virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
                            btPersistentManifold** manifold, int numManifolds,
                            btTypedConstraint** constraints, int numConstraints,
                            const btContactSolverInfo& info, btIDebugDraw* debugDrawer,
                            btStackAlloc* stackAlloc, btDispatcher* dispatcher)
{
    btSequentialImpulseConstraintSolver::solveGroup(bodies, numBodies,
                                                    manifold, numManifolds,
                                                    constraints, numConstraints,
                                                    info, debugDrawer,
                                                    stackAlloc, dispatcher);

    for(int i = 0; i < numConstraints; i++)
    {
        if(constraintIsOfInterest(constraints[i]) && constraintIsViolated(constraints[i]))
        {
          constraints[i]->setEnabled(false);
        }
    }

    return 0;
}
---JvdL---

Re: Disable slider constraint when limit is violated

Posted: Mon Oct 17, 2011 4:20 pm
by PaulMartz
That's a novel approach, thanks for posting it. I'll note it for future reference.

However it doesn't actually address how to detect when the slider constraint is in violation of a specific limit. And if the answer is to just keep doing what I'm doing by comparing the origin of the world transform, then I'm good to go.
-Paul

Re: Disable slider constraint when limit is violated

Posted: Tue Oct 18, 2011 3:22 am
by jarno
For a slider I think what will work is to compare the distance between the constraint's m_calculatedTransformA and m_calculatedTransformB, for example:

Code: Select all

if((constraint->getCalculatedTransformA().getOrigin() -
    constraint->getCalculatedTransformB().getOrigin()).length2() >= breaking_dist2)
  // then disable constraint
You can do a similar thing to detect angle violations. For that I suggest using btTransformUtil::calculateDiffAxisAngle() to get the angle between the A and B transforms.

---JvdL---