Exemplo n.º 1
0
void makeFence(Level* level, const NewtonWorld* newtonWorld)
{
    CollisionSet fencePartsCollisions;
    fencePartsCollisions.insert(level->getCollision("fence"));
    //fencePartsCollisions.insert(level->getCollision("fenceClip1"));
    //fencePartsCollisions.insert(level->getCollision("fenceClip2"));
    fencePartsCollisions.insert(level->getCollision("fenceTop"));

    Collision* heightMap = level->getCollision("level");

    for (size_t fencesVectorIdx = 0; fencesVectorIdx < level->m_fences.size(); fencesVectorIdx++)
    {
        const vector<Vector>& fence = level->m_fences[fencesVectorIdx];
        for (size_t i = 0; i < fence.size() - 1; i++)
        {    
            const Vector startPoint = fence[i];
            const Vector endPoint = fence[i + 1];
            Vector delta(endPoint - startPoint);
            const Vector rotation(0, - delta.getRotationY(), 0);
            
            float howMany = delta.magnitude() / fenceSpacing;
            delta /= howMany;
            for (int j = 0; j < howMany; j++)
            {
                const string bodyID = "fence" + cast<string>(fencesVectorIdx) + "_" + cast<string>(i) + "_" + cast<string>(j);

                Body* body = new Body(bodyID, level, fencePartsCollisions);
                if (Network::instance->m_isSingle == false)
                {
                    NewtonBodySetMassMatrix(body->m_newtonBody, 0, 0, 0, 0);
                }
                body->m_soundable = true;

                Vector position = Vector(startPoint + delta * static_cast<float>(j));
                position.y = fenceHeight / 2 + heightMap->getHeight(position.x, position.z) + 0.05f;
                body->setTransform(position, rotation);

                NewtonWorldFreezeBody(newtonWorld, body->m_newtonBody);
                NewtonBodySetAutoFreeze(body->m_newtonBody, 1);

                level->m_bodies[bodyID] = body;
            }
        }
    }
}
Exemplo n.º 2
0
void
bullet::PhysicsWorld::notifyCollisions()
{
    CollisionSet currentCollisions;
    Collider::Ptr colliders[2] = { nullptr, nullptr };
    const int numManifolds = _bulletDynamicsWorld->getDispatcher()->getNumManifolds();

    for (int i = 0; i < numManifolds; ++i)
    {
        btPersistentManifold* manifold = _bulletDynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);

        auto foundColliderIt = _colliderReverseMap.find(manifold->getBody0());
        colliders[0] = foundColliderIt != _colliderReverseMap.end()
            ? foundColliderIt->second
            : nullptr;

        foundColliderIt = _colliderReverseMap.find(manifold->getBody1());
        colliders[1] = foundColliderIt != _colliderReverseMap.end()
            ? foundColliderIt->second
            : nullptr;

        if (colliders[0] == nullptr || colliders[1] == nullptr)
            continue;
        //if (!colliderData[0]->triggerCollisions() && !colliderData[1]->triggerCollisions())
        //    continue;

        // a collision exists between to valid colliders
        auto collision = std::make_pair(colliders[0]->uid(),  colliders[1]->uid());

        if (collision.first > collision.second)
            std::swap(collision.first, collision.second);

        if (_collisions.find(collision) == _collisions.end()) // inserted only once
        {
            if (colliders[0]->triggerCollisions())
                colliders[0]->collisionStarted()->execute(colliders[0], colliders[1]);
            if (colliders[1]->triggerCollisions())
                colliders[1]->collisionStarted()->execute(colliders[1], colliders[0]);
        }

        currentCollisions.insert(collision);
    }

    // FIXME: not optimal at all.
    // find and notify collisions that are not present anymore as the difference with the intersection
    // between the previous collision set and the current one.

    CollisionSet lostCollisions;
    
    std::set_difference(
        _collisions.begin(), _collisions.end(),
        currentCollisions.begin(), currentCollisions.end(),
        std::inserter(lostCollisions, lostCollisions.end())
    );

    for (auto& collision : lostCollisions)
    {
        auto foundColliderIt = _uidToCollider.find(collision.first);
        colliders[0] = foundColliderIt != _uidToCollider.end()
            ? foundColliderIt->second
            : nullptr;

        foundColliderIt = _uidToCollider.find(collision.second);
        colliders[1] = foundColliderIt != _uidToCollider.end()
            ? foundColliderIt->second
            : nullptr;

        if (colliders[0] == nullptr || colliders[1] == nullptr)
            continue;

        // colliders assured to trigger collisions at this point.
        colliders[0]->collisionEnded()->execute(colliders[0], colliders[1]);
        colliders[1]->collisionEnded()->execute(colliders[1], colliders[0]);
    }

    _collisions.swap(currentCollisions);
}