Extra2D/Extra2D/include/extra2d/scene/Camera.h

384 lines
7.4 KiB
C++
Raw 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 <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