diff options
Diffstat (limited to 'game')
| -rw-r--r-- | game/src/plugins/viewer.c | 113 |
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 | ||
| 30 | struct State { | 31 | static const bool RenderBoundingBoxes = false; |
| 31 | Scene* scene; | 32 | static const R DefaultCameraSpeed = (R)6.0; |
| 32 | Model* model; | 33 | static const R DefaultMouseSensitivity = (R)(10 * TO_RAD); |
| 33 | SceneCamera* camera; | 34 | static const vec3 DefaultCameraPosition = (vec3){0, 2, 5}; |
| 34 | }; | 35 | |
| 36 | typedef struct CameraCommand { | ||
| 37 | bool CameraMoveLeft : 1; | ||
| 38 | bool CameraMoveRight : 1; | ||
| 39 | bool CameraMoveForward : 1; | ||
| 40 | bool CameraMoveBackward : 1; | ||
| 41 | } CameraCommand; | ||
| 42 | |||
| 43 | typedef 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 | |||
| 52 | typedef 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. |
| 37 | static const Texture* load_environment_map(Gfx* gfx) { | 60 | static 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 | ||
| 192 | static 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 | |||
| 156 | void update(Game* game, State* state, double t, double dt) { | 224 | void 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 | ||
| 267 | void resize(Game* game, State* state, int width, int height) { | 354 | void resize(Game* game, State* state, int width, int height) { |
