mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 16:13:28 +02:00
improved findEntities(sphere) to check against Non-AABBox of entities
This commit is contained in:
parent
d0118e80a7
commit
d34ad2af42
2 changed files with 77 additions and 14 deletions
|
@ -609,25 +609,83 @@ EntityItemPointer EntityTreeElement::getClosestEntity(glm::vec3 position) const
|
|||
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<EntityItemPointer>& foundEntities) const {
|
||||
float compareRadius = searchRadius * searchRadius;
|
||||
forEachEntity([&](EntityItemPointer entity) {
|
||||
// For iteration like this, avoid the use of square roots by comparing distances squared
|
||||
float distanceSquared = glm::length2(entity->getPosition() - searchPosition);
|
||||
float otherRadius = entity->getRadius();
|
||||
if (distanceSquared < (compareRadius + (otherRadius * otherRadius))) {
|
||||
|
||||
AABox entityBox = entity->getAABox();
|
||||
|
||||
// if the sphere doesn't intersect with our world frame AABox, we don't need to consider the more complex case
|
||||
glm::vec3 penetration;
|
||||
if (entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) {
|
||||
|
||||
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
||||
// FIXME - consider allowing the entity to determine penetration so that
|
||||
// entities could presumably dull actuall hull testing if they wanted to
|
||||
|
||||
// determine the worldToEntityMatrix that doesn't include scale because
|
||||
// we're going to use the registration aware aa box in the entity frame
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getRotation());
|
||||
glm::mat4 translation = glm::translate(entity->getPosition());
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
glm::vec3 dimensions = entity->getDimensions();
|
||||
glm::vec3 registrationPoint = entity->getRegistrationPoint();
|
||||
glm::vec3 corner = -(dimensions * registrationPoint);
|
||||
|
||||
AABox entityFrameBox(corner, dimensions);
|
||||
|
||||
glm::vec3 entityFrameSearchPosition = glm::vec3(worldToEntityMatrix * glm::vec4(searchPosition, 1.0f));
|
||||
if (entityFrameBox.findSpherePenetration(entityFrameSearchPosition, searchRadius, penetration)) {
|
||||
foundEntities.push_back(entity);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EntityTreeElement::getEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities) {
|
||||
forEachEntity([&](EntityItemPointer entity) {
|
||||
AABox entityBox = entity->getAABox();
|
||||
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
||||
// FIXME - consider allowing the entity to determine penetration so that
|
||||
// entities could presumably dull actuall hull testing if they wanted to
|
||||
// FIXME - is there an easy way to translate the search cube into something in the
|
||||
// entity frame that can be easily tested against?
|
||||
// simple algorithm is probably:
|
||||
// if target box is fully inside search box == yes
|
||||
// if search box is fully inside target box == yes
|
||||
// for each face of search box:
|
||||
// translate the triangles of the face into the box frame
|
||||
// test the triangles of the face against the box?
|
||||
// if translated search face triangle intersect target box
|
||||
// add to result
|
||||
//
|
||||
|
||||
// If the entities AABox touches the search cube then consider it to be found
|
||||
if (entityBox.touches(cube)) {
|
||||
foundEntities.push_back(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: change this to use better bounding shape for entity than sphere
|
||||
void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItemPointer>& foundEntities) {
|
||||
AACube entityCube;
|
||||
void EntityTreeElement::getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities) {
|
||||
forEachEntity([&](EntityItemPointer entity) {
|
||||
float radius = entity->getRadius();
|
||||
// NOTE: we actually do cube-cube collision queries here, which is sloppy but good enough for now
|
||||
// TODO: decide whether to replace entityCube-cube query with sphere-cube (requires a square root
|
||||
// but will be slightly more accurate).
|
||||
entityCube.setBox(entity->getPosition() - glm::vec3(radius), 2.0f * radius);
|
||||
if (entityCube.touches(box)) {
|
||||
AABox entityBox = entity->getAABox();
|
||||
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
||||
// FIXME - consider allowing the entity to determine penetration so that
|
||||
// entities could presumably dull actuall hull testing if they wanted to
|
||||
// FIXME - is there an easy way to translate the search cube into something in the
|
||||
// entity frame that can be easily tested against?
|
||||
// simple algorithm is probably:
|
||||
// if target box is fully inside search box == yes
|
||||
// if search box is fully inside target box == yes
|
||||
// for each face of search box:
|
||||
// translate the triangles of the face into the box frame
|
||||
// test the triangles of the face against the box?
|
||||
// if translated search face triangle intersect target box
|
||||
// add to result
|
||||
//
|
||||
|
||||
// If the entities AABox touches the search cube then consider it to be found
|
||||
if (entityBox.touches(box)) {
|
||||
foundEntities.push_back(entity);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -180,7 +180,12 @@ public:
|
|||
/// finds all entities that touch a box
|
||||
/// \param box the query box
|
||||
/// \param entities[out] vector of non-const EntityItemPointer
|
||||
void getEntities(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||
void getEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
/// finds all entities that touch a box
|
||||
/// \param box the query box
|
||||
/// \param entities[out] vector of non-const EntityItemPointer
|
||||
void getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
EntityItemPointer getEntityWithID(uint32_t id) const;
|
||||
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||
|
|
Loading…
Reference in a new issue