From 82984e1a5a79e93735a37515115457a3db03d101 Mon Sep 17 00:00:00 2001 From: zongor Date: Thu, 24 Jul 2025 14:45:32 -0400 Subject: [PATCH] add camera controls --- src/camera.h | 4 +++- src/main.cpp | 38 +++++++++++++++++++++++++++++++++++-- src/simulation.cpp | 47 ++++++++++++---------------------------------- src/simulation.h | 4 ++-- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/camera.h b/src/camera.h index 0baa326..cde4b3d 100644 --- a/src/camera.h +++ b/src/camera.h @@ -26,8 +26,10 @@ public: void move_to(Point3 loc) { center = loc; } + Point3 position() { return center; } + private: - int image_height; // Rendered image height + int image_height; // Rendered image height Point3 center = Point3(0, 0, 0); Point3 pixel00_loc; // Location of pixel 0, 0 Vec3 pixel_delta_u; // Offset to pixel to the right diff --git a/src/main.cpp b/src/main.cpp index 2f5752e..96d33d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "camera.h" #include "canvas.h" #include "simulation.h" #include @@ -14,9 +15,14 @@ int main() { Canvas canvas(image_width, image_height); RingBuffer buffer(64); + Camera cam; + cam.aspect_ratio = 16.0 / 9.0; + cam.image_width = 400; + cam.move_to(Point3(0, 10, 100)); std::thread sim(simulation_thread, std::ref(buffer)); - std::thread render(render_thread, std::ref(buffer), std::ref(canvas)); + std::thread render(render_thread, std::ref(buffer), std::ref(canvas), + std::ref(cam)); SDL_Init(SDL_INIT_VIDEO); int scale = 3; @@ -32,6 +38,8 @@ int main() { SDL_TEXTUREACCESS_STREAMING, canvas.width, canvas.height); + float camera_speed = 10.0f; // tweak as needed + while (running) { void *pixels; int pitch; @@ -44,10 +52,36 @@ int main() { SDL_RenderCopy(renderer, texture, nullptr, &dest); SDL_RenderPresent(renderer); + Point3 move(0, 0, 0); + SDL_Event e; while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) + if (e.type == SDL_QUIT) { running = false; + } else if (e.type == SDL_KEYDOWN) { + switch (e.key.keysym.sym) { + case SDLK_w: + move.z() -= camera_speed; + break; // forward + case SDLK_s: + move.z() += camera_speed; + break; // backward + case SDLK_a: + move.x() -= camera_speed; + break; // left + case SDLK_d: + move.x() += camera_speed; + break; // right + case SDLK_q: + move.y() += camera_speed; + break; // up + case SDLK_e: + move.y() -= camera_speed; + break; // down + } + + cam.move_to(cam.position() + move); // assuming cam.position exists + } } std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60fps diff --git a/src/simulation.cpp b/src/simulation.cpp index ea00bed..a82cfa1 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -64,47 +64,29 @@ void simulation_thread(RingBuffer &buffer) { size_t n_bodies = state.bodies.size(); for (size_t m1_idx = 0; m1_idx < n_bodies; m1_idx++) { - Vec3 a_g = {0, 0, 0}; + Vec3 a_g; for (size_t m2_idx = 0; m2_idx < n_bodies; m2_idx++) { if (m2_idx != m1_idx) { - Vec3 r_vector; + Vec3 r_vector = + state.bodies[m1_idx].position - state.bodies[m2_idx].position; + double r_mag = r_vector.length(); - r_vector.x() = state.bodies[m1_idx].position.x() - - state.bodies[m2_idx].position.x(); - r_vector.y() = state.bodies[m1_idx].position.y() - - state.bodies[m2_idx].position.y(); - r_vector.z() = state.bodies[m1_idx].position.z() - - state.bodies[m2_idx].position.z(); + double acceleration = + -BIG_G * state.bodies[m2_idx].mass / (r_mag * r_mag); - float r_mag = - sqrt(r_vector.x() * r_vector.x() + r_vector.y() * r_vector.y() + - r_vector.z() * r_vector.z()); + Vec3 r_unit_vector = r_vector / r_mag; - float acceleration = - -1.0 * BIG_G * (state.bodies[m2_idx].mass) / pow(r_mag, 2.0); - - Vec3 r_unit_vector = {r_vector.x() / r_mag, r_vector.y() / r_mag, - r_vector.z() / r_mag}; - - a_g.x() += acceleration * r_unit_vector.x(); - a_g.y() += acceleration * r_unit_vector.y(); - a_g.z() += acceleration * r_unit_vector.z(); + a_g += r_unit_vector * acceleration; } } - state.bodies[m1_idx].velocity.x() += a_g.x() * bdt; - state.bodies[m1_idx].velocity.y() += a_g.y() * bdt; - state.bodies[m1_idx].velocity.z() += a_g.z() * bdt; + state.bodies[m1_idx].velocity += a_g * bdt; } for (size_t entity_idx = 0; entity_idx < n_bodies; entity_idx++) { - state.bodies[entity_idx].position.x() += - state.bodies[entity_idx].velocity.x() * bdt; - state.bodies[entity_idx].position.y() += - state.bodies[entity_idx].velocity.y() * bdt; - state.bodies[entity_idx].position.z() += - state.bodies[entity_idx].velocity.z() * bdt; + state.bodies[entity_idx].position += + state.bodies[entity_idx].velocity * bdt; } // Try to push it into the buffer @@ -124,12 +106,7 @@ void simulation_thread(RingBuffer &buffer) { /** * Render thread. */ -void render_thread(RingBuffer &buffer, Canvas &canvas) { - Camera cam; - cam.aspect_ratio = 16.0 / 9.0; - cam.image_width = 400; - cam.move_to(Point3(0, 10, 100)); - +void render_thread(RingBuffer &buffer, Canvas &canvas, Camera &cam) { while (running) { auto maybe_state = buffer.pop(); if (maybe_state.has_value()) { diff --git a/src/simulation.h b/src/simulation.h index 048bc49..a05412b 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -2,8 +2,8 @@ #define SIMULATION_H #include "canvas.h" +#include "camera.h" #include "ring_buffer.h" -#include "vec3.h" #include #include #include @@ -25,6 +25,6 @@ struct SimulationState { extern std::atomic running; void simulation_thread(RingBuffer &buffer); -void render_thread(RingBuffer &buffer, Canvas &canvas); +void render_thread(RingBuffer &buffer, Canvas &canvas, Camera &cam); #endif