mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 16:26:17 +02:00
Move bullet references in collision pick API to PhysicsEngine
This commit is contained in:
parent
4ca9899000
commit
5ec277e458
7 changed files with 121 additions and 142 deletions
|
@ -6656,7 +6656,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
|
||||
auto pickScriptingInterface = DependencyManager::get<PickScriptingInterface>();
|
||||
pickScriptingInterface->registerMetaTypes(scriptEngine.data());
|
||||
pickScriptingInterface->setCollisionWorld(_physicsEngine->getDynamicsWorld());
|
||||
pickScriptingInterface->setPhysicsEngine(_physicsEngine);
|
||||
|
||||
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
||||
connect(scriptEngine.data(), &ScriptEngine::printedMessage,
|
||||
|
|
|
@ -271,12 +271,9 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi
|
|||
// Cannot compute result
|
||||
return std::make_shared<CollisionPickResult>();
|
||||
}
|
||||
|
||||
auto entityCollisionCallback = AllObjectMotionStatesCallback<EntityMotionState>(pick.shapeInfo, pick.transform);
|
||||
btCollisionWorld* collisionWorld = const_cast<btCollisionWorld*>(_collisionWorld);
|
||||
collisionWorld->contactTest(&entityCollisionCallback.collisionObject, entityCollisionCallback);
|
||||
|
||||
return std::make_shared<CollisionPickResult>(pick, entityCollisionCallback.intersectingObjects, std::vector<CollisionPickResult::EntityIntersection>());
|
||||
|
||||
const auto& intersectingEntities = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_ENTITY, pick.shapeInfo, pick.transform);
|
||||
return std::make_shared<CollisionPickResult>(pick, intersectingEntities, std::vector<EntityIntersection>());
|
||||
}
|
||||
|
||||
PickResultPointer CollisionPick::getOverlayIntersection(const CollisionRegion& pick) {
|
||||
|
@ -289,70 +286,10 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi
|
|||
return std::make_shared<CollisionPickResult>();
|
||||
}
|
||||
|
||||
auto avatarCollisionCallback = AllObjectMotionStatesCallback<AvatarMotionState>(pick.shapeInfo, pick.transform);
|
||||
btCollisionWorld* collisionWorld = const_cast<btCollisionWorld*>(_collisionWorld);
|
||||
collisionWorld->contactTest(&avatarCollisionCallback.collisionObject, avatarCollisionCallback);
|
||||
|
||||
return std::make_shared<CollisionPickResult>(pick, std::vector<CollisionPickResult::EntityIntersection>(), avatarCollisionCallback.intersectingObjects);
|
||||
const auto& intersectingAvatars = _physicsEngine->getCollidingInRegion(MOTIONSTATE_TYPE_AVATAR, pick.shapeInfo, pick.transform);
|
||||
return std::make_shared<CollisionPickResult>(pick, std::vector<EntityIntersection>(), intersectingAvatars);
|
||||
}
|
||||
|
||||
PickResultPointer CollisionPick::getHUDIntersection(const CollisionRegion& pick) {
|
||||
return getDefaultResult(QVariantMap());
|
||||
}
|
||||
|
||||
RigidBodyFilterResultCallback::RigidBodyFilterResultCallback(const ShapeInfo& shapeInfo, const Transform& transform) :
|
||||
btCollisionWorld::ContactResultCallback(), collisionObject() {
|
||||
const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||
|
||||
collisionObject.setCollisionShape(const_cast<btCollisionShape*>(collisionShape));
|
||||
|
||||
btTransform bulletTransform;
|
||||
bulletTransform.setOrigin(glmToBullet(transform.getTranslation()));
|
||||
bulletTransform.setRotation(glmToBullet(transform.getRotation()));
|
||||
|
||||
collisionObject.setWorldTransform(bulletTransform);
|
||||
}
|
||||
|
||||
RigidBodyFilterResultCallback::~RigidBodyFilterResultCallback() {
|
||||
ObjectMotionState::getShapeManager()->releaseShape(collisionObject.getCollisionShape());
|
||||
}
|
||||
|
||||
bool RigidBodyFilterResultCallback::needsCollision(btBroadphaseProxy* proxy) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
btScalar RigidBodyFilterResultCallback::addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) {
|
||||
const btCollisionObject* otherBody;
|
||||
btVector3 point;
|
||||
btVector3 otherPoint;
|
||||
if (colObj0->m_collisionObject == &collisionObject) {
|
||||
otherBody = colObj1->m_collisionObject;
|
||||
point = cp.m_localPointA;
|
||||
otherPoint = cp.m_localPointB;
|
||||
}
|
||||
else {
|
||||
otherBody = colObj0->m_collisionObject;
|
||||
point = cp.m_localPointB;
|
||||
otherPoint = cp.m_localPointA;
|
||||
}
|
||||
if (!(otherBody->getInternalType() & btCollisionObject::CO_RIGID_BODY)) {
|
||||
return 0;
|
||||
}
|
||||
const btRigidBody* collisionCandidate = static_cast<const btRigidBody*>(otherBody);
|
||||
const btMotionState* motionStateCandidate = collisionCandidate->getMotionState();
|
||||
|
||||
checkOrAddCollidingState(motionStateCandidate, point, otherPoint);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T = ObjectMotionState>
|
||||
void AllObjectMotionStatesCallback<T>::checkOrAddCollidingState(const btMotionState* otherMotionState, btVector3& point, btVector3& otherPoint) {
|
||||
const T* candidate = dynamic_cast<const T*>(otherMotionState);
|
||||
if (!candidate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is the correct object type. Add it to the list.
|
||||
intersectingObjects.emplace_back(candidate->getObjectID(), bulletToGLM(point), bulletToGLM(otherPoint));
|
||||
}
|
|
@ -8,44 +8,13 @@
|
|||
#ifndef hifi_CollisionPick_h
|
||||
#define hifi_CollisionPick_h
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
|
||||
#include <avatar/AvatarMotionState.h>
|
||||
#include <EntityMotionState.h>
|
||||
#include <BulletUtil.h>
|
||||
#include <PhysicsEngine.h>
|
||||
#include <model-networking/ModelCache.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <Pick.h>
|
||||
|
||||
class CollisionPickResult : public PickResult {
|
||||
public:
|
||||
struct EntityIntersection {
|
||||
EntityIntersection() { }
|
||||
|
||||
EntityIntersection(const EntityIntersection& entityIntersection) :
|
||||
id(entityIntersection.id),
|
||||
pickCollisionPoint(entityIntersection.pickCollisionPoint),
|
||||
entityCollisionPoint(entityIntersection.entityCollisionPoint) {
|
||||
}
|
||||
|
||||
EntityIntersection(QUuid id, glm::vec3 pickCollisionPoint, glm::vec3 entityCollisionPoint) :
|
||||
id(id),
|
||||
pickCollisionPoint(pickCollisionPoint),
|
||||
entityCollisionPoint(entityCollisionPoint) {
|
||||
}
|
||||
|
||||
QVariantMap toVariantMap() {
|
||||
QVariantMap variantMap;
|
||||
variantMap["objectID"] = id;
|
||||
variantMap["pickCollisionPoint"] = vec3toVariant(pickCollisionPoint);
|
||||
variantMap["entityCollisionPoint"] = vec3toVariant(entityCollisionPoint);
|
||||
return variantMap;
|
||||
}
|
||||
|
||||
QUuid id;
|
||||
glm::vec3 pickCollisionPoint;
|
||||
glm::vec3 entityCollisionPoint;
|
||||
};
|
||||
|
||||
CollisionPickResult() {}
|
||||
CollisionPickResult(const QVariantMap& pickVariant) : PickResult(pickVariant) {}
|
||||
|
||||
|
@ -73,13 +42,21 @@ public:
|
|||
|
||||
QVariantList qIntersectingEntities;
|
||||
for (auto intersectingEntity : intersectingEntities) {
|
||||
qIntersectingEntities.append(intersectingEntity.toVariantMap());
|
||||
QVariantMap qIntersectingEntity;
|
||||
qIntersectingEntity["objectID"] = intersectingEntity.id;
|
||||
qIntersectingEntity["pickCollisionPoint"] = vec3toVariant(intersectingEntity.pickCollisionPoint);
|
||||
qIntersectingEntity["entityCollisionPoint"] = vec3toVariant(intersectingEntity.entityCollisionPoint);
|
||||
qIntersectingEntities.append(qIntersectingEntity);
|
||||
}
|
||||
variantMap["intersectingEntities"] = qIntersectingEntities;
|
||||
|
||||
QVariantList qIntersectingAvatars;
|
||||
for (auto intersectingAvatar : intersectingAvatars) {
|
||||
qIntersectingAvatars.append(intersectingAvatar.toVariantMap());
|
||||
QVariantMap qIntersectingAvatar;
|
||||
qIntersectingAvatar["objectID"] = intersectingAvatar.id;
|
||||
qIntersectingAvatar["pickCollisionPoint"] = vec3toVariant(intersectingAvatar.pickCollisionPoint);
|
||||
qIntersectingAvatar["entityCollisionPoint"] = vec3toVariant(intersectingAvatar.entityCollisionPoint);
|
||||
qIntersectingAvatars.append(qIntersectingAvatar);
|
||||
}
|
||||
variantMap["intersectingAvatars"] = qIntersectingAvatars;
|
||||
|
||||
|
@ -111,10 +88,10 @@ public:
|
|||
|
||||
class CollisionPick : public Pick<CollisionRegion> {
|
||||
public:
|
||||
CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, CollisionRegion collisionRegion, const btCollisionWorld* collisionWorld) :
|
||||
CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, CollisionRegion collisionRegion, PhysicsEnginePointer physicsEngine) :
|
||||
Pick(filter, maxDistance, enabled),
|
||||
_mathPick(collisionRegion),
|
||||
_collisionWorld(collisionWorld) {
|
||||
_physicsEngine(physicsEngine) {
|
||||
}
|
||||
|
||||
CollisionRegion getMathematicalPick() const override;
|
||||
|
@ -130,38 +107,8 @@ protected:
|
|||
void computeShapeInfo(CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<GeometryResource> resource);
|
||||
|
||||
CollisionRegion _mathPick;
|
||||
const btCollisionWorld* _collisionWorld;
|
||||
PhysicsEnginePointer _physicsEngine;
|
||||
QSharedPointer<GeometryResource> _cachedResource;
|
||||
};
|
||||
|
||||
// Callback for checking the motion states of all colliding rigid bodies for candidacy to be added to a list
|
||||
struct RigidBodyFilterResultCallback : public btCollisionWorld::ContactResultCallback {
|
||||
RigidBodyFilterResultCallback(const ShapeInfo& shapeInfo, const Transform& transform);
|
||||
|
||||
~RigidBodyFilterResultCallback();
|
||||
|
||||
RigidBodyFilterResultCallback(btCollisionObject& testCollisionObject) :
|
||||
btCollisionWorld::ContactResultCallback(), collisionObject(testCollisionObject) {
|
||||
}
|
||||
|
||||
btCollisionObject collisionObject;
|
||||
|
||||
virtual bool needsCollision(btBroadphaseProxy* proxy) const;
|
||||
|
||||
// Check candidacy for adding to a list
|
||||
virtual void checkOrAddCollidingState(const btMotionState* otherMotionState, btVector3& point, btVector3& otherPoint) = 0;
|
||||
|
||||
btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) override;
|
||||
};
|
||||
|
||||
// Callback for getting colliding ObjectMotionStates in the world, or optionally a more specific type.
|
||||
template <typename T = ObjectMotionState>
|
||||
struct AllObjectMotionStatesCallback : public RigidBodyFilterResultCallback {
|
||||
AllObjectMotionStatesCallback(const ShapeInfo& shapeInfo, const Transform& transform) : RigidBodyFilterResultCallback(shapeInfo, transform) { }
|
||||
|
||||
std::vector<CollisionPickResult::EntityIntersection> intersectingObjects;
|
||||
|
||||
void checkOrAddCollidingState(const btMotionState* otherMotionState, btVector3& point, btVector3& otherPoint) override;
|
||||
};
|
||||
|
||||
#endif // hifi_CollisionPick_h
|
|
@ -157,7 +157,7 @@ unsigned int PickScriptingInterface::createCollisionPick(const QVariant& propert
|
|||
|
||||
CollisionRegion collisionRegion(propMap);
|
||||
|
||||
return DependencyManager::get<PickManager>()->addPick(PickQuery::Collision, std::make_shared<CollisionPick>(filter, maxDistance, enabled, collisionRegion, _collisionWorld));
|
||||
return DependencyManager::get<PickManager>()->addPick(PickQuery::Collision, std::make_shared<CollisionPick>(filter, maxDistance, enabled, collisionRegion, _physicsEngine));
|
||||
}
|
||||
|
||||
void PickScriptingInterface::enablePick(unsigned int uid) {
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
#define hifi_PickScriptingInterface_h
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <PhysicsEngine.h>
|
||||
#include <Pick.h>
|
||||
|
||||
/**jsdoc
|
||||
|
@ -277,12 +277,12 @@ public slots:
|
|||
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
|
||||
|
||||
// Set to allow CollisionPicks to have access to the physics engine
|
||||
void setCollisionWorld(const btCollisionWorld* collisionWorld) {
|
||||
_collisionWorld = collisionWorld;
|
||||
void setPhysicsEngine(PhysicsEnginePointer physicsEngine) {
|
||||
_physicsEngine = physicsEngine;
|
||||
}
|
||||
|
||||
protected:
|
||||
const btCollisionWorld* _collisionWorld;
|
||||
PhysicsEnginePointer _physicsEngine;
|
||||
};
|
||||
|
||||
#endif // hifi_PickScriptingInterface_h
|
||||
|
|
|
@ -840,3 +840,75 @@ void PhysicsEngine::setShowBulletConstraintLimits(bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
struct AllContactsCallback : public btCollisionWorld::ContactResultCallback {
|
||||
AllContactsCallback(MotionStateType desiredObjectType, const ShapeInfo& shapeInfo, const Transform& transform) :
|
||||
desiredObjectType(desiredObjectType),
|
||||
btCollisionWorld::ContactResultCallback(),
|
||||
collisionObject() {
|
||||
const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||
|
||||
collisionObject.setCollisionShape(const_cast<btCollisionShape*>(collisionShape));
|
||||
|
||||
btTransform bulletTransform;
|
||||
bulletTransform.setOrigin(glmToBullet(transform.getTranslation()));
|
||||
bulletTransform.setRotation(glmToBullet(transform.getRotation()));
|
||||
|
||||
collisionObject.setWorldTransform(bulletTransform);
|
||||
}
|
||||
|
||||
~AllContactsCallback() {
|
||||
ObjectMotionState::getShapeManager()->releaseShape(collisionObject.getCollisionShape());
|
||||
}
|
||||
|
||||
AllContactsCallback(btCollisionObject& testCollisionObject) :
|
||||
btCollisionWorld::ContactResultCallback(), collisionObject(testCollisionObject) {
|
||||
}
|
||||
|
||||
MotionStateType desiredObjectType;
|
||||
btCollisionObject collisionObject;
|
||||
std::vector<EntityIntersection> intersectingObjects;
|
||||
|
||||
virtual bool needsCollision(btBroadphaseProxy* proxy) const {
|
||||
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 point;
|
||||
btVector3 otherPoint;
|
||||
if (colObj0->m_collisionObject == &collisionObject) {
|
||||
otherBody = colObj1->m_collisionObject;
|
||||
point = cp.m_localPointA;
|
||||
otherPoint = cp.m_localPointB;
|
||||
}
|
||||
else {
|
||||
otherBody = colObj0->m_collisionObject;
|
||||
point = cp.m_localPointB;
|
||||
otherPoint = cp.m_localPointA;
|
||||
}
|
||||
|
||||
if (!(otherBody->getInternalType() & btCollisionObject::CO_RIGID_BODY)) {
|
||||
return 0;
|
||||
}
|
||||
const btRigidBody* collisionCandidate = static_cast<const btRigidBody*>(otherBody);
|
||||
const btMotionState* motionStateCandidate = collisionCandidate->getMotionState();
|
||||
|
||||
const ObjectMotionState* candidate = dynamic_cast<const ObjectMotionState*>(motionStateCandidate);
|
||||
if (!candidate || candidate->getType() != desiredObjectType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is the correct object type. Add it to the list.
|
||||
intersectingObjects.emplace_back(candidate->getObjectID(), bulletToGLM(point), bulletToGLM(otherPoint));
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<EntityIntersection> PhysicsEngine::getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const {
|
||||
auto contactCallback = AllContactsCallback(desiredObjectType, regionShapeInfo, regionTransform);
|
||||
_dynamicsWorld->contactTest(&contactCallback.collisionObject, contactCallback);
|
||||
|
||||
return contactCallback.intersectingObjects;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,26 @@ public:
|
|||
void* _b; // ObjectMotionState pointer
|
||||
};
|
||||
|
||||
struct EntityIntersection {
|
||||
EntityIntersection() { }
|
||||
|
||||
EntityIntersection(const EntityIntersection& entityIntersection) :
|
||||
id(entityIntersection.id),
|
||||
pickCollisionPoint(entityIntersection.pickCollisionPoint),
|
||||
entityCollisionPoint(entityIntersection.entityCollisionPoint) {
|
||||
}
|
||||
|
||||
EntityIntersection(QUuid id, glm::vec3 selfCollisionPoint, glm::vec3 otherCollisionPoint) :
|
||||
id(id),
|
||||
pickCollisionPoint(selfCollisionPoint),
|
||||
entityCollisionPoint(otherCollisionPoint) {
|
||||
}
|
||||
|
||||
QUuid id;
|
||||
glm::vec3 pickCollisionPoint;
|
||||
glm::vec3 entityCollisionPoint;
|
||||
};
|
||||
|
||||
using ContactMap = std::map<ContactKey, ContactInfo>;
|
||||
using CollisionEvents = std::vector<Collision>;
|
||||
|
||||
|
@ -105,6 +125,9 @@ public:
|
|||
void setShowBulletConstraints(bool value);
|
||||
void setShowBulletConstraintLimits(bool value);
|
||||
|
||||
// Function for getting colliding ObjectMotionStates in the world of specified type
|
||||
std::vector<EntityIntersection> getCollidingInRegion(MotionStateType desiredObjectType, const ShapeInfo& regionShapeInfo, const Transform& regionTransform) const;
|
||||
|
||||
private:
|
||||
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
|
||||
void addObjectToDynamicsWorld(ObjectMotionState* motionState);
|
||||
|
|
Loading…
Reference in a new issue