40#include "utility/graphic/position.hpp"
42#include "utility/math/vector.hpp"
44#include "utility/graphic/mesh.hpp"
46namespace utility::graphic
52 template<
typename Type>
60 template<CanBeRayComponent RayComponentType>
class Ray
84 if (squaredLength == RayComponentType {}) {
85 throw std::invalid_argument(
"Ray direction must be non-zero");
130 :
_origin(std::move(other._origin))
142 if (
this != &other) {
156 if (
this != &other) {
157 _origin = std::move(other._origin);
164 ~Ray(
void) =
default;
246 pointAt(RayComponentType distanceParameter)
const
257 at(RayComponentType distanceParameter)
const
259 return pointAt(distanceParameter);
298 return !(*
this == other);
313 template<
typename RectanglePoseType>
317 const auto rectangleOrientation = rectanglePose.getOrientation();
320 rectangleOrientation.getRight();
322 rectangleOrientation.getUp();
324 rectangleOrientation.getForward();
326 const RayComponentType halfWidth =
327 static_cast<RayComponentType
>(rectangleSize[0])
328 / RayComponentType { 2 };
329 const RayComponentType halfHeight =
330 static_cast<RayComponentType
>(rectangleSize[1])
331 / RayComponentType { 2 };
340 topLeft + right * halfWidth + up * halfHeight;
342 const RayComponentType denominator =
345 if (denominator == RayComponentType {}) {
350 if (math::dot(toOrigin, planeNormal) == RayComponentType {}) {
359 const RayComponentType t =
360 math::dot(toCenter, planeNormal) / denominator;
362 if (t < RayComponentType {}) {
369 intersectionPoint - rectangleCenter;
371 const RayComponentType rightCoord = math::dot(localPoint, right);
372 const RayComponentType upCoord = math::dot(localPoint, up);
374 return (rightCoord >= -halfWidth && rightCoord <= halfWidth
375 && upCoord >= -halfHeight && upCoord <= halfHeight);
387 float length,
float radius,
int segments,
392 auto dir = utility::math::normalize(
_direction);
397 if (std::abs(utility::math::dot(dir, up)) > 0.99f)
401 utility::math::normalize(utility::math::cross(dir, up));
402 auto realUp = utility::math::cross(right, dir);
407 for (
int i = 0; i < segments; ++i) {
408 float a0 = 2.0f * M_PI * i / segments;
409 float a1 = 2.0f * M_PI * (i + 1) / segments;
411 auto offset0 = right * (std::cos(a0) * radius)
412 + realUp * (std::sin(a0) * radius);
414 auto offset1 = right * (std::cos(a1) * radius)
415 + realUp * (std::sin(a1) * radius);
418 static_cast<uint32_t
>(mesh.getVertices().size());
424 auto p0 = start + offset0;
425 auto p1 = start + offset1;
426 auto p2 = end + offset0;
427 auto p3 = end + offset1;
431 mesh.addVertex(vertex);
435 mesh.addVertex(vertex);
439 mesh.addVertex(vertex);
443 mesh.addVertex(vertex);
445 mesh.addIndex(base + 0);
446 mesh.addIndex(base + 1);
447 mesh.addIndex(base + 2);
449 mesh.addIndex(base + 2);
450 mesh.addIndex(base + 1);
451 mesh.addIndex(base + 3);
474 std::ostream &operator<<(std::ostream &stream,
const RayF &ray);
482 std::ostream &operator<<(std::ostream &stream,
const RayD &ray);
The Mesh class represents a 3D mesh used for rendering in a graphics application.
Position in 3D space represented as a vector of three PositionComponentType components (x,...
Geometric ray with arithmetic component type and fixed dimension.
math::Vector< RayComponentType, 3 > at(RayComponentType distanceParameter) const
Alias for pointAt to match common ray APIs.
Ray(void)
Default constructor creating a ray at origin along the first axis.
const Position< RayComponentType > & origin(void) const noexcept
Access the ray origin by const reference.
void setDirection(const math::Vector< RayComponentType, 3 > &direction)
Set the ray direction.
void setOrigin(const math::Vector< RayComponentType, 3 > &origin)
Set the ray origin.
utility::graphic::Mesh convertToMesh(float length, float radius, int segments, utility::graphic::Color32Bit color={ 255, 255, 255, 255 }) const
Convert the ray into a mesh representation for visualization.
math::Vector< RayComponentType, 3 > normalizedDirection() const
Get a normalized copy of the ray direction.
Ray & operator=(Ray &&other) noexcept
Move assignment operator.
math::Vector< RayComponentType, 3 > getOrigin() const
Get the ray origin.
const math::Vector< RayComponentType, 3 > & direction(void) const noexcept
Access the ray direction by const reference.
Ray(Ray &&other) noexcept
Move constructor.
bool operator==(const Ray &other) const
Equality comparison.
Ray & operator=(const Ray &other)
Copy assignment operator.
Ray translated(const math::Vector< RayComponentType, 3 > &offset) const
Get translated ray copy.
bool operator!=(const Ray &other) const
Inequality comparison.
void translate(const math::Vector< RayComponentType, 3 > &offset)
Translate ray origin by the provided offset.
math::Vector< RayComponentType, 3 > pointAt(RayComponentType distanceParameter) const
Evaluate a point on the ray at the provided parameter.
bool intersectRectangle(const RectanglePoseType &rectanglePose, const math::Vector2F &rectangleSize) const
Check for intersection with an axis-aligned rectangle plane.
static void validateDirection(const math::Vector< RayComponentType, 3 > &direction)
Validate that a direction vector is non-zero.
Ray(math::Vector< RayComponentType, 3 > origin, math::Vector< RayComponentType, 3 > direction)
Construct ray from origin and direction.
math::Vector< RayComponentType, 3 > getDirection(void) const
Get the ray direction.
void setOrigin(const Position< RayComponentType > &origin)
Set the ray origin using a Position value.
Ray(const Ray &other)
Copy constructor.
Position< RayComponentType > _origin
Origin point of the ray.
math::Vector< RayComponentType, 3 > _direction
Direction vector of the ray (must be non-zero).
Vertex type containing common mesh attributes.
void setPosition(const Position< VectorComponent > &position)
Set vertex position.
void setColor(const Color32Bit &color)
Set vertex color.
3D vector class inheriting from glm::vec3.
Concept to constrain position component type.
Concept to ensure the type can be used as a ray component.
Concept to constrain vector component type.