summaryrefslogtreecommitdiff
path: root/scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene.cpp')
-rw-r--r--scene.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/scene.cpp b/scene.cpp
new file mode 100644
index 0000000..89f6f75
--- /dev/null
+++ b/scene.cpp
@@ -0,0 +1,67 @@
+#include "camera.hpp"
+#include "model.hpp"
+#include "scene.hpp"
+
+void update_scene(
+ Model_Scene& ms,
+ Device* dev,
+ const Camera& cam,
+ 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(cam, 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 };
+}