summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-03 10:02:38 +1100
committerquou <quou@disroot.org>2025-01-03 10:04:16 +1100
commitef4fca980f59a0b258ea3a48e60a7359839a4bb0 (patch)
tree04928df6d73118300e73b76bd5ab6e0abc2c923f
parentc22b015b9184cf468781b92015e2aed03cd9721a (diff)
orbit camera
-rw-r--r--c2.cpp90
-rw-r--r--model.cpp2
2 files changed, 77 insertions, 15 deletions
diff --git a/c2.cpp b/c2.cpp
index d7b475e..e721190 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -91,6 +91,71 @@ static Sampler_Id create_clamped_linear(Device* dev) {
return dev->create_sampler("repeated linear", s);
}
+struct Orbit_Cam : public Camera {
+ bool first_frame;
+ v3f target;
+ int px, py;
+ int pscroll;
+ float yrot = 0.0f;
+ static constexpr float sense = 5.0f;
+ static constexpr float min_dist = 0.3f;
+
+ void init() {
+ pscroll = 0;
+ first_frame = true;
+ target = v3f(0.0f);
+ position = v3f(0.0f, 0.0f, -5.0f);
+ Camera::init(
+ 90.0f,
+ v3f::normalised(target - position),
+ position
+ );
+ }
+
+ void update(const App& app) {
+ float dx = ((float)(px - app.mx) / (float)app.w) * sense;
+ float dy = ((float)(py - app.my) / (float)app.h) * sense;
+ int dscroll = pscroll - app.scrolly;
+ if (app.mjp(mbtn_middle) || app.mjp(mbtn_right))
+ dx = dy = 0.0f;
+ if (app.mp(mbtn_middle)) {
+ v3f left = v3f::cross(forward, v3f(0.0f, 1.0f, 0.0f));
+ v3f up = v3f::cross(forward, left);
+ float dist = v3f::mag(position - target);
+ position += left * v3f(dx) * dist;
+ position += up * v3f(dy) * dist;
+ target = position + forward * dist;
+ forward = v3f::normalised(target - position);
+ }
+ if (app.mp(mbtn_right)) {
+ m4f rotation = m4f::rotate(
+ m4f::identity(),
+ forward.z < 0.0f? (float)dy: (float)-dy,
+ v3f(1.0f, 0.0f, 0.0f)
+ ) * m4f::rotate(
+ m4f::identity(),
+ (float)dx,
+ v3f(0.0f, 1.0f, 0.0f)
+ );
+ v4f pos = v4f(position - target, 0.0f);
+ yrot += dy;
+ pos = rotation * pos;
+ position = target + v3f(pos.x, pos.y, pos.z);
+ forward = v3f::normalised(target - position);
+ }
+ if (dscroll) {
+ v3f zp = position - forward * (float)dscroll;
+ float dist = v3f::mag(zp - target);
+ if (dist < min_dist || v3f::dot(forward, zp - target) > 0.0f)
+ zp = target - forward * min_dist;
+ position = zp;
+ }
+ px = app.mx;
+ py = app.my;
+ pscroll = app.scrolly;
+ }
+};
+
struct Config_Buffer {
float offset[2];
};
@@ -112,7 +177,7 @@ extern "C" int entrypoint() {
Texture_Id default_texture;
Model_Instance* monkey, * monkey2;
Model_Scene scene;
- Camera camera;
+ Orbit_Cam camera;
Buffer_Id vbo, cbuf;
Sampler_Id clamped_linear;
C2* app = App::create<C2>("c2");
@@ -176,11 +241,7 @@ extern "C" int entrypoint() {
dev,
(Model*)assets.load("monkey.mdl")
);
- camera.init(
- 90.0f,
- v3f(0.0f, 0.0f, 1.0f),
- v3f(0.0f, 0.0f, 0.0f)
- );
+ camera.init();
while (app->running) {
Arena frame_arena;
init_arena(&frame_arena, per_frame, per_frame_memory_size);
@@ -254,23 +315,24 @@ extern "C" int entrypoint() {
Render_Pass& pass2 = pb.build_rp();
Texture& bb = dev->get_texture(dev->get_backbuffer());
- monkey->transform = (m4f::translate(
+ monkey->transform = m4f::translate(
m4f::identity(),
- v3f(0.0f, 0.0f, -5.0f)
- ) * m4f::rotate(
+ v3f(0.0f, 0.0f, 0.0f)
+ )/* * m4f::rotate(
m4f::identity(),
rot,
raxis
- ));
- monkey2->transform = (m4f::translate(
+ )*/;
+ monkey2->transform = m4f::translate(
m4f::identity(),
- v3f(2.0f, 0.0f, -7.0f)
- ) * m4f::rotate(
+ v3f(2.0f, 0.0f, 2.0f)
+ )/* * m4f::rotate(
m4f::identity(),
rot * 2.0f,
v3f(1.0f, 0.0f, 0.0f)
- ));
+ )*/;
camera.asp = (float)bb.w / (float)bb.h;
+ camera.update(*app);
scene.update(camera, dev);
ctx.debug_push("scene");
ctx.debug_push("depth prepass");
diff --git a/model.cpp b/model.cpp
index 0b1dee7..4c5edcc 100644
--- a/model.cpp
+++ b/model.cpp
@@ -304,7 +304,7 @@ void Model_Instance::update_cbuffers(
0,
c * sizeof *mats
);
- m4f view_projection = cam.get_proj();
+ m4f view_projection = cam.get_proj() * cam.get_view();
for (i = 0; i < c; i++) {
Mat_Cbuffer& mat = mats[i];
Material& sm = *meshes[i].material;