mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 20:58:30 +02:00
fist cut at basic TriangleSet class
This commit is contained in:
parent
807e15ade9
commit
9908723bb9
5 changed files with 144 additions and 28 deletions
|
@ -376,24 +376,26 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
}
|
||||
|
||||
for (const auto& subMeshBox : _calculatedMeshBoxes) {
|
||||
bool intersectedSubMesh = false;
|
||||
float subMeshDistance = std::numeric_limits<float>::max();
|
||||
|
||||
if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace, subMeshSurfaceNormal)) {
|
||||
if (distanceToSubMesh < bestDistance) {
|
||||
if (pickAgainstTriangles) {
|
||||
// check our triangles here....
|
||||
const QVector<Triangle>& meshTriangles = _calculatedMeshTriangles[subMeshIndex];
|
||||
for(const auto& triangle : meshTriangles) {
|
||||
float thisTriangleDistance;
|
||||
if (findRayTriangleIntersection(origin, direction, triangle, thisTriangleDistance)) {
|
||||
if (thisTriangleDistance < bestDistance) {
|
||||
bestDistance = thisTriangleDistance;
|
||||
intersectedSomething = true;
|
||||
face = subMeshFace;
|
||||
surfaceNormal = triangle.getNormal();
|
||||
extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
|
||||
}
|
||||
}
|
||||
|
||||
float subMeshDistance;
|
||||
glm::vec3 subMeshNormal;
|
||||
const auto& meshTriangleSet = _meshTriangleSets[subMeshIndex];
|
||||
bool intersectedMesh = meshTriangleSet.findRayIntersection(origin, direction, subMeshDistance, subMeshNormal);
|
||||
|
||||
if (intersectedMesh && subMeshDistance < bestDistance) {
|
||||
bestDistance = subMeshDistance;
|
||||
intersectedSomething = true;
|
||||
face = subMeshFace;
|
||||
surfaceNormal = subMeshNormal;
|
||||
extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
|
||||
}
|
||||
|
||||
} else {
|
||||
// this is the non-triangle picking case...
|
||||
bestDistance = distanceToSubMesh;
|
||||
|
@ -401,9 +403,13 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
face = subMeshFace;
|
||||
surfaceNormal = subMeshSurfaceNormal;
|
||||
extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
|
||||
|
||||
intersectedSubMesh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
subMeshIndex++;
|
||||
}
|
||||
_mutex.unlock();
|
||||
|
@ -451,18 +457,8 @@ bool Model::convexHullContains(glm::vec3 point) {
|
|||
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) {
|
||||
if (_meshTriangleSets[subMeshIndex].convexHullContains(point)) {
|
||||
// It's inside this mesh, return true.
|
||||
_mutex.unlock();
|
||||
return true;
|
||||
|
@ -486,12 +482,20 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
|||
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;
|
||||
|
||||
if (!_calculatedMeshBoxesValid || calculatedMeshTrianglesNeeded || (!_calculatedMeshPartBoxesValid && pickAgainstTriangles) ) {
|
||||
|
||||
if (pickAgainstTriangles) {
|
||||
qDebug() << "RECALCULATING triangles!";
|
||||
} else {
|
||||
qDebug() << "RECALCULATING boxes!";
|
||||
}
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
int numberOfMeshes = geometry.meshes.size();
|
||||
_calculatedMeshBoxes.resize(numberOfMeshes);
|
||||
_calculatedMeshTriangles.clear();
|
||||
_calculatedMeshTriangles.resize(numberOfMeshes);
|
||||
_calculatedMeshPartBoxes.clear();
|
||||
_meshTriangleSets.clear();
|
||||
_meshTriangleSets.resize(numberOfMeshes);
|
||||
|
||||
for (int i = 0; i < numberOfMeshes; i++) {
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
Extents scaledMeshExtents = calculateScaledOffsetExtents(mesh.meshExtents, _translation, _rotation);
|
||||
|
@ -499,6 +503,8 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
|||
_calculatedMeshBoxes[i] = AABox(scaledMeshExtents);
|
||||
|
||||
if (pickAgainstTriangles) {
|
||||
auto& thisMeshTriangleSet = _meshTriangleSets[i];
|
||||
|
||||
QVector<Triangle> thisMeshTriangles;
|
||||
for (int j = 0; j < mesh.parts.size(); j++) {
|
||||
const FBXMeshPart& part = mesh.parts.at(j);
|
||||
|
@ -550,6 +556,9 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
|||
thisMeshTriangles.push_back(tri1);
|
||||
thisMeshTriangles.push_back(tri2);
|
||||
|
||||
thisMeshTriangleSet.insertTriangle(tri1);
|
||||
thisMeshTriangleSet.insertTriangle(tri2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,11 +591,13 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
|||
Triangle tri = { v0, v1, v2 };
|
||||
|
||||
thisMeshTriangles.push_back(tri);
|
||||
|
||||
thisMeshTriangleSet.insertTriangle(tri);
|
||||
|
||||
}
|
||||
}
|
||||
_calculatedMeshPartBoxes[QPair<int,int>(i, j)] = thisPartBounds;
|
||||
}
|
||||
_calculatedMeshTriangles[i] = thisMeshTriangles;
|
||||
_calculatedMeshPartBoxesValid = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <render/Scene.h>
|
||||
#include <Transform.h>
|
||||
#include <SpatiallyNestable.h>
|
||||
#include <TriangleSet.h>
|
||||
|
||||
#include "GeometryCache.h"
|
||||
#include "TextureCache.h"
|
||||
|
@ -362,8 +363,8 @@ protected:
|
|||
bool _calculatedMeshPartBoxesValid;
|
||||
QVector<AABox> _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes
|
||||
bool _calculatedMeshBoxesValid;
|
||||
QVector< TriangleSet > _meshTriangleSets; // world coordinate triangles for all sub meshes
|
||||
|
||||
QVector< QVector<Triangle> > _calculatedMeshTriangles; // world coordinate triangles for all sub meshes
|
||||
bool _calculatedMeshTrianglesValid;
|
||||
QMutex _mutex;
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ public:
|
|||
|
||||
bool isInvalid() const { return _corner == INFINITY_VECTOR; }
|
||||
|
||||
void clear() { _corner = INFINITY_VECTOR; _scale = glm::vec3(0.0f); }
|
||||
|
||||
private:
|
||||
glm::vec3 getClosestPointOnFace(const glm::vec3& point, BoxFace face) const;
|
||||
glm::vec3 getClosestPointOnFace(const glm::vec4& origin, const glm::vec4& direction, BoxFace face) const;
|
||||
|
|
69
libraries/shared/src/TriangleSet.cpp
Normal file
69
libraries/shared/src/TriangleSet.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// TriangleSet.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 3/2/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "GLMHelpers.h"
|
||||
#include "TriangleSet.h"
|
||||
|
||||
void TriangleSet::insertTriangle(const Triangle& t) {
|
||||
_triangles.push_back(t);
|
||||
|
||||
_bounds += t.v0;
|
||||
_bounds += t.v1;
|
||||
_bounds += t.v2;
|
||||
}
|
||||
|
||||
void TriangleSet::clear() {
|
||||
_triangles.clear();
|
||||
_bounds.clear();
|
||||
}
|
||||
|
||||
// Determine of the given ray (origin/direction) in model space intersects with any triangles
|
||||
// in the set. If an intersection occurs, the distance and surface normal will be provided.
|
||||
bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
float& distance, glm::vec3& surfaceNormal) const {
|
||||
|
||||
float bestDistance = std::numeric_limits<float>::max();
|
||||
float thisTriangleDistance;
|
||||
bool intersectedSomething = false;
|
||||
|
||||
for (const auto& triangle : _triangles) {
|
||||
if (findRayTriangleIntersection(origin, direction, triangle, thisTriangleDistance)) {
|
||||
if (thisTriangleDistance < bestDistance) {
|
||||
bestDistance = thisTriangleDistance;
|
||||
intersectedSomething = true;
|
||||
surfaceNormal = triangle.getNormal();
|
||||
distance = bestDistance;
|
||||
//face = subMeshFace;
|
||||
//extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersectedSomething;
|
||||
}
|
||||
|
||||
|
||||
bool TriangleSet::convexHullContains(const glm::vec3& point) const {
|
||||
if (!_bounds.contains(point)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool insideMesh = true; // optimistic
|
||||
for (const auto& triangle : _triangles) {
|
||||
if (!isPointBehindTrianglesPlane(point, triangle.v0, triangle.v1, triangle.v2)) {
|
||||
// it's not behind at least one so we bail
|
||||
insideMesh = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return insideMesh;
|
||||
}
|
||||
|
33
libraries/shared/src/TriangleSet.h
Normal file
33
libraries/shared/src/TriangleSet.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// TriangleSet.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 3/2/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#include "AABox.h"
|
||||
#include "GeometryUtil.h"
|
||||
|
||||
class TriangleSet {
|
||||
public:
|
||||
void insertTriangle(const Triangle& t);
|
||||
void clear();
|
||||
|
||||
// Determine of the given ray (origin/direction) in model space intersects with any triangles
|
||||
// in the set. If an intersection occurs, the distance and surface normal will be provided.
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
float& distance, glm::vec3& surfaceNormal) const;
|
||||
|
||||
bool convexHullContains(const glm::vec3& point) const; // this point is "inside" all triangles
|
||||
const AABox& getBounds() const;
|
||||
|
||||
private:
|
||||
QVector<Triangle> _triangles;
|
||||
AABox _bounds;
|
||||
};
|
Loading…
Reference in a new issue