Files
lity3d/Engine/Rendering/camera.c
T
shuiyu1123 7a0533d21a sync: user's Lity3D_source.zip changes
- Engine core: improved initialization and lifecycle
- Renderer: camera and rendering pipeline updates
- Editor: updated editor code
- Window: improved window handling
- Demo/main.c: scene demo with AssetManager + scene loading
- build.bat: updated build script
- 11 files modified from user's manual edits
2026-07-12 12:13:50 +08:00

136 lines
3.8 KiB
C

#include "camera.h"
#include <math.h>
#include <string.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
Camera camera_perspective(float fov_y, float aspect, float near_z, float far_z) {
Camera cam = {0};
cam.type = CAMERA_PERSPECTIVE;
cam.position = (Vec3){0, 0, -5};
cam.target = (Vec3){0, 0, 0};
cam.up = (Vec3){0, 1, 0};
cam.fov_y = fov_y;
cam.aspect = aspect;
cam.near_z = near_z;
cam.far_z = far_z;
cam.dirty = 1;
return cam;
}
Camera camera_orthographic(float width, float height, float near_z, float far_z) {
Camera cam = {0};
cam.type = CAMERA_ORTHOGRAPHIC;
cam.position = (Vec3){0, 0, -5};
cam.target = (Vec3){0, 0, 0};
cam.up = (Vec3){0, 1, 0};
cam.ortho_width = width;
cam.ortho_height = height;
cam.near_z = near_z;
cam.far_z = far_z;
cam.dirty = 1;
return cam;
}
void camera_update(Camera* camera) {
if (!camera->dirty) return;
mat4_lookat(&camera->position, &camera->target, &camera->up, &camera->view);
if (camera->type == CAMERA_PERSPECTIVE) {
mat4_perspective(camera->fov_y, camera->aspect, camera->near_z, camera->far_z, &camera->projection);
} else {
mat4_orthographic(camera->ortho_width, camera->ortho_height, camera->near_z, camera->far_z, &camera->projection);
}
camera->dirty = 0;
}
const Mat4* camera_get_view(Camera* camera) {
camera_update(camera);
return &camera->view;
}
const Mat4* camera_get_projection(Camera* camera) {
camera_update(camera);
return &camera->projection;
}
void camera_move_forward(Camera* camera, float distance) {
Vec3 dir;
vec3_sub(&camera->target, &camera->position, &dir);
vec3_normalize(&dir, &dir);
Vec3 move;
vec3_scale(&dir, distance, &move);
vec3_add(&camera->position, &move, &camera->position);
vec3_add(&camera->target, &move, &camera->target);
camera->dirty = 1;
}
void camera_move_right(Camera* camera, float distance) {
Vec3 forward, right;
vec3_sub(&camera->target, &camera->position, &forward);
vec3_normalize(&forward, &forward);
vec3_cross(&camera->up, &forward, &right);
vec3_normalize(&right, &right);
Vec3 move;
vec3_scale(&right, distance, &move);
vec3_add(&camera->position, &move, &camera->position);
vec3_add(&camera->target, &move, &camera->target);
camera->dirty = 1;
}
void camera_move_up(Camera* camera, float distance) {
Vec3 move;
vec3_scale(&camera->up, distance, &move);
vec3_add(&camera->position, &move, &camera->position);
vec3_add(&camera->target, &move, &camera->target);
camera->dirty = 1;
}
void camera_rotate_yaw(Camera* camera, float angle) {
Vec3 forward;
vec3_sub(&camera->target, &camera->position, &forward);
float cs = cosf(angle), sn = sinf(angle);
Vec3 right;
vec3_cross(&forward, &camera->up, &right);
vec3_normalize(&right, &right);
Vec3 new_forward = {
forward.x * cs + right.x * sn,
forward.y * cs + right.y * sn,
forward.z * cs + right.z * sn,
};
vec3_add(&camera->position, &new_forward, &camera->target);
camera->dirty = 1;
}
void camera_rotate_pitch(Camera* camera, float angle) {
Vec3 forward;
vec3_sub(&camera->target, &camera->position, &forward);
Vec3 right;
vec3_cross(&forward, &camera->up, &right);
vec3_normalize(&right, &right);
float cs = cosf(angle), sn = sinf(angle);
Vec3 new_forward = {
forward.x * cs + camera->up.x * sn,
forward.y * cs + camera->up.y * sn,
forward.z * cs + camera->up.z * sn,
};
Vec3 new_up;
vec3_cross(&right, &new_forward, &new_up);
camera->up = new_up;
vec3_add(&camera->position, &new_forward, &camera->target);
camera->dirty = 1;
}
void camera_look_at(Camera* camera, Vec3 target) {
camera->target = target;
camera->dirty = 1;
}