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; }
uint8_t getCollisionMask() const { return _collisionMask; }
void setCollisionMask(uint8_t value);
void setCollisionMask(uint8_t value) { _collisionMask = value; }
bool getCollisionsWillMove() const { return _collisionsWillMove; }
void setCollisionsWillMove(bool value) { _collisionsWillMove = value; }

View file

@ -80,9 +80,9 @@ EntityMotionState::~EntityMotionState() {
_entity = nullptr;
}
void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) {
void EntityMotionState::updateServerPhysicsVariables() {
assert(entityTreeIsLocked());
if (_entity->getSimulatorID() == sessionID) {
if (_entity->getSimulatorID() == PhysicsEngine::getSessionID()) {
// don't slam these values if we are the simulation owner
return;
}
@ -96,10 +96,10 @@ void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) {
}
// virtual
bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
assert(entityTreeIsLocked());
updateServerPhysicsVariables(engine->getSessionID());
ObjectMotionState::handleEasyChanges(flags, engine);
updateServerPhysicsVariables();
ObjectMotionState::handleEasyChanges(flags);
if (flags & Simulation::DIRTY_SIMULATOR_ID) {
_loopsWithoutOwner = 0;
@ -113,7 +113,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine
_outgoingPriority = NO_PRORITY;
} else {
_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
_outgoingPriority = NO_PRORITY;
}
@ -135,7 +135,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine
// virtual
bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
updateServerPhysicsVariables(engine->getSessionID());
updateServerPhysicsVariables();
return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
}
@ -523,6 +523,17 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
uint32_t dirtyFlags = 0;
if (_body && _entity) {
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
int bodyFlags = _body->getCollisionFlags();
bool isMoving = _entity->isMoving();
@ -633,7 +644,16 @@ void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& ma
mask = PhysicsEngine::getCollisionMask(group);
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);
virtual ~EntityMotionState();
void updateServerPhysicsVariables(const QUuid& sessionID);
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine);
void updateServerPhysicsVariables();
virtual bool handleEasyChanges(uint32_t& flags);
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
/// \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) {
btTransform worldTrans = _body->getWorldTransform();
btVector3 newPosition = glmToBullet(getObjectPosition());
@ -251,7 +251,7 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) {
// no HARD flags remain, so do any EASY changes
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
handleEasyChanges(flags, engine);
handleEasyChanges(flags);
}
return true;
}
@ -268,7 +268,7 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
}
}
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)
// so we check again before we reinsert:

View file

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

View file

@ -42,6 +42,19 @@ int16_t PhysicsEngine::getCollisionMask(int16_t group) {
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) :
_originOffset(offset),
_myAvatarController(nullptr) {
@ -209,7 +222,7 @@ VectorOfMotionStates PhysicsEngine::changeObjects(const VectorOfMotionStates& ob
stillNeedChange.push_back(object);
}
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
if (object->handleEasyChanges(flags, this)) {
if (object->handleEasyChanges(flags)) {
object->clearIncomingDirtyFlags();
} else {
stillNeedChange.push_back(object);

View file

@ -53,8 +53,8 @@ public:
~PhysicsEngine();
void init();
void setSessionUUID(const QUuid& sessionID) { _sessionID = sessionID; }
const QUuid& getSessionID() const { return _sessionID; }
static void setSessionUUID(const QUuid& sessionID);
static const QUuid& getSessionID();
void removeObjects(const VectorOfMotionStates& objects);
void removeObjects(const SetOfMotionStates& objects); // only called during teardown
@ -122,7 +122,6 @@ private:
bool _dumpNextStats = false;
bool _hasOutgoingChanges = false;
QUuid _sessionID;
CollisionEvents _collisionEvents;
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_OTHER_AVATAR;
const uint8_t USER_COLLISION_MASK_AVATARS = USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_OTHER_AVATAR;
#endif // hifi_PhysicsCollisionGroups_h