diff --git a/src/3d_helpers.cc b/src/3d_helpers.cc index 850893f..f1209bc 100644 --- a/src/3d_helpers.cc +++ b/src/3d_helpers.cc @@ -125,3 +125,21 @@ Matrix scale_matrix_xyz(float x, float y, float z) { Matrix operator*(const Matrix &a, const Matrix &b) { return MatrixMultiply(a, b); } + +bool ray_to_xz_plane(const Ray &ray, float &x_out, float &z_out) { + if (ray.direction.y == 0.0F) { + return false; + } + // y = 0 -> amount to set ray.dir to set ray.pos to zero + // 0 = py + dy * amount + // amount = -py / dy + float amount = -ray.position.y / ray.direction.y; + + // x = px + dx * amount + x_out = ray.position.x + ray.direction.x * amount; + + // z = pz + dz * amount + z_out = ray.position.z + ray.direction.z * amount; + + return true; +} diff --git a/src/3d_helpers.h b/src/3d_helpers.h index ba1d095..8e1b3e1 100644 --- a/src/3d_helpers.h +++ b/src/3d_helpers.h @@ -18,6 +18,9 @@ extern Matrix scale_matrix_xyz(float x, float y, float z); extern Matrix operator*(const Matrix &a, const Matrix &b); +/// Returns true if intersects with xz plane. +extern bool ray_to_xz_plane(const Ray &ray, float &x_out, float &z_out); + // Unimplemented as this function isn't really needed and it exposes some // weirdness regarding column-major matrices. // extern Vector4 operator*(const Matrix &m, const Vector4 &v); diff --git a/src/screen_trunner.cc b/src/screen_trunner.cc index 8e1a615..8c76a62 100644 --- a/src/screen_trunner.cc +++ b/src/screen_trunner.cc @@ -4,6 +4,10 @@ #include #include +#ifndef NDEBUG +#include +#endif + // local includes #include "3d_helpers.h" #include "ems.h" @@ -20,7 +24,9 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr stack) TEMP_matrix(get_identity_matrix()), camera_pos{0.0F, 4.0F, 4.0F}, camera_target{0.0F, 0.0F, 0.0F}, - pos_value(0.0F) { + pos_value(0.0F), + mouse_px(0), + mouse_pz(0) { TEMP_cube_model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = TEMP_cube_texture; TEMP_cube_model.transform = TEMP_cube_model.transform * @@ -43,6 +49,26 @@ bool TRunnerScreen::update(float dt) { camera_pos.x = std::sin(pos_value) * 4.0F; camera_pos.z = std::cos(pos_value) * 4.0F; camera_to_targets(dt); + + if (IsMouseButtonPressed(0)) { + float press_x = GetTouchX(); + float press_y = GetTouchY(); + Ray ray = GetMouseRay(Vector2{press_x, press_y}, camera); +#ifndef NDEBUG + std::cout << "X: " << press_x << ", Y: " << press_y << std::endl; + std::cout << "Ray pos: " << ray.position.x << ", " << ray.position.y << ", " + << ray.position.z << " Ray dir: " << ray.direction.x << ", " + << ray.direction.y << ", " << ray.direction.z << std::endl; +#endif + if (!ray_to_xz_plane(ray, mouse_px, mouse_pz)) { + mouse_px = 0.0F; + mouse_pz = 0.0F; +#ifndef NDEBUG + std::cerr << "Ray intersected xz plane out of bounds!\n"; +#endif + } + } + return false; } @@ -53,7 +79,8 @@ bool TRunnerScreen::draw() { for (int z = -25; z <= 25; ++z) { for (int x = -25; x <= 25; ++x) { - if (x == 0 && z == 0) { + if (x == (int)(mouse_px > 0.0F ? mouse_px + 0.5F : mouse_px - 0.5F) && + z == (int)(mouse_pz > 0.0F ? mouse_pz + 0.5F : mouse_pz - 0.5F)) { default_material.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE; } else { default_material.maps[MATERIAL_MAP_DIFFUSE].color = @@ -75,6 +102,10 @@ bool TRunnerScreen::draw() { .bindPose = TEMP_cube_model.bindPose}, Vector3{0.0F, 0.0F, -4.0F}, 1.0F, WHITE); + // TODO DEBUG + DrawLine3D(Vector3{0.0F, 0.0F, 0.0F}, Vector3{mouse_px, 0.0F, mouse_pz}, + BLACK); + EndMode3D(); EndDrawing(); diff --git a/src/screen_trunner.h b/src/screen_trunner.h index 46ea5ab..7d762e1 100644 --- a/src/screen_trunner.h +++ b/src/screen_trunner.h @@ -10,7 +10,7 @@ // third party includes #include -constexpr float POS_VALUE_INC_RATE = 0.5F; +constexpr float POS_VALUE_INC_RATE = 0.2F; constexpr float CAMERA_UPDATE_RATE = 1.0F; class TRunnerScreen : public Screen { @@ -50,6 +50,8 @@ class TRunnerScreen : public Screen { Vector3 camera_pos; Vector3 camera_target; float pos_value; + float mouse_px; + float mouse_pz; void camera_to_targets(float dt); };