mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-15 16:13:26 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea8f3d8d51 | |||
| 08d2ccc03a | |||
| 21ec23d77b | |||
| 2c4ff37062 | |||
| 695a8035b5 |
32
CONTRIBUTING.md
Normal file
32
CONTRIBUTING.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
## 🤝 Contributing to OMath or other Orange's Projects
|
||||||
|
|
||||||
|
### ❕ Prerequisites
|
||||||
|
|
||||||
|
- A working up-to-date OMath installation
|
||||||
|
- C++ knowledge
|
||||||
|
- Git knowledge
|
||||||
|
- Ability to ask for help (Feel free to create empty pull-request or PM a maintainer
|
||||||
|
in [Telegram](https://t.me/orange_cpp))
|
||||||
|
|
||||||
|
### ⏬ Setting up OMath
|
||||||
|
|
||||||
|
Please read INSTALL.md file in repository
|
||||||
|
|
||||||
|
### 🔀 Pull requests and Branches
|
||||||
|
|
||||||
|
In order to send code back to the official OMath repository, you must first create a copy of OMath on your github
|
||||||
|
account ([fork](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)) and
|
||||||
|
then [create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) back to OMath.
|
||||||
|
|
||||||
|
OMath developement is performed on multiple branches. Changes are then pull requested into master. By default, changes
|
||||||
|
merged into master will not roll out to stable build users unless the `stable` tag is updated.
|
||||||
|
|
||||||
|
### 📜 Code-Style
|
||||||
|
|
||||||
|
The orange code-style can be found in `.clang-format`.
|
||||||
|
|
||||||
|
### 📦 Building
|
||||||
|
|
||||||
|
OMath has already created the `cmake-build` and `out` directories where cmake/bin files are located. By default, you
|
||||||
|
can build OMath by running `cmake --build cmake-build/build/windows-release --target omath -j 6` in the source
|
||||||
|
directory.
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// Created by Vlad on 8/6/2025.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "omath/engines/iw_engine/formulas.hpp"
|
||||||
|
#include "omath/projectile_prediction/projectile.hpp"
|
||||||
|
#include "omath/projectile_prediction/target.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace omath::projectile_prediction::traits
|
||||||
|
{
|
||||||
|
class IwEngineTrait final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr static Vector3<float> predict_projectile_position(const Projectile& projectile, const float pitch,
|
||||||
|
const float yaw, const float time,
|
||||||
|
const float gravity) noexcept
|
||||||
|
{
|
||||||
|
auto current_pos = projectile.m_origin
|
||||||
|
+ iw_engine::forward_vector({iw_engine::PitchAngle::from_degrees(-pitch),
|
||||||
|
iw_engine::YawAngle::from_degrees(yaw),
|
||||||
|
iw_engine::RollAngle::from_degrees(0)})
|
||||||
|
* projectile.m_launch_speed * time;
|
||||||
|
current_pos.z -= (gravity * projectile.m_gravity_scale) * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return current_pos;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr Vector3<float> predict_target_position(const Target& target, const float time,
|
||||||
|
const float gravity) noexcept
|
||||||
|
{
|
||||||
|
auto predicted = target.m_origin + target.m_velocity * time;
|
||||||
|
|
||||||
|
if (target.m_is_airborne)
|
||||||
|
predicted.z -= gravity * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return predicted;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_vector_2d_distance(const Vector3<float>& delta) noexcept
|
||||||
|
{
|
||||||
|
return std::sqrt(delta.x * delta.x + delta.y * delta.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr static float get_vector_height_coordinate(const Vector3<float>& vec) noexcept
|
||||||
|
{
|
||||||
|
return vec.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile,
|
||||||
|
Vector3<float> predicted_target_position,
|
||||||
|
const std::optional<float> projectile_pitch) noexcept
|
||||||
|
{
|
||||||
|
const auto delta2d = calc_vector_2d_distance(predicted_target_position - projectile.m_origin);
|
||||||
|
const auto height = delta2d * std::tan(angles::degrees_to_radians(projectile_pitch.value()));
|
||||||
|
|
||||||
|
return {predicted_target_position.x, predicted_target_position.y, projectile.m_origin.z + height};
|
||||||
|
}
|
||||||
|
// Due to specification of maybe_calculate_projectile_launch_pitch_angle, pitch angle must be:
|
||||||
|
// 89 look up, -89 look down
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_pitch_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto distance = origin.distance_to(view_to);
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::asin(delta.z / distance));
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::atan2(delta.y, delta.x));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace omath::projectile_prediction::traits
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// Created by Vlad on 8/6/2025.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "omath/engines/opengl_engine/formulas.hpp"
|
||||||
|
#include "omath/projectile_prediction/projectile.hpp"
|
||||||
|
#include "omath/projectile_prediction/target.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace omath::projectile_prediction::traits
|
||||||
|
{
|
||||||
|
class OpenGlEngineTrait final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr static Vector3<float> predict_projectile_position(const Projectile& projectile, const float pitch,
|
||||||
|
const float yaw, const float time,
|
||||||
|
const float gravity) noexcept
|
||||||
|
{
|
||||||
|
auto current_pos = projectile.m_origin
|
||||||
|
+ opengl_engine::forward_vector({opengl_engine::PitchAngle::from_degrees(-pitch),
|
||||||
|
opengl_engine::YawAngle::from_degrees(yaw),
|
||||||
|
opengl_engine::RollAngle::from_degrees(0)})
|
||||||
|
* projectile.m_launch_speed * time;
|
||||||
|
current_pos.y -= (gravity * projectile.m_gravity_scale) * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return current_pos;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr Vector3<float> predict_target_position(const Target& target, const float time,
|
||||||
|
const float gravity) noexcept
|
||||||
|
{
|
||||||
|
auto predicted = target.m_origin + target.m_velocity * time;
|
||||||
|
|
||||||
|
if (target.m_is_airborne)
|
||||||
|
predicted.y -= gravity * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return predicted;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_vector_2d_distance(const Vector3<float>& delta) noexcept
|
||||||
|
{
|
||||||
|
return std::sqrt(delta.x * delta.x + delta.z * delta.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr static float get_vector_height_coordinate(const Vector3<float>& vec) noexcept
|
||||||
|
{
|
||||||
|
return vec.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile,
|
||||||
|
Vector3<float> predicted_target_position,
|
||||||
|
const std::optional<float> projectile_pitch) noexcept
|
||||||
|
{
|
||||||
|
const auto delta2d = calc_vector_2d_distance(predicted_target_position - projectile.m_origin);
|
||||||
|
const auto height = delta2d * std::tan(angles::degrees_to_radians(projectile_pitch.value()));
|
||||||
|
|
||||||
|
return {predicted_target_position.x, predicted_target_position.y + height, projectile.m_origin.z};
|
||||||
|
}
|
||||||
|
// Due to specification of maybe_calculate_projectile_launch_pitch_angle, pitch angle must be:
|
||||||
|
// 89 look up, -89 look down
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_pitch_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto distance = origin.distance_to(view_to);
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::asin(delta.y / distance));
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::atan2(delta.z, delta.x));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace omath::projectile_prediction::traits
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// Created by Vlad on 8/6/2025.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "omath/engines/unity_engine/formulas.hpp"
|
||||||
|
#include "omath/projectile_prediction/projectile.hpp"
|
||||||
|
#include "omath/projectile_prediction/target.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace omath::projectile_prediction::traits
|
||||||
|
{
|
||||||
|
class UnityEngineTrait final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr static Vector3<float> predict_projectile_position(const Projectile& projectile, const float pitch,
|
||||||
|
const float yaw, const float time,
|
||||||
|
const float gravity) noexcept
|
||||||
|
{
|
||||||
|
auto current_pos = projectile.m_origin
|
||||||
|
+ unity_engine::forward_vector({unity_engine::PitchAngle::from_degrees(-pitch),
|
||||||
|
unity_engine::YawAngle::from_degrees(yaw),
|
||||||
|
unity_engine::RollAngle::from_degrees(0)})
|
||||||
|
* projectile.m_launch_speed * time;
|
||||||
|
current_pos.y -= (gravity * projectile.m_gravity_scale) * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return current_pos;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr Vector3<float> predict_target_position(const Target& target, const float time,
|
||||||
|
const float gravity) noexcept
|
||||||
|
{
|
||||||
|
auto predicted = target.m_origin + target.m_velocity * time;
|
||||||
|
|
||||||
|
if (target.m_is_airborne)
|
||||||
|
predicted.y -= gravity * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return predicted;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_vector_2d_distance(const Vector3<float>& delta) noexcept
|
||||||
|
{
|
||||||
|
return std::sqrt(delta.x * delta.x + delta.z * delta.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr static float get_vector_height_coordinate(const Vector3<float>& vec) noexcept
|
||||||
|
{
|
||||||
|
return vec.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile,
|
||||||
|
Vector3<float> predicted_target_position,
|
||||||
|
const std::optional<float> projectile_pitch) noexcept
|
||||||
|
{
|
||||||
|
const auto delta2d = calc_vector_2d_distance(predicted_target_position - projectile.m_origin);
|
||||||
|
const auto height = delta2d * std::tan(angles::degrees_to_radians(projectile_pitch.value()));
|
||||||
|
|
||||||
|
return {predicted_target_position.x, predicted_target_position.y + height, projectile.m_origin.z};
|
||||||
|
}
|
||||||
|
// Due to specification of maybe_calculate_projectile_launch_pitch_angle, pitch angle must be:
|
||||||
|
// 89 look up, -89 look down
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_pitch_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto distance = origin.distance_to(view_to);
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::asin(delta.y / distance));
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::atan2(delta.z, delta.x));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace omath::projectile_prediction::traits
|
||||||
@@ -142,7 +142,7 @@ namespace omath
|
|||||||
[[nodiscard]] Vector2 normalized() const noexcept
|
[[nodiscard]] Vector2 normalized() const noexcept
|
||||||
{
|
{
|
||||||
const Type len = length();
|
const Type len = length();
|
||||||
return len > 0.f ? *this / len : *this;
|
return len > static_cast<Type>(0) ? *this / len : *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
[[nodiscard]] constexpr Type length_sqr() const noexcept
|
[[nodiscard]] constexpr Type length_sqr() const noexcept
|
||||||
@@ -153,8 +153,8 @@ namespace omath
|
|||||||
constexpr Vector2& abs() noexcept
|
constexpr Vector2& abs() noexcept
|
||||||
{
|
{
|
||||||
// FIXME: Replace with std::abs, if it will become constexprable
|
// FIXME: Replace with std::abs, if it will become constexprable
|
||||||
x = x < 0 ? -x : x;
|
x = x < static_cast<Type>(0) ? -x : x;
|
||||||
y = y < 0 ? -y : y;
|
y = y < static_cast<Type>(0) ? -y : y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +202,11 @@ namespace omath
|
|||||||
{
|
{
|
||||||
return {static_cast<float>(this->x), static_cast<float>(this->y)};
|
return {static_cast<float>(this->x), static_cast<float>(this->y)};
|
||||||
}
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static Vector3<float> from_im_vec2(const ImVec2& other) noexcept
|
||||||
|
{
|
||||||
|
return {static_cast<Type>(other.x), static_cast<Type>(other.y)};
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ namespace omath
|
|||||||
{
|
{
|
||||||
const Type len = this->length();
|
const Type len = this->length();
|
||||||
|
|
||||||
return len != 0 ? *this / len : *this;
|
return len != static_cast<Type>(0) ? *this / len : *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Type length_2d() const noexcept
|
[[nodiscard]] Type length_2d() const noexcept
|
||||||
@@ -221,7 +221,7 @@ namespace omath
|
|||||||
{
|
{
|
||||||
const auto bottom = length() * other.length();
|
const auto bottom = length() * other.length();
|
||||||
|
|
||||||
if (bottom == 0.f)
|
if (bottom == static_cast<Type>(0))
|
||||||
return std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE);
|
return std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE);
|
||||||
|
|
||||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom));
|
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom));
|
||||||
@@ -230,7 +230,7 @@ namespace omath
|
|||||||
[[nodiscard]] bool is_perpendicular(const Vector3& other) const noexcept
|
[[nodiscard]] bool is_perpendicular(const Vector3& other) const noexcept
|
||||||
{
|
{
|
||||||
if (const auto angle = angle_between(other))
|
if (const auto angle = angle_between(other))
|
||||||
return angle->as_degrees() == 90.f;
|
return angle->as_degrees() == static_cast<Type>(90);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace omath
|
|||||||
constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w): Vector3<Type>(x, y, z), w(w)
|
constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w): Vector3<Type>(x, y, z), w(w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
constexpr Vector4() noexcept : Vector3<Type>(), w(0) {};
|
constexpr Vector4() noexcept: Vector3<Type>(), w(static_cast<Type>(0)) {};
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr bool operator==(const Vector4& other) const noexcept
|
constexpr bool operator==(const Vector4& other) const noexcept
|
||||||
@@ -169,6 +169,12 @@ namespace omath
|
|||||||
static_cast<float>(w),
|
static_cast<float>(w),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static Vector4<float> from_im_vec4(const ImVec4& other) noexcept
|
||||||
|
{
|
||||||
|
return {static_cast<Type>(other.x), static_cast<Type>(other.y), static_cast<Type>(other.z)};
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|||||||
Reference in New Issue
Block a user