Extra2D/include/scene/components/camera_component.h

281 lines
6.4 KiB
C++
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.

#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