twn_draw.h: new camera api

This commit is contained in:
veclavtalica 2024-10-28 12:34:48 +03:00
parent 1d35a3859b
commit d11143ac86
7 changed files with 73 additions and 41 deletions

View File

@ -24,40 +24,34 @@ static void ingame_tick(State *state) {
input_bind_action_control("mouse_capture_toggle", CONTROL_ESCAPE);
if (scn->mouse_captured) {
const float sensitivity = 0.6f; /* TODO: put this in a better place */
const float sensitivity = 0.4f * (float)DEG2RAD; /* TODO: put this in a better place */
scn->yaw += (float)ctx.mouse_movement.x * sensitivity;
scn->pitch -= (float)ctx.mouse_movement.y * sensitivity;
scn->pitch = clampf(scn->pitch, -89.0f, 89.0f);
const float yaw_rad = scn->yaw * (float)DEG2RAD;
const float pitch_rad = scn->pitch * (float)DEG2RAD;
scn->cam.target = m_vec_norm(((Vec3){
cosf(yaw_rad) * cosf(pitch_rad),
sinf(pitch_rad),
sinf(yaw_rad) * cosf(pitch_rad)
}));
scn->pitch = clampf(scn->pitch, (float)-M_PI * 0.49f, (float)M_PI * 0.49f);
}
const Vec3 right = m_vec_norm(m_vec_cross(scn->cam.target, scn->cam.up));
DrawCameraFromPrincipalAxesResult dir_and_up =
draw_camera_from_principal_axes(scn->pos, (float)M_PI_2, scn->roll, scn->pitch, scn->yaw);
const Vec3 right = m_vec_norm(m_vec_cross(dir_and_up.direction, dir_and_up.up));
const float speed = 0.04f; /* TODO: put this in a better place */
if (input_is_action_pressed("player_left"))
scn->cam.pos = vec3_sub(scn->cam.pos, m_vec_scale(right, speed));
scn->pos = vec3_sub(scn->pos, m_vec_scale(right, speed));
if (input_is_action_pressed("player_right"))
scn->cam.pos = vec3_add(scn->cam.pos, m_vec_scale(right, speed));
scn->pos = vec3_add(scn->pos, m_vec_scale(right, speed));
if (input_is_action_pressed("player_forward"))
scn->cam.pos = vec3_add(scn->cam.pos, m_vec_scale(scn->cam.target, speed));
scn->pos = vec3_add(scn->pos, m_vec_scale(dir_and_up.direction, speed));
if (input_is_action_pressed("player_backward"))
scn->cam.pos = vec3_sub(scn->cam.pos, m_vec_scale(scn->cam.target, speed));
scn->pos = vec3_sub(scn->pos, m_vec_scale(dir_and_up.direction, speed));
if (input_is_action_pressed("player_jump"))
scn->cam.pos.y += speed;
scn->pos.y += speed;
if (input_is_action_pressed("player_run"))
scn->cam.pos.y -= speed;
scn->pos.y -= speed;
/* toggle mouse capture with end key */
if (input_is_action_just_pressed("mouse_capture_toggle"))
@ -65,14 +59,12 @@ static void ingame_tick(State *state) {
input_set_mouse_captured(scn->mouse_captured);
draw_camera(&scn->cam);
#define TERRAIN_FREQUENCY 0.1f
for (int ly = 64; ly--;) {
for (int lx = 64; lx--;) {
float x = SDL_truncf(scn->cam.pos.x + 32 - (float)lx);
float y = SDL_truncf(scn->cam.pos.z + 32 - (float)ly);
float x = SDL_truncf(scn->pos.x + 32 - (float)lx);
float y = SDL_truncf(scn->pos.z + 32 - (float)ly);
float d0 = stb_perlin_noise3((float)x * TERRAIN_FREQUENCY, (float)y * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 3 - 6;
float d1 = stb_perlin_noise3((float)(x + 1) * TERRAIN_FREQUENCY, (float)y * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 3 - 6;
@ -114,7 +106,6 @@ Scene *ingame_scene(State *state) {
new_scene->base.tick = ingame_tick;
new_scene->base.end = ingame_end;
new_scene->cam = (Camera){ .pos = { 32, 0, 1 }, .up = { 0, 1, 0 }, .fov = (float)M_PI_2 };
new_scene->mouse_captured = true;
m_audio(m_set(path, "music/mod65.xm"),

View File

@ -12,9 +12,7 @@
typedef struct SceneIngame {
Scene base;
Camera cam;
/* TODO: put this in a better place */
Vec3 pos;
float yaw;
float pitch;
float roll;

View File

@ -3,7 +3,6 @@
#include "twn_types.h"
#include "twn_option.h"
#include "twn_camera.h"
#include "twn_engine_api.h"
#include <stdbool.h>
@ -76,8 +75,21 @@ TWN_API void draw_triangle(char const *path,
// Vec2 scaling,
// Rect uvs);
/* pushes a camera state to be used for all future unfurl_* commands */
TWN_API void draw_camera(const Camera *camera);
/* sets a perspective 3d camera to be used for all 3d commands */
TWN_API void draw_camera(Vec3 position, float fov, Vec3 up, Vec3 direction);
/* same as draw_camera(), but with specific use case */
/* direction and up vectors are inferred from roll, pitch and yaw parameters (in radians) */
/* return value is direction and up vectors, so that you can use them in logic (such as controllers) */
typedef struct DrawCameraFromPrincipalAxesResult {
Vec3 direction;
Vec3 up;
} DrawCameraFromPrincipalAxesResult;
DrawCameraFromPrincipalAxesResult TWN_API draw_camera_from_principal_axes(Vec3 position,
float fov,
float roll,
float pitch,
float yaw);
/* expects '*' masks that will be expanded to 6 names: 'up', 'down', 'east', 'west', 'north' and 'south' */
TWN_API void draw_skybox(const char *paths);

View File

@ -1,8 +1,9 @@
#include "twn_draw_c.h"
#include "twn_draw.h"
#include "twn_engine_context_c.h"
#include "twn_camera.h"
#include "twn_camera_c.h"
#include "twn_types.h"
#include "twn_vec.h"
#include <SDL2/SDL.h>
#include <stb_ds.h>
@ -382,8 +383,39 @@ void render(void) {
}
void draw_camera(const Camera *const camera) {
/* TODO: skip recaulculating if it's the same? */
camera_projection_matrix = camera_perspective(camera);
camera_look_at_matrix = camera_look_at(camera);
void draw_camera(Vec3 position, float fov, Vec3 up, Vec3 direction) {
Camera const camera = {
.fov = fov,
.pos = position,
.target = direction,
.up = up,
};
camera_projection_matrix = camera_perspective(&camera);
camera_look_at_matrix = camera_look_at(&camera);
}
/* TODO: https://stackoverflow.com/questions/62493770/how-to-add-roll-in-camera-class */
DrawCameraFromPrincipalAxesResult draw_camera_from_principal_axes(Vec3 position, float fov, float roll, float pitch, float yaw) {
(void)roll;
float yawc, yaws, pitchc, pitchs;
sincosf(yaw, &yaws, &yawc);
sincosf(pitch, &pitchs, &pitchc);
Camera const camera = {
.fov = fov,
.pos = position,
.target = m_vec_norm(((Vec3){
yawc * pitchc,
pitchs,
yaws * pitchc,
})),
.up = (Vec3){0, 1, 0},
};
camera_projection_matrix = camera_perspective(&camera);
camera_look_at_matrix = camera_look_at(&camera);
return (DrawCameraFromPrincipalAxesResult) {
.direction = camera.target,
.up = camera.up,
};
}

View File

@ -1,4 +1,4 @@
#include "twn_camera.h"
#include "twn_camera_c.h"
#include "twn_vec.h"
#include "twn_engine_context_c.h"

View File

@ -2,7 +2,6 @@
#define TWN_CAMERA_H
#include "twn_types.h"
#include "twn_engine_api.h"
/* TODO: make it cached? */
/* for example, perspective matrix only needs recaluclation on FOV change */
@ -15,8 +14,8 @@ typedef struct Camera {
float fov; /* field of view, in radians */
} Camera;
TWN_API Matrix4 camera_look_at(const Camera *camera);
Matrix4 camera_look_at(const Camera *camera);
TWN_API Matrix4 camera_perspective(const Camera *const camera);
Matrix4 camera_perspective(const Camera *const camera);
#endif