mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-19 11:43:26 +00:00
Compare commits
6 Commits
v5.0.0
...
1041256fac
| Author | SHA1 | Date | |
|---|---|---|---|
| 1041256fac | |||
| 88012e2524 | |||
| 4561dbe0e7 | |||
| b50f759675 | |||
| 85b672fdf3 | |||
| 360734f252 |
4
.idea/editor.xml
generated
4
.idea/editor.xml
generated
@@ -17,7 +17,7 @@
|
|||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
|
|
||||||
namespace omath::collision
|
namespace omath::collision
|
||||||
{
|
{
|
||||||
template<class V>
|
template<class V, class FloatingType>
|
||||||
concept EpaVector = requires(const V& a, const V& b, float s) {
|
concept EpaVector = requires(const V& a, const V& b, FloatingType s) {
|
||||||
{ a - b } -> std::same_as<V>;
|
{ a - b } -> std::same_as<V>;
|
||||||
{ a.cross(b) } -> std::same_as<V>;
|
{ a.cross(b) } -> std::same_as<V>;
|
||||||
{ a.dot(b) } -> std::same_as<float>;
|
{ a.dot(b) } -> std::same_as<FloatingType>;
|
||||||
{ -a } -> std::same_as<V>;
|
{ -a } -> std::same_as<V>;
|
||||||
{ a * s } -> std::same_as<V>;
|
{ a * s } -> std::same_as<V>;
|
||||||
{ a / s } -> std::same_as<V>;
|
{ a / s } -> std::same_as<V>;
|
||||||
@@ -28,13 +28,18 @@ namespace omath::collision
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using VectorType = ColliderInterfaceType::VectorType;
|
using VectorType = ColliderInterfaceType::VectorType;
|
||||||
static_assert(EpaVector<VectorType>, "VertexType must satisfy EpaVector concept");
|
static_assert(EpaVector<VectorType, typename VectorType::ContainedType>,
|
||||||
|
"VertexType must satisfy EpaVector concept");
|
||||||
|
|
||||||
|
private:
|
||||||
|
using FloatingType = VectorType::ContainedType;
|
||||||
|
|
||||||
|
public:
|
||||||
struct Result final
|
struct Result final
|
||||||
{
|
{
|
||||||
VectorType normal{}; // from A to B
|
VectorType normal{}; // from A to B
|
||||||
VectorType penetration_vector;
|
VectorType penetration_vector;
|
||||||
float depth{0.0f};
|
FloatingType depth{0.0};
|
||||||
int iterations{0};
|
int iterations{0};
|
||||||
int num_vertices{0};
|
int num_vertices{0};
|
||||||
int num_faces{0};
|
int num_faces{0};
|
||||||
@@ -43,7 +48,7 @@ namespace omath::collision
|
|||||||
struct Params final
|
struct Params final
|
||||||
{
|
{
|
||||||
int max_iterations{64};
|
int max_iterations{64};
|
||||||
float tolerance{1e-4f}; // absolute tolerance on distance growth
|
FloatingType tolerance{1e-4}; // absolute tolerance on distance growth
|
||||||
};
|
};
|
||||||
// Precondition: simplex.size()==4 and contains the origin.
|
// Precondition: simplex.size()==4 and contains the origin.
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@@ -81,7 +86,7 @@ namespace omath::collision
|
|||||||
|
|
||||||
// Get the furthest point in face normal direction
|
// Get the furthest point in face normal direction
|
||||||
const VectorType p = support_point(a, b, face.n);
|
const VectorType p = support_point(a, b, face.n);
|
||||||
const float p_dist = face.n.dot(p);
|
const auto p_dist = face.n.dot(p);
|
||||||
|
|
||||||
// Converged if we can’t push the face closer than tolerance
|
// Converged if we can’t push the face closer than tolerance
|
||||||
if (p_dist - face.d <= params.tolerance)
|
if (p_dist - face.d <= params.tolerance)
|
||||||
@@ -136,7 +141,7 @@ namespace omath::collision
|
|||||||
{
|
{
|
||||||
int i0, i1, i2;
|
int i0, i1, i2;
|
||||||
VectorType n; // unit outward normal
|
VectorType n; // unit outward normal
|
||||||
float d; // n · v0 (>=0 ideally because origin is inside)
|
FloatingType d; // n · v0 (>=0 ideally because origin is inside)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Edge final
|
struct Edge final
|
||||||
@@ -146,7 +151,7 @@ namespace omath::collision
|
|||||||
|
|
||||||
struct HeapItem final
|
struct HeapItem final
|
||||||
{
|
{
|
||||||
float d;
|
FloatingType d;
|
||||||
int idx;
|
int idx;
|
||||||
};
|
};
|
||||||
struct HeapCmp final
|
struct HeapCmp final
|
||||||
@@ -178,7 +183,7 @@ namespace omath::collision
|
|||||||
static bool visible_from(const Face& f, const VectorType& p)
|
static bool visible_from(const Face& f, const VectorType& p)
|
||||||
{
|
{
|
||||||
// positive if p is in front of the face
|
// positive if p is in front of the face
|
||||||
return f.n.dot(p) - f.d > 1e-7f;
|
return f.n.dot(p) - f.d > static_cast<FloatingType>(1e-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_edge_boundary(std::pmr::vector<Edge>& boundary, int a, int b)
|
static void add_edge_boundary(std::pmr::vector<Edge>& boundary, int a, int b)
|
||||||
@@ -198,19 +203,20 @@ namespace omath::collision
|
|||||||
const VectorType& a1 = vertexes[i1];
|
const VectorType& a1 = vertexes[i1];
|
||||||
const VectorType& a2 = vertexes[i2];
|
const VectorType& a2 = vertexes[i2];
|
||||||
VectorType n = (a1 - a0).cross(a2 - a0);
|
VectorType n = (a1 - a0).cross(a2 - a0);
|
||||||
if (n.dot(n) <= 1e-30f)
|
if (n.dot(n) <= static_cast<FloatingType>(1e-30))
|
||||||
{
|
{
|
||||||
n = any_perp_vec(a1 - a0); // degenerate guard
|
n = any_perp_vec(a1 - a0); // degenerate guard
|
||||||
}
|
}
|
||||||
// Ensure normal points outward (away from origin): require n·a0 >= 0
|
// Ensure normal points outward (away from origin): require n·a0 >= 0
|
||||||
if (n.dot(a0) < 0.0f)
|
if (n.dot(a0) < static_cast<FloatingType>(0.0))
|
||||||
{
|
{
|
||||||
std::swap(i1, i2);
|
std::swap(i1, i2);
|
||||||
n = -n;
|
n = -n;
|
||||||
}
|
}
|
||||||
const float inv_len = 1.0f / std::sqrt(std::max(n.dot(n), 1e-30f));
|
const auto inv_len =
|
||||||
|
static_cast<FloatingType>(1.0) / std::sqrt(std::max(n.dot(n), static_cast<FloatingType>(1e-30)));
|
||||||
n = n * inv_len;
|
n = n * inv_len;
|
||||||
const float d = n.dot(a0);
|
const auto d = n.dot(a0);
|
||||||
return {i0, i1, i2, n, d};
|
return {i0, i1, i2, n, d};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +229,7 @@ namespace omath::collision
|
|||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
static constexpr bool near_zero_vec(const V& v, const float eps = 1e-7f)
|
static constexpr bool near_zero_vec(const V& v, const FloatingType eps = 1e-7f)
|
||||||
{
|
{
|
||||||
return v.dot(v) <= eps * eps;
|
return v.dot(v) <= eps * eps;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,59 +80,93 @@ namespace omath::projection
|
|||||||
{
|
{
|
||||||
m_view_angles = TraitClass::calc_look_at_angle(m_origin, target);
|
m_view_angles = TraitClass::calc_look_at_angle(m_origin, target);
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_view_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
[[nodiscard]]
|
||||||
[[nodiscard]] Mat4X4Type calc_view_projection_matrix() const noexcept
|
Vector3<float> get_forward() const noexcept
|
||||||
{
|
{
|
||||||
return TraitClass::calc_projection_matrix(m_field_of_view, m_view_port, m_near_plane_distance,
|
const auto& view_matrix = get_view_matrix();
|
||||||
m_far_plane_distance)
|
return {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
||||||
* TraitClass::calc_view_matrix(m_view_angles, m_origin);
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
Vector3<float> get_right() const noexcept
|
||||||
|
{
|
||||||
|
const auto& view_matrix = get_view_matrix();
|
||||||
|
return {view_matrix[0, 0], view_matrix[0, 1], view_matrix[0, 2]};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
Vector3<float> get_up() const noexcept
|
||||||
|
{
|
||||||
|
const auto& view_matrix = get_view_matrix();
|
||||||
|
return {view_matrix[1, 0], view_matrix[1, 1], view_matrix[1, 2]};
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
[[nodiscard]] const Mat4X4Type& get_view_projection_matrix() const noexcept
|
[[nodiscard]] const Mat4X4Type& get_view_projection_matrix() const noexcept
|
||||||
{
|
{
|
||||||
if (!m_view_projection_matrix.has_value())
|
if (!m_view_projection_matrix.has_value())
|
||||||
m_view_projection_matrix = calc_view_projection_matrix();
|
m_view_projection_matrix = get_projection_matrix() * get_view_matrix();
|
||||||
|
|
||||||
return m_view_projection_matrix.value();
|
return m_view_projection_matrix.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const Mat4X4Type& get_view_matrix() const noexcept
|
||||||
|
{
|
||||||
|
if (!m_view_matrix.has_value())
|
||||||
|
m_view_matrix = TraitClass::calc_view_matrix(m_view_angles, m_origin);
|
||||||
|
|
||||||
|
return m_view_matrix.value();
|
||||||
|
}
|
||||||
|
[[nodiscard]] const Mat4X4Type& get_projection_matrix() const noexcept
|
||||||
|
{
|
||||||
|
if (!m_projection_matrix.has_value())
|
||||||
|
m_projection_matrix = TraitClass::calc_projection_matrix(m_field_of_view, m_view_port,
|
||||||
|
m_near_plane_distance, m_far_plane_distance);
|
||||||
|
|
||||||
|
return m_projection_matrix.value();
|
||||||
|
}
|
||||||
|
|
||||||
void set_field_of_view(const FieldOfView& fov) noexcept
|
void set_field_of_view(const FieldOfView& fov) noexcept
|
||||||
{
|
{
|
||||||
m_field_of_view = fov;
|
m_field_of_view = fov;
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_projection_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_near_plane(const float near) noexcept
|
void set_near_plane(const float near) noexcept
|
||||||
{
|
{
|
||||||
m_near_plane_distance = near;
|
m_near_plane_distance = near;
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_projection_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_far_plane(const float far) noexcept
|
void set_far_plane(const float far) noexcept
|
||||||
{
|
{
|
||||||
m_far_plane_distance = far;
|
m_far_plane_distance = far;
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_projection_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_view_angles(const ViewAnglesType& view_angles) noexcept
|
void set_view_angles(const ViewAnglesType& view_angles) noexcept
|
||||||
{
|
{
|
||||||
m_view_angles = view_angles;
|
m_view_angles = view_angles;
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_view_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_origin(const Vector3<float>& origin) noexcept
|
void set_origin(const Vector3<float>& origin) noexcept
|
||||||
{
|
{
|
||||||
m_origin = origin;
|
m_origin = origin;
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_view_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_view_port(const ViewPort& view_port) noexcept
|
void set_view_port(const ViewPort& view_port) noexcept
|
||||||
{
|
{
|
||||||
m_view_port = view_port;
|
m_view_port = view_port;
|
||||||
m_view_projection_matrix = std::nullopt;
|
m_view_projection_matrix = std::nullopt;
|
||||||
|
m_projection_matrix = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const FieldOfView& get_field_of_view() const noexcept
|
[[nodiscard]] const FieldOfView& get_field_of_view() const noexcept
|
||||||
@@ -283,7 +317,8 @@ namespace omath::projection
|
|||||||
Angle<float, 0.f, 180.f, AngleFlags::Clamped> m_field_of_view;
|
Angle<float, 0.f, 180.f, AngleFlags::Clamped> m_field_of_view;
|
||||||
|
|
||||||
mutable std::optional<Mat4X4Type> m_view_projection_matrix;
|
mutable std::optional<Mat4X4Type> m_view_projection_matrix;
|
||||||
|
mutable std::optional<Mat4X4Type> m_projection_matrix;
|
||||||
|
mutable std::optional<Mat4X4Type> m_view_matrix;
|
||||||
float m_far_plane_distance;
|
float m_far_plane_distance;
|
||||||
float m_near_plane_distance;
|
float m_near_plane_distance;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user