Good Place. Good Things. Good Time.

Physics engine and rigidbody sleep optimization

I am trying to add sleep optimization to my little physics engine(just for learning). I use SAT for collision detection that returns penetration normal and depth without contact points. Objects are put to sleep after 180 frames if their velocity is less then eps. When objects are stacked and in sleeping state when i add velocity to the bottom object, objects on top remain in sleep mode and just float in the air. Can sleeping be implemented without contact points at all?
This is done in 3d.

This is collision loop:

void Physics::updateReal(float dt){
    auto& rbs = EntitySystem::instance()->_rigidbodies;

    for (auto rb : rbs) {

    for (int i = 0; i < 1; ++i) { //can be called multiple times per frame to improve stability
        //std::cout << "########" << std::endl;
        for (auto rb : rbs) {
            if (!rb->isAwake() || rb->_inverseMass == 0.0f) continue;       //skip static and sleeping rbs

            //colliders c1 of current rigidbody
            std::vector RBColliders; rb->thisEntity()->getColliders(RBColliders);

            for (auto c1 : RBColliders) {
                glm::vec3 o, d; c1->getAABB(o, d); std::vector colliders2;
                SpatialPartitioning::instance()->queryAABB(colliders2, o, d, BVH_COLLIDERS);

                for (BVHTreeContainee* c2bvh : colliders2) {
                    auto c2 = (Collider*)c2bvh;
                    if (!c2->isRigidbody()) continue;
                    if (c1 == c2) continue;
                    if (c1->getEntity() == c2->getEntity()) continue;

                    //std::cout << c1->getEntity()->gameObject()->name << " AND " << c2->getEntity()->gameObject()->name << std::endl;
                    collide(c1, c2);
                //blackList.push_back(c1);  //c1 is all tested

This is integration of rigidbody:

void Rigidbody::integrate(float dt){
    if (_inverseMass == 0.0f) return;
    auto trans = thisEntity()->transform();

    if (glm::length(_velocity) < 3.5f)  ++_sleepStage;
    else                                _sleepStage = 0;

    if (_sleepStage > 180) { _awake = false; return; }

    std::cout << "# " << glm::length(_velocity) << " " << _sleepStage << std::endl;

    //euler integration of position
    _velocity.y -= _gravity * dt;           //rhs = ubrzanje * dt, lhs = brzina
    trans->addPosition(_velocity * dt);     //rhs = brzina * dt, lhs = pozicija

This function is called to resolve collision:

inline void Physics::collisionResolution(Collider* c1, Collider* c2, glm::vec3 mtvAxis, float mtvDist, bool flip){
    auto A = c1->getRigidbody();
    auto B = c2->getRigidbody();

    if (flip) mtvAxis *= -1.f;
    mtvDist /= 2.f;

    if(A->_inverseMass > 0.0f && A->isAwake())
        c1->getEntity()->transform()->addPosition(mtvAxis * mtvDist);
    if(B->_inverseMass > 0.0f && B->isAwake())
        c2->getEntity()->transform()->addPosition(-mtvAxis * mtvDist);

    glm::vec3 rv = A->_velocity - B->_velocity;
    float velAlongNormal = glm::dot(rv, mtvAxis);
    if (velAlongNormal > 0.0f) return;

    float e = 0.2f;
    float j = -(1.0f + e) * velAlongNormal;
    j /= A->_inverseMass + B->_inverseMass;

    glm::vec3 impulse = mtvAxis * j;

    glm::vec3 impulseA = impulse * A->_inverseMass;
    glm::vec3 impulseB = impulse * B->_inverseMass;

    A->setAwake();  //sets _awake to true
    A->_velocity += impulseA;

    B->_velocity -= impulseB;

    glm::vec3 t = rv - (mtvAxis * velAlongNormal);

    if (glm::length(t) == 0.0f) return;
    t = glm::normalize(t);

    float jt = -glm::dot(rv, t);
    jt /= A->_inverseMass + B->_inverseMass;
    if (jt == 0.0f) return;

    float friction = glm::sqrt(0.03f);
    if (jt > j * friction)
        jt = j * friction;
    else if (jt < -j * friction)
        jt = -j * friction;

    glm::vec3 tangentImpuse = t * jt;
    A->_velocity += tangentImpuse * A->_inverseMass;
    B->_velocity -= tangentImpuse * B->_inverseMass;


Search more articles here: Physics engine and rigidbody sleep optimization

Read original article here: Physics engine and rigidbody sleep optimization

Disclaimers and Denial of responsibility..!

Denial of responsibility! is an automatic aggregator of all media around the world. In each content, the hyperlink to the primary source is specified. All trademarks belong to their rightful owners, all materials to their authors. If you are the owner of the content and do not want us to publish your materials, please contact us by email – . The content will be deleted within 72 hours.
You might also like
Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.