summaryrefslogtreecommitdiff
path: root/game/src
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-09-16 19:56:58 -0700
committer3gg <3gg@shellblade.net>2024-09-16 19:56:58 -0700
commit68ba3c0f45faa71b989b0a05fd974405a21cfd7b (patch)
tree93ee8c2605cbb7711e2827bb47f88e12d2eeb4a4 /game/src
parent420970c8b83f20a4a2411af687e9d4a38a5fe81a (diff)
Add camera control.
Diffstat (limited to 'game/src')
-rw-r--r--game/src/plugins/viewer.c113
1 files changed, 100 insertions, 13 deletions
diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c
index f621b00..5fc4be7 100644
--- a/game/src/plugins/viewer.c
+++ b/game/src/plugins/viewer.c
@@ -1,5 +1,6 @@
1#include "plugin.h" 1#include "plugin.h"
2 2
3#include <gfx/app.h>
3#include <gfx/asset.h> 4#include <gfx/asset.h>
4#include <gfx/renderer.h> 5#include <gfx/renderer.h>
5#include <gfx/scene.h> 6#include <gfx/scene.h>
@@ -27,11 +28,33 @@ static const char* BOXES =
27 28
28#define DEFAULT_SCENE_FILE GIRL 29#define DEFAULT_SCENE_FILE GIRL
29 30
30struct State { 31static const bool RenderBoundingBoxes = false;
31 Scene* scene; 32static const R DefaultCameraSpeed = (R)6.0;
32 Model* model; 33static const R DefaultMouseSensitivity = (R)(10 * TO_RAD);
33 SceneCamera* camera; 34static const vec3 DefaultCameraPosition = (vec3){0, 2, 5};
34}; 35
36typedef struct CameraCommand {
37 bool CameraMoveLeft : 1;
38 bool CameraMoveRight : 1;
39 bool CameraMoveForward : 1;
40 bool CameraMoveBackward : 1;
41} CameraCommand;
42
43typedef struct CameraController {
44 R camera_speed; // Camera movement speed.
45 R mouse_sensitivity; // Controls the degree with which mouse movements
46 // rotate the camera.
47 vec2 prev_mouse_position; // Mouse position in the previous frame.
48 bool rotating; // When true, subsequent mouse movements cause the
49 // camera to rotate.
50} CameraController;
51
52typedef struct State {
53 Scene* scene;
54 Model* model;
55 SceneCamera* camera;
56 CameraController camera_controller;
57} State;
35 58
36/// Load the skyquad texture. 59/// Load the skyquad texture.
37static const Texture* load_environment_map(Gfx* gfx) { 60static const Texture* load_environment_map(Gfx* gfx) {
@@ -131,8 +154,21 @@ bool init(Game* game, State** pp_state) {
131 if (anima) { 154 if (anima) {
132 gfx_play_animation( 155 gfx_play_animation(
133 anima, &(AnimationPlaySettings){.name = "Walk", .loop = true}); 156 anima, &(AnimationPlaySettings){.name = "Walk", .loop = true});
157 // TODO: Interpolate animations.
158 /*gfx_play_animation(
159 anima,
160 &(AnimationPlaySettings){.name = "Jumping-jack-lower", .loop = true});
161 gfx_play_animation(
162 anima, &(AnimationPlaySettings){
163 .name = "Jumping-jack-arms-mid", .loop = true});*/
134 } 164 }
135 165
166 spatial3_set_position(
167 &gfx_get_camera_camera(state->camera)->spatial, DefaultCameraPosition);
168
169 state->camera_controller.camera_speed = DefaultCameraSpeed;
170 state->camera_controller.mouse_sensitivity = DefaultMouseSensitivity;
171
136 *pp_state = state; 172 *pp_state = state;
137 return true; 173 return true;
138 174
@@ -153,19 +189,68 @@ void shutdown(Game* game, State* state) {
153 } 189 }
154} 190}
155 191
192static void update_camera(
193 CameraController* controller, R dt, vec2 mouse_position,
194 CameraCommand command, Spatial3* camera) {
195 assert(controller);
196 assert(camera);
197
198 // Translation.
199 const R move_x = (R)(command.CameraMoveLeft ? -1 : 0) +
200 (R)(command.CameraMoveRight ? 1 : 0);
201 const R move_y = (R)(command.CameraMoveForward ? 1 : 0) +
202 (R)(command.CameraMoveBackward ? -1 : 0);
203 const vec2 translation =
204 vec2_scale(vec2_make(move_x, move_y), controller->camera_speed * dt);
205 spatial3_move_right(camera, translation.x);
206 spatial3_move_forwards(camera, translation.y);
207
208 // Rotation.
209 if (controller->rotating) {
210 const vec2 mouse_delta =
211 vec2_sub(mouse_position, controller->prev_mouse_position);
212
213 const vec2 rotation =
214 vec2_scale(mouse_delta, controller->mouse_sensitivity * dt);
215
216 spatial3_global_yaw(camera, -rotation.x);
217 spatial3_pitch(camera, -rotation.y);
218 }
219
220 // Update controller state.
221 controller->prev_mouse_position = mouse_position;
222}
223
156void update(Game* game, State* state, double t, double dt) { 224void update(Game* game, State* state, double t, double dt) {
157 assert(game); 225 assert(game);
158 assert(state); 226 assert(state);
159 assert(state->scene); 227 assert(state->scene);
160 assert(state->camera); 228 assert(state->camera);
161 229
162 const vec3 orbit_point = vec3_make(0, 2, 0); 230 double mouse_x, mouse_y;
163 Camera* camera = gfx_get_camera_camera(state->camera); 231 gfx_app_get_mouse_position(&mouse_x, &mouse_y);
164 spatial3_orbit( 232 const vec2 mouse_position = {(R)mouse_x, (R)mouse_y};
165 &camera->spatial, orbit_point, 233
166 /*radius=*/5, 234 const CameraCommand camera_command = (CameraCommand){
167 /*azimuth=*/(R)(t * 0.5), /*zenith=*/0); 235 .CameraMoveLeft = gfx_app_is_key_pressed(KeyA),
168 spatial3_lookat(&camera->spatial, orbit_point); 236 .CameraMoveRight = gfx_app_is_key_pressed(KeyD),
237 .CameraMoveForward = gfx_app_is_key_pressed(KeyW),
238 .CameraMoveBackward = gfx_app_is_key_pressed(KeyS),
239 };
240
241 state->camera_controller.rotating = gfx_app_is_mouse_button_pressed(LMB);
242
243 update_camera(
244 &state->camera_controller, (R)dt, mouse_position, camera_command,
245 &gfx_get_camera_camera(state->camera)->spatial);
246
247 // const vec3 orbit_point = vec3_make(0, 2, 0);
248 // Camera* camera = gfx_get_camera_camera(state->camera);
249 // spatial3_orbit(
250 // &camera->spatial, orbit_point,
251 // /*radius=*/5,
252 // /*azimuth=*/(R)(t * 0.5), /*zenith=*/0);
253 // spatial3_lookat(&camera->spatial, orbit_point);
169 254
170 gfx_update(state->scene, state->camera, (R)t); 255 gfx_update(state->scene, state->camera, (R)t);
171} 256}
@@ -261,7 +346,9 @@ void render(const Game* game, const State* state) {
261 .scene = state->scene, 346 .scene = state->scene,
262 .camera = state->camera}); 347 .camera = state->camera});
263 348
264 render_bounding_boxes(game, state); 349 if (RenderBoundingBoxes) {
350 render_bounding_boxes(game, state);
351 }
265} 352}
266 353
267void resize(Game* game, State* state, int width, int height) { 354void resize(Game* game, State* state, int width, int height) {