-
Notifications
You must be signed in to change notification settings - Fork 0
/
Geometry.cpp
111 lines (88 loc) · 3.18 KB
/
Geometry.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "Geometry.h"
#include "Window.h"
#include <algorithm>
#include <fstream>
#include <sstream>
#include <iostream>
#include <glm/gtx/transform.hpp>
#include <glm/ext.hpp>
Geometry::Geometry(MeshBank::refID dataID, std::shared_ptr<Shader> shader)
: shader{std::move(shader)}, dataID{dataID},
data{MeshBank::I()->get(dataID)}, boundObj{Window::I().BoundShader()} {
float minX, minY, minZ;
float maxX, maxY, maxZ;
minX = minY = minZ = std::numeric_limits<float>::max();
maxX = maxY = maxZ = std::numeric_limits<float>::min();
for (auto &element : data) {
minX = std::min(minX, element.min.x);
minY = std::min(minY, element.min.y);
minZ = std::min(minZ, element.min.z);
maxX = std::max(maxX, element.max.x);
maxY = std::max(maxY, element.max.y);
maxZ = std::max(maxZ, element.max.z);
}
glm::vec3 min{minX, minY, minZ};
glm::vec3 max{maxX, maxY, maxZ};
Bound bound{min, max};
boundObj.setBound(bound);
glm::vec3 center = (max + min) / 2.0f;
glm::mat4 T = glm::translate(-center);
glm::vec3 rangeVec = (max - min) / 2.0f;
float range = std::max({rangeVec.x, rangeVec.y, rangeVec.z});
glm::mat4 S = glm::scale((1.0f / range) * glm::vec3{1.0f});
base = S * T;
}
void Geometry::draw(const glm::mat4 &parent,
const glm::mat4 &view,
const glm::mat4 &projection) {
shader->use();
shader->put("model", parent * base);
shader->put("view", view);
shader->put("projection", projection);
shader->put("cameraPos", Window::I().CameraPos());
for (auto &element: data) {
glBindVertexArray(element.VAO);
put(element.material);
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(element.vertices.size()));
glBindVertexArray(0);
}
boundObj.draw(parent * base, view, projection);
}
void Geometry::update(std::chrono::milliseconds delta) {
}
std::list<Node *> Geometry::hit(const Ray &ray) {
return std::list<Node *>{};
}
void Geometry::put(const std::shared_ptr<const Material> &material) {
shader->put("material.ambient", material->ka);
shader->put("material.diffuse", material->kd);
shader->put("material.specular", material->ks);
shader->put("material.shiny", material->shiny);
shader->put("material.hasKaMap", material->hasKaMap);
shader->put("material.hasKdMap", material->hasKdMap);
shader->put("material.kaMap", (int) 0);
shader->put("material.kdMap", (int) 1);
if (material->hasKaMap) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, material->kaMap);
}
if (material->hasKdMap) {
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, material->kdMap);
}
}
Bound Geometry::getBound() const {
return boundObj.getBound();
}
std::list<Node *> Geometry::hit(const Bound &bound, const glm::mat4 &parent) {
Bound alignedBound = boundObj.getBound().align(parent * base);
// intersect in global axis
if (alignedBound.intersect(bound)) {
boundObj.setActive();
return std::list<Node *>{this};
}
else {
boundObj.setPassive();
return std::list<Node *>{};
}
}