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
|
#include "camera.hpp"
#include "model.hpp"
#include "scene.hpp"
void update_scene(
Model_Scene& ms,
Device* dev,
World& w
) {
for (auto v : w.view<Transform, C_Model>()) {
auto& t = v.get<Transform>();
auto& m = v.get<C_Model>();
m.i->transform = t.mat;
}
ms.update(dev);
}
std::pair<Entity_Id, int> scene_pick(
World& world,
const Camera& cam,
int w,
int h,
int mx,
int my
) {
v2f uv = (2.0f * v2f(mx, my) - v2f(w, h)) / (float)h;
v4f e =
cam.get_proj().inverse() *
v4f(uv.x, uv.y, -1.0f, 1.0f);
e.z = -1.0f; e.w = 0.0f;
v4f d4 = cam.get_view().inverse() * e;
v3f d = v3f::normalised(v3f(d4.x, d4.y, d4.z));
const v3f& o = cam.position;
float t = INFINITY;
Entity_Id r1 = 0;
int r2 = -1;
for (auto v : world.view<C_Model>()) {
Model_Instance& inst = *v.get<C_Model>().i;
Model* m = inst.m;
int j;
for (j = 0; j < m->mesh_count; j++) {
AABB& b = inst.bounds[j];
v3f id = 1.0f / d;
v3f t1 = (b.min - o) * id;
v3f t2 = (b.max - o) * id;
float tmin = std::max(std::max(
std::min(t1.x, t2.x),
std::min(t1.y, t2.y)),
std::min(t1.z, t2.z)
);
float tmax = std::min(std::min(
std::max(t1.x, t2.x),
std::max(t1.y, t2.y)),
std::max(t1.z, t2.z)
);
if (tmax < 0.0f || tmin > tmax)
continue;
if (tmin < t) {
t = tmin;
r1 = v.entity();
r2 = j;
}
}
}
return { r1, r2 };
}
|