Compare commits

...

6 Commits

Author SHA1 Message Date
1041256fac Revert "removed useless include"
This reverts commit 88012e2524.
2026-02-18 06:07:27 +03:00
88012e2524 removed useless include 2026-02-18 05:53:16 +03:00
4561dbe0e7 fix 2026-02-18 05:51:46 +03:00
b50f759675 more template stuff 2026-02-18 05:51:18 +03:00
85b672fdf3 Merge pull request #152 from orange-cpp/feature/camera_improvement
added more methods
2026-02-17 07:57:35 +03:00
360734f252 added more methods 2026-02-17 07:39:45 +03:00
3 changed files with 69 additions and 28 deletions

4
.idea/editor.xml generated
View File

@@ -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" />

View File

@@ -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 cant push the face closer than tolerance // Converged if we cant 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;
} }

View File

@@ -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;