]> git.seodisparate.com - jumpartifact.com_demo_0/commitdiff
Add helper fn to calc. ray/plane intersection
authorStephen Seo <seo.disparate@gmail.com>
Mon, 7 Aug 2023 12:38:39 +0000 (21:38 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Mon, 7 Aug 2023 12:39:59 +0000 (21:39 +0900)
.gitignore
src/3d_helpers.cc
src/3d_helpers.h
src/test/test.cc

index cf3998301af042d16a8a9fc96dcdb6a154ce6362..984437f81edb5d93cb9777689c26990c07fa17f4 100644 (file)
@@ -2,3 +2,4 @@
 /objdir/
 compile_commands.json
 /.cache/
+/test
index f1209bc063c78b70c22387640774ae614d83b591..ec4f3ea98467774e2d8f64bf4dd196dcc0007e5c 100644 (file)
@@ -143,3 +143,20 @@ bool ray_to_xz_plane(const Ray &ray, float &x_out, float &z_out) {
 
   return true;
 }
+
+std::optional<Vector3> 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};
+}
index 8e1b3e13fdf9677f36fb89e92ab52784deb729b2..88b0021f45c35ff06ceba4a3f88ce88879fc9c1c 100644 (file)
@@ -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 <optional>
+
 // third party includes
 #include <raylib.h>
 
@@ -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<Vector3> 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);
index 53e87c68c3d9325cfa8a5576afb0735111bb96d3..bf5536b68f6e02b3a34e7d67103e21fde5616ed6 100644 (file)
@@ -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;
 }