Applying custom position based constraints in physics engine

Please don't post Bullet support questions here, use the above forums instead.
Post Reply
korzen303
Posts: 30
Joined: Thu Dec 19, 2013 12:13 pm

Applying custom position based constraints in physics engine

Post by korzen303 »

Hi,

I need to apply my custom position based constraints (for elastic rod) on a chain of rigidbodies in Unity, which uses PhysX underneath (but the problem concerns any physics engine really).
To keep things simple let say that I want to apply a simple distance constraint between positions of two rigid bodies governed by PhysX.
In my PBD framework I predict positions using Explicit Euler integration, then apply constraints to these predicted positions, I update velocity (predictedPositions - positions) / dt, followed by positions = predictedPositions.

The question is how to do the positions and velocity update when the numerical integration is held by PhysX or Bullet or any other physics engine?
Just to add that the PhysX API is not fully exposed. I can modify things only between full physics update.

I have tried something like this. The constraints are very sloppy, as in my opinion, the momentum is not considered (there is no prediction step)

Code: Select all

                
            //copy positions from the physics engine
            for (int i = 0; i < pointsCount; i++)
                m_predPositions[i] = m_rigidbodies[i].position;
            
            //modify predicted position
            for (int si = 0; si < solverIterations; si++)
                ProjectDistanceConstraints(m_predPositions[i]);
            
            //apply changes back to the engine
            for (int i = 0; i < pointsCount; i++)
            {
                m_rigidbodies[i].velocity = (m_predPositions[i] - m_rigidbodies[i].position) * dtInv;
                m_rigidbodies[i].position = m_predPositions[i];
            }
I have also tried something like below, but this yields weird results (way to stiff and unstable)

Code: Select all

                
                m_rigidbodies[i].AddForce((m_predPositions[i] - m_rigidbodies[i].position) * dtInv, ForceMode.VelocityChange);
                m_rigidbodies[i].position = m_predPositions[i];
Thanks a lot
korzen303
Posts: 30
Joined: Thu Dec 19, 2013 12:13 pm

Re: Applying custom position based constraints in physics en

Post by korzen303 »

OK, I solved this by storing the position from the previous time-step and treating the current position as a predicted one.
Seems to work OK, but it is oscillating much more than the standard PBD.
And the collisions also often eject rod particles too much. This is probably due to partial overwriting the PhysX collision response.

Is there a way to do it better?

Code: Select all

void FixedUpdate()
{

    float dt =  Time.fixedDeltaTime;
    float dtInv = 1.0f / dt;
    float dtInv2 = 2.0f / dt;

    for (int i = 0; i < rod.pointsCount; i++)
    {
        m_predPositions[i] = m_rigidbodies[i].position;
        m_predRotations[i] = m_rigidbodies[i].rotation;
    }

    for (int si = 0; si < solverIterations; si++)
    {
        ApplyRodConstraints();
    }

    for (int i = 0; i < rod.pointsCount; i++)
    {
        m_rigidbodies[i].velocity = (m_predPositions[i] - m_prevPositions[i]) * dtInv;
        m_prevPositions[i] = m_predPositions[i];
        m_rigidbodies[i].position = m_predPositions[i];

        Quaternion relRot = m_predRotations[i] * Quaternion.Inverse(m_prevRotations[i]) ;
        m_rigidbodies[i].angularVelocity = new Vector3(relRot.x, relRot.y, relRot.z) * dtInv2;
        m_prevRotations[i] = m_predRotations[i];
        m_rigidbodies[i].rotation = m_predRotations[i];
    }

}
Post Reply