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};
+}
#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>
/// 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);
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;
}