Move Vectormath main
C++20 game and graphics mathematics
Loading...
Searching...
No Matches
Capsule3.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <optional>
5#include <type_traits>
6
7#include <mv/math/Vec4.hpp>
9
10namespace mv::math
11{
12 // A capsule is the sphere-swept segment described by Ericson, Real-Time
13 // Collision Detection (2005), section 4.5. Start+radius share one SIMD
14 // lane group so the semantic value stays 32 bytes rather than 48.
15 template <typename T>
16 requires std::is_floating_point_v<T>
18 {
19 public:
20 using Component = T;
21
23
26 {
27 if (!centerLine.IsFinite() || !(radius >= T(0)) ||
28 !std::isfinite(radius))
29 {
30 return std::nullopt;
31 }
32 return Capsule3(centerLine, radius, UncheckedTag{});
33 }
34
35 [[nodiscard]] static std::optional<Capsule3> TryFromEndpointsRadius(
36 const Point3<T>& start, const Point3<T>& end, T radius) noexcept
37 {
39 }
40
42 {
43 return Point3<T>(StartRadius_.X(), StartRadius_.Y(),
44 StartRadius_.Z());
45 }
46
48 {
49 return End_;
50 }
51
53 {
54 return Segment3<T>(Start(), End_);
55 }
56
58 {
59 return StartRadius_.W();
60 }
61
63 {
64 return Start() == End_;
65 }
66
68 {
69 return CenterLine().IsFinite() && Radius() >= T(0) &&
70 std::isfinite(Radius());
71 }
72
73 [[nodiscard]] friend bool operator==(const Capsule3& left,
74 const Capsule3& right) noexcept
75 {
76 return left.StartRadius_ == right.StartRadius_ &&
77 left.End_ == right.End_;
78 }
79
80 private:
81 struct UncheckedTag
82 {
83 };
84
85 Capsule3(const Segment3<T>& centerLine, T radius, UncheckedTag) noexcept
86 :
87 StartRadius_(centerLine.Start().X(),
88 centerLine.Start().Y(),
89 centerLine.Start().Z(),
90 radius),
91 End_(centerLine.End())
92 {
93 }
94
95 Vec4<T> StartRadius_{};
96 Point3<T> End_{};
97 };
98
101} // namespace mv::math
102
103static_assert(sizeof(mv::math::Capsule3f) == 32);
104static_assert(alignof(mv::math::Capsule3f) == 16);
105static_assert(std::is_trivially_copyable_v<mv::math::Capsule3f>);
106static_assert(std::is_standard_layout_v<mv::math::Capsule3f>);
107static_assert(sizeof(mv::math::Capsule3d) == 64);
108static_assert(alignof(mv::math::Capsule3d) == 32);
109static_assert(std::is_trivially_copyable_v<mv::math::Capsule3d>);
110static_assert(std::is_standard_layout_v<mv::math::Capsule3d>);
static std::optional< Capsule3 > TryFromEndpointsRadius(const Point3< T > &start, const Point3< T > &end, T radius) noexcept
Definition Capsule3.hpp:35
const Point3< T > & End() const noexcept
Definition Capsule3.hpp:47
Segment3< T > CenterLine() const noexcept
Definition Capsule3.hpp:52
friend bool operator==(const Capsule3 &left, const Capsule3 &right) noexcept
Definition Capsule3.hpp:73
T Radius() const noexcept
Definition Capsule3.hpp:57
Point3< T > Start() const noexcept
Definition Capsule3.hpp:41
Capsule3() noexcept=default
bool IsFinite() const noexcept
Definition Capsule3.hpp:67
bool IsDegenerate() const noexcept
Definition Capsule3.hpp:62
static std::optional< Capsule3 > TryFromSegmentRadius(const Segment3< T > &centerLine, T radius) noexcept
Definition Capsule3.hpp:24
Capsule3< double > Capsule3d
Definition Capsule3.hpp:100
Capsule3< float > Capsule3f
Definition Capsule3.hpp:99