-
Notifications
You must be signed in to change notification settings - Fork 0
/
mesh.cpp
84 lines (65 loc) · 2.41 KB
/
mesh.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "mesh.hpp"
Mesh::Mesh(std::shared_ptr<Geometry> geometry, std::shared_ptr<Material> material) : geometry{geometry}, material{material} {
update();
}
void Mesh::intersect(Ray& ray, HitRecord& hitRecord, uint& count) const {
Ray transformedRay = ray;
transformedRay.origin = invModelMatrix * vec4(ray.origin, 1.0f);
// Not normalized to handle scale transform
transformedRay.direction = invModelMatrix * vec4(ray.direction, 0.0f);
transformedRay.invDirection = 1.0f / transformedRay.direction;
geometry->intersect(transformedRay, hitRecord, count);
ray.t = transformedRay.t;
}
void Mesh::update() {
modelMatrix = identity<mat4>();
modelMatrix = glm::scale(modelMatrix, vec3(scale));
modelMatrix = glm::rotate(modelMatrix, rotation.x, vec3(1, 0, 0));
modelMatrix = glm::rotate(modelMatrix, rotation.y, vec3(0, 1, 0));
modelMatrix = glm::rotate(modelMatrix, rotation.z, vec3(0, 0, 1));
modelMatrix = glm::translate(modelMatrix, vec3(inverse(modelMatrix) * vec4(translation, 1.0f)));
modelMatrix = glm::translate(modelMatrix, -geometry->centroid);
invModelMatrix = inverse(modelMatrix);
normalMatrix = transpose(invModelMatrix);
aabbMin = vec3{FLT_MAX};
aabbMax = vec3{-FLT_MAX};
for (const auto& corner : geometry->corners) {
aabbMin = min(aabbMin, vec3(modelMatrix * vec4(corner, 1.0f)));
aabbMax = max(aabbMax, vec3(modelMatrix * vec4(corner, 1.0f)));
}
centroid = aabbMin + 0.5f * (aabbMax - aabbMin);
}
void Mesh::setPosition(vec3 t) {
translation = t;
update();
}
void Mesh::setRotationX(float angle) {
rotation.x = angle;
update();
}
void Mesh::setRotationY(float angle) {
rotation.y = angle;
update();
}
void Mesh::setRotationZ(float angle) {
rotation.z = angle;
update();
}
void Mesh::setScale(float scale) {
this->scale = scale;
update();
}
void Mesh::centerGeometry() {
translation = -geometry->centroid;
update();
}
vec3 Mesh::getMin() const {
return aabbMin;
}
vec3 Mesh::getMax() const {
return aabbMax;
}
GPUMesh::GPUMesh(const Mesh& mesh, GPUGeometry* geometry, GPUMaterial* material) : invModelMatrix{mesh.invModelMatrix},
normalMatrix{mesh.normalMatrix},
geometry{geometry},
material{material} {}