strichmaennchen git · main
git clone https://git.christianimmanuel.de/games/strichmaennchen.gitwget https://git.christianimmanuel.de/games/strichmaennchen/archive/strichmaennchen.tar.gzcamera.c raw
#include "camera.h"
#include "human.h"
#include "renderer.h"
#include <math.h>
#define M_PI 3.14159265358979323846
#define DEG2RAD(x) ((x) * (3.14159265358979323846f / 180.0f))
float cosf(float x);
float sinf(float x);
float sqrtf(float x);
void Camera_init(Camera* cam, Vec3 position, float yaw, float pitch, float fov) {
cam->position = position;
cam->yaw = yaw;
cam->pitch = pitch;
cam->up = vec3(0.0f, 1.0f, 0.0f);
cam->fov = fov;
// calculate initial front
Vec3 front;
front.x = cosf(DEG2RAD(yaw)) * cosf(DEG2RAD(pitch));
front.y = sinf(DEG2RAD(pitch));
front.z = sinf(DEG2RAD(yaw)) * cosf(DEG2RAD(pitch));
float len = sqrtf(front.x*front.x + front.y*front.y + front.z*front.z);
cam->front.x = front.x / len;
cam->front.y = front.y / len;
cam->front.z = front.z / len;
}
void Camera_rotate(Camera* cam, float yaw_delta, float pitch_delta) {
cam->yaw += yaw_delta;
cam->pitch += pitch_delta;
if (cam->pitch > 89.0f) cam->pitch = 89.0f;
if (cam->pitch < -89.0f) cam->pitch = -89.0f;
}
void Camera_update(Camera* cam, Renderer* renderer) {
// Compute front vector
Vec3 front;
front.x = cosf(DEG2RAD(cam->yaw)) * cosf(DEG2RAD(cam->pitch));
front.y = sinf(DEG2RAD(cam->pitch));
front.z = sinf(DEG2RAD(cam->yaw)) * cosf(DEG2RAD(cam->pitch));
// Normalize
float len = sqrtf(front.x*front.x + front.y*front.y + front.z*front.z);
cam->front.x = front.x / len;
cam->front.y = front.y / len;
cam->front.z = front.z / len;
// Recompute right and up
Vec3 world_up = {0,1,0};
cam->right = vec3_normalize(vec3_cross(cam->front, world_up));
cam->up = vec3_normalize(vec3_cross(cam->right, cam->front));
cam->projection = mat4_perspective(cam->fov,
(float)renderer->width / renderer->height,
0.1f, 100.0f);
cam->view = mat4_lookAt(cam->position,
vec3_add(cam->position, cam->front),
cam->up);
}
void Camera_move(Camera* cam, Userinput* input, float dt) {
// Flattened forward for walking
Vec3 flatFront = cam->front;
flatFront.y = 0.0f;
flatFront = vec3_normalize(flatFront);
Vec3 move = vec3_scale(flatFront, input->move_forward);
move = vec3_add(move, vec3_scale(cam->right, input->move_sideway));
// Normalize to prevent faster diagonal movement
float len = sqrtf(move.x*move.x + move.y*move.y + move.z*move.z);
if (len > 0.0f) move = vec3_scale(move, 1.0f / len);
float speed = 5.0f * dt;
cam->position = vec3_add(cam->position, vec3_scale(move, speed));
}
void Camera_followPlayer(Camera *cam, Human *player) {
cam->position = vec3_add(player->object->position, (Vec3){0, 1.6f, 0}); // eye height
}
Mat4 Camera_getViewMatrix(Camera* cam) {
// Simple LookAt: pos, target=pos+front, up
Vec3 target = vec3_add(cam->position, cam->front);
return mat4_lookAt(cam->position, target, cam->up);
}