mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 12:13:42 +02:00
Added a more efficient convexHullContains to Model
New version computes each submesh's bounding box once and checks against it before checking against triangles.
This commit is contained in:
parent
4911aa58bc
commit
b7263eeacf
2 changed files with 56 additions and 0 deletions
|
@ -573,6 +573,61 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
return intersectedSomething;
|
||||
}
|
||||
|
||||
bool Model::convexHullContains(glm::vec3 point) {
|
||||
// if we aren't active, we can't compute that yet...
|
||||
if (!isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// extents is the entity relative, scaled, centered extents of the entity
|
||||
glm::vec3 position = _translation;
|
||||
glm::mat4 rotation = glm::mat4_cast(_rotation);
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::mat4 modelToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix);
|
||||
|
||||
Extents modelExtents = getMeshExtents(); // NOTE: unrotated
|
||||
|
||||
glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum;
|
||||
glm::vec3 corner = -(dimensions * _registrationPoint); // since we're going to do the ray picking in the model frame of reference
|
||||
AABox modelFrameBox(corner, dimensions);
|
||||
|
||||
glm::vec3 modelFramePoint = glm::vec3(worldToModelMatrix * glm::vec4(point, 1.0f));
|
||||
|
||||
// we can use the AABox's ray intersection by mapping our origin and direction into the model frame
|
||||
// and testing intersection there.
|
||||
if (modelFrameBox.contains(modelFramePoint)){
|
||||
if (!_calculatedMeshTrianglesValid) {
|
||||
recalculateMeshBoxes(true);
|
||||
}
|
||||
|
||||
// If we are inside the models box, then consider the submeshes...
|
||||
int subMeshIndex = 0;
|
||||
foreach(const AABox& subMeshBox, _calculatedMeshBoxes) {
|
||||
if (subMeshBox.contains(point)) {
|
||||
bool insideMesh = true;
|
||||
// To be inside the sub mesh, we need to be behind every triangles' planes
|
||||
const QVector<Triangle>& meshTriangles = _calculatedMeshTriangles[subMeshIndex];
|
||||
foreach (const Triangle& triangle, meshTriangles) {
|
||||
if (!isPointBehindTrianglesPlane(point, triangle.v0, triangle.v1, triangle.v2)) {
|
||||
// it's not behind at least one so we bail
|
||||
insideMesh = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (insideMesh) {
|
||||
// It's inside this mesh, return true.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
subMeshIndex++;
|
||||
}
|
||||
}
|
||||
// It wasn't in any mesh, return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: we seem to call this too often when things haven't actually changed... look into optimizing this
|
||||
void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
||||
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;
|
||||
|
|
|
@ -213,6 +213,7 @@ public:
|
|||
|
||||
bool findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
BoxFace& face, QString& extraInfo, bool pickAgainstTriangles = false);
|
||||
bool convexHullContains(glm::vec3 point);
|
||||
|
||||
protected:
|
||||
QSharedPointer<NetworkGeometry> _geometry;
|
||||
|
|
Loading…
Reference in a new issue