add camera tilt
This commit is contained in:
+37
-18
@@ -19,6 +19,8 @@
|
||||
|
||||
using namespace M;
|
||||
|
||||
#define NEAR_PLANE (0.01f)
|
||||
|
||||
SDL_GPUDevice *device;
|
||||
SDL_Window *window;
|
||||
|
||||
@@ -37,11 +39,11 @@ Sint32 window_height;
|
||||
|
||||
bool Running = true;
|
||||
|
||||
#define view_width 16
|
||||
#define view_height 9
|
||||
M4x4 view_matrix = view (V3_(0.0f, 0.0f, 0.0f), radians(45.0f), 10.0f);
|
||||
M4x4 inverse_view_matrix = inverse_view(V3_(0.0f, 0.0f, 0.0f), radians(45.0f), 10.0f);
|
||||
|
||||
M4x4 projection_matrix = projection (radians(45.0f), 1.0f, 0.001f);
|
||||
M4x4 inverse_projection_matrix = inverse_projection(radians(45.0f), 1.0f, 0.001f);
|
||||
M4x4 projection_matrix = projection (radians(45.0f), 16.0f / 9.0f, NEAR_PLANE);
|
||||
M4x4 inverse_projection_matrix = inverse_projection(radians(45.0f), 16.0f / 9.0f, NEAR_PLANE);
|
||||
|
||||
struct Vertex {
|
||||
V3 pos;
|
||||
@@ -84,11 +86,12 @@ struct PerFrame {
|
||||
float fovy_degrees;
|
||||
float camera_x;
|
||||
float camera_y;
|
||||
float camera_z;
|
||||
float camera_distance;
|
||||
float camera_tilt;
|
||||
Uint32 map_width;
|
||||
};
|
||||
|
||||
PerFrame per_frame = { 1.0f, 45.0f, 0, 0, -10 };
|
||||
PerFrame per_frame = { 1.0f, 45.0f, 0.0f, 0.0f, 10.0f, 45.0f };
|
||||
|
||||
typedef struct {
|
||||
Uint16 type;
|
||||
@@ -590,6 +593,13 @@ ImVec4 sRGB_to_linear(ImVec4 linear) {
|
||||
return ImVec4(red, green, blue, linear.w);
|
||||
}
|
||||
|
||||
V3 Unproject(V3 screen_pos) {
|
||||
V4 result = inverse_view_matrix * inverse_projection_matrix * V4_(screen_pos, 1.0f);
|
||||
result.xyz /= result.w;
|
||||
|
||||
return result.xyz;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
load_map();
|
||||
|
||||
@@ -908,7 +918,7 @@ int main(int argc, char **argv) {
|
||||
.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||
|
||||
.max_anisotropy = 16.0f,
|
||||
.enable_anisotropy = true,
|
||||
// .enable_anisotropy = true,
|
||||
};
|
||||
|
||||
point_sampler = SDL_CreateGPUSampler(device, &point_sampler_info);
|
||||
@@ -1033,8 +1043,9 @@ int main(int argc, char **argv) {
|
||||
selected_rotation = -1;
|
||||
}
|
||||
|
||||
ImGui::DragFloat("fovy", &per_frame.fovy_degrees);
|
||||
ImGui::DragFloat("camera_z", &per_frame.camera_z);
|
||||
ImGui::DragFloat("fovy", &per_frame.fovy_degrees);
|
||||
ImGui::DragFloat("camera_distance", &per_frame.camera_distance, 0.25f, 1.0f, INFINITY);
|
||||
ImGui::DragFloat("camera_tilt", &per_frame.camera_tilt, 0.25f, 0.0f, 89.0f);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
@@ -1079,7 +1090,7 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
|
||||
if (event.key.key == SDLK_UP || event.key.key == SDLK_W) {
|
||||
player.pos_y = clamp(0, player.pos_y - 1, map_height - 1);
|
||||
player.pos_y = clamp(0, player.pos_y + 1, map_height - 1);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_LEFT || event.key.key == SDLK_A) {
|
||||
@@ -1087,7 +1098,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_DOWN || event.key.key == SDLK_S) {
|
||||
player.pos_y = clamp(0, player.pos_y + 1, map_height - 1);
|
||||
player.pos_y = clamp(0, player.pos_y - 1, map_height - 1);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_RIGHT || event.key.key == SDLK_D) {
|
||||
@@ -1110,12 +1121,17 @@ int main(int argc, char **argv) {
|
||||
float mouse_x = event.button.x;
|
||||
float mouse_y = event.button.y;
|
||||
|
||||
V2 mouse = remap(V2{ 0, 0 }, V2{ (float)window_width, (float)window_height }, V2{ -1, -1 }, V2{ 1, 1 }, V2{ mouse_x, mouse_y });
|
||||
V4 mouse_world = inverse_projection_matrix * V4{ mouse.x, mouse.y, -per_frame.camera_z * 0.001f, 1 };
|
||||
mouse_world.xy *= mouse_world.w;
|
||||
V2 mouse = remap(V2{ 0, 0 }, V2{ (float)window_width, (float)window_height }, V2{ -1, 1 }, V2{ 1, -1 }, V2{ mouse_x, mouse_y });
|
||||
V3 camera_position = (inverse_view_matrix * V4_(0, 0, 0, 1)).xyz;
|
||||
|
||||
Sint32 tile_x = roundf(mouse_world.x) + player.pos_x;
|
||||
Sint32 tile_y = roundf(mouse_world.y) + player.pos_y;
|
||||
V3 probe = Unproject(V3_(mouse, .5));
|
||||
V3 ray_dir = normalize(probe - camera_position);
|
||||
|
||||
float t = -camera_position.z / ray_dir.z;
|
||||
V3 floor_intersection = camera_position + (t * ray_dir);
|
||||
|
||||
Sint32 tile_x = roundf(floor_intersection.x);
|
||||
Sint32 tile_y = roundf(floor_intersection.y);
|
||||
|
||||
if (selected_tile != -1) {
|
||||
if(0 <= tile_x && tile_x < map_width &&
|
||||
@@ -1182,8 +1198,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
SDL_PushGPUVertexUniformData(command_buffer, 0, &per_frame, sizeof(per_frame));
|
||||
|
||||
projection_matrix = projection (radians(per_frame.fovy_degrees), per_frame.aspect_ratio, 0.001f);
|
||||
inverse_projection_matrix = inverse_projection(radians(per_frame.fovy_degrees), per_frame.aspect_ratio, 0.001f);
|
||||
view_matrix = view (V3_((float)player.pos_x, (float)player.pos_y, 0), radians(per_frame.camera_tilt), per_frame.camera_distance);
|
||||
inverse_view_matrix = inverse_view(V3_((float)player.pos_x, (float)player.pos_y, 0), radians(per_frame.camera_tilt), per_frame.camera_distance);
|
||||
|
||||
projection_matrix = projection (radians(per_frame.fovy_degrees), per_frame.aspect_ratio, NEAR_PLANE);
|
||||
inverse_projection_matrix = inverse_projection(radians(per_frame.fovy_degrees), per_frame.aspect_ratio, NEAR_PLANE);
|
||||
|
||||
SDL_GPUColorTargetInfo color_target_info = {
|
||||
.texture = swapchain_texture,
|
||||
|
||||
@@ -873,6 +873,30 @@ namespace M {
|
||||
};
|
||||
}
|
||||
|
||||
M4x4 view(V3 player_pos, float tilt, float camera_distance) {
|
||||
float s = sinf(-tilt);
|
||||
float c = cosf(-tilt);
|
||||
|
||||
return M4x4_(
|
||||
1, 0, 0, -player_pos.x,
|
||||
0, c, s, c * -player_pos.y,
|
||||
0, -s, c, s * player_pos.y + camera_distance,
|
||||
0, 0, 0, 1
|
||||
);
|
||||
}
|
||||
|
||||
M4x4 inverse_view(V3 player_pos, float tilt, float camera_distance) {
|
||||
float s = sinf(-tilt);
|
||||
float c = cosf(-tilt);
|
||||
|
||||
return M4x4_(
|
||||
1, 0, 0, player_pos.x,
|
||||
0, c, -s, s * camera_distance + player_pos.y,
|
||||
0, s, c, c * -camera_distance,
|
||||
0, 0, 0, 1
|
||||
);
|
||||
}
|
||||
|
||||
M4x4 projection(float fovy, float aspect, float near) {
|
||||
float g = 1.0 / tanf(fovy * 0.5);
|
||||
|
||||
|
||||
@@ -258,6 +258,16 @@ namespace M {
|
||||
float _a;
|
||||
};
|
||||
|
||||
struct {
|
||||
V3 xyz;
|
||||
float _w2;
|
||||
};
|
||||
|
||||
struct {
|
||||
float _x2;
|
||||
V3 yzw;
|
||||
};
|
||||
|
||||
struct {
|
||||
V3 rgb;
|
||||
float _a2;
|
||||
@@ -268,6 +278,16 @@ namespace M {
|
||||
V3 gba;
|
||||
};
|
||||
|
||||
struct {
|
||||
V3 uvs;
|
||||
float _t2;
|
||||
};
|
||||
|
||||
struct {
|
||||
float _u2;
|
||||
V3 vst;
|
||||
};
|
||||
|
||||
struct {
|
||||
float E[4];
|
||||
};
|
||||
@@ -461,6 +481,9 @@ namespace M {
|
||||
|
||||
M4x4 transpose(M4x4 a);
|
||||
|
||||
M4x4 view (V3 player_pos, float tilt, float camera_distance);
|
||||
M4x4 inverse_view(V3 player_pos, float tilt, float camera_distance);
|
||||
|
||||
M4x4 projection (float fovy, float aspect, float near);
|
||||
M4x4 inverse_projection(float fovy, float aspect, float near);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user