Extra2D/include/scene/components/camera_component.h

281 lines
6.4 KiB
C
Raw Permalink Normal View History

#pragma once
#include <scene/component.h>
#include <types/math/rect.h>
#include <types/math/mat4.h>
#include <types/math/vec2.h>
namespace extra2d {
/**
* @brief
*
*
*/
class CameraComponent : public Component {
public:
static constexpr const char* TYPE_NAME = "Camera";
/**
* @brief
*/
enum class ProjectionType {
Orthographic, // 正交投影
Perspective // 透视投影
};
/**
* @brief
*/
CameraComponent();
/**
* @brief
* @return
*/
const char* getTypeName() const override { return TYPE_NAME; }
// ========================================
// 投影设置
// ========================================
/**
* @brief
* @param type
*/
void setProjectionType(ProjectionType type);
/**
* @brief
* @return
*/
ProjectionType getProjectionType() const { return projType_; }
/**
* @brief
* @param left
* @param right
* @param bottom
* @param top
* @param near
* @param far
*/
void setOrtho(float left, float right, float bottom, float top, float near, float far);
/**
* @brief
* @param fov
* @param aspect
* @param near
* @param far
*/
void setPerspective(float fov, float aspect, float near, float far);
// ========================================
// 变换属性(缩放、旋转)
// ========================================
/**
* @brief
* @param zoom 1.0>1<1
*/
void setZoom(float zoom);
/**
* @brief
* @return
*/
float getZoom() const { return zoom_; }
/**
* @brief
* @param degrees
*/
void setRotation(float degrees);
/**
* @brief
* @return
*/
float getRotation() const { return rotation_; }
// ========================================
// 矩阵获取
// ========================================
/**
* @brief
* @return
*/
Mat4 getViewMatrix() const;
/**
* @brief
* @return
*/
Mat4 getProjectionMatrix() const;
/**
* @brief
* @return
*/
Mat4 getViewProjectionMatrix() const;
// ========================================
// 坐标转换
// ========================================
/**
* @brief
* @param screenPos
* @return
*/
Vec2 screenToWorld(const Vec2& screenPos) const;
/**
* @brief
* @param x X坐标
* @param y Y坐标
* @return
*/
Vec2 screenToWorld(float x, float y) const;
/**
* @brief
* @param worldPos
* @return
*/
Vec2 worldToScreen(const Vec2& worldPos) const;
/**
* @brief
* @param x X坐标
* @param y Y坐标
* @return
*/
Vec2 worldToScreen(float x, float y) const;
// ========================================
// 视口
// ========================================
/**
* @brief
* @param viewport
*/
void setViewport(const Rect& viewport);
/**
* @brief
* @return
*/
Rect getViewport() const { return viewport_; }
// ========================================
// 边界限制
// ========================================
/**
* @brief
* @param bounds
*/
void setBounds(const Rect& bounds);
/**
* @brief
*/
void clearBounds();
/**
* @brief
* @return
*/
bool hasBounds() const { return hasBounds_; }
/**
* @brief
*/
void clampToBounds();
// ========================================
// 移动相机
// ========================================
/**
* @brief
* @param offset
*/
void move(const Vec2& offset);
/**
* @brief
* @param x X方向偏移量
* @param y Y方向偏移量
*/
void move(float x, float y);
/**
* @brief
* @param target
*/
void lookAt(const Vec2& target);
private:
/**
* @brief
*/
void markViewDirty() { viewDirty_ = true; vpDirty_ = true; }
/**
* @brief
*/
void markProjDirty() { projDirty_ = true; vpDirty_ = true; }
/**
* @brief
*/
void updateViewMatrix() const;
/**
* @brief
*/
void updateProjectionMatrix() const;
ProjectionType projType_ = ProjectionType::Orthographic;
// 投影参数
float left_ = 0.0f;
float right_ = 800.0f;
float bottom_ = 600.0f;
float top_ = 0.0f;
float near_ = -1.0f;
float far_ = 1.0f;
// 透视投影参数
float fov_ = 60.0f;
float aspect_ = 16.0f / 9.0f;
// 变换属性
float zoom_ = 1.0f;
float rotation_ = 0.0f;
// 视口
Rect viewport_;
// 边界限制
Rect bounds_;
bool hasBounds_ = false;
// 缓存矩阵mutable 用于 const 方法中延迟计算)
mutable Mat4 viewMatrix_ = Mat4(1.0f);
mutable Mat4 projMatrix_ = Mat4(1.0f);
mutable Mat4 vpMatrix_ = Mat4(1.0f);
// 脏标记
mutable bool viewDirty_ = true;
mutable bool projDirty_ = true;
mutable bool vpDirty_ = true;
};
} // namespace extra2d