From 0d367470313533ed2e170762e24dbabc60c79714 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 7 Aug 2023 21:38:39 +0900 Subject: [PATCH] Add helper fn to calc. ray/plane intersection --- .gitignore | 1 + src/3d_helpers.cc | 17 +++++++++++++++++ src/3d_helpers.h | 6 ++++++ src/test/test.cc | 25 +++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/.gitignore b/.gitignore index cf39983..984437f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /objdir/ compile_commands.json /.cache/ +/test diff --git a/src/3d_helpers.cc b/src/3d_helpers.cc index f1209bc..ec4f3ea 100644 --- a/src/3d_helpers.cc +++ b/src/3d_helpers.cc @@ -143,3 +143,20 @@ bool ray_to_xz_plane(const Ray &ray, float &x_out, float &z_out) { return true; } + +std::optional ray_to_plane(const Ray &ray, const Ray &plane) { + // Ray dir and plane normal. + float rd_pn = Vector3DotProduct(ray.direction, plane.direction); + if (rd_pn == 0.0F) { + return std::nullopt; + } + + float amount = (Vector3DotProduct(plane.position, plane.direction) - + Vector3DotProduct(ray.position, plane.direction)) / + rd_pn; + + // Amount * ray_dir + ray_pos == plane intersection. + return Vector3{ray.position.x + ray.direction.x * amount, + ray.position.y + ray.direction.y * amount, + ray.position.z + ray.direction.z * amount}; +} diff --git a/src/3d_helpers.h b/src/3d_helpers.h index 8e1b3e1..88b0021 100644 --- a/src/3d_helpers.h +++ b/src/3d_helpers.h @@ -1,6 +1,9 @@ #ifndef JUMPARTIFACT_DOT_COM_DEMO_0_3D_HELPERS_H_ #define JUMPARTIFACT_DOT_COM_DEMO_0_3D_HELPERS_H_ +// standard library includes +#include + // third party includes #include @@ -21,6 +24,9 @@ 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); +/// plane.direction is plane normal, plane.position is position on plane. +extern std::optional ray_to_plane(const Ray &ray, const Ray &plane); + // 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/test/test.cc b/src/test/test.cc index 53e87c6..bf5536b 100644 --- a/src/test/test.cc +++ b/src/test/test.cc @@ -230,6 +230,31 @@ int main() { ASSERT_FLOAT_EQUALS(m.m15, 1.0F); } + { + // ray_to_plane tests. + auto result = + ray_to_plane(Ray{Vector3{0.0F, 0.0F, 1.0F}, Vector3{0.0F, 1.0F, 0.0F}}, + Ray{Vector3{0.0F, 2.0F, 0.0F}, Vector3{0.0F, 1.0F, 0.0F}}); + ASSERT_TRUE(result.has_value()); + ASSERT_FLOAT_EQUALS(0.0F, result.value().x); + ASSERT_FLOAT_EQUALS(2.0F, result.value().y); + ASSERT_FLOAT_EQUALS(1.0F, result.value().z); + + result = + ray_to_plane(Ray{Vector3{7.0F, 2.0F, 1.0F}, Vector3{0.0F, 1.0F, 0.0F}}, + Ray{Vector3{0.0F, 5.0F, 0.0F}, Vector3{0.0F, 1.0F, 0.0F}}); + ASSERT_TRUE(result.has_value()); + ASSERT_FLOAT_EQUALS(7.0F, result.value().x); + ASSERT_FLOAT_EQUALS(5.0F, result.value().y); + ASSERT_FLOAT_EQUALS(1.0F, result.value().z); + + // Parallel to plane test. + result = + ray_to_plane(Ray{Vector3{7.0F, 2.0F, 1.0F}, Vector3{0.0F, 0.0F, 1.0F}}, + Ray{Vector3{0.0F, 5.0F, 0.0F}, Vector3{0.0F, 1.0F, 0.0F}}); + ASSERT_FALSE(result.has_value()); + } + std::cout << "Finished tests.\n"; return 0; } -- 2.49.0