mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 04:34:38 +02:00
Add threshold parameter to collision pick with minimum of 0
This commit is contained in:
parent
51683b0b53
commit
397b03d5d5
4 changed files with 28 additions and 11 deletions
|
@ -391,7 +391,7 @@ PickResultPointer CollisionPick::getEntityIntersection(const CollisionRegion& pi
|
|||
return std::make_shared<CollisionPickResult>(pick.toVariantMap(), CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
||||
}
|
||||
|
||||
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform);
|
||||
auto entityIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_ENTITIES, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||
filterIntersections(entityIntersections);
|
||||
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector<ContactTestResult>());
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ PickResultPointer CollisionPick::getAvatarIntersection(const CollisionRegion& pi
|
|||
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_NOT_LOADED, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());
|
||||
}
|
||||
|
||||
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform);
|
||||
auto avatarIntersections = _physicsEngine->contactTest(USER_COLLISION_MASK_AVATARS, *pick.shapeInfo, pick.transform, USER_COLLISION_GROUP_DYNAMIC, pick.threshold);
|
||||
filterIntersections(avatarIntersections);
|
||||
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector<ContactTestResult>(), avatarIntersections);
|
||||
}
|
||||
|
|
|
@ -898,11 +898,12 @@ void PhysicsEngine::setShowBulletConstraintLimits(bool value) {
|
|||
}
|
||||
|
||||
struct AllContactsCallback : public btCollisionWorld::ContactResultCallback {
|
||||
AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject) :
|
||||
AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject, float threshold) :
|
||||
btCollisionWorld::ContactResultCallback(),
|
||||
collisionObject(),
|
||||
contacts(),
|
||||
myAvatarCollisionObject(myAvatarCollisionObject) {
|
||||
myAvatarCollisionObject(myAvatarCollisionObject),
|
||||
threshold(threshold) {
|
||||
const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||
|
||||
collisionObject.setCollisionShape(const_cast<btCollisionShape*>(collisionShape));
|
||||
|
@ -924,8 +925,13 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback {
|
|||
btCollisionObject collisionObject;
|
||||
std::vector<ContactTestResult> contacts;
|
||||
btCollisionObject* myAvatarCollisionObject;
|
||||
btScalar threshold;
|
||||
|
||||
btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) override {
|
||||
if (cp.m_distance1 > -threshold) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const btCollisionObject* otherBody;
|
||||
btVector3 penetrationPoint;
|
||||
btVector3 otherPenetrationPoint;
|
||||
|
@ -968,14 +974,14 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
std::vector<ContactTestResult> PhysicsEngine::contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group) const {
|
||||
std::vector<ContactTestResult> PhysicsEngine::contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group, float threshold) 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) {
|
||||
myAvatarCollisionObject = _myAvatarController->getCollisionObject();
|
||||
}
|
||||
|
||||
auto contactCallback = AllContactsCallback((int32_t)mask, (int32_t)group, regionShapeInfo, regionTransform, myAvatarCollisionObject);
|
||||
auto contactCallback = AllContactsCallback((int32_t)mask, (int32_t)group, regionShapeInfo, regionTransform, myAvatarCollisionObject, threshold);
|
||||
_dynamicsWorld->contactTest(&contactCallback.collisionObject, contactCallback);
|
||||
|
||||
return contactCallback.contacts;
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
|
||||
// Function for getting colliding objects in the world of specified type
|
||||
// See PhysicsCollisionGroups.h for mask flags.
|
||||
std::vector<ContactTestResult> contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC) const;
|
||||
std::vector<ContactTestResult> contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC, float threshold = 0.0f) const;
|
||||
|
||||
private:
|
||||
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
|
||||
|
|
|
@ -254,12 +254,13 @@ public:
|
|||
};
|
||||
|
||||
/**jsdoc
|
||||
* A CollisionPick defines a volume for checking collisions in the physics simulation.
|
||||
* A CollisionRegion defines a volume for checking collisions in the physics simulation.
|
||||
|
||||
* @typedef {object} CollisionPick
|
||||
* @typedef {object} CollisionRegion
|
||||
* @property {Shape} shape - The information about the collision region's size and shape.
|
||||
* @property {Vec3} position - The position of the collision region, relative to a parent if defined.
|
||||
* @property {Quat} orientation - The orientation of the collision region, relative to a parent if defined.
|
||||
* @property {float} threshold - The approximate minimum penetration depth for a test object to be considered in contact with the collision region.
|
||||
* @property {Uuid} parentID - The ID of the parent, either an avatar, an entity, or an overlay.
|
||||
* @property {number} parentJointIndex - The joint of the parent to parent to, for example, the joints on the model of an avatar. (default = 0, no joint)
|
||||
* @property {string} joint - If "Mouse," parents the pick to the mouse. If "Head," parents the pick to MyAvatar's head. Otherwise, parents to the joint of the given name on MyAvatar.
|
||||
|
@ -269,6 +270,7 @@ public:
|
|||
CollisionRegion() { }
|
||||
|
||||
CollisionRegion(const CollisionRegion& collisionRegion) :
|
||||
threshold(collisionRegion.threshold),
|
||||
modelURL(collisionRegion.modelURL),
|
||||
shapeInfo(std::make_shared<ShapeInfo>()),
|
||||
transform(collisionRegion.transform)
|
||||
|
@ -299,6 +301,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (pickVariant["threshold"].isValid()) {
|
||||
threshold = glm::max(0.0f, pickVariant["threshold"].toFloat());
|
||||
}
|
||||
|
||||
if (pickVariant["position"].isValid()) {
|
||||
transform.setTranslation(vec3FromVariant(pickVariant["position"]));
|
||||
}
|
||||
|
@ -317,6 +323,8 @@ public:
|
|||
|
||||
collisionRegion["shape"] = shape;
|
||||
|
||||
collisionRegion["threshold"] = threshold;
|
||||
|
||||
collisionRegion["position"] = vec3toVariant(transform.getTranslation());
|
||||
collisionRegion["orientation"] = quatToVariant(transform.getRotation());
|
||||
|
||||
|
@ -324,13 +332,15 @@ public:
|
|||
}
|
||||
|
||||
operator bool() const override {
|
||||
return !(glm::any(glm::isnan(transform.getTranslation())) ||
|
||||
return !std::isnan(threshold) &&
|
||||
!(glm::any(glm::isnan(transform.getTranslation())) ||
|
||||
glm::any(glm::isnan(transform.getRotation())) ||
|
||||
shapeInfo->getType() == SHAPE_TYPE_NONE);
|
||||
}
|
||||
|
||||
bool operator==(const CollisionRegion& other) const {
|
||||
return glm::all(glm::equal(transform.getTranslation(), other.transform.getTranslation())) &&
|
||||
return threshold == other.threshold &&
|
||||
glm::all(glm::equal(transform.getTranslation(), other.transform.getTranslation())) &&
|
||||
glm::all(glm::equal(transform.getRotation(), other.transform.getRotation())) &&
|
||||
glm::all(glm::equal(transform.getScale(), other.transform.getScale())) &&
|
||||
shapeInfo->getType() == other.shapeInfo->getType() &&
|
||||
|
@ -354,6 +364,7 @@ public:
|
|||
// We can't compute the shapeInfo here without loading the model first, so we delegate that responsibility to the owning CollisionPick
|
||||
std::shared_ptr<ShapeInfo> shapeInfo = std::make_shared<ShapeInfo>();
|
||||
Transform transform;
|
||||
float threshold;
|
||||
};
|
||||
|
||||
namespace std {
|
||||
|
|
Loading…
Reference in a new issue