mirror of
https://github.com/JulianGro/overte.git
synced 2025-05-01 07:13:02 +02:00
Implement Entities.findInFrustum() method
This commit is contained in:
parent
ce58edc4e0
commit
38c2efa22f
8 changed files with 148 additions and 12 deletions
|
@ -21,6 +21,7 @@
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#include "LightEntityItem.h"
|
#include "LightEntityItem.h"
|
||||||
#include "ModelEntityItem.h"
|
#include "ModelEntityItem.h"
|
||||||
|
#include "QVariantGLM.h"
|
||||||
#include "SimulationOwner.h"
|
#include "SimulationOwner.h"
|
||||||
#include "ZoneEntityItem.h"
|
#include "ZoneEntityItem.h"
|
||||||
|
|
||||||
|
@ -550,14 +551,6 @@ QVector<QUuid> EntityScriptingInterface::findEntities(const glm::vec3& center, f
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QUuid> EntityScriptingInterface::findEntitiesInView(const glm::vec3& center, float radius) const {
|
|
||||||
QVector<QUuid> result;
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const {
|
QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const {
|
||||||
QVector<QUuid> result;
|
QVector<QUuid> result;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
@ -574,6 +567,48 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QUuid> EntityScriptingInterface::findEntitiesInFrustum(QVariantMap frustum) const {
|
||||||
|
QVector<QUuid> result;
|
||||||
|
|
||||||
|
const QString POSITION_PROPERTY = "position";
|
||||||
|
bool positionOK = frustum.contains(POSITION_PROPERTY);
|
||||||
|
glm::vec3 position = positionOK ? qMapToGlmVec3(frustum[POSITION_PROPERTY]) : glm::vec3();
|
||||||
|
|
||||||
|
const QString ORIENTATION_PROPERTY = "orientation";
|
||||||
|
bool orientationOK = frustum.contains(ORIENTATION_PROPERTY);
|
||||||
|
glm::quat orientation = orientationOK ? qMapToGlmQuat(frustum[ORIENTATION_PROPERTY]) : glm::quat();
|
||||||
|
|
||||||
|
const QString PROJECTION_PROPERTY = "projection";
|
||||||
|
bool projectionOK = frustum.contains(PROJECTION_PROPERTY);
|
||||||
|
glm::mat4 projection = projectionOK ? qMapToGlmMat4(frustum[PROJECTION_PROPERTY]) : glm::mat4();
|
||||||
|
|
||||||
|
const QString CENTER_RADIUS_PROPERTY = "centerRadius";
|
||||||
|
bool centerRadiusOK = frustum.contains(CENTER_RADIUS_PROPERTY);
|
||||||
|
float centerRadius = centerRadiusOK ? frustum[CENTER_RADIUS_PROPERTY].toFloat() : 0.0f;
|
||||||
|
|
||||||
|
if (positionOK && orientationOK && projectionOK && centerRadiusOK) {
|
||||||
|
ViewFrustum viewFrustum;
|
||||||
|
viewFrustum.setPosition(position);
|
||||||
|
viewFrustum.setOrientation(orientation);
|
||||||
|
viewFrustum.setProjection(projection);
|
||||||
|
viewFrustum.setCenterRadius(centerRadius);
|
||||||
|
viewFrustum.calculate();
|
||||||
|
|
||||||
|
if (_entityTree) {
|
||||||
|
QVector<EntityItemPointer> entities;
|
||||||
|
_entityTree->withReadLock([&] {
|
||||||
|
_entityTree->findEntities(viewFrustum, entities);
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach(EntityItemPointer entity, entities) {
|
||||||
|
result << entity->getEntityItemID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
||||||
const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) {
|
const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) {
|
||||||
|
|
||||||
|
|
|
@ -127,14 +127,19 @@ public slots:
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
Q_INVOKABLE QVector<QUuid> findEntities(const glm::vec3& center, float radius) const;
|
Q_INVOKABLE QVector<QUuid> findEntities(const glm::vec3& center, float radius) const;
|
||||||
|
|
||||||
/// finds models within the search sphere specified by the center point and radius
|
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
|
||||||
Q_INVOKABLE QVector<QUuid> findEntitiesInView(const glm::vec3& center, float radius) const;
|
|
||||||
|
|
||||||
/// finds models within the box specified by the corner and dimensions
|
/// finds models within the box specified by the corner and dimensions
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
Q_INVOKABLE QVector<QUuid> findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const;
|
Q_INVOKABLE QVector<QUuid> findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const;
|
||||||
|
|
||||||
|
/// finds models within the frustum
|
||||||
|
/// the frustum must have the following properties:
|
||||||
|
/// - position
|
||||||
|
/// - orientation
|
||||||
|
/// - projection
|
||||||
|
/// - centerRadius
|
||||||
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
|
Q_INVOKABLE QVector<QUuid> findEntitiesInFrustum(QVariantMap frustum) const;
|
||||||
|
|
||||||
/// If the scripting context has visible entities, this will determine a ray intersection, the results
|
/// If the scripting context has visible entities, this will determine a ray intersection, the results
|
||||||
/// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate
|
/// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate
|
||||||
/// will be false.
|
/// will be false.
|
||||||
|
|
|
@ -688,6 +688,31 @@ void EntityTree::findEntities(const AABox& box, QVector<EntityItemPointer>& foun
|
||||||
foundEntities.swap(args._foundEntities);
|
foundEntities.swap(args._foundEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FindInFrustumArgs {
|
||||||
|
public:
|
||||||
|
ViewFrustum frustum;
|
||||||
|
QVector<EntityItemPointer> entities;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool EntityTree::findInFrustumOperation(OctreeElementPointer element, void* extraData) {
|
||||||
|
FindInFrustumArgs* args = static_cast<FindInFrustumArgs*>(extraData);
|
||||||
|
if (element->isInView(args->frustum)) {
|
||||||
|
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||||
|
entityTreeElement->getEntities(args->frustum, args->entities);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: assumes caller has handled locking
|
||||||
|
void EntityTree::findEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities) {
|
||||||
|
FindInFrustumArgs args = { frustum, QVector<EntityItemPointer>() };
|
||||||
|
// NOTE: This should use recursion, since this is a spatial operation
|
||||||
|
recurseTreeWithOperation(findInFrustumOperation, &args);
|
||||||
|
// swap the two lists of entity pointers instead of copy
|
||||||
|
foundEntities.swap(args.entities);
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
||||||
EntityItemID entityID(id);
|
EntityItemID entityID(id);
|
||||||
return findEntityByEntityItemID(entityID);
|
return findEntityByEntityItemID(entityID);
|
||||||
|
|
|
@ -153,6 +153,11 @@ public:
|
||||||
/// \remark Side effect: any initial contents in entities will be lost
|
/// \remark Side effect: any initial contents in entities will be lost
|
||||||
void findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
void findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
|
/// finds all entities within a frustum
|
||||||
|
/// \parameter frustum the query frustum
|
||||||
|
/// \param foundEntities[out] vector of EntityItemPointer
|
||||||
|
void findEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
|
|
||||||
|
@ -276,6 +281,7 @@ protected:
|
||||||
static bool findInSphereOperation(OctreeElementPointer element, void* extraData);
|
static bool findInSphereOperation(OctreeElementPointer element, void* extraData);
|
||||||
static bool findInCubeOperation(OctreeElementPointer element, void* extraData);
|
static bool findInCubeOperation(OctreeElementPointer element, void* extraData);
|
||||||
static bool findInBoxOperation(OctreeElementPointer element, void* extraData);
|
static bool findInBoxOperation(OctreeElementPointer element, void* extraData);
|
||||||
|
static bool findInFrustumOperation(OctreeElementPointer element, void* extraData);
|
||||||
static bool sendEntitiesOperation(OctreeElementPointer element, void* extraData);
|
static bool sendEntitiesOperation(OctreeElementPointer element, void* extraData);
|
||||||
|
|
||||||
void notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode);
|
void notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode);
|
||||||
|
|
|
@ -796,6 +796,17 @@ void EntityTreeElement::getEntities(const AABox& box, QVector<EntityItemPointer>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeElement::getEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities) {
|
||||||
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
|
bool success;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
|
// FIXME - See FIXMEs for similar methods above.
|
||||||
|
if (!success || frustum.boxIntersectsFrustum(entityBox) || frustum.boxIntersectsKeyhole(entityBox)) {
|
||||||
|
foundEntities.push_back(entity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
||||||
EntityItemPointer foundEntity = NULL;
|
EntityItemPointer foundEntity = NULL;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
|
|
@ -194,6 +194,11 @@ public:
|
||||||
/// \param entities[out] vector of non-const EntityItemPointer
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
void getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
void getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
|
/// finds all entities that touch a frustum
|
||||||
|
/// \param frustum the query frustum
|
||||||
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
|
void getEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
EntityItemPointer getEntityWithID(uint32_t id) const;
|
EntityItemPointer getEntityWithID(uint32_t id) const;
|
||||||
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||||
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
|
@ -62,3 +62,48 @@ void qListtoRgbColor(const QVariant& q, rgbColor& returnValue) {
|
||||||
returnValue[GREEN_INDEX] = qList[GREEN_INDEX].toInt();
|
returnValue[GREEN_INDEX] = qList[GREEN_INDEX].toInt();
|
||||||
returnValue[BLUE_INDEX] = qList[BLUE_INDEX].toInt();
|
returnValue[BLUE_INDEX] = qList[BLUE_INDEX].toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec3 qMapToGlmVec3(const QVariant& q) {
|
||||||
|
QVariantMap qMap = q.toMap();
|
||||||
|
if (qMap.contains("x") && qMap.contains("y") && qMap.contains("y")) {
|
||||||
|
return glm::vec3(
|
||||||
|
qMap["x"].toFloat(),
|
||||||
|
qMap["y"].toFloat(),
|
||||||
|
qMap["z"].toFloat()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat qMapToGlmQuat(const QVariant& q) {
|
||||||
|
QVariantMap qMap = q.toMap();
|
||||||
|
if (qMap.contains("w") && qMap.contains("x") && qMap.contains("y") && qMap.contains("z")) {
|
||||||
|
return glm::quat(
|
||||||
|
qMap["w"].toFloat(),
|
||||||
|
qMap["x"].toFloat(),
|
||||||
|
qMap["y"].toFloat(),
|
||||||
|
qMap["z"].toFloat()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 qMapToGlmMat4(const QVariant& q) {
|
||||||
|
QVariantMap qMap = q.toMap();
|
||||||
|
if (qMap.contains("r0c0") && qMap.contains("r1c0") && qMap.contains("r2c0") && qMap.contains("r3c0")
|
||||||
|
&& qMap.contains("r0c1") && qMap.contains("r1c1") && qMap.contains("r2c1") && qMap.contains("r3c1")
|
||||||
|
&& qMap.contains("r0c2") && qMap.contains("r1c2") && qMap.contains("r2c2") && qMap.contains("r3c2")
|
||||||
|
&& qMap.contains("r0c3") && qMap.contains("r1c3") && qMap.contains("r2c3") && qMap.contains("r3c3")) {
|
||||||
|
return glm::mat4(
|
||||||
|
qMap["r0c0"].toFloat(), qMap["r1c0"].toFloat(), qMap["r2c0"].toFloat(), qMap["r3c0"].toFloat(),
|
||||||
|
qMap["r0c1"].toFloat(), qMap["r1c1"].toFloat(), qMap["r2c1"].toFloat(), qMap["r3c1"].toFloat(),
|
||||||
|
qMap["r0c2"].toFloat(), qMap["r1c2"].toFloat(), qMap["r2c2"].toFloat(), qMap["r3c2"].toFloat(),
|
||||||
|
qMap["r0c3"].toFloat(), qMap["r1c3"].toFloat(), qMap["r2c3"].toFloat(), qMap["r3c3"].toFloat()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,3 +27,7 @@ QVariantMap glmToQMap(const glm::quat& glmQuat);
|
||||||
glm::vec3 qListToGlmVec3(const QVariant& q);
|
glm::vec3 qListToGlmVec3(const QVariant& q);
|
||||||
glm::quat qListToGlmQuat(const QVariant& q);
|
glm::quat qListToGlmQuat(const QVariant& q);
|
||||||
void qListtoRgbColor(const QVariant& q, rgbColor& returnValue);
|
void qListtoRgbColor(const QVariant& q, rgbColor& returnValue);
|
||||||
|
|
||||||
|
glm::vec3 qMapToGlmVec3(const QVariant& q);
|
||||||
|
glm::quat qMapToGlmQuat(const QVariant& q);
|
||||||
|
glm::mat4 qMapToGlmMat4(const QVariant& q);
|
||||||
|
|
Loading…
Reference in a new issue