void PhysicsEngine::bumpAndPruneContacts(ObjectMotionState* motionState) { // Find all objects that touch the object corresponding to motionState and flag the other objects // for simulation ownership by the local simulation. assert(motionState); btCollisionObject* object = motionState->getRigidBody(); int numManifolds = _collisionDispatcher->getNumManifolds(); for (int i = 0; i < numManifolds; ++i) { btPersistentManifold* contactManifold = _collisionDispatcher->getManifoldByIndexInternal(i); if (contactManifold->getNumContacts() > 0) { const btCollisionObject* objectA = static_cast<const btCollisionObject*>(contactManifold->getBody0()); const btCollisionObject* objectB = static_cast<const btCollisionObject*>(contactManifold->getBody1()); if (objectB == object) { if (!objectA->isStaticOrKinematicObject()) { ObjectMotionState* motionStateA = static_cast<ObjectMotionState*>(objectA->getUserPointer()); if (motionStateA) { motionStateA->bump(VOLUNTEER_SIMULATION_PRIORITY); objectA->setActivationState(ACTIVE_TAG); } } } else if (objectA == object) { if (!objectB->isStaticOrKinematicObject()) { ObjectMotionState* motionStateB = static_cast<ObjectMotionState*>(objectB->getUserPointer()); if (motionStateB) { motionStateB->bump(VOLUNTEER_SIMULATION_PRIORITY); objectB->setActivationState(ACTIVE_TAG); } } } } } removeContacts(motionState); }
void ContactModel::botDisconnected() { MAGNORMOBOT *bot = qobject_cast<MAGNORMOBOT*>(sender()); beginResetModel(); removeContacts(bot); endResetModel(); }
void PhysicsEngine::removeObject(ObjectMotionState* object) { // wake up anything touching this object bump(object); removeContacts(object); btRigidBody* body = object->getRigidBody(); assert(body); _dynamicsWorld->removeRigidBody(body); }
void ContactModel::botDestroyed() { MAGNORMOBOT *bot = qobject_cast<MAGNORMOBOT*>(sender()); conduits.removeOne(bot); if (hasContacts(bot)) { beginResetModel(); removeContacts(bot); endResetModel(); } }
void PhysicsEngine::stepSimulation() { CProfileManager::Reset(); BT_PROFILE("stepSimulation"); // NOTE: the grand order of operations is: // (1) pull incoming changes // (2) step simulation // (3) synchronize outgoing motion states // (4) send outgoing packets const float MAX_TIMESTEP = (float)PHYSICS_ENGINE_MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP; float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds()); _clock.reset(); float timeStep = btMin(dt, MAX_TIMESTEP); if (_myAvatarController) { BT_PROFILE("avatarController"); // TODO: move this stuff outside and in front of stepSimulation, because // the updateShapeIfNecessary() call needs info from MyAvatar and should // be done on the main thread during the pre-simulation stuff if (_myAvatarController->needsRemoval()) { _myAvatarController->setDynamicsWorld(nullptr); // We must remove any existing contacts for the avatar so that any new contacts will have // valid data. MyAvatar's RigidBody is the ONLY one in the simulation that does not yet // have a MotionState so we pass nullptr to removeContacts(). removeContacts(nullptr); } _myAvatarController->updateShapeIfNecessary(); if (_myAvatarController->needsAddition()) { _myAvatarController->setDynamicsWorld(_dynamicsWorld); } _myAvatarController->preSimulation(); } auto onSubStep = [this]() { updateContactMap(); }; int numSubsteps = _dynamicsWorld->stepSimulationWithSubstepCallback(timeStep, PHYSICS_ENGINE_MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP, onSubStep); if (numSubsteps > 0) { BT_PROFILE("postSimulation"); _numSubsteps += (uint32_t)numSubsteps; ObjectMotionState::setWorldSimulationStep(_numSubsteps); if (_myAvatarController) { _myAvatarController->postSimulation(); } _hasOutgoingChanges = true; } }
void ChannelContactModel::onGroupMembersChanged(const Tp::Contacts &groupMembersAdded, const Tp::Contacts &groupLocalPendingMembersAdded, const Tp::Contacts &groupRemotePendingMembersAdded, const Tp::Contacts &groupMembersRemoved, const Tp::Channel::GroupMemberChangeDetails &details) { kDebug(); Q_UNUSED(groupLocalPendingMembersAdded); Q_UNUSED(groupRemotePendingMembersAdded); Q_UNUSED(details); addContacts(groupMembersAdded); removeContacts(groupMembersRemoved); }