[CORE][ADD] Add hit API to Mesh

- Moller Trumbore algorithm is used
This commit is contained in:
Linloir 2022-12-18 16:08:35 +08:00
parent 308dd81f06
commit 0d4a22f0ce
No known key found for this signature in database
GPG Key ID: 58EEB209A0F2C366
2 changed files with 38 additions and 0 deletions

View File

@ -53,3 +53,38 @@ void Mesh::setupMesh() {
//_vao.setVertexAttributePointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)OFFSETOF(Vertex, _tangent)); //_vao.setVertexAttributePointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)OFFSETOF(Vertex, _tangent));
//_vao.setVertexAttributePointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)OFFSETOF(Vertex, _bitangent)); //_vao.setVertexAttributePointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)OFFSETOF(Vertex, _bitangent));
} }
HitRecord Mesh::hit(const Ray& ray) const {
// Test whether the ray hits the mesh
// Traverse the indices to test every triangle
for (int i = 0; i < _indices.size(); i += 3) {
// Get the three vertices of the triangle
Vertex v0 = _vertices[_indices[i]];
Vertex v1 = _vertices[_indices[i + 1]];
Vertex v2 = _vertices[_indices[i + 2]];
// Moller Trumbore algorithm
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
glm::vec3 edge1 = v1._position - v0._position;
glm::vec3 edge2 = v2._position - v0._position;
glm::vec3 pvec = glm::cross(ray.direction(), edge2);
float det = glm::dot(edge1, pvec);
if (det < 0.0001f) continue;
float invDet = 1.0f / det;
glm::vec3 tvec = ray.origin() - v0._position;
float u = glm::dot(tvec, pvec) * invDet;
if (u < 0.0f || u > 1.0f) continue;
glm::vec3 qvec = glm::cross(tvec, edge1);
float v = glm::dot(ray.direction(), qvec) * invDet;
if (v < 0.0f || u + v > 1.0f) continue;
float t = glm::dot(edge2, qvec) * invDet;
if (t > 0.0001f) {
// Hit
glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));
glm::vec3 hitPoint = ray.origin() + t * ray.direction();
return HitRecord(hitPoint, normal);
}
}
return HitRecord();
}

View File

@ -6,6 +6,8 @@
#include "texture.h" #include "texture.h"
#include "vao.h" #include "vao.h"
#include "shader.h" #include "shader.h"
#include "ray.h"
#include "hitrecord.h"
class Mesh { class Mesh {
private: private:
@ -34,6 +36,7 @@ public:
public: public:
void render(const ShaderProgram& shader) const ; void render(const ShaderProgram& shader) const ;
HitRecord hit(const Ray& ray) const;
private: private:
void setupMesh(); void setupMesh();