384 lines
7.4 KiB
C++
384 lines
7.4 KiB
C++
#pragma once
|
||
|
||
#include <extra2d/base/Object.h>
|
||
#include <extra2d/math/Math.h>
|
||
#include <extra2d/gfx/GFXDef.h>
|
||
#include <glm/mat4x4.hpp>
|
||
#include <string>
|
||
|
||
namespace extra2d {
|
||
|
||
namespace gfx {
|
||
class Device;
|
||
}
|
||
|
||
class Node;
|
||
class RenderScene;
|
||
|
||
/**
|
||
* @brief 相机投影类型
|
||
*/
|
||
enum class CameraProjection {
|
||
Ortho,
|
||
Perspective,
|
||
};
|
||
|
||
/**
|
||
* @brief 相机信息结构
|
||
*/
|
||
struct CameraInfo {
|
||
std::string name;
|
||
Node* node{nullptr};
|
||
CameraProjection projection{CameraProjection::Ortho};
|
||
u32 priority{0};
|
||
u32 targetDisplay{0};
|
||
};
|
||
|
||
/**
|
||
* @brief 2D 相机类
|
||
*
|
||
* 管理 2D 场景的视图和投影变换。
|
||
* 参考 Cocos Creator 的 Camera 设计。
|
||
*/
|
||
class Camera : public RefCounted {
|
||
public:
|
||
/**
|
||
* @brief 创建相机
|
||
* @param device GFX 设备
|
||
* @return 相机引用
|
||
*/
|
||
static Ref<Camera> create(gfx::Device* device);
|
||
|
||
/**
|
||
* @brief 构造函数
|
||
* @param device GFX 设备
|
||
*/
|
||
explicit Camera(gfx::Device* device);
|
||
|
||
/**
|
||
* @brief 析构函数
|
||
*/
|
||
~Camera() override;
|
||
|
||
/**
|
||
* @brief 初始化相机
|
||
* @param info 相机信息
|
||
* @return 成功返回 true
|
||
*/
|
||
bool initialize(const CameraInfo& info);
|
||
|
||
/**
|
||
* @brief 销毁相机
|
||
*/
|
||
void destroy();
|
||
|
||
/**
|
||
* @brief 更新相机
|
||
* @param forceUpdate 是否强制更新
|
||
*/
|
||
void update(bool forceUpdate = false);
|
||
|
||
/**
|
||
* @brief 调整相机大小
|
||
* @param width 宽度
|
||
* @param height 高度
|
||
*/
|
||
void resize(u32 width, u32 height);
|
||
|
||
// ==================== 变换方法 ====================
|
||
|
||
/**
|
||
* @brief 将屏幕坐标转换为世界坐标
|
||
* @param screenPos 屏幕坐标
|
||
* @return 世界坐标
|
||
*/
|
||
Vec2 screenToWorld(const Vec2& screenPos);
|
||
|
||
/**
|
||
* @brief 将世界坐标转换为屏幕坐标
|
||
* @param worldPos 世界坐标
|
||
* @return 屏幕坐标
|
||
*/
|
||
Vec2 worldToScreen(const Vec2& worldPos);
|
||
|
||
/**
|
||
* @brief 将屏幕点转换为射线(用于拾取)
|
||
* @param x 屏幕 X 坐标
|
||
* @param y 屏幕 Y 坐标
|
||
* @return 射线原点(2D 使用)
|
||
*/
|
||
Vec2 screenPointToRay(float x, float y);
|
||
|
||
// ==================== 属性访问器 ====================
|
||
|
||
/**
|
||
* @brief 设置关联节点
|
||
* @param node 节点指针
|
||
*/
|
||
void setNode(Node* node);
|
||
|
||
/**
|
||
* @brief 获取关联节点
|
||
* @return 节点指针
|
||
*/
|
||
Node* getNode() const;
|
||
|
||
/**
|
||
* @brief 设置是否启用
|
||
* @param enabled 是否启用
|
||
*/
|
||
void setEnabled(bool enabled);
|
||
|
||
/**
|
||
* @brief 检查是否启用
|
||
* @return 如果启用返回 true
|
||
*/
|
||
bool isEnabled() const;
|
||
|
||
/**
|
||
* @brief 设置正交高度
|
||
* @param height 正交高度
|
||
*/
|
||
void setOrthoHeight(float height);
|
||
|
||
/**
|
||
* @brief 获取正交高度
|
||
* @return 正交高度
|
||
*/
|
||
float getOrthoHeight() const;
|
||
|
||
/**
|
||
* @brief 设置投影类型
|
||
* @param projection 投影类型
|
||
*/
|
||
void setProjectionType(CameraProjection projection);
|
||
|
||
/**
|
||
* @brief 获取投影类型
|
||
* @return 投影类型
|
||
*/
|
||
CameraProjection getProjectionType() const;
|
||
|
||
/**
|
||
* @brief 设置视场角
|
||
* @param fov 视场角(弧度)
|
||
*/
|
||
void setFov(float fov);
|
||
|
||
/**
|
||
* @brief 获取视场角
|
||
* @return 视场角(弧度)
|
||
*/
|
||
float getFov() const;
|
||
|
||
/**
|
||
* @brief 设置近裁剪面
|
||
* @param near 近裁剪面距离
|
||
*/
|
||
void setNearClip(float near);
|
||
|
||
/**
|
||
* @brief 获取近裁剪面
|
||
* @return 近裁剪面距离
|
||
*/
|
||
float getNearClip() const;
|
||
|
||
/**
|
||
* @brief 设置远裁剪面
|
||
* @param far 远裁剪面距离
|
||
*/
|
||
void setFarClip(float far);
|
||
|
||
/**
|
||
* @brief 获取远裁剪面
|
||
* @return 远裁剪面距离
|
||
*/
|
||
float getFarClip() const;
|
||
|
||
/**
|
||
* @brief 设置清除颜色
|
||
* @param color 清除颜色
|
||
*/
|
||
void setClearColor(const gfx::Color& color);
|
||
|
||
/**
|
||
* @brief 获取清除颜色
|
||
* @return 清除颜色
|
||
*/
|
||
const gfx::Color& getClearColor() const;
|
||
|
||
/**
|
||
* @brief 设置清除标志
|
||
* @param flag 清除标志
|
||
*/
|
||
void setClearFlag(gfx::ClearFlagBit flag);
|
||
|
||
/**
|
||
* @brief 获取清除标志
|
||
* @return 清除标志
|
||
*/
|
||
gfx::ClearFlagBit getClearFlag() const;
|
||
|
||
/**
|
||
* @brief 设置优先级
|
||
* @param priority 优先级
|
||
*/
|
||
void setPriority(u32 priority);
|
||
|
||
/**
|
||
* @brief 获取优先级
|
||
* @return 优先级
|
||
*/
|
||
u32 getPriority() const;
|
||
|
||
/**
|
||
* @brief 获取宽度
|
||
* @return 宽度
|
||
*/
|
||
u32 getWidth() const;
|
||
|
||
/**
|
||
* @brief 获取高度
|
||
* @return 高度
|
||
*/
|
||
u32 getHeight() const;
|
||
|
||
/**
|
||
* @brief 获取宽高比
|
||
* @return 宽高比
|
||
*/
|
||
float getAspect() const;
|
||
|
||
/**
|
||
* @brief 获取视图矩阵
|
||
* @return 视图矩阵
|
||
*/
|
||
const glm::mat4& getMatView() const;
|
||
|
||
/**
|
||
* @brief 获取投影矩阵
|
||
* @return 投影矩阵
|
||
*/
|
||
const glm::mat4& getMatProj() const;
|
||
|
||
/**
|
||
* @brief 获取视图投影矩阵
|
||
* @return 视图投影矩阵
|
||
*/
|
||
const glm::mat4& getMatViewProj() const;
|
||
|
||
/**
|
||
* @brief 获取相机名称
|
||
* @return 相机名称
|
||
*/
|
||
const std::string& getName() const;
|
||
|
||
/**
|
||
* @brief 获取所属渲染场景
|
||
* @return 渲染场景指针
|
||
*/
|
||
RenderScene* getScene() const;
|
||
|
||
/**
|
||
* @brief 附加到渲染场景
|
||
* @param scene 渲染场景
|
||
*/
|
||
void attachToScene(RenderScene* scene);
|
||
|
||
/**
|
||
* @brief 从渲染场景分离
|
||
*/
|
||
void detachFromScene();
|
||
|
||
/**
|
||
* @brief 设置可见性掩码
|
||
* @param visibility 可见性掩码
|
||
*/
|
||
void setVisibility(u32 visibility);
|
||
|
||
/**
|
||
* @brief 获取可见性掩码
|
||
* @return 可见性掩码
|
||
*/
|
||
u32 getVisibility() const;
|
||
|
||
/**
|
||
* @brief 设置相机位置
|
||
* @param pos 位置
|
||
*/
|
||
void setPosition(const Vec2& pos);
|
||
|
||
/**
|
||
* @brief 获取相机位置
|
||
* @return 位置
|
||
*/
|
||
const Vec2& getPosition() const;
|
||
|
||
/**
|
||
* @brief 设置相机前向
|
||
* @param forward 前向向量
|
||
*/
|
||
void setForward(const Vec2& forward);
|
||
|
||
/**
|
||
* @brief 获取相机前向
|
||
* @return 前向向量
|
||
*/
|
||
const Vec2& getForward() const;
|
||
|
||
/**
|
||
* @brief 获取相机 ID
|
||
* @return 相机 ID
|
||
*/
|
||
u32 getCameraId() const;
|
||
|
||
protected:
|
||
/**
|
||
* @brief 更新投影矩阵
|
||
*/
|
||
void updateProjection();
|
||
|
||
/**
|
||
* @brief 更新视图矩阵
|
||
*/
|
||
void updateView();
|
||
|
||
private:
|
||
gfx::Device* device_{nullptr};
|
||
RenderScene* scene_{nullptr};
|
||
Node* node_{nullptr};
|
||
|
||
std::string name_;
|
||
u32 cameraId_{0};
|
||
bool enabled_{false};
|
||
|
||
CameraProjection projection_{CameraProjection::Ortho};
|
||
float aspect_{1.0f};
|
||
float orthoHeight_{10.0f};
|
||
float fov_{0.785398f};
|
||
float nearClip_{1.0f};
|
||
float farClip_{1000.0f};
|
||
|
||
gfx::Color clearColor_{0.2f, 0.2f, 0.2f, 1.0f};
|
||
gfx::ClearFlagBit clearFlag_{gfx::ClearFlagBit::ALL};
|
||
|
||
u32 width_{0};
|
||
u32 height_{0};
|
||
u32 priority_{0};
|
||
u32 visibility_{0xFFFFFFFF};
|
||
|
||
Vec2 position_{0, 0};
|
||
Vec2 forward_{0, -1};
|
||
|
||
glm::mat4 matView_{1.0f};
|
||
glm::mat4 matProj_{1.0f};
|
||
glm::mat4 matViewProj_{1.0f};
|
||
|
||
bool isProjDirty_{true};
|
||
bool isViewDirty_{true};
|
||
|
||
static u32 s_cameraIdCounter;
|
||
};
|
||
|
||
} // namespace extra2d
|