summaryrefslogtreecommitdiff
path: root/model.cpp
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-13 20:56:13 +1100
committerquou <quou@disroot.org>2025-01-13 20:56:13 +1100
commit014077c89bb3c50718d56430f387109ad43508b6 (patch)
tree02fa1ab03218fc22de4d875b7d8d593cbc19d67c /model.cpp
parent4d5cdc97a044a39fabbfb980b2e48a817a6e485f (diff)
basic picking and debug rendering
Diffstat (limited to 'model.cpp')
-rw-r--r--model.cpp78
1 files changed, 71 insertions, 7 deletions
diff --git a/model.cpp b/model.cpp
index 9e78b19..03a24e0 100644
--- a/model.cpp
+++ b/model.cpp
@@ -9,6 +9,8 @@ extern "C" {
}
#include <string.h>
+#include <stdio.h>
+#include <algorithm>
struct MVP_Cbuffer {
m4f model;
@@ -273,7 +275,7 @@ m4f Camera::get_proj() const {
return m4f::pers(fov, asp, near, far);
}
-void Model_Instance::init(Device* dev, Model* model) {
+void Model_Instance::init(Device* dev, Heap* h, Model* model) {
m = model;
mvp = dev->create_buffer(
"Model instance MVP",
@@ -287,11 +289,26 @@ void Model_Instance::init(Device* dev, Model* model) {
Buffer_Flags::constant_buffer |
Buffer_Flags::cpu_readwrite
);
+ bounds = (AABB*)heap_alloc(
+ h,
+ sizeof *bounds * model->mesh_count
+ );
}
-void Model_Instance::destroy(Device* dev) {
+void Model_Instance::destroy(Device* dev, Heap* h) {
dev->destroy_buffer(mat);
dev->destroy_buffer(mvp);
+ heap_free(h, bounds);
+}
+
+void Model_Instance::update() {
+ Mesh* meshes = m->get_meshes();
+ int i, c = m->mesh_count;
+ for (i = 0; i < c; i++)
+ bounds[i] = m4f::transform(
+ transform * meshes[i].world,
+ meshes[i].bound
+ );
}
void Model_Instance::update_cbuffers(
@@ -400,12 +417,34 @@ void Model_Instance::render(
}
}
+int Model_Instance::pick(const v3f& o, const v3f& d) {
+ int i, c = m->mesh_count;
+ for (i = 0; i < c; i++) {
+ AABB& b = bounds[i];
+ 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;
+ }
+ return i;
+ }
+ return -1;
+}
+
void Model_Scene::init(
Arena* arena,
int max_instances,
Sampler_Id s
) {
- instances = (Model_Instance*)arena_alloc(arena, max_instances);
+ int hs;
+ h = (Heap*)arena_alloc(arena, sizeof *h);
+ hs = arena->size - arena->ptr - allocation_default_alignment - 1;
+ init_heap(h, arena_alloc(arena, hs), hs);
+ instances = (Model_Instance*)heap_alloc(h, max_instances);
count = 0;
max = max_instances;
sampler = s;
@@ -417,7 +456,7 @@ Model_Instance* Model_Scene::instantiate(
) {
Model_Instance* instance = &instances[count++];
assert(count <= max);
- instance->init(dev, model);
+ instance->init(dev, h, model);
return instance;
}
@@ -427,7 +466,7 @@ void Model_Scene::uninstantiate(
) {
int idx = model - instances;
int last = count - 1;
- model->destroy(dev);
+ model->destroy(dev, h);
instances[idx] = instances[last];
count = last;
}
@@ -435,8 +474,10 @@ void Model_Scene::uninstantiate(
void Model_Scene::update(const Camera& cam, Device* dev) {
int i;
Model_Instance* instance = instances;
- for (i = 0; i < count; i++, instance++)
+ for (i = 0; i < count; i++, instance++) {
+ instance->update();
instance->update_cbuffers(dev, cam);
+ }
}
void Model_Scene::render(
@@ -456,5 +497,28 @@ void Model_Scene::destroy(Device* dev) {
int i;
Model_Instance* instance = instances;
for (i = 0; i < count; i++, instance++)
- instance->destroy(dev);
+ instance->destroy(dev, h);
+}
+
+std::pair<Model_Instance*, int> Model_Scene::pick(
+ const Camera& cam,
+ int w,
+ int h,
+ int mx,
+ int my
+) {
+ int i, c = count;
+ 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));
+ for (i = 0; i < c; i++) {
+ int m = instances[i].pick(cam.position, d);
+ if (m >= 0) return { &instances[i], m };
+ }
+ return { 0, -1 };
}
+