mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 07:27:04 +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>());
|
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);
|
filterIntersections(entityIntersections);
|
||||||
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_LOADED, entityIntersections, std::vector<ContactTestResult>());
|
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>());
|
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);
|
filterIntersections(avatarIntersections);
|
||||||
return std::make_shared<CollisionPickResult>(pick, CollisionPickResult::LOAD_STATE_LOADED, std::vector<ContactTestResult>(), 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 {
|
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(),
|
btCollisionWorld::ContactResultCallback(),
|
||||||
collisionObject(),
|
collisionObject(),
|
||||||
contacts(),
|
contacts(),
|
||||||
myAvatarCollisionObject(myAvatarCollisionObject) {
|
myAvatarCollisionObject(myAvatarCollisionObject),
|
||||||
|
threshold(threshold) {
|
||||||
const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
const btCollisionShape* collisionShape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||||
|
|
||||||
collisionObject.setCollisionShape(const_cast<btCollisionShape*>(collisionShape));
|
collisionObject.setCollisionShape(const_cast<btCollisionShape*>(collisionShape));
|
||||||
|
@ -924,8 +925,13 @@ struct AllContactsCallback : public btCollisionWorld::ContactResultCallback {
|
||||||
btCollisionObject collisionObject;
|
btCollisionObject collisionObject;
|
||||||
std::vector<ContactTestResult> contacts;
|
std::vector<ContactTestResult> contacts;
|
||||||
btCollisionObject* myAvatarCollisionObject;
|
btCollisionObject* myAvatarCollisionObject;
|
||||||
|
btScalar threshold;
|
||||||
|
|
||||||
btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) override {
|
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;
|
const btCollisionObject* otherBody;
|
||||||
btVector3 penetrationPoint;
|
btVector3 penetrationPoint;
|
||||||
btVector3 otherPenetrationPoint;
|
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
|
// TODO: Give MyAvatar a motion state so we don't have to do this
|
||||||
btCollisionObject* myAvatarCollisionObject = nullptr;
|
btCollisionObject* myAvatarCollisionObject = nullptr;
|
||||||
if ((mask & USER_COLLISION_GROUP_MY_AVATAR) && _myAvatarController) {
|
if ((mask & USER_COLLISION_GROUP_MY_AVATAR) && _myAvatarController) {
|
||||||
myAvatarCollisionObject = _myAvatarController->getCollisionObject();
|
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);
|
_dynamicsWorld->contactTest(&contactCallback.collisionObject, contactCallback);
|
||||||
|
|
||||||
return contactCallback.contacts;
|
return contactCallback.contacts;
|
||||||
|
|
|
@ -142,7 +142,7 @@ public:
|
||||||
|
|
||||||
// Function for getting colliding objects in the world of specified type
|
// Function for getting colliding objects in the world of specified type
|
||||||
// See PhysicsCollisionGroups.h for mask flags.
|
// 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:
|
private:
|
||||||
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
|
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
|
||||||
|
|
|
@ -254,12 +254,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**jsdoc
|
/**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 {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 {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 {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 {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 {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.
|
* @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() { }
|
||||||
|
|
||||||
CollisionRegion(const CollisionRegion& collisionRegion) :
|
CollisionRegion(const CollisionRegion& collisionRegion) :
|
||||||
|
threshold(collisionRegion.threshold),
|
||||||
modelURL(collisionRegion.modelURL),
|
modelURL(collisionRegion.modelURL),
|
||||||
shapeInfo(std::make_shared<ShapeInfo>()),
|
shapeInfo(std::make_shared<ShapeInfo>()),
|
||||||
transform(collisionRegion.transform)
|
transform(collisionRegion.transform)
|
||||||
|
@ -299,6 +301,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pickVariant["threshold"].isValid()) {
|
||||||
|
threshold = glm::max(0.0f, pickVariant["threshold"].toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
if (pickVariant["position"].isValid()) {
|
if (pickVariant["position"].isValid()) {
|
||||||
transform.setTranslation(vec3FromVariant(pickVariant["position"]));
|
transform.setTranslation(vec3FromVariant(pickVariant["position"]));
|
||||||
}
|
}
|
||||||
|
@ -317,6 +323,8 @@ public:
|
||||||
|
|
||||||
collisionRegion["shape"] = shape;
|
collisionRegion["shape"] = shape;
|
||||||
|
|
||||||
|
collisionRegion["threshold"] = threshold;
|
||||||
|
|
||||||
collisionRegion["position"] = vec3toVariant(transform.getTranslation());
|
collisionRegion["position"] = vec3toVariant(transform.getTranslation());
|
||||||
collisionRegion["orientation"] = quatToVariant(transform.getRotation());
|
collisionRegion["orientation"] = quatToVariant(transform.getRotation());
|
||||||
|
|
||||||
|
@ -324,13 +332,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const override {
|
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())) ||
|
glm::any(glm::isnan(transform.getRotation())) ||
|
||||||
shapeInfo->getType() == SHAPE_TYPE_NONE);
|
shapeInfo->getType() == SHAPE_TYPE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const CollisionRegion& other) const {
|
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.getRotation(), other.transform.getRotation())) &&
|
||||||
glm::all(glm::equal(transform.getScale(), other.transform.getScale())) &&
|
glm::all(glm::equal(transform.getScale(), other.transform.getScale())) &&
|
||||||
shapeInfo->getType() == other.shapeInfo->getType() &&
|
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
|
// 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>();
|
std::shared_ptr<ShapeInfo> shapeInfo = std::make_shared<ShapeInfo>();
|
||||||
Transform transform;
|
Transform transform;
|
||||||
|
float threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
Loading…
Reference in a new issue