Files
omath/docs/engines/frostbite/camera_trait.md
Orange 8142d800c7 Styles navbar for wider display and consistent spacing
Widens the navbar container to accommodate more content.
Adjusts padding of navbar items for tighter spacing.
Prevents line wrapping and enables horizontal scrolling on smaller screens.
2025-11-01 12:14:36 +03:00

109 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `omath::frostbite_engine::CameraTrait` — plug-in trait for `projection::Camera`
> Header: `omath/engines/frostbite_engine/traits/camera_trait.hpp` • Impl: `omath/engines/frostbite_engine/traits/camera_trait.cpp`
> Namespace: `omath::frostbite_engine`
> Purpose: provide Frostbite-style **look-at**, **view**, and **projection** math to the generic `omath::projection::Camera` (satisfies `CameraEngineConcept`).
---
## Summary
`CameraTrait` exposes three `static` functions:
* `calc_look_at_angle(origin, look_at)` computes Euler angles so the camera at `origin` looks at `look_at`. Implementation normalizes the direction, computes **pitch** as `-asin(dir.y)` and **yaw** as `atan2(dir.x, dir.z)`; **roll** is `0`. Pitch/yaw are returned using the projects strong angle types (`PitchAngle`, `YawAngle`, `RollAngle`).
* `calc_view_matrix(angles, origin)` delegates to Frostbite formulas `frostbite_engine::calc_view_matrix`, producing a `Mat4X4` view matrix for the given angles and origin.
* `calc_projection_matrix(fov, viewport, near, far)` builds a perspective projection by calling `calc_perspective_projection_matrix(fov_degrees, aspect, near, far)`, where `aspect = viewport.aspect_ratio()`. Accepts `FieldOfView` (degrees).
The traits types (`ViewAngles`, `Mat4X4`, angle aliases) and helpers live in the Frostbite engine math headers included by the trait (`formulas.hpp`) and the shared projection header (`projection/camera.hpp`).
---
## API
```cpp
namespace omath::frostbite_engine {
class CameraTrait final {
public:
// Compute Euler angles (pitch/yaw/roll) to look from cam_origin to look_at.
static ViewAngles
calc_look_at_angle(const Vector3<float>& cam_origin,
const Vector3<float>& look_at) noexcept;
// Build view matrix for given angles and origin.
static Mat4X4
calc_view_matrix(const ViewAngles& angles,
const Vector3<float>& cam_origin) noexcept;
// Build perspective projection from FOV (deg), viewport, near/far.
static Mat4X4
calc_projection_matrix(const projection::FieldOfView& fov,
const projection::ViewPort& view_port,
float near, float far) noexcept;
};
} // namespace omath::frostbite_engine
```
Uses: `Vector3<float>`, `ViewAngles` (pitch/yaw/roll), `Mat4X4`, `projection::FieldOfView`, `projection::ViewPort`.
---
## Behavior & conventions
* **Angles from look-at**:
```
dir = normalize(look_at - origin)
pitch = -asin(dir.y) // +Y is up
yaw = atan2(dir.x, dir.z)
roll = 0
```
Returned as `PitchAngle::from_radians(...)`, `YawAngle::from_radians(...)`, etc.
* **View matrix**: built by the Frostbite engine helper `frostbite_engine::calc_view_matrix(angles, origin)` to match the engines handedness and axis conventions.
* **Projection**: uses `calc_perspective_projection_matrix(fov.as_degrees(), viewport.aspect_ratio(), near, far)`. Pass your **vertical FOV** in degrees via `FieldOfView`; the helper computes a standard perspective matrix.
---
## Using with `projection::Camera`
Create a camera whose math is driven by this trait:
```cpp
using Mat4 = Mat4X4; // from Frostbite math headers
using Angs = ViewAngles; // pitch/yaw/roll type
using FBcam = omath::projection::Camera<Mat4, Angs, omath::frostbite_engine::CameraTrait>;
omath::projection::ViewPort vp{1920.f, 1080.f};
auto fov = omath::projection::FieldOfView::from_degrees(70.f);
FBcam cam(
/*position*/ {0.f, 1.7f, -3.f},
/*angles*/ omath::frostbite_engine::CameraTrait::calc_look_at_angle({0,1.7f,-3},{0,1.7f,0}),
/*viewport*/ vp,
/*fov*/ fov,
/*near*/ 0.1f,
/*far*/ 1000.f
);
```
This satisfies `CameraEngineConcept` expected by `projection::Camera` (look-at, view, projection) as declared in the trait header.
---
## Notes & tips
* Ensure your `ViewAngles` aliases (`PitchAngle`, `YawAngle`, `RollAngle`) match the projects angle policy (ranges/normalization). The implementation constructs them **from radians**.
* `aspect_ratio()` is taken directly from `ViewPort` (`width / height`), so keep both positive and non-zero.
* `near` must be > 0 and `< far` for a valid projection matrix (enforced by your math helpers).
---
## See also
* Frostbite math helpers in `omath/engines/frostbite_engine/formulas.hpp` (view/projection builders used above).
* Generic camera wrapper `omath::projection::Camera` and its `CameraEngineConcept` (this trait is designed to plug straight into it).