diff --git a/.idea/editor.xml b/.idea/editor.xml
index 2eff1af..bce786e 100644
--- a/.idea/editor.xml
+++ b/.idea/editor.xml
@@ -17,7 +17,7 @@
-
+
@@ -110,7 +110,7 @@
-
+
diff --git a/include/omath/engines/cry_engine/camera.hpp b/include/omath/engines/cry_engine/camera.hpp
new file mode 100644
index 0000000..0db847f
--- /dev/null
+++ b/include/omath/engines/cry_engine/camera.hpp
@@ -0,0 +1,13 @@
+//
+// Created by Vlad on 3/22/2025.
+//
+
+#pragma once
+#include "omath/engines/cry_engine/constants.hpp"
+#include "omath/projection/camera.hpp"
+#include "traits/camera_trait.hpp"
+
+namespace omath::cry_engine
+{
+ using Camera = projection::Camera;
+} // namespace omath::cry_engine
\ No newline at end of file
diff --git a/include/omath/engines/cry_engine/traits/camera_trait.hpp b/include/omath/engines/cry_engine/traits/camera_trait.hpp
new file mode 100644
index 0000000..b760c65
--- /dev/null
+++ b/include/omath/engines/cry_engine/traits/camera_trait.hpp
@@ -0,0 +1,24 @@
+//
+// Created by Vlad on 8/10/2025.
+//
+
+#pragma once
+#include "omath/engines/cry_engine/formulas.hpp"
+#include "omath/projection/camera.hpp"
+
+namespace omath::cry_engine
+{
+ class CameraTrait final
+ {
+ public:
+ [[nodiscard]]
+ static ViewAngles calc_look_at_angle(const Vector3& cam_origin, const Vector3& look_at) noexcept;
+
+ [[nodiscard]]
+ static Mat4X4 calc_view_matrix(const ViewAngles& angles, const Vector3& cam_origin) noexcept;
+ [[nodiscard]]
+ static Mat4X4 calc_projection_matrix(const projection::FieldOfView& fov, const projection::ViewPort& view_port,
+ float near, float far) noexcept;
+ };
+
+} // namespace omath::unreal_engine
\ No newline at end of file
diff --git a/include/omath/engines/cry_engine/traits/pred_engine_trait.hpp b/include/omath/engines/cry_engine/traits/pred_engine_trait.hpp
new file mode 100644
index 0000000..353fce2
--- /dev/null
+++ b/include/omath/engines/cry_engine/traits/pred_engine_trait.hpp
@@ -0,0 +1,76 @@
+//
+// Created by Vlad on 8/6/2025.
+//
+#pragma once
+#include "omath/engines/cry_engine/formulas.hpp"
+#include "omath/projectile_prediction/projectile.hpp"
+#include "omath/projectile_prediction/target.hpp"
+#include
+
+namespace omath::cry_engine
+{
+ class PredEngineTrait final
+ {
+ public:
+ constexpr static Vector3 predict_projectile_position(const projectile_prediction::Projectile& projectile,
+ const float pitch, const float yaw,
+ const float time, const float gravity) noexcept
+ {
+ auto current_pos = projectile.m_origin
+ + forward_vector({PitchAngle::from_degrees(-pitch), YawAngle::from_degrees(yaw),
+ 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 predict_target_position(const projectile_prediction::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& delta) noexcept
+ {
+ return std::sqrt(delta.x * delta.x + delta.y * delta.y);
+ }
+
+ [[nodiscard]]
+ constexpr static float get_vector_height_coordinate(const Vector3& vec) noexcept
+ {
+ return vec.z;
+ }
+
+ [[nodiscard]]
+ static Vector3 calc_viewpoint_from_angles(const projectile_prediction::Projectile& projectile,
+ Vector3 predicted_target_position,
+ const std::optional 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& origin, const Vector3& view_to) noexcept
+ {
+ const auto direction = (view_to - origin).normalized();
+ return angles::radians_to_degrees(std::asin(direction.z));
+ }
+ [[nodiscard]]
+ static float calc_direct_yaw_angle(const Vector3& origin, const Vector3& view_to) noexcept
+ {
+ const auto direction = (view_to - origin).normalized();
+
+ return angles::radians_to_degrees(std::atan2(direction.y, direction.z));
+ };
+ };
+} // namespace omath::unity_engine
diff --git a/source/engines/cry_engine/camera_trait.cpp b/source/engines/cry_engine/camera_trait.cpp
new file mode 100644
index 0000000..63c1e01
--- /dev/null
+++ b/source/engines/cry_engine/camera_trait.cpp
@@ -0,0 +1,26 @@
+//
+// Created by Vlad on 8/11/2025.
+//
+#include "omath/engines/cry_engine/traits/camera_trait.hpp"
+
+namespace omath::cry_engine
+{
+
+ ViewAngles CameraTrait::calc_look_at_angle(const Vector3& cam_origin, const Vector3& look_at) noexcept
+ {
+ 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)};
+ }
+ Mat4X4 CameraTrait::calc_view_matrix(const ViewAngles& angles, const Vector3& cam_origin) noexcept
+ {
+ return cry_engine::calc_view_matrix(angles, cam_origin);
+ }
+ Mat4X4 CameraTrait::calc_projection_matrix(const projection::FieldOfView& fov,
+ const projection::ViewPort& view_port, const float near,
+ const float far) noexcept
+ {
+ return calc_perspective_projection_matrix(fov.as_degrees(), view_port.aspect_ratio(), near, far);
+ }
+} // namespace omath::unity_engine
\ No newline at end of file