From 83ededfd37961ef157b1dd63497b32a2a090cc7e Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 13 Aug 2018 14:51:13 -0700 Subject: [PATCH 01/14] Pass collision filter flags into AllContactsCallback for more efficient collision filtering --- libraries/physics/src/PhysicsEngine.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index ef8c28bdc6..efe1bddc97 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -863,6 +863,9 @@ void PhysicsEngine::setShowBulletConstraintLimits(bool value) { } } +const int32_t CONTACT_CALLBACK_FLAG_ENTITY = BULLET_COLLISION_GROUP_STATIC | BULLET_COLLISION_GROUP_KINEMATIC | BULLET_COLLISION_GROUP_DYNAMIC; +const int32_t CONTACT_CALLBACK_FLAG_AVATAR = USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_OTHER_AVATAR; + struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { AllContactsCallback(MotionStateType desiredObjectType, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject) : btCollisionWorld::ContactResultCallback(), @@ -879,6 +882,14 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { bulletTransform.setRotation(glmToBullet(transform.getRotation())); collisionObject.setWorldTransform(bulletTransform); + + m_collisionFilterGroup = ~0; // Everything collidable should collide with our test object unless we set the filter mask otherwise + if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR) { + m_collisionFilterMask = CONTACT_CALLBACK_FLAG_AVATAR; + } + else { + m_collisionFilterMask = CONTACT_CALLBACK_FLAG_ENTITY; + } } ~AllContactsCallback() { @@ -890,10 +901,6 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { std::vector contacts; btCollisionObject* myAvatarCollisionObject; - bool needsCollision(btBroadphaseProxy* proxy) const override { - return true; - } - btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) override { const btCollisionObject* otherBody; btVector3 penetrationPoint; From 61d12923ea794373ee6b951ea16125f9ebc2aff2 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 13 Aug 2018 16:49:51 -0700 Subject: [PATCH 02/14] Do not copy list of collision pick contact points when filtering them --- interface/src/raypick/CollisionPick.cpp | 20 ++++++++++---------- interface/src/raypick/CollisionPick.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 2 +- libraries/physics/src/PhysicsEngine.h | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 87c8c91e6d..a70882eed0 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -308,20 +308,18 @@ CollisionRegion CollisionPick::getMathematicalPick() const { return _mathPick; } -const std::vector CollisionPick::filterIntersections(const std::vector& intersections) const { - std::vector filteredIntersections; - +void CollisionPick::filterIntersections(std::vector& intersections) const { const QVector& ignoreItems = getIgnoreItems(); const QVector& includeItems = getIncludeItems(); bool isWhitelist = includeItems.size(); - for (const auto& intersection : intersections) { + for (int i = 0; i < intersections.size(); i++) { + auto& intersection = intersections[i]; const QUuid& id = intersection.foundID; - if (!ignoreItems.contains(id) && (!isWhitelist || includeItems.contains(id))) { - filteredIntersections.push_back(intersection); + if (ignoreItems.contains(id) || (isWhitelist && !includeItems.contains(id))) { + intersections[i] = intersections[intersections.size()-1]; + intersections.pop_back(); } } - - return filteredIntersections; } PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pick) { @@ -330,7 +328,8 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } - const auto& entityIntersections = filterIntersections(_physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, *pick.shapeInfo, pick.transform)); + auto& entityIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, *pick.shapeInfo, pick.transform); + filterIntersections(entityIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector()); } @@ -344,7 +343,8 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } - const auto& avatarIntersections = filterIntersections(_physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, *pick.shapeInfo, pick.transform)); + auto& avatarIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, *pick.shapeInfo, pick.transform); + filterIntersections(avatarIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector(), avatarIntersections); } diff --git a/interface/src/raypick/CollisionPick.h b/interface/src/raypick/CollisionPick.h index b3a7186893..bfc3487a62 100644 --- a/interface/src/raypick/CollisionPick.h +++ b/interface/src/raypick/CollisionPick.h @@ -92,7 +92,7 @@ protected: // Returns true if pick.shapeInfo is valid. Otherwise, attempts to get the shapeInfo ready for use. bool isShapeInfoReady(); void computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer resource); - const std::vector filterIntersections(const std::vector& intersections) const; + void filterIntersections(std::vector& intersections) const; CollisionRegion _mathPick; PhysicsEnginePointer _physicsEngine; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index efe1bddc97..cfe255e561 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -944,7 +944,7 @@ protected: } }; -const std::vector PhysicsEngine::getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const { +std::vector PhysicsEngine::getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const { // TODO: Give MyAvatar a motion state so we don't have to do this btCollisionObject* myAvatarCollisionObject = nullptr; if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR && _myAvatarController) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index c5ab0cfdee..854d61844f 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -126,7 +126,7 @@ public: void setShowBulletConstraintLimits(bool value); // Function for getting colliding ObjectMotionStates in the world of specified type - const std::vector getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const; + std::vector getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const; private: QList removeDynamicsForBody(btRigidBody* body); From aa4a6b2eaedb8f578d7bcd2a2dcd7a4e112028f0 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 13 Aug 2018 17:26:20 -0700 Subject: [PATCH 03/14] Convert entityIntersections/avatarIntersections lists in CollisionPickResult to shared pointers --- interface/src/raypick/CollisionPick.cpp | 27 +++++++++++++------------ interface/src/raypick/CollisionPick.h | 26 ++++++++++++++---------- libraries/physics/src/PhysicsEngine.cpp | 9 ++++----- libraries/physics/src/PhysicsEngine.h | 2 +- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index a70882eed0..f05fb208f1 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -15,8 +15,8 @@ #include "ScriptEngineLogging.h" #include "UUIDHasher.h" -void buildObjectIntersectionsMap(IntersectionType intersectionType, const std::vector& objectIntersections, std::unordered_map& intersections, std::unordered_map& collisionPointPairs) { - for (auto& objectIntersection : objectIntersections) { +void buildObjectIntersectionsMap(IntersectionType intersectionType, const std::shared_ptr> objectIntersections, std::unordered_map& intersections, std::unordered_map& collisionPointPairs) { + for (auto& objectIntersection : *objectIntersections) { auto at = intersections.find(objectIntersection.foundID); if (at == intersections.end()) { QVariantMap intersectingObject; @@ -308,16 +308,17 @@ CollisionRegion CollisionPick::getMathematicalPick() const { return _mathPick; } -void CollisionPick::filterIntersections(std::vector& intersections) const { +void CollisionPick::filterIntersections(std::shared_ptr> intersections) const { const QVector& ignoreItems = getIgnoreItems(); const QVector& includeItems = getIncludeItems(); bool isWhitelist = includeItems.size(); - for (int i = 0; i < intersections.size(); i++) { - auto& intersection = intersections[i]; + int n = (int)intersections->size(); + for (int i = 0; i < n; i++) { + auto& intersection = (*intersections)[i]; const QUuid& id = intersection.foundID; if (ignoreItems.contains(id) || (isWhitelist && !includeItems.contains(id))) { - intersections[i] = intersections[intersections.size()-1]; - intersections.pop_back(); + intersection = (*intersections)[--n]; + intersections->pop_back(); } } } @@ -325,29 +326,29 @@ void CollisionPick::filterIntersections(std::vector& intersec PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pick) { if (!isShapeInfoReady()) { // Cannot compute result - return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); + return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } auto& entityIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, *pick.shapeInfo, pick.transform); filterIntersections(entityIntersections); - return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector()); + return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::make_shared>()); } PickResultPointer CollisionPick::getOverlayIntersection(const CollisionRegion& pick) { - return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); + return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pick) { if (!isShapeInfoReady()) { // Cannot compute result - return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); + return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } auto& avatarIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, *pick.shapeInfo, pick.transform); filterIntersections(avatarIntersections); - return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector(), avatarIntersections); + return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::make_shared>(), avatarIntersections); } PickResultPointer CollisionPick::getHUDIntersection(const CollisionRegion& pick) { - return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); + return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } \ No newline at end of file diff --git a/interface/src/raypick/CollisionPick.h b/interface/src/raypick/CollisionPick.h index bfc3487a62..2f383f3a58 100644 --- a/interface/src/raypick/CollisionPick.h +++ b/interface/src/raypick/CollisionPick.h @@ -24,10 +24,14 @@ public: CollisionPickResult() {} CollisionPickResult(const QVariantMap& pickVariant) : PickResult(pickVariant) {} - CollisionPickResult(const CollisionRegion& searchRegion, LoadState loadState, const std::vector& entityIntersections, const std::vector& avatarIntersections) : + CollisionPickResult(const CollisionRegion& searchRegion, + LoadState loadState, + std::shared_ptr> entityIntersections = std::make_shared>(), + std::shared_ptr> avatarIntersections = std::make_shared>() + ) : PickResult(searchRegion.toVariantMap()), loadState(loadState), - intersects(entityIntersections.size() || avatarIntersections.size()), + intersects(entityIntersections->size() || avatarIntersections->size()), entityIntersections(entityIntersections), avatarIntersections(avatarIntersections) { } @@ -41,8 +45,8 @@ public: LoadState loadState { LOAD_STATE_UNKNOWN }; bool intersects { false }; - std::vector entityIntersections; - std::vector avatarIntersections; + std::shared_ptr> entityIntersections { std::make_shared>() }; + std::shared_ptr> avatarIntersections { std::make_shared>() }; QVariantMap toVariantMap() const override; @@ -52,14 +56,14 @@ public: PickResultPointer compareAndProcessNewResult(const PickResultPointer& newRes) override { const std::shared_ptr newCollisionResult = std::static_pointer_cast(newRes); - for (ContactTestResult& entityIntersection : newCollisionResult->entityIntersections) { - entityIntersections.push_back(entityIntersection); + for (ContactTestResult& entityIntersection : *(newCollisionResult->entityIntersections)) { + entityIntersections->push_back(entityIntersection); } - for (ContactTestResult& avatarIntersection : newCollisionResult->avatarIntersections) { - avatarIntersections.push_back(avatarIntersection); + for (ContactTestResult& avatarIntersection : *(newCollisionResult->avatarIntersections)) { + avatarIntersections->push_back(avatarIntersection); } - intersects = entityIntersections.size() || avatarIntersections.size(); + intersects = entityIntersections->size() || avatarIntersections->size(); if (newCollisionResult->loadState == LOAD_STATE_NOT_LOADED || loadState == LOAD_STATE_UNKNOWN) { loadState = (LoadState)newCollisionResult->loadState; } @@ -81,7 +85,7 @@ public: CollisionRegion getMathematicalPick() const override; PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { - return std::make_shared(pickVariant, CollisionPickResult::LOAD_STATE_UNKNOWN, std::vector(), std::vector()); + return std::make_shared(pickVariant, CollisionPickResult::LOAD_STATE_UNKNOWN, std::make_shared>(), std::make_shared>()); } PickResultPointer getEntityIntersection(const CollisionRegion& pick) override; PickResultPointer getOverlayIntersection(const CollisionRegion& pick) override; @@ -92,7 +96,7 @@ protected: // Returns true if pick.shapeInfo is valid. Otherwise, attempts to get the shapeInfo ready for use. bool isShapeInfoReady(); void computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer resource); - void filterIntersections(std::vector& intersections) const; + void filterIntersections(std::shared_ptr> intersections) const; CollisionRegion _mathPick; PhysicsEnginePointer _physicsEngine; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index cfe255e561..83ad0dc24a 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -871,7 +871,6 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { btCollisionWorld::ContactResultCallback(), desiredObjectType(desiredObjectType), collisionObject(), - contacts(), myAvatarCollisionObject(myAvatarCollisionObject) { const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); @@ -898,7 +897,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { MotionStateType desiredObjectType; btCollisionObject collisionObject; - std::vector contacts; + std::shared_ptr> contacts = std::make_shared>(); btCollisionObject* myAvatarCollisionObject; btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) override { @@ -917,7 +916,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { // TODO: Give MyAvatar a motion state so we don't have to do this if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR && myAvatarCollisionObject && myAvatarCollisionObject == otherBody) { - contacts.emplace_back(Physics::getSessionUUID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); + contacts->emplace_back(Physics::getSessionUUID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); return 0; } @@ -933,7 +932,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { } // This is the correct object type. Add it to the list. - contacts.emplace_back(candidate->getObjectID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); + contacts->emplace_back(candidate->getObjectID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); return 0; } @@ -944,7 +943,7 @@ protected: } }; -std::vector PhysicsEngine::getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const { +std::shared_ptr> PhysicsEngine::getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const { // TODO: Give MyAvatar a motion state so we don't have to do this btCollisionObject* myAvatarCollisionObject = nullptr; if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR && _myAvatarController) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 854d61844f..64109199ed 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -126,7 +126,7 @@ public: void setShowBulletConstraintLimits(bool value); // Function for getting colliding ObjectMotionStates in the world of specified type - std::vector getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const; + std::shared_ptr> getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const; private: QList removeDynamicsForBody(btRigidBody* body); From 67ff05739a2c7d4593081d954391f40e76a60d59 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 15 Aug 2018 11:05:52 -0700 Subject: [PATCH 04/14] Take advantage of CollisionPickResult intersections being shared pointers to avoid copying on result comparison --- interface/src/raypick/CollisionPick.cpp | 27 +++++++++++++++++++++++++ interface/src/raypick/CollisionPick.h | 18 +---------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index f05fb208f1..d763fc5c27 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -15,6 +15,33 @@ #include "ScriptEngineLogging.h" #include "UUIDHasher.h" +PickResultPointer CollisionPickResult::compareAndProcessNewResult(const PickResultPointer& newRes) { + const std::shared_ptr newCollisionResult = std::static_pointer_cast(newRes); + + if (entityIntersections->size()) { + for (ContactTestResult& entityIntersection : *(newCollisionResult->entityIntersections)) { + entityIntersections->push_back(entityIntersection); + } + } else { + entityIntersections = newCollisionResult->entityIntersections; + } + + if (avatarIntersections->size()) { + for (ContactTestResult& avatarIntersection : *(newCollisionResult->avatarIntersections)) { + avatarIntersections->push_back(avatarIntersection); + } + } else { + avatarIntersections = newCollisionResult->avatarIntersections; + } + + intersects = entityIntersections->size() || avatarIntersections->size(); + if (newCollisionResult->loadState == LOAD_STATE_NOT_LOADED || loadState == LOAD_STATE_UNKNOWN) { + loadState = (LoadState)newCollisionResult->loadState; + } + + return std::make_shared(*this); +} + void buildObjectIntersectionsMap(IntersectionType intersectionType, const std::shared_ptr> objectIntersections, std::unordered_map& intersections, std::unordered_map& collisionPointPairs) { for (auto& objectIntersection : *objectIntersections) { auto at = intersections.find(objectIntersection.foundID); diff --git a/interface/src/raypick/CollisionPick.h b/interface/src/raypick/CollisionPick.h index 2f383f3a58..40f2450776 100644 --- a/interface/src/raypick/CollisionPick.h +++ b/interface/src/raypick/CollisionPick.h @@ -53,23 +53,7 @@ public: bool doesIntersect() const override { return intersects; } bool checkOrFilterAgainstMaxDistance(float maxDistance) override { return true; } - PickResultPointer compareAndProcessNewResult(const PickResultPointer& newRes) override { - const std::shared_ptr newCollisionResult = std::static_pointer_cast(newRes); - - for (ContactTestResult& entityIntersection : *(newCollisionResult->entityIntersections)) { - entityIntersections->push_back(entityIntersection); - } - for (ContactTestResult& avatarIntersection : *(newCollisionResult->avatarIntersections)) { - avatarIntersections->push_back(avatarIntersection); - } - - intersects = entityIntersections->size() || avatarIntersections->size(); - if (newCollisionResult->loadState == LOAD_STATE_NOT_LOADED || loadState == LOAD_STATE_UNKNOWN) { - loadState = (LoadState)newCollisionResult->loadState; - } - - return std::make_shared(*this); - } + PickResultPointer compareAndProcessNewResult(const PickResultPointer& newRes) override; }; class CollisionPick : public Pick { From 130cb70a52d55c9d04c97da5780d56f213f0b333 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 16 Aug 2018 10:39:13 -0700 Subject: [PATCH 05/14] Do not create a reference to a shared pointer in CollisionPick.cpp --- interface/src/raypick/CollisionPick.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index d763fc5c27..d065d6fabe 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -356,7 +356,7 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } - auto& entityIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, *pick.shapeInfo, pick.transform); + auto entityIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, *pick.shapeInfo, pick.transform); filterIntersections(entityIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::make_shared>()); } @@ -371,7 +371,7 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } - auto& avatarIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, *pick.shapeInfo, pick.transform); + auto avatarIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, *pick.shapeInfo, pick.transform); filterIntersections(avatarIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::make_shared>(), avatarIntersections); } From 2933038d04ee0a4a55d46a2ea7110790df4d381b Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 17 Aug 2018 12:50:50 -0700 Subject: [PATCH 06/14] Rename PhysicsEngine::getCollidingInRegion to contactTest and change it to accept collision flags instead of a MotionState enum --- interface/src/raypick/CollisionPick.cpp | 5 ++-- libraries/physics/src/PhysicsEngine.cpp | 26 ++++++------------- libraries/physics/src/PhysicsEngine.h | 5 ++-- libraries/shared/src/PhysicsCollisionGroups.h | 1 + 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index d065d6fabe..59fe6504ca 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -12,6 +12,7 @@ #include +#include "PhysicsCollisionGroups.h" #include "ScriptEngineLogging.h" #include "UUIDHasher.h" @@ -356,7 +357,7 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } - auto entityIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, *pick.shapeInfo, pick.transform); + auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform); filterIntersections(entityIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::make_shared>()); } @@ -371,7 +372,7 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } - auto avatarIntersections = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, *pick.shapeInfo, pick.transform); + auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform); filterIntersections(avatarIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::make_shared>(), avatarIntersections); } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 83ad0dc24a..37afadc21b 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -863,13 +863,9 @@ void PhysicsEngine::setShowBulletConstraintLimits(bool value) { } } -const int32_t CONTACT_CALLBACK_FLAG_ENTITY = BULLET_COLLISION_GROUP_STATIC | BULLET_COLLISION_GROUP_KINEMATIC | BULLET_COLLISION_GROUP_DYNAMIC; -const int32_t CONTACT_CALLBACK_FLAG_AVATAR = USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_OTHER_AVATAR; - struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { - AllContactsCallback(MotionStateType desiredObjectType, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject) : + AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject) : btCollisionWorld::ContactResultCallback(), - desiredObjectType(desiredObjectType), collisionObject(), myAvatarCollisionObject(myAvatarCollisionObject) { const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); @@ -882,20 +878,14 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { collisionObject.setWorldTransform(bulletTransform); - m_collisionFilterGroup = ~0; // Everything collidable should collide with our test object unless we set the filter mask otherwise - if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR) { - m_collisionFilterMask = CONTACT_CALLBACK_FLAG_AVATAR; - } - else { - m_collisionFilterMask = CONTACT_CALLBACK_FLAG_ENTITY; - } + m_collisionFilterMask = mask; + m_collisionFilterGroup = group; } ~AllContactsCallback() { ObjectMotionState::getShapeManager()->releaseShape(collisionObject.getCollisionShape()); } - MotionStateType desiredObjectType; btCollisionObject collisionObject; std::shared_ptr> contacts = std::make_shared>(); btCollisionObject* myAvatarCollisionObject; @@ -915,7 +905,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { } // TODO: Give MyAvatar a motion state so we don't have to do this - if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR && myAvatarCollisionObject && myAvatarCollisionObject == otherBody) { + if ((m_collisionFilterMask & BULLET_COLLISION_GROUP_MY_AVATAR) && myAvatarCollisionObject && myAvatarCollisionObject == otherBody) { contacts->emplace_back(Physics::getSessionUUID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); return 0; } @@ -927,7 +917,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { const btMotionState* motionStateCandidate = collisionCandidate->getMotionState(); const ObjectMotionState* candidate = dynamic_cast(motionStateCandidate); - if (!candidate || candidate->getType() != desiredObjectType) { + if (!candidate) { return 0; } @@ -943,14 +933,14 @@ protected: } }; -std::shared_ptr> PhysicsEngine::getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const { +std::shared_ptr> PhysicsEngine::contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group) const { // TODO: Give MyAvatar a motion state so we don't have to do this btCollisionObject* myAvatarCollisionObject = nullptr; - if (desiredObjectType == MOTIONSTATE_TYPE_AVATAR && _myAvatarController) { + if ((mask & USER_COLLISION_GROUP_MY_AVATAR) && _myAvatarController) { myAvatarCollisionObject = _myAvatarController->getCollisionObject(); } - auto contactCallback = AllContactsCallback(desiredObjectType, regionShapeInfo, regionTransform, myAvatarCollisionObject); + auto contactCallback = AllContactsCallback((int32_t)mask, (int32_t)group, regionShapeInfo, regionTransform, myAvatarCollisionObject); _dynamicsWorld->contactTest(&contactCallback.collisionObject, contactCallback); return contactCallback.contacts; diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 64109199ed..7c4d5392d6 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -125,8 +125,9 @@ public: void setShowBulletConstraints(bool value); void setShowBulletConstraintLimits(bool value); - // Function for getting colliding ObjectMotionStates in the world of specified type - std::shared_ptr> getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const; + // Function for getting colliding objects in the world of specified type + // See PhysicsCollisionGroups.h for mask flags. + std::shared_ptr> contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC) const; private: QList removeDynamicsForBody(btRigidBody* body); diff --git a/libraries/shared/src/PhysicsCollisionGroups.h b/libraries/shared/src/PhysicsCollisionGroups.h index ef18cb0b0e..cae3918a3f 100644 --- a/libraries/shared/src/PhysicsCollisionGroups.h +++ b/libraries/shared/src/PhysicsCollisionGroups.h @@ -104,6 +104,7 @@ const uint16_t ENTITY_COLLISION_MASK_DEFAULT = USER_COLLISION_GROUP_OTHER_AVATAR; const uint16_t USER_COLLISION_MASK_AVATARS = USER_COLLISION_GROUP_MY_AVATAR | USER_COLLISION_GROUP_OTHER_AVATAR; +const uint16_t USER_COLLISION_MASK_ENTITIES = USER_COLLISION_GROUP_STATIC | USER_COLLISION_GROUP_DYNAMIC | USER_COLLISION_GROUP_KINEMATIC; const int32_t NUM_USER_COLLISION_GROUPS = 5; From e3c39020dcd04da661ad87c833d411ce7f5f4327 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 17 Aug 2018 12:54:47 -0700 Subject: [PATCH 07/14] Exit early from CollisionPick::filterIntersections on empty blacklist --- interface/src/raypick/CollisionPick.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 59fe6504ca..52650966d3 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -340,6 +340,11 @@ void CollisionPick::filterIntersections(std::shared_ptr& ignoreItems = getIgnoreItems(); const QVector& includeItems = getIncludeItems(); bool isWhitelist = includeItems.size(); + + if (!isWhitelist && !ignoreItems.size()) { + return; + } + int n = (int)intersections->size(); for (int i = 0; i < n; i++) { auto& intersection = (*intersections)[i]; From 6081d63f5317cc0bab726029dde9b727d4a7bfb1 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 17 Aug 2018 13:17:35 -0700 Subject: [PATCH 08/14] Use std::vector::insert for merging CollisionPickResults --- interface/src/raypick/CollisionPick.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 52650966d3..a7ee534528 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -20,17 +20,13 @@ PickResultPointer CollisionPickResult::compareAndProcessNewResult(const PickResu const std::shared_ptr newCollisionResult = std::static_pointer_cast(newRes); if (entityIntersections->size()) { - for (ContactTestResult& entityIntersection : *(newCollisionResult->entityIntersections)) { - entityIntersections->push_back(entityIntersection); - } + entityIntersections->insert(entityIntersections->cend(), newCollisionResult->entityIntersections->begin(), newCollisionResult->entityIntersections->end()); } else { entityIntersections = newCollisionResult->entityIntersections; } if (avatarIntersections->size()) { - for (ContactTestResult& avatarIntersection : *(newCollisionResult->avatarIntersections)) { - avatarIntersections->push_back(avatarIntersection); - } + avatarIntersections->insert(avatarIntersections->cend(), newCollisionResult->avatarIntersections->begin(), newCollisionResult->avatarIntersections->end()); } else { avatarIntersections = newCollisionResult->avatarIntersections; } From 51940898d9a7027a1b20e6fcb4bf78ac3d654b73 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 17 Aug 2018 16:23:31 -0700 Subject: [PATCH 09/14] Do not implicitly convert size of vector to bool in CollisionPick::filterIntersections --- interface/src/raypick/CollisionPick.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index a7ee534528..01264a252d 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -335,9 +335,9 @@ CollisionRegion CollisionPick::getMathematicalPick() const { void CollisionPick::filterIntersections(std::shared_ptr> intersections) const { const QVector& ignoreItems = getIgnoreItems(); const QVector& includeItems = getIncludeItems(); - bool isWhitelist = includeItems.size(); + bool isWhitelist = !includeItems.empty(); - if (!isWhitelist && !ignoreItems.size()) { + if (!isWhitelist && ignoreItems.empty()) { return; } From 2a182a00337ae57edc0109c77db8aca6cd4506fe Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 20 Aug 2018 09:24:07 -0700 Subject: [PATCH 10/14] Revert "Do not create a reference to a shared pointer in CollisionPick.cpp" This reverts commit 130cb70a52d55c9d04c97da5780d56f213f0b333. --- interface/src/raypick/CollisionPick.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 01264a252d..004017ca15 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -358,7 +358,7 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } - auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform); + auto& entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform); filterIntersections(entityIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::make_shared>()); } @@ -372,8 +372,8 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi // Cannot compute result return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); } - - auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform); + + auto &avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform); filterIntersections(avatarIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::make_shared>(), avatarIntersections); } From 74f482b36133640d52725e6149e6af64c48ae28f Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 20 Aug 2018 10:15:28 -0700 Subject: [PATCH 11/14] Revert "Convert entityIntersections/avatarIntersections lists in" This reverts commit aa4a6b2eaedb8f578d7bcd2a2dcd7a4e112028f0. --- interface/src/raypick/CollisionPick.cpp | 36 ++++++++++++------------- interface/src/raypick/CollisionPick.h | 16 +++++------ libraries/physics/src/PhysicsEngine.cpp | 9 ++++--- libraries/physics/src/PhysicsEngine.h | 2 +- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 004017ca15..b93c5b6dbb 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -19,19 +19,19 @@ PickResultPointer CollisionPickResult::compareAndProcessNewResult(const PickResultPointer& newRes) { const std::shared_ptr newCollisionResult = std::static_pointer_cast(newRes); - if (entityIntersections->size()) { - entityIntersections->insert(entityIntersections->cend(), newCollisionResult->entityIntersections->begin(), newCollisionResult->entityIntersections->end()); + if (entityIntersections.size()) { + entityIntersections.insert(entityIntersections.cend(), newCollisionResult->entityIntersections.begin(), newCollisionResult->entityIntersections.end()); } else { entityIntersections = newCollisionResult->entityIntersections; } - if (avatarIntersections->size()) { - avatarIntersections->insert(avatarIntersections->cend(), newCollisionResult->avatarIntersections->begin(), newCollisionResult->avatarIntersections->end()); + if (avatarIntersections.size()) { + avatarIntersections.insert(avatarIntersections.cend(), newCollisionResult->avatarIntersections.begin(), newCollisionResult->avatarIntersections.end()); } else { avatarIntersections = newCollisionResult->avatarIntersections; } - intersects = entityIntersections->size() || avatarIntersections->size(); + intersects = entityIntersections.size() || avatarIntersections.size(); if (newCollisionResult->loadState == LOAD_STATE_NOT_LOADED || loadState == LOAD_STATE_UNKNOWN) { loadState = (LoadState)newCollisionResult->loadState; } @@ -39,8 +39,8 @@ PickResultPointer CollisionPickResult::compareAndProcessNewResult(const PickResu return std::make_shared(*this); } -void buildObjectIntersectionsMap(IntersectionType intersectionType, const std::shared_ptr> objectIntersections, std::unordered_map& intersections, std::unordered_map& collisionPointPairs) { - for (auto& objectIntersection : *objectIntersections) { +void buildObjectIntersectionsMap(IntersectionType intersectionType, const std::vector& objectIntersections, std::unordered_map& intersections, std::unordered_map& collisionPointPairs) { + for (auto& objectIntersection : objectIntersections) { auto at = intersections.find(objectIntersection.foundID); if (at == intersections.end()) { QVariantMap intersectingObject; @@ -332,7 +332,7 @@ CollisionRegion CollisionPick::getMathematicalPick() const { return _mathPick; } -void CollisionPick::filterIntersections(std::shared_ptr> intersections) const { +void CollisionPick::filterIntersections(std::vector& intersections) const { const QVector& ignoreItems = getIgnoreItems(); const QVector& includeItems = getIncludeItems(); bool isWhitelist = !includeItems.empty(); @@ -341,13 +341,13 @@ void CollisionPick::filterIntersections(std::shared_ptrsize(); + int n = (int)intersections.size(); for (int i = 0; i < n; i++) { - auto& intersection = (*intersections)[i]; + auto& intersection = intersections[i]; const QUuid& id = intersection.foundID; if (ignoreItems.contains(id) || (isWhitelist && !includeItems.contains(id))) { - intersection = (*intersections)[--n]; - intersections->pop_back(); + intersections[i] = intersections[--n]; + intersections.pop_back(); } } } @@ -355,29 +355,29 @@ void CollisionPick::filterIntersections(std::shared_ptr(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); + return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } auto& entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform); filterIntersections(entityIntersections); - return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::make_shared>()); + return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector()); } PickResultPointer CollisionPick::getOverlayIntersection(const CollisionRegion& pick) { - return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); + return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pick) { if (!isShapeInfoReady()) { // Cannot compute result - return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); + return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } auto &avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform); filterIntersections(avatarIntersections); - return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::make_shared>(), avatarIntersections); + return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector(), avatarIntersections); } PickResultPointer CollisionPick::getHUDIntersection(const CollisionRegion& pick) { - return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::make_shared>(), std::make_shared>()); + return std::make_shared(pick.toVariantMap(), isShapeInfoReady() ? CollisionPickResult::LOAD_STATE_LOADED : CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } \ No newline at end of file diff --git a/interface/src/raypick/CollisionPick.h b/interface/src/raypick/CollisionPick.h index 40f2450776..6631238737 100644 --- a/interface/src/raypick/CollisionPick.h +++ b/interface/src/raypick/CollisionPick.h @@ -24,14 +24,10 @@ public: CollisionPickResult() {} CollisionPickResult(const QVariantMap& pickVariant) : PickResult(pickVariant) {} - CollisionPickResult(const CollisionRegion& searchRegion, - LoadState loadState, - std::shared_ptr> entityIntersections = std::make_shared>(), - std::shared_ptr> avatarIntersections = std::make_shared>() - ) : + CollisionPickResult(const CollisionRegion& searchRegion, LoadState loadState, const std::vector& entityIntersections, const std::vector& avatarIntersections) : PickResult(searchRegion.toVariantMap()), loadState(loadState), - intersects(entityIntersections->size() || avatarIntersections->size()), + intersects(entityIntersections.size() || avatarIntersections.size()), entityIntersections(entityIntersections), avatarIntersections(avatarIntersections) { } @@ -45,8 +41,8 @@ public: LoadState loadState { LOAD_STATE_UNKNOWN }; bool intersects { false }; - std::shared_ptr> entityIntersections { std::make_shared>() }; - std::shared_ptr> avatarIntersections { std::make_shared>() }; + std::vector entityIntersections; + std::vector avatarIntersections; QVariantMap toVariantMap() const override; @@ -69,7 +65,7 @@ public: CollisionRegion getMathematicalPick() const override; PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { - return std::make_shared(pickVariant, CollisionPickResult::LOAD_STATE_UNKNOWN, std::make_shared>(), std::make_shared>()); + return std::make_shared(pickVariant, CollisionPickResult::LOAD_STATE_UNKNOWN, std::vector(), std::vector()); } PickResultPointer getEntityIntersection(const CollisionRegion& pick) override; PickResultPointer getOverlayIntersection(const CollisionRegion& pick) override; @@ -80,7 +76,7 @@ protected: // Returns true if pick.shapeInfo is valid. Otherwise, attempts to get the shapeInfo ready for use. bool isShapeInfoReady(); void computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer resource); - void filterIntersections(std::shared_ptr> intersections) const; + void filterIntersections(std::vector& intersections) const; CollisionRegion _mathPick; PhysicsEnginePointer _physicsEngine; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 37afadc21b..5685e8a6f3 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -867,6 +867,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject) : btCollisionWorld::ContactResultCallback(), collisionObject(), + contacts(), myAvatarCollisionObject(myAvatarCollisionObject) { const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); @@ -887,7 +888,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { } btCollisionObject collisionObject; - std::shared_ptr> contacts = std::make_shared>(); + std::vector contacts; btCollisionObject* myAvatarCollisionObject; btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) override { @@ -906,7 +907,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { // TODO: Give MyAvatar a motion state so we don't have to do this if ((m_collisionFilterMask & BULLET_COLLISION_GROUP_MY_AVATAR) && myAvatarCollisionObject && myAvatarCollisionObject == otherBody) { - contacts->emplace_back(Physics::getSessionUUID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); + contacts.emplace_back(Physics::getSessionUUID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); return 0; } @@ -922,7 +923,7 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback { } // This is the correct object type. Add it to the list. - contacts->emplace_back(candidate->getObjectID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); + contacts.emplace_back(candidate->getObjectID(), bulletToGLM(penetrationPoint), bulletToGLM(otherPenetrationPoint)); return 0; } @@ -933,7 +934,7 @@ protected: } }; -std::shared_ptr> PhysicsEngine::contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group) const { +std::vector PhysicsEngine::contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group) const { // TODO: Give MyAvatar a motion state so we don't have to do this btCollisionObject* myAvatarCollisionObject = nullptr; if ((mask & USER_COLLISION_GROUP_MY_AVATAR) && _myAvatarController) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 7c4d5392d6..c6e165632b 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -127,7 +127,7 @@ public: // Function for getting colliding objects in the world of specified type // See PhysicsCollisionGroups.h for mask flags. - std::shared_ptr> contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC) const; + std::vector contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC) const; private: QList removeDynamicsForBody(btRigidBody* body); From 444224a11a558fe4b6a856af70a8be4d122c24e5 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 20 Aug 2018 11:07:52 -0700 Subject: [PATCH 12/14] Fix ignoring elements in CollisionPick::filterIntersections --- interface/src/raypick/CollisionPick.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index b93c5b6dbb..8162b27b60 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -348,6 +348,7 @@ void CollisionPick::filterIntersections(std::vector& intersec if (ignoreItems.contains(id) || (isWhitelist && !includeItems.contains(id))) { intersections[i] = intersections[--n]; intersections.pop_back(); + --i; } } } From 813290aad81e6b6203b840e04a23056d44da64f1 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 20 Aug 2018 11:23:22 -0700 Subject: [PATCH 13/14] Do filtering with copy vector in CollisionPick::filterIntersections --- interface/src/raypick/CollisionPick.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 8162b27b60..889a241bcc 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -341,16 +341,18 @@ void CollisionPick::filterIntersections(std::vector& intersec return; } + std::vector filteredIntersections; + int n = (int)intersections.size(); for (int i = 0; i < n; i++) { auto& intersection = intersections[i]; const QUuid& id = intersection.foundID; - if (ignoreItems.contains(id) || (isWhitelist && !includeItems.contains(id))) { - intersections[i] = intersections[--n]; - intersections.pop_back(); - --i; + if (!ignoreItems.contains(id) && (!isWhitelist || includeItems.contains(id))) { + filteredIntersections.push_back(intersection); } } + + intersections = filteredIntersections; } PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pick) { From 9c36519e8762351e85adbee1aa6b75ca379ae6eb Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 20 Aug 2018 12:42:23 -0700 Subject: [PATCH 14/14] Fix cross-platform build error in ColliisonPick.cpp (binding to temporary) --- interface/src/raypick/CollisionPick.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp index 889a241bcc..9f2e6da2e8 100644 --- a/interface/src/raypick/CollisionPick.cpp +++ b/interface/src/raypick/CollisionPick.cpp @@ -361,7 +361,7 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } - auto& entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform); + auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform); filterIntersections(entityIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector()); } @@ -376,7 +376,7 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi return std::make_shared(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector(), std::vector()); } - auto &avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform); + auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform); filterIntersections(avatarIntersections); return std::make_shared(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector(), avatarIntersections); }