Extra2D/include/scene/node.h

244 lines
7.6 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 <algorithm>
#include <core/color.h>
#include <core/math_types.h>
#include <core/types.h>
#include <event/event_dispatcher.h>
#include <functional>
#include <renderer/renderer.h>
#include <memory>
#include <string>
#include <vector>
namespace extra2d {
// 前向声明
class Scene;
class Renderer;
struct RenderCommand;
// ============================================================================
// 节点基类 - 场景图的基础
// ============================================================================
class Node : public std::enable_shared_from_this<Node> {
public:
Node();
virtual ~Node();
// ------------------------------------------------------------------------
// 层级管理
// ------------------------------------------------------------------------
void addChild(Ptr<Node> child);
/**
* @brief 批量添加子节点
* @param children 子节点列表
*/
void addChildren(std::vector<Ptr<Node>> &&children);
void removeChild(Ptr<Node> child);
void removeChildByName(const std::string &name);
void removeFromParent();
void removeAllChildren();
Ptr<Node> parent() const { return parent_.lock(); }
const std::vector<Ptr<Node>> &children() const { return children_; }
Ptr<Node> childByName(const std::string &name) const;
Ptr<Node> childByTag(int tag) const;
// ------------------------------------------------------------------------
// 变换属性
// ------------------------------------------------------------------------
void setPosition(const Vec2 &pos);
void setPosition(float x, float y);
Vec2 pos() const { return position_; }
void setRotation(float degrees);
float rot() const { return rotation_; }
void setScale(const Vec2 &scale);
void setScale(float scale);
void setScale(float x, float y);
Vec2 scale() const { return scale_; }
void setAnchor(const Vec2 &anchor);
void setAnchor(float x, float y);
Vec2 anchor() const { return anchor_; }
void setSkew(const Vec2 &skew);
void setSkew(float x, float y);
Vec2 skew() const { return skew_; }
void setOpacity(float opacity);
float opacity() const { return opacity_; }
void setVisible(bool visible);
bool visible() const { return visible_; }
/**
* @brief 设置颜色
* @param color RGB颜色
*/
void setColor(const Color3B &color);
Color3B getColor() const { return color_; }
/**
* @brief 设置X轴翻转
*/
void setFlipX(bool flipX);
bool flipX() const { return flipX_; }
/**
* @brief 设置Y轴翻转
*/
void setFlipY(bool flipY);
bool flipY() const { return flipY_; }
void setZOrder(int zOrder);
int zOrder() const { return zOrder_; }
// ------------------------------------------------------------------------
// 世界变换
// ------------------------------------------------------------------------
Vec2 convertToWorldSpace(const Vec2 &localPos) const;
Vec2 convertToNodeSpace(const Vec2 &worldPos) const;
glm::mat4 getLocalTransform() const;
glm::mat4 getWorldTransform() const;
/**
* @brief 标记变换矩阵为脏状态,并传播到所有子节点
*/
void markTransformDirty();
/**
* @brief 批量更新变换矩阵
* 在渲染前统一计算所有脏节点的变换矩阵,避免逐节点计算时的重复递归
*/
void batchUpdateTransforms();
/**
* @brief 获取变换脏标记状态
*/
bool isTransformDirty() const { return transformDirty_; }
bool isWorldTransformDirty() const { return worldTransformDirty_; }
// ------------------------------------------------------------------------
// 名称和标签
// ------------------------------------------------------------------------
void setName(const std::string &name) { name_ = name; }
const std::string &name() const { return name_; }
void setTag(int tag) { tag_ = tag; }
int tag() const { return tag_; }
// ------------------------------------------------------------------------
// 生命周期回调
// ------------------------------------------------------------------------
virtual void onEnter();
virtual void onExit();
virtual void onUpdate(float dt);
virtual void onRender(Renderer &renderer);
virtual void onAttachToScene(Scene *scene);
virtual void onDetachFromScene();
// ------------------------------------------------------------------------
// 边界框
// ------------------------------------------------------------------------
virtual Rect boundingBox() const;
// ------------------------------------------------------------------------
// 事件系统
// ------------------------------------------------------------------------
EventDispatcher &getEventDispatcher() { return eventDispatcher_; }
// ------------------------------------------------------------------------
// 内部方法
// ------------------------------------------------------------------------
void update(float dt);
void render(Renderer &renderer);
void sortChildren();
bool isRunning() const { return running_; }
Scene *getScene() const { return scene_; }
// 多线程渲染命令收集
virtual void collectRenderCommands(std::vector<RenderCommand> &commands,
int parentZOrder = 0);
protected:
// 子类重写
virtual void onDraw(Renderer &renderer) {}
virtual void onUpdateNode(float dt) {}
virtual void generateRenderCommand(std::vector<RenderCommand> &commands,
int zOrder) {};
// 供子类访问的内部状态
Vec2 &getPositionRef() { return position_; }
Vec2 &getScaleRef() { return scale_; }
Vec2 &getAnchorRef() { return anchor_; }
float getRotationRef() { return rotation_; }
float getOpacityRef() { return opacity_; }
private:
// ==========================================================================
// 成员变量按类型大小降序排列,减少内存对齐填充
// 64位系统对齐std::string(32) > glm::mat4(64) > std::vector(24) >
// double(8) > float(4) > int(4) > bool(1)
// ==========================================================================
// 1. 大块内存64字节
mutable glm::mat4 localTransform_; // 64 bytes
mutable glm::mat4 worldTransform_; // 64 bytes
// 2. 字符串和容器24-32字节
std::string name_; // 32 bytes
std::vector<Ptr<Node>> children_; // 24 bytes
// 3. 子节点索引(加速查找)
std::unordered_map<std::string, WeakPtr<Node>> nameIndex_; // 56 bytes
std::unordered_map<int, WeakPtr<Node>> tagIndex_; // 56 bytes
// 4. 事件分发器
EventDispatcher eventDispatcher_; // 大小取决于实现
// 5. 父节点引用
WeakPtr<Node> parent_; // 16 bytes
// 7. 变换属性(按访问频率分组)
Vec2 position_ = Vec2::Zero(); // 8 bytes
Vec2 scale_ = Vec2(1.0f, 1.0f); // 8 bytes
Vec2 anchor_ = Vec2(0.5f, 0.5f); // 8 bytes
Vec2 skew_ = Vec2::Zero(); // 8 bytes
// 8. 浮点属性
float rotation_ = 0.0f; // 4 bytes
float opacity_ = 1.0f; // 4 bytes
// 10. 颜色属性
Color3B color_ = Color3B(255, 255, 255); // 3 bytes
// 11. 整数属性
int zOrder_ = 0; // 4 bytes
int tag_ = -1; // 4 bytes
// 12. 布尔属性
bool flipX_ = false; // 1 byte
bool flipY_ = false; // 1 byte
// 11. 场景指针
Scene *scene_ = nullptr; // 8 bytes
// 9. 布尔标志(打包在一起)
mutable bool transformDirty_ = true; // 1 byte
mutable bool worldTransformDirty_ = true; // 1 byte
bool childrenOrderDirty_ = false; // 1 byte
bool visible_ = true; // 1 byte
bool running_ = false; // 1 byte
};
} // namespace extra2d