mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-18 18:23:26 +00:00
Compare commits
6 Commits
02d909f77d
...
0876af3c14
| Author | SHA1 | Date | |
|---|---|---|---|
| 0876af3c14 | |||
| e46a369ddc | |||
| 630ffa69f6 | |||
| 609970cdfe | |||
| e935155022 | |||
| 800082e4b3 |
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/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" 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/=CppClassNeedsConstructorBecauseOfUninitializedMember/@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/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" 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/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
|
||||
@@ -22,4 +22,4 @@ namespace omath::cry_engine
|
||||
using RollAngle = Angle<float, -180.f, 180.f, AngleFlags::Normalized>;
|
||||
|
||||
using ViewAngles = omath::ViewAngles<PitchAngle, YawAngle, RollAngle>;
|
||||
} // namespace omath::frostbite_engine
|
||||
} // namespace omath::cry_engine
|
||||
@@ -71,4 +71,4 @@ namespace omath::cry_engine
|
||||
{
|
||||
return meters_to_units(kilometers * static_cast<FloatingType>(1000));
|
||||
}
|
||||
} // namespace omath::frostbite_engine
|
||||
} // namespace omath::cry_engine
|
||||
|
||||
12
include/omath/engines/cry_engine/mesh.hpp
Normal file
12
include/omath/engines/cry_engine/mesh.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// Created by Vladislav on 09.11.2025.
|
||||
//
|
||||
#pragma once
|
||||
#include "constants.hpp"
|
||||
#include "omath/3d_primitives/mesh.hpp"
|
||||
#include "traits/mesh_trait.hpp"
|
||||
|
||||
namespace omath::cry_engine
|
||||
{
|
||||
using Mesh = primitives::Mesh<Mat4X4, ViewAngles, MeshTrait>;
|
||||
}
|
||||
@@ -21,4 +21,4 @@ namespace omath::cry_engine
|
||||
float near, float far) noexcept;
|
||||
};
|
||||
|
||||
} // namespace omath::unreal_engine
|
||||
} // namespace omath::cry_engine
|
||||
@@ -70,7 +70,7 @@ namespace omath::cry_engine
|
||||
{
|
||||
const auto direction = (view_to - origin).normalized();
|
||||
|
||||
return angles::radians_to_degrees(std::atan2(direction.y, direction.z));
|
||||
return angles::radians_to_degrees(-std::atan2(direction.x, direction.y));
|
||||
};
|
||||
};
|
||||
} // namespace omath::unity_engine
|
||||
} // namespace omath::cry_engine
|
||||
|
||||
@@ -220,6 +220,12 @@ namespace omath
|
||||
{
|
||||
return std::make_tuple(x, y);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr std::array<Type, 2> as_array() const noexcept
|
||||
{
|
||||
return {x, y};
|
||||
}
|
||||
#ifdef OMATH_IMGUI_INTEGRATION
|
||||
[[nodiscard]]
|
||||
constexpr ImVec2 to_im_vec2() const noexcept
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "omath/trigonometry/angle.hpp"
|
||||
#include "omath/linear_algebra/vector2.hpp"
|
||||
#include "omath/trigonometry/angle.hpp"
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <functional>
|
||||
@@ -233,7 +233,8 @@ namespace omath
|
||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_perpendicular(const Vector3& other, Type epsilon = static_cast<Type>(0.0001)) const noexcept
|
||||
[[nodiscard]] bool is_perpendicular(const Vector3& other,
|
||||
Type epsilon = static_cast<Type>(0.0001)) const noexcept
|
||||
{
|
||||
if (const auto angle = angle_between(other))
|
||||
return std::abs(angle->as_degrees() - static_cast<Type>(90)) <= epsilon;
|
||||
@@ -274,6 +275,12 @@ namespace omath
|
||||
{
|
||||
return length() >= other.length();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr std::array<Type, 3> as_array() const noexcept
|
||||
{
|
||||
return {this->x, this->y, z};
|
||||
}
|
||||
};
|
||||
} // namespace omath
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include "omath/linear_algebra/vector3.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace omath
|
||||
{
|
||||
@@ -183,6 +183,12 @@ namespace omath
|
||||
return length() >= other.length();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr std::array<Type, 4> as_array() const noexcept
|
||||
{
|
||||
return {this->x, this->y, this->z, w};
|
||||
}
|
||||
|
||||
#ifdef OMATH_IMGUI_INTEGRATION
|
||||
[[nodiscard]]
|
||||
constexpr ImVec4 to_im_vec4() const noexcept
|
||||
@@ -200,7 +206,7 @@ namespace omath
|
||||
return {static_cast<Type>(other.x), static_cast<Type>(other.y), static_cast<Type>(other.z)};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
} // namespace omath
|
||||
|
||||
template<> struct std::hash<omath::Vector4<float>>
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace omath::cry_engine
|
||||
{
|
||||
const auto direction = (look_at - cam_origin).normalized();
|
||||
|
||||
return {PitchAngle::from_radians(-std::asin(direction.z)),
|
||||
YawAngle::from_radians(std::atan2(direction.y, direction.x)), RollAngle::from_radians(0.f)};
|
||||
return {PitchAngle::from_radians(std::asin(direction.z)),
|
||||
YawAngle::from_radians(-std::atan2(direction.x, direction.y)), RollAngle::from_radians(0.f)};
|
||||
}
|
||||
Mat4X4 CameraTrait::calc_view_matrix(const ViewAngles& angles, const Vector3<float>& cam_origin) noexcept
|
||||
{
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace omath::cry_engine
|
||||
}
|
||||
Mat4X4 rotation_matrix(const ViewAngles& angles) noexcept
|
||||
{
|
||||
return mat_rotation_axis_z<float, MatStoreType::ROW_MAJOR>(angles.roll)
|
||||
* mat_rotation_axis_y<float, MatStoreType::ROW_MAJOR>(angles.yaw)
|
||||
return mat_rotation_axis_z<float, MatStoreType::ROW_MAJOR>(angles.yaw)
|
||||
* mat_rotation_axis_y<float, MatStoreType::ROW_MAJOR>(angles.roll)
|
||||
* mat_rotation_axis_x<float, MatStoreType::ROW_MAJOR>(angles.pitch);
|
||||
}
|
||||
Mat4X4 calc_perspective_projection_matrix(const float field_of_view, const float aspect_ratio, const float near,
|
||||
|
||||
240
tests/engines/unit_test_cry_engine.cpp
Normal file
240
tests/engines/unit_test_cry_engine.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
//
|
||||
// Created by Vladislav on 19.02.2026.
|
||||
//
|
||||
#include <gtest/gtest.h>
|
||||
#include <omath/engines/cry_engine/camera.hpp>
|
||||
#include <omath/engines/cry_engine/constants.hpp>
|
||||
#include <omath/engines/cry_engine/formulas.hpp>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
using namespace omath;
|
||||
TEST(unit_test_cry_engine, look_at_forward)
|
||||
{
|
||||
const auto angles = cry_engine::CameraTrait::calc_look_at_angle({}, cry_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = cry_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), cry_engine::k_abs_forward.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_cry_engine, look_at_right)
|
||||
{
|
||||
const auto angles = cry_engine::CameraTrait::calc_look_at_angle({}, cry_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = cry_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), cry_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_cry_engine, look_at_up)
|
||||
{
|
||||
const auto angles = cry_engine::CameraTrait::calc_look_at_angle({}, cry_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = cry_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), cry_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, look_at_back)
|
||||
{
|
||||
const auto angles = cry_engine::CameraTrait::calc_look_at_angle({}, -cry_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = cry_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-cry_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_cry_engine, look_at_left)
|
||||
{
|
||||
const auto angles = cry_engine::CameraTrait::calc_look_at_angle({}, -cry_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = cry_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-cry_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_cry_engine, look_at_down)
|
||||
{
|
||||
const auto angles = cry_engine::CameraTrait::calc_look_at_angle({}, -cry_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = cry_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-cry_engine::k_abs_up).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, RightVector)
|
||||
{
|
||||
const auto right = omath::cry_engine::right_vector({});
|
||||
|
||||
EXPECT_EQ(right, omath::cry_engine::k_abs_right);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, UpVector)
|
||||
{
|
||||
const auto up = omath::cry_engine::up_vector({});
|
||||
EXPECT_EQ(up, omath::cry_engine::k_abs_up);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, ProjectTargetMovedFromCamera)
|
||||
{
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(60.f);
|
||||
const auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.01f, 1000.f);
|
||||
|
||||
for (float distance = 0.02f; distance < 100.f; distance += 0.01f)
|
||||
{
|
||||
const auto projected = cam.world_to_screen({0, distance, 0});
|
||||
|
||||
EXPECT_TRUE(projected.has_value());
|
||||
|
||||
if (!projected.has_value())
|
||||
continue;
|
||||
|
||||
EXPECT_NEAR(projected->x, 640, 0.00001f);
|
||||
EXPECT_NEAR(projected->y, 360, 0.00001f);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, CameraSetAndGetFov)
|
||||
{
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
|
||||
auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
|
||||
|
||||
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 90.f);
|
||||
cam.set_field_of_view(omath::projection::FieldOfView::from_degrees(50.f));
|
||||
|
||||
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 50.f);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, CameraSetAndGetOrigin)
|
||||
{
|
||||
auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);
|
||||
|
||||
EXPECT_EQ(cam.get_origin(), omath::Vector3<float>{});
|
||||
cam.set_field_of_view(omath::projection::FieldOfView::from_degrees(50.f));
|
||||
|
||||
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 50.f);
|
||||
}
|
||||
TEST(unit_test_cry_engine, loook_at_random_all_axis)
|
||||
{
|
||||
std::mt19937 gen(std::random_device{}()); // Seed with a non-deterministic source
|
||||
std::uniform_real_distribution<float> dist(-1000.f, 1000.f);
|
||||
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
|
||||
auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.001f, 10000.f);
|
||||
|
||||
std::size_t failed_points = 0;
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
const auto position_to_look = omath::Vector3<float>{dist(gen), dist(gen), dist(gen)};
|
||||
|
||||
if (cam.get_origin().distance_to(position_to_look) < 10)
|
||||
continue;
|
||||
|
||||
cam.look_at(position_to_look);
|
||||
|
||||
auto projected_pos = cam.world_to_view_port(position_to_look);
|
||||
|
||||
EXPECT_TRUE(projected_pos.has_value());
|
||||
|
||||
if (!projected_pos)
|
||||
continue;
|
||||
|
||||
if (std::abs(projected_pos->x - 0.f) >= 0.0001f || std::abs(projected_pos->y - 0.f) >= 0.0001f)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, loook_at_random_x_axis)
|
||||
{
|
||||
std::mt19937 gen(std::random_device{}()); // Seed with a non-deterministic source
|
||||
std::uniform_real_distribution<float> dist(-1000.f, 1000.f);
|
||||
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
|
||||
auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.001f, 10000.f);
|
||||
|
||||
std::size_t failed_points = 0;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
const auto position_to_look = omath::Vector3<float>{dist(gen), 0.f, 0.f};
|
||||
if (cam.get_origin().distance_to(position_to_look) < 10)
|
||||
continue;
|
||||
|
||||
cam.look_at(position_to_look);
|
||||
|
||||
auto projected_pos = cam.world_to_view_port(position_to_look);
|
||||
|
||||
EXPECT_TRUE(projected_pos.has_value());
|
||||
|
||||
if (!projected_pos)
|
||||
continue;
|
||||
|
||||
if (std::abs(projected_pos->x - 0.f) >= 0.001f || std::abs(projected_pos->y - 0.f) >= 0.001f)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, loook_at_random_y_axis)
|
||||
{
|
||||
std::mt19937 gen(std::random_device{}()); // Seed with a non-deterministic source
|
||||
std::uniform_real_distribution<float> dist(-1000.f, 1000.f);
|
||||
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
|
||||
auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.001f, 10000.f);
|
||||
|
||||
std::size_t failed_points = 0;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
const auto position_to_look = omath::Vector3<float>{0.f, dist(gen), 0.f};
|
||||
if (cam.get_origin().distance_to(position_to_look) < 10)
|
||||
continue;
|
||||
|
||||
cam.look_at(position_to_look);
|
||||
|
||||
auto projected_pos = cam.world_to_view_port(position_to_look);
|
||||
|
||||
EXPECT_TRUE(projected_pos.has_value());
|
||||
|
||||
if (!projected_pos)
|
||||
continue;
|
||||
|
||||
if (std::abs(projected_pos->x - 0.f) >= 0.01f || std::abs(projected_pos->y - 0.f) >= 0.01f)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
|
||||
TEST(unit_test_cry_engine, loook_at_random_z_axis)
|
||||
{
|
||||
std::mt19937 gen(std::random_device{}()); // Seed with a non-deterministic source
|
||||
std::uniform_real_distribution<float> dist(-1000.f, 1000.f);
|
||||
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
|
||||
auto cam = omath::cry_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.001f, 10000.f);
|
||||
|
||||
std::size_t failed_points = 0;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
const auto position_to_look = omath::Vector3<float>{0.f, 0.f, dist(gen)};
|
||||
if (cam.get_origin().distance_to(position_to_look) < 10)
|
||||
continue;
|
||||
|
||||
cam.look_at(position_to_look);
|
||||
|
||||
auto projected_pos = cam.world_to_view_port(position_to_look);
|
||||
|
||||
EXPECT_TRUE(projected_pos.has_value());
|
||||
|
||||
if (!projected_pos)
|
||||
continue;
|
||||
|
||||
if (std::abs(projected_pos->x - 0.f) >= 0.01f || std::abs(projected_pos->y - 0.f) >= 0.01f)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <omath/engines/frostbite_engine/formulas.hpp>
|
||||
#include <print>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
TEST(unit_test_frostbite_engine, UnitsToCentimeters_BasicValues)
|
||||
{
|
||||
@@ -352,4 +353,55 @@ TEST(unit_test_frostbite_engine, loook_at_random_z_axis)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
}
|
||||
TEST(unit_test_frostbite_engine, look_at_right)
|
||||
{
|
||||
const auto angles = omath::frostbite_engine::CameraTrait::calc_look_at_angle({}, omath::frostbite_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::frostbite_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), omath::frostbite_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_frostbite_engine, look_at_up)
|
||||
{
|
||||
const auto angles = omath::frostbite_engine::CameraTrait::calc_look_at_angle({}, omath::frostbite_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::frostbite_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), omath::frostbite_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_frostbite_engine, look_at_back)
|
||||
{
|
||||
const auto angles = omath::frostbite_engine::CameraTrait::calc_look_at_angle({}, -omath::frostbite_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::frostbite_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), (-omath::frostbite_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_frostbite_engine, look_at_left)
|
||||
{
|
||||
const auto angles = omath::frostbite_engine::CameraTrait::calc_look_at_angle({}, -omath::frostbite_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::frostbite_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), (-omath::frostbite_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_frostbite_engine, look_at_down)
|
||||
{
|
||||
const auto angles = omath::frostbite_engine::CameraTrait::calc_look_at_angle({}, -omath::frostbite_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::frostbite_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), (-omath::frostbite_engine::k_abs_up).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <omath/engines/iw_engine/constants.hpp>
|
||||
#include <omath/engines/iw_engine/formulas.hpp>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
TEST(unit_test_iw_engine, ForwardVector)
|
||||
{
|
||||
@@ -223,4 +224,60 @@ TEST(unit_test_iw_engine, loook_at_random_z_axis)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
TEST(unit_test_iw_engine, look_at_forward)
|
||||
{
|
||||
const auto angles = omath::iw_engine::CameraTrait::calc_look_at_angle({}, omath::iw_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::iw_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::iw_engine::k_abs_forward.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_iw_engine, look_at_right)
|
||||
{
|
||||
const auto angles = omath::iw_engine::CameraTrait::calc_look_at_angle({}, omath::iw_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::iw_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::iw_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_iw_engine, look_at_up)
|
||||
{
|
||||
const auto angles = omath::iw_engine::CameraTrait::calc_look_at_angle({}, omath::iw_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::iw_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::iw_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_iw_engine, look_at_back)
|
||||
{
|
||||
const auto angles = omath::iw_engine::CameraTrait::calc_look_at_angle({}, -omath::iw_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::iw_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::iw_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_iw_engine, look_at_left)
|
||||
{
|
||||
const auto angles = omath::iw_engine::CameraTrait::calc_look_at_angle({}, -omath::iw_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::iw_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::iw_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_iw_engine, look_at_down)
|
||||
{
|
||||
const auto angles = omath::iw_engine::CameraTrait::calc_look_at_angle({}, -omath::iw_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::iw_engine::forward_vector(angles);
|
||||
EXPECT_NEAR(dir_vector.z, -0.99984f, 0.0001f);
|
||||
EXPECT_NEAR(dir_vector.x,- 0.017f, 0.01f);
|
||||
EXPECT_NEAR(dir_vector.y, 0.f, 0.001f);
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <omath/engines/opengl_engine/constants.hpp>
|
||||
#include <omath/engines/opengl_engine/formulas.hpp>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
TEST(unit_test_opengl, UnitsToCentimeters_BasicValues)
|
||||
{
|
||||
@@ -337,4 +338,60 @@ TEST(unit_test_opengl_engine, loook_at_random_z_axis)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
|
||||
TEST(unit_test_opengl_engine, look_at_forward)
|
||||
{
|
||||
const auto angles = omath::opengl_engine::CameraTrait::calc_look_at_angle({}, omath::opengl_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::opengl_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::opengl_engine::k_abs_forward.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_opengl_engine, look_at_right)
|
||||
{
|
||||
const auto angles = omath::opengl_engine::CameraTrait::calc_look_at_angle({}, omath::opengl_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::opengl_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::opengl_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_opengl_engine, look_at_up)
|
||||
{
|
||||
const auto angles = omath::opengl_engine::CameraTrait::calc_look_at_angle({}, omath::opengl_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::opengl_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::opengl_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_opengl_engine, look_at_back)
|
||||
{
|
||||
const auto angles = omath::opengl_engine::CameraTrait::calc_look_at_angle({}, -omath::opengl_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::opengl_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::opengl_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_opengl_engine, look_at_left)
|
||||
{
|
||||
const auto angles = omath::opengl_engine::CameraTrait::calc_look_at_angle({}, -omath::opengl_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::opengl_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::opengl_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_opengl_engine, look_at_down)
|
||||
{
|
||||
const auto angles = omath::opengl_engine::CameraTrait::calc_look_at_angle({}, -omath::opengl_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::opengl_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::opengl_engine::k_abs_up).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <omath/engines/source_engine/constants.hpp>
|
||||
#include <omath/engines/source_engine/formulas.hpp>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
TEST(unit_test_source_engine_units, HammerUnitsToCentimeters_BasicValues)
|
||||
{
|
||||
@@ -365,4 +366,60 @@ TEST(unit_test_source_engine, loook_at_random_z_axis)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
TEST(unit_test_source_engine, look_at_forward)
|
||||
{
|
||||
const auto angles = omath::source_engine::CameraTrait::calc_look_at_angle({}, omath::source_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::source_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::source_engine::k_abs_forward.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_source_engine, look_at_right)
|
||||
{
|
||||
const auto angles = omath::source_engine::CameraTrait::calc_look_at_angle({}, omath::source_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::source_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::source_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_source_engine, look_at_up)
|
||||
{
|
||||
const auto angles = omath::source_engine::CameraTrait::calc_look_at_angle({}, omath::source_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::source_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::source_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_source_engine, look_at_back)
|
||||
{
|
||||
const auto angles = omath::source_engine::CameraTrait::calc_look_at_angle({}, -omath::source_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::source_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::source_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_source_engine, look_at_left)
|
||||
{
|
||||
const auto angles = omath::source_engine::CameraTrait::calc_look_at_angle({}, -omath::source_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::source_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::source_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_source_engine, look_at_down)
|
||||
{
|
||||
const auto angles = omath::source_engine::CameraTrait::calc_look_at_angle({}, -omath::source_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::source_engine::forward_vector(angles);
|
||||
EXPECT_NEAR(dir_vector.z, -0.99984f, 0.0001f);
|
||||
EXPECT_NEAR(dir_vector.x,- 0.017f, 0.01f);
|
||||
EXPECT_NEAR(dir_vector.y, 0.f, 0.001f);
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <omath/engines/unity_engine/formulas.hpp>
|
||||
#include <print>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
TEST(unit_test_unity_engine, UnitsToCentimeters_BasicValues)
|
||||
{
|
||||
@@ -207,7 +208,8 @@ TEST(unit_test_unity_engine, Project)
|
||||
constexpr auto fov = omath::projection::FieldOfView::from_degrees(60.f);
|
||||
|
||||
const auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.03f, 1000.f);
|
||||
const auto proj = cam.world_to_screen<omath::unity_engine::Camera::ScreenStart::BOTTOM_LEFT_CORNER>({10.f, 3, 10.f});
|
||||
const auto proj =
|
||||
cam.world_to_screen<omath::unity_engine::Camera::ScreenStart::BOTTOM_LEFT_CORNER>({10.f, 3, 10.f});
|
||||
|
||||
EXPECT_NEAR(proj->x, 1263.538, 0.001f);
|
||||
EXPECT_NEAR(proj->y, 547.061f, 0.001f);
|
||||
@@ -353,4 +355,65 @@ TEST(unit_test_unity_engine, loook_at_random_z_axis)
|
||||
failed_points++;
|
||||
}
|
||||
EXPECT_LE(failed_points, 100);
|
||||
}
|
||||
}
|
||||
TEST(unit_test_unity_engine, look_at_forward)
|
||||
{
|
||||
const auto angles = omath::unity_engine::CameraTrait::calc_look_at_angle({}, omath::unity_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unity_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), omath::unity_engine::k_abs_forward.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unity_engine, look_at_right)
|
||||
{
|
||||
const auto angles = omath::unity_engine::CameraTrait::calc_look_at_angle({}, omath::unity_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unity_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), omath::unity_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unity_engine, look_at_up)
|
||||
{
|
||||
const auto angles = omath::unity_engine::CameraTrait::calc_look_at_angle({}, omath::unity_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unity_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), omath::unity_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_unity_engine, look_at_back)
|
||||
{
|
||||
const auto angles = omath::unity_engine::CameraTrait::calc_look_at_angle({}, -omath::unity_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unity_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), (-omath::unity_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unity_engine, look_at_left)
|
||||
{
|
||||
const auto angles = omath::unity_engine::CameraTrait::calc_look_at_angle({}, -omath::unity_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unity_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), (-omath::unity_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unity_engine, look_at_down)
|
||||
{
|
||||
const auto angles = omath::unity_engine::CameraTrait::calc_look_at_angle({}, -omath::unity_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unity_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] :
|
||||
std::views::zip(dir_vector.as_array(), (-omath::unity_engine::k_abs_up).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <omath/engines/unreal_engine/formulas.hpp>
|
||||
#include <print>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
|
||||
TEST(unit_test_unreal_engine, ForwardVector)
|
||||
{
|
||||
@@ -361,4 +362,59 @@ TEST(unit_test_unreal_engine, ConstexprConversions)
|
||||
static_assert(cm == 100000.0, "units_to_centimeters constexpr failed");
|
||||
static_assert(m == 1000.0, "units_to_meters constexpr failed");
|
||||
static_assert(km == 1.0, "units_to_kilometers constexpr failed");
|
||||
}
|
||||
TEST(unit_test_unreal_engine, look_at_forward)
|
||||
{
|
||||
const auto angles = omath::unreal_engine::CameraTrait::calc_look_at_angle({}, omath::unreal_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unreal_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::unreal_engine::k_abs_forward.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unreal_engine, look_at_right)
|
||||
{
|
||||
const auto angles = omath::unreal_engine::CameraTrait::calc_look_at_angle({}, omath::unreal_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unreal_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::unreal_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unreal_engine, look_at_up)
|
||||
{
|
||||
const auto angles = omath::unreal_engine::CameraTrait::calc_look_at_angle({}, omath::unreal_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unreal_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), omath::unreal_engine::k_abs_right.as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(unit_test_unreal_engine, look_at_back)
|
||||
{
|
||||
const auto angles = omath::unreal_engine::CameraTrait::calc_look_at_angle({}, -omath::unreal_engine::k_abs_forward);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unreal_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::unreal_engine::k_abs_forward).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unreal_engine, look_at_left)
|
||||
{
|
||||
const auto angles = omath::unreal_engine::CameraTrait::calc_look_at_angle({}, -omath::unreal_engine::k_abs_right);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unreal_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::unreal_engine::k_abs_right).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
TEST(unit_test_unreal_engine, look_at_down)
|
||||
{
|
||||
const auto angles = omath::unreal_engine::CameraTrait::calc_look_at_angle({}, -omath::unreal_engine::k_abs_up);
|
||||
|
||||
// ReSharper disable once CppTooWideScopeInitStatement
|
||||
const auto dir_vector = omath::unreal_engine::forward_vector(angles);
|
||||
for (const auto& [result, etalon] : std::views::zip(dir_vector.as_array(), (-omath::unreal_engine::k_abs_up).as_array()))
|
||||
EXPECT_NEAR(result, etalon, 0.0001f);
|
||||
}
|
||||
Reference in New Issue
Block a user