82 lines
2.8 KiB
C++
82 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include <Orange/Math/Basic.h>
|
|
#include <Orange/Math/Transform.h>
|
|
|
|
namespace orange
|
|
{
|
|
enum class ProjectionType
|
|
{
|
|
Perspective,
|
|
InfinitePerspective,
|
|
Orthographic,
|
|
};
|
|
|
|
struct Camera
|
|
{
|
|
void lookAt(const vec3& position, const vec3& up = {0.0f, 1.0f, 0.0f})
|
|
{
|
|
transform.orientation =
|
|
conjugate(Math::lookAt<quat>(transform.position, position, up));
|
|
}
|
|
|
|
void offsetOrientation(const Radian& yaw, const Radian& pitch)
|
|
{
|
|
const quat yawRot = angleAxis(yaw, vec3{0.0f, 1.0f, 0.0f});
|
|
const quat pitchRot = angleAxis(pitch, right());
|
|
|
|
transform.orientation = yawRot * pitchRot * transform.orientation;
|
|
}
|
|
|
|
vec3 forward() const { return transform.orientation * vec3{0.0f, 0.0f, -1.0f}; }
|
|
vec3 backward() const { return transform.orientation * vec3{0.0f, 0.0f, +1.0f}; }
|
|
|
|
vec3 right() const { return transform.orientation * vec3{+1.0f, 0.0f, 0.0f}; }
|
|
vec3 left() const { return transform.orientation * vec3{-1.0f, 0.0f, 0.0f}; }
|
|
|
|
vec3 up() const { return transform.orientation * vec3{0.0f, +1.0f, 0.0f}; }
|
|
vec3 down() const { return transform.orientation * vec3{0.0f, -1.0f, 0.0f}; }
|
|
|
|
mat4 matrix() const { return projection() * view(); }
|
|
mat4 projection() const
|
|
{
|
|
if (projectionType == ProjectionType::Perspective)
|
|
{
|
|
return Math::perspective(
|
|
fieldOfView, viewportAspectRatio, nearPlane, farPlane);
|
|
}
|
|
else if (projectionType == ProjectionType::InfinitePerspective)
|
|
{
|
|
return Math::infinitePerspective(
|
|
fieldOfView, viewportAspectRatio, nearPlane);
|
|
}
|
|
else if (projectionType == ProjectionType::Orthographic)
|
|
{
|
|
const float distance = 0.5f * (farPlane - nearPlane);
|
|
return Math::ortho(
|
|
-orthoScale * viewportAspectRatio,
|
|
orthoScale * viewportAspectRatio,
|
|
-orthoScale, orthoScale,
|
|
-distance, distance);
|
|
}
|
|
|
|
return mat4{};
|
|
}
|
|
mat4 view() const
|
|
{
|
|
return Math::scale(vec3{1.0f} / transform.scale) *
|
|
quaternionToMatrix4(conjugate(transform.orientation)) *
|
|
Math::translate(-transform.position);
|
|
|
|
}
|
|
|
|
Transform transform = {};
|
|
Radian fieldOfView = Degree(90.0f);
|
|
float orthoScale = 1.0f;
|
|
float nearPlane = 0.1f;
|
|
float farPlane = 1024.0f;
|
|
float viewportAspectRatio = 1.0f;
|
|
ProjectionType projectionType = ProjectionType::Perspective;
|
|
};
|
|
}
|