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; } } } }
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); }