collision mask bit reinterpretation

also cache sessionID in static methods inside PhysicsEngine
This commit is contained in:
Andrew Meadows 2016-01-07 16:56:13 -08:00
parent 502921e877
commit 6c49d81475
8 changed files with 52 additions and 19 deletions

View file

@ -275,7 +275,7 @@ public:
void setIgnoreForCollisions(bool value) { _ignoreForCollisions = value; } void setIgnoreForCollisions(bool value) { _ignoreForCollisions = value; }
uint8_t getCollisionMask() const { return _collisionMask; } uint8_t getCollisionMask() const { return _collisionMask; }
void setCollisionMask(uint8_t value); void setCollisionMask(uint8_t value) { _collisionMask = value; }
bool getCollisionsWillMove() const { return _collisionsWillMove; } bool getCollisionsWillMove() const { return _collisionsWillMove; }
void setCollisionsWillMove(bool value) { _collisionsWillMove = value; } void setCollisionsWillMove(bool value) { _collisionsWillMove = value; }

View file

@ -80,9 +80,9 @@ EntityMotionState::~EntityMotionState() {
_entity = nullptr; _entity = nullptr;
} }
void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) { void EntityMotionState::updateServerPhysicsVariables() {
assert(entityTreeIsLocked()); assert(entityTreeIsLocked());
if (_entity->getSimulatorID() == sessionID) { if (_entity->getSimulatorID() == PhysicsEngine::getSessionID()) {
// don't slam these values if we are the simulation owner // don't slam these values if we are the simulation owner
return; return;
} }
@ -96,10 +96,10 @@ void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) {
} }
// virtual // virtual
bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) { bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
assert(entityTreeIsLocked()); assert(entityTreeIsLocked());
updateServerPhysicsVariables(engine->getSessionID()); updateServerPhysicsVariables();
ObjectMotionState::handleEasyChanges(flags, engine); ObjectMotionState::handleEasyChanges(flags);
if (flags & Simulation::DIRTY_SIMULATOR_ID) { if (flags & Simulation::DIRTY_SIMULATOR_ID) {
_loopsWithoutOwner = 0; _loopsWithoutOwner = 0;
@ -113,7 +113,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine
_outgoingPriority = NO_PRORITY; _outgoingPriority = NO_PRORITY;
} else { } else {
_nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; _nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS;
if (engine->getSessionID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) { if (PhysicsEngine::getSessionID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) {
// we own the simulation or our priority looses to (or ties with) remote // we own the simulation or our priority looses to (or ties with) remote
_outgoingPriority = NO_PRORITY; _outgoingPriority = NO_PRORITY;
} }
@ -135,7 +135,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine
// virtual // virtual
bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) { bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
updateServerPhysicsVariables(engine->getSessionID()); updateServerPhysicsVariables();
return ObjectMotionState::handleHardAndEasyChanges(flags, engine); return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
} }
@ -523,6 +523,17 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
uint32_t dirtyFlags = 0; uint32_t dirtyFlags = 0;
if (_body && _entity) { if (_body && _entity) {
dirtyFlags = _entity->getDirtyFlags(); dirtyFlags = _entity->getDirtyFlags();
if (dirtyFlags | Simulation::DIRTY_SIMULATOR_ID) {
// when SIMULATOR_ID changes we must check for reinterpretation of asymmetric collision mask
// bits for the avatar groups (e.g. MY_AVATAR vs OTHER_AVATAR)
uint8_t entityCollisionMask = _entity->getCollisionMask();
if ((bool)(entityCollisionMask & USER_COLLISION_GROUP_MY_AVATAR) !=
(bool)(entityCollisionMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
// bits are asymmetric --> flag for reinsertion in physics simulation
dirtyFlags |= Simulation::DIRTY_COLLISION_GROUP;
}
}
// we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings // we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings
int bodyFlags = _body->getCollisionFlags(); int bodyFlags = _body->getCollisionFlags();
bool isMoving = _entity->isMoving(); bool isMoving = _entity->isMoving();
@ -633,7 +644,16 @@ void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& ma
mask = PhysicsEngine::getCollisionMask(group); mask = PhysicsEngine::getCollisionMask(group);
if (_entity) { if (_entity) {
mask &= (int16_t)(_entity->getCollisionMask()); uint8_t entityCollisionMask = _entity->getCollisionMask();
if ((bool)(entityCollisionMask & USER_COLLISION_GROUP_MY_AVATAR) !=
(bool)(entityCollisionMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
// asymmetric avatar collision mask bits
if (!_entity->getSimulatorID().isNull() && _entity->getSimulatorID() != PhysicsEngine::getSessionID()) {
// someone else owns the simulation, so we swap the interpretation of the bits
entityCollisionMask ^= USER_COLLISION_MASK_AVATARS | ~entityCollisionMask;
}
}
mask &= (int16_t)(entityCollisionMask);
} }
} }

View file

@ -28,8 +28,8 @@ public:
EntityMotionState(btCollisionShape* shape, EntityItemPointer item); EntityMotionState(btCollisionShape* shape, EntityItemPointer item);
virtual ~EntityMotionState(); virtual ~EntityMotionState();
void updateServerPhysicsVariables(const QUuid& sessionID); void updateServerPhysicsVariables();
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine); virtual bool handleEasyChanges(uint32_t& flags);
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine); virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem /// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem

View file

@ -164,7 +164,7 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) {
} }
} }
bool ObjectMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) { bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
if (flags & Simulation::DIRTY_POSITION) { if (flags & Simulation::DIRTY_POSITION) {
btTransform worldTrans = _body->getWorldTransform(); btTransform worldTrans = _body->getWorldTransform();
btVector3 newPosition = glmToBullet(getObjectPosition()); btVector3 newPosition = glmToBullet(getObjectPosition());
@ -251,7 +251,7 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) { if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) {
// no HARD flags remain, so do any EASY changes // no HARD flags remain, so do any EASY changes
if (flags & EASY_DIRTY_PHYSICS_FLAGS) { if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
handleEasyChanges(flags, engine); handleEasyChanges(flags);
} }
return true; return true;
} }
@ -268,7 +268,7 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
} }
} }
if (flags & EASY_DIRTY_PHYSICS_FLAGS) { if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
handleEasyChanges(flags, engine); handleEasyChanges(flags);
} }
// it is possible there are no HARD flags at this point (if DIRTY_SHAPE was removed) // it is possible there are no HARD flags at this point (if DIRTY_SHAPE was removed)
// so we check again before we reinsert: // so we check again before we reinsert:

View file

@ -80,7 +80,7 @@ public:
ObjectMotionState(btCollisionShape* shape); ObjectMotionState(btCollisionShape* shape);
~ObjectMotionState(); ~ObjectMotionState();
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine); virtual bool handleEasyChanges(uint32_t& flags);
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine); virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
void updateBodyMaterialProperties(); void updateBodyMaterialProperties();

View file

@ -42,6 +42,19 @@ int16_t PhysicsEngine::getCollisionMask(int16_t group) {
return mask ? *mask : BULLET_COLLISION_MASK_DEFAULT; return mask ? *mask : BULLET_COLLISION_MASK_DEFAULT;
} }
QUuid _sessionID;
// static
void PhysicsEngine::setSessionUUID(const QUuid& sessionID) {
_sessionID = sessionID;
}
// static
const QUuid& PhysicsEngine::getSessionID() {
return _sessionID;
}
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
_originOffset(offset), _originOffset(offset),
_myAvatarController(nullptr) { _myAvatarController(nullptr) {
@ -209,7 +222,7 @@ VectorOfMotionStates PhysicsEngine::changeObjects(const VectorOfMotionStates& ob
stillNeedChange.push_back(object); stillNeedChange.push_back(object);
} }
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) { } else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
if (object->handleEasyChanges(flags, this)) { if (object->handleEasyChanges(flags)) {
object->clearIncomingDirtyFlags(); object->clearIncomingDirtyFlags();
} else { } else {
stillNeedChange.push_back(object); stillNeedChange.push_back(object);

View file

@ -53,8 +53,8 @@ public:
~PhysicsEngine(); ~PhysicsEngine();
void init(); void init();
void setSessionUUID(const QUuid& sessionID) { _sessionID = sessionID; } static void setSessionUUID(const QUuid& sessionID);
const QUuid& getSessionID() const { return _sessionID; } static const QUuid& getSessionID();
void removeObjects(const VectorOfMotionStates& objects); void removeObjects(const VectorOfMotionStates& objects);
void removeObjects(const SetOfMotionStates& objects); // only called during teardown void removeObjects(const SetOfMotionStates& objects); // only called during teardown
@ -122,7 +122,6 @@ private:
bool _dumpNextStats = false; bool _dumpNextStats = false;
bool _hasOutgoingChanges = false; bool _hasOutgoingChanges = false;
QUuid _sessionID;
CollisionEvents _collisionEvents; CollisionEvents _collisionEvents;
QHash<QUuid, EntityActionPointer> _objectActions; QHash<QUuid, EntityActionPointer> _objectActions;

View file

@ -80,5 +80,6 @@ const uint8_t ENTITY_COLLISION_MASK_DEFAULT =
USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_MY_AVATAR |
USER_COLLISION_GROUP_OTHER_AVATAR; USER_COLLISION_GROUP_OTHER_AVATAR;
const uint8_t USER_COLLISION_MASK_AVATARS = USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_OTHER_AVATAR;
#endif // hifi_PhysicsCollisionGroups_h #endif // hifi_PhysicsCollisionGroups_h