diff options
author | quou <quou@disroot.org> | 2025-01-03 10:02:38 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-03 10:04:16 +1100 |
commit | ef4fca980f59a0b258ea3a48e60a7359839a4bb0 (patch) | |
tree | 04928df6d73118300e73b76bd5ab6e0abc2c923f | |
parent | c22b015b9184cf468781b92015e2aed03cd9721a (diff) |
orbit camera
-rw-r--r-- | c2.cpp | 90 | ||||
-rw-r--r-- | model.cpp | 2 |
2 files changed, 77 insertions, 15 deletions
@@ -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"); @@ -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; |