add camera controls

This commit is contained in:
zongor 2025-07-24 14:45:32 -04:00
parent 4198468b4a
commit 82984e1a5a
4 changed files with 53 additions and 40 deletions

View File

@ -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

View File

@ -1,3 +1,4 @@
#include "camera.h"
#include "canvas.h"
#include "simulation.h"
#include <SDL2/SDL.h>
@ -14,9 +15,14 @@ int main() {
Canvas canvas(image_width, image_height);
RingBuffer<SimulationState> 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

View File

@ -64,47 +64,29 @@ void simulation_thread(RingBuffer<SimulationState> &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<SimulationState> &buffer) {
/**
* Render thread.
*/
void render_thread(RingBuffer<SimulationState> &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<SimulationState> &buffer, Canvas &canvas, Camera &cam) {
while (running) {
auto maybe_state = buffer.pop();
if (maybe_state.has_value()) {

View File

@ -2,8 +2,8 @@
#define SIMULATION_H
#include "canvas.h"
#include "camera.h"
#include "ring_buffer.h"
#include "vec3.h"
#include <atomic>
#include <memory>
#include <mutex>
@ -25,6 +25,6 @@ struct SimulationState {
extern std::atomic<bool> running;
void simulation_thread(RingBuffer<SimulationState> &buffer);
void render_thread(RingBuffer<SimulationState> &buffer, Canvas &canvas);
void render_thread(RingBuffer<SimulationState> &buffer, Canvas &canvas, Camera &cam);
#endif