mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 07:03:25 +00:00
110 lines
4.5 KiB
Markdown
110 lines
4.5 KiB
Markdown
# `omath::unreal_engine::CameraTrait` — plug-in trait for `projection::Camera`
|
||
|
||
> Header: `omath/engines/unreal_engine/traits/camera_trait.hpp` • Impl: `omath/engines/unreal_engine/traits/camera_trait.cpp`
|
||
> Namespace: `omath::unreal_engine`
|
||
> Purpose: provide Unreal Engine-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.z)` and **yaw** as `atan2(dir.y, dir.x)`; **roll** is `0`. Pitch/yaw are returned using the project's strong angle types (`PitchAngle`, `YawAngle`, `RollAngle`).
|
||
* `calc_view_matrix(angles, origin)` – delegates to Unreal Engine formulas `unreal_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 trait's types (`ViewAngles`, `Mat4X4`, angle aliases) and helpers live in the Unreal Engine math headers included by the trait (`formulas.hpp`) and the shared projection header (`projection/camera.hpp`).
|
||
|
||
---
|
||
|
||
## API
|
||
|
||
```cpp
|
||
namespace omath::unreal_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::unreal_engine
|
||
```
|
||
|
||
Uses: `Vector3<float>`, `ViewAngles` (pitch/yaw/roll), `Mat4X4`, `projection::FieldOfView`, `projection::ViewPort`.
|
||
|
||
---
|
||
|
||
## Behavior & conventions
|
||
|
||
* **Angles from look-at** (Z-up coordinate system):
|
||
|
||
```
|
||
dir = normalize(look_at - origin)
|
||
pitch = asin(dir.z) // +Z is up
|
||
yaw = atan2(dir.y, dir.x) // horizontal rotation
|
||
roll = 0
|
||
```
|
||
|
||
Returned as `PitchAngle::from_radians(...)`, `YawAngle::from_radians(...)`, etc.
|
||
|
||
* **View matrix**: built by the Unreal Engine helper `unreal_engine::calc_view_matrix(angles, origin)` to match the engine's 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 Unreal Engine math headers
|
||
using Angs = ViewAngles; // pitch/yaw/roll type
|
||
using UEcam = omath::projection::Camera<Mat4, Angs, omath::unreal_engine::CameraTrait>;
|
||
|
||
omath::projection::ViewPort vp{1920.f, 1080.f};
|
||
auto fov = omath::projection::FieldOfView::from_degrees(90.f);
|
||
|
||
UEcam cam(
|
||
/*position*/ {1000.f, 500.f, 200.f},
|
||
/*angles*/ omath::unreal_engine::CameraTrait::calc_look_at_angle({1000,500,200},{0,0,200}),
|
||
/*viewport*/ vp,
|
||
/*fov*/ fov,
|
||
/*near*/ 10.f,
|
||
/*far*/ 100000.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 project's 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).
|
||
* Unreal Engine uses **Z-up**: pitch angles control vertical look, positive = up.
|
||
|
||
---
|
||
|
||
## See also
|
||
|
||
* Unreal Engine math helpers in `omath/engines/unreal_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).
|