From faf99dfc68fe9fc2c143eb4bf3614d4f741425e2 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Fri, 13 Mar 2026 01:35:46 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/XCGameEngine架构设计.md | 6025 ++++++++++++++++++++++ docs/XCVolumeRenderer渲染引擎架构设计.md | 1845 +++++++ imgui.ini | 24 + 3 files changed, 7894 insertions(+) create mode 100644 docs/XCGameEngine架构设计.md create mode 100644 docs/XCVolumeRenderer渲染引擎架构设计.md create mode 100644 imgui.ini diff --git a/docs/XCGameEngine架构设计.md b/docs/XCGameEngine架构设计.md new file mode 100644 index 00000000..b505f2c4 --- /dev/null +++ b/docs/XCGameEngine架构设计.md @@ -0,0 +1,6025 @@ +# XCEngine - 仿Unity引擎架构设计文档 + +> **⚠️ 重要声明(严禁修改!)** +> 下文出现矛盾时永远以开头声明为准!!!!!!!! +> 本架构**1:1参考传统Unity引擎架构**(GameObject + MonoBehaviour模式),**不是Unity DOTS**! +> +> - 组件是**类**(引用类型),包含数据和行为 +> - 实体是GameObject容器 +> - 系统是OOP风格的类 +> - 不是纯数据组件 + 纯函数系统的DOTS模式 +> - 不是SoA内存布局(**除粒子系统性能关键路径外**) +> - 不要被"ECS"这个词误导,这里是传统Unity的Component模式 +> - TransformComponent继承自Component,与Unity的GetComponent\() API行为一致 + +--- + +## 文档信息 + +- **版本**: 1.0 +- **日期**: 2026-03-12 +- **状态**: 架构设计文档 +- **目标**: 构建类Unity的专业游戏引擎 + +--- + +## 第一章 整体架构概览 + +### 1.1 架构设计原则 + +本引擎采用**分层架构**结合**模块化设计**,遵循以下核心原则: + +1. **关注点分离 (Separation of Concerns)**: 各系统独立演化,通过明确定义的接口通信 +2. **依赖倒置 (Dependency Inversion)**: 上层模块依赖抽象接口,不依赖具体实现 +3. **开闭原则 (Open-Closed)**: 对扩展开放,对修改封闭 +4. **单一职责 (Single Responsibility)**: 每个模块只负责一项职责 +5. **数据驱动 (Data-Driven)**: 引擎行为由数据(组件、资源、配置)驱动 +6. **组件化架构**: 采用类Unity的组件模式,组件挂载在实体上 +7. **渲染抽象**: 跨 API 的渲染接口,便于多平台支持 + +### 1.2 整体架构图 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ XCGameEngine │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐│ +│ │ Editor │ │ Runtime │ │ Toolchain ││ +│ │ (编辑器) │ │ (运行时) │ │ (工具链) ││ +│ ├─────────────────┤ ├─────────────────┤ ├─────────────────────────┤│ +│ │ • UI Framework │ │ • Game Loop │ │ • Asset Processor ││ +│ │ • Scene View │ │ • Component Update │ │ • Shader Compiler ││ +│ │ • Inspector │ │ • Physics Sim │ │ • Mesh Optimizer ││ +│ │ • Hierarchy │ │ • Audio Engine │ │ • Texture Compressor ││ +│ │ • Project │ │ • Script VM │ │ • Build Pipeline ││ +│ │ • Console │ │ • Networking │ │ • Profiler ││ +│ └────────┬────────┘ └────────┬────────┘ └────────────┬────────────┘│ +│ │ │ │ │ +│ └───────────────────────┼──────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ Engine Core │ │ +│ ├────────────────────────────────────────────────────────────────────────┤ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐│ │ +│ │ │ Renderer │ │ Scene │ │ Resource │ │ Components ││ │ +│ │ │ (渲染) │ │ (场景) │ │ (资源) │ │ (组件系统) ││ │ +│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘│ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐│ │ +│ │ │ Physics │ │ Audio │ │ Script │ │ Math ││ │ +│ │ │ (物理) │ │ (音频) │ │ (脚本) │ │ (数学) ││ │ +│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘│ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐│ │ +│ │ │ Memory │ │ Thread │ │ Network │ │ File ││ │ +│ │ │ (内存) │ │ (线程) │ │ (网络) │ │ (文件) ││ │ +│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘│ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ Platform Layer │ │ +│ ├────────────────────────────────────────────────────────────────────────┤ │ +│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │ │ +│ │ │ D3D12 │ │ Vulkan │ │ Metal │ │ OpenGL │ │ │ +│ │ └─────────┘ └─────────┘ └─────────┘ └─────────────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### 1.3 目录结构设计 + +``` +XCVolumeRenderer/ +├── engine/ # 引擎核心库(静态库) +│ ├── CMakeLists.txt +│ ├── include/ +│ │ └── XCGameEngine/ +│ │ ├── Core/ # 核心基础 +│ │ │ ├── Assert.h +│ │ │ ├── Enum.h +│ │ │ ├── Flags.h +│ │ │ ├── TypeTraits.h +│ │ │ ├── Variant.h +│ │ │ └── UniquePtr.h +│ │ ├── Math/ # 数学库 +│ │ │ ├── Vector2.h +│ │ │ ├── Vector3.h +│ │ │ ├── Vector4.h +│ │ │ ├── Matrix2.h +│ │ │ ├── Matrix3.h +│ │ │ ├── Matrix4.h +│ │ │ ├── Quaternion.h +│ │ │ ├── Transform.h +│ │ │ ├── Color.h +│ │ │ ├── MathUtils.h +│ │ │ ├── Ray.h +│ │ │ ├── Plane.h +│ │ │ ├── Sphere.h +│ │ │ ├── Box.h +│ │ │ └── Frustum.h +│ │ ├── Containers/ # 容器 +│ │ │ ├── Array.h +│ │ │ ├── FixedArray.h +│ │ │ ├── Vector.h +│ │ │ ├── Map.h +│ │ │ ├── Set.h +│ │ │ ├── HashMap.h +│ │ │ ├── String.h +│ │ │ └── RingBuffer.h +│ │ ├── Memory/ # 内存管理 +│ │ │ ├── Allocator.h +│ │ │ ├── StackAllocator.h +│ │ │ ├── PoolAllocator.h +│ │ │ ├── FreeListAllocator.h +│ │ │ ├── ProxyAllocator.h +│ │ │ └── MemoryUtils.h +│ │ ├── Threading/ # 线程 +│ │ │ ├── Thread.h +│ │ │ ├── Mutex.h +│ │ │ ├── RWLock.h +│ │ │ ├── Semaphore.h +│ │ │ ├── ThreadPool.h +│ │ │ ├── TaskSystem.h +│ │ │ ├── SpinLock.h +│ │ │ └── Atomic.h +│ │ ├── IO/ # 文件IO +│ │ │ ├── FileSystem.h +│ │ │ ├── Path.h +│ │ │ ├── Stream.h +│ │ │ ├── FileReader.h +│ │ │ ├── FileWriter.h +│ │ │ ├── Archive.h +│ │ │ └── Compression.h +│ │ ├── Debug/ # 调试 +│ │ │ ├── Logger.h +│ │ │ ├── Profiler.h +│ │ │ ├── DebugDraw.h +│ │ │ ├── Assertion.h +│ │ │ └── Traces.h +│ │ ├── Components/ # 组件系统(类Unity GameObject模式) +│ │ │ ├── GameObject.h # 游戏对象 +│ │ │ ├── Component.h # 组件基类 +│ │ │ └── System.h # 系统基类 +│ │ ├── Scene/ # 场景系统 +│ │ │ ├── Scene.h +│ │ │ ├── SceneLoader.h +│ │ │ ├── SceneSerializer.h +│ │ │ ├── SubScene.h +│ │ │ └── SceneManager.h +│ │ ├── Renderer/ # 渲染系统 +│ │ │ ├── ForwardDeclarations.h +│ │ │ ├── Device.h +│ │ │ ├── Context.h +│ │ │ ├── SwapChain.h +│ │ │ ├── Buffer.h +│ │ │ ├── Texture.h +│ │ │ ├── Shader.h +│ │ │ ├── Pipeline.h +│ │ │ ├── RenderPass.h +│ │ │ ├── RenderTarget.h +│ │ │ ├── CommandList.h +│ │ │ ├── CommandQueue.h +│ │ │ ├── Descriptor.h +│ │ │ ├── Fence.h +│ │ │ ├── QueryHeap.h +│ │ │ ├── GpuResource.h +│ │ │ ├── GpuAllocator.h +│ │ │ ├── GpuEvent.h +│ │ │ ├── RenderModule.h +│ │ │ ├── RenderGraph.h +│ │ │ ├── Light.h +│ │ │ ├── Camera.h +│ │ │ ├── Material.h +│ │ │ ├── Mesh.h +│ │ │ ├── Skybox.h +│ │ │ ├── DebugRenderer.h +│ │ │ └── PostProcess.h +│ │ ├── Resources/ # 资源系统 +│ │ │ ├── Resource.h +│ │ │ ├── ResourceManager.h +│ │ │ ├── ResourceLoader.h +│ │ │ ├── ResourceCache.h +│ │ │ ├── AssetDatabase.h +│ │ │ ├── ImportSettings.h +│ │ │ ├── ResourceCooker.h +│ │ │ └── Bundle.h +│ │ ├── Physics/ # 物理系统 +│ │ │ ├── PhysicsWorld.h +│ │ │ ├── RigidBody.h +│ │ │ ├── Collider.h +│ │ │ ├── Joint.h +│ │ │ ├── CharacterController.h +│ │ │ ├── Trigger.h +│ │ │ ├── Raycast.h +│ │ │ ├── ForceField.h +│ │ │ └── PhysicsMaterial.h +│ │ ├── Audio/ # 音频系统 +│ │ │ ├── AudioEngine.h +│ │ │ ├── AudioSource.h +│ │ │ ├── AudioListener.h +│ │ │ ├── AudioClip.h +│ │ │ ├── AudioMixer.h +│ │ │ ├── AudioEffect.h +│ │ │ └── AudioBanks.h +│ │ ├── Scripting/ # 脚本系统 +│ │ │ ├── ScriptEngine.h +│ │ │ ├── ScriptClass.h +│ │ │ ├── ScriptObject.h +│ │ │ ├── ScriptMethod.h +│ │ │ ├── MonoBridge.h +│ │ │ ├── LuaBridge.h +│ │ │ └── AngelScript.h +│ │ ├── Animation/ # 动画系统 +│ │ │ ├── Animator.h +│ │ │ ├── AnimationClip.h +│ │ │ ├── AnimationCurve.h +│ │ │ ├── AnimationState.h +│ │ │ ├── AnimationBlendTree.h +│ │ │ ├── Skeleton.h +│ │ │ ├── Bone.h +│ │ │ ├── Skinning.h +│ │ │ └── BlendShape.h +│ │ ├── Particles/ # 粒子系统 +│ │ │ ├── ParticleSystem.h +│ │ │ ├── ParticleEmitter.h +│ │ │ ├── ParticleRenderer.h +│ │ │ ├── ParticleForce.h +│ │ │ ├── GPUParticles.h +│ │ │ └── VFXGraph.h +│ │ ├── Networking/ # 网络系统 +│ │ │ ├── NetworkManager.h +│ │ │ ├── NetworkClient.h +│ │ │ ├── NetworkServer.h +│ │ │ ├── NetworkPeer.h +│ │ │ ├── Packet.h +│ │ │ ├── Serializer.h +│ │ │ ├── RPC.h +│ │ │ ├── NetworkTransform.h +│ │ │ └── NetcodeProtocol.h +│ │ ├── UI/ # UI系统 +│ │ │ ├── Canvas.h +│ │ │ ├── Element.h +│ │ │ ├── Image.h +│ │ │ ├── Text.h +│ │ │ ├── Button.h +│ │ │ ├── ScrollView.h +│ │ │ ├── LayoutGroup.h +│ │ │ ├── UIRenderer.h +│ │ │ └── Font.h +│ │ ├── Navigation/ # 导航系统 +│ │ │ ├── NavMesh.h +│ │ │ ├── NavMeshAgent.h +│ │ │ ├── NavMeshQuery.h +│ │ │ ├── Obstacle.h +│ │ │ └── CrowdSystem.h +│ │ ├── Platforms/ # 平台层 +│ │ │ ├── Platform.h +│ │ │ ├── Windows.h +│ │ │ ├── Linux.h +│ │ │ ├── MacOS.h +│ │ │ ├── Android.h +│ │ │ ├── IOS.h +│ │ │ └── Web.h +│ │ └── XCGameEngine.h # 主头文件 +│ ├── src/ +│ │ ├── Core/ +│ │ ├── Math/ +│ │ ├── Components/ # 组件系统 +│ │ ├── Scene/ +│ │ ├── Renderer/ +│ │ ├── Resources/ +│ │ ├── Physics/ +│ │ ├── Audio/ +│ │ ├── Scripting/ +│ │ └── ... +│ └── third_party/ # 第三方库 +│ ├── stb/ +│ ├── json/ +│ ├── lua/ +│ ├── physx/ +│ └── etc. +│ +├── editor/ # 编辑器项目(你的UI) +│ ├── CMakeLists.txt +│ ├── src/ +│ │ ├── Application.h/cpp +│ │ ├── main.cpp +│ │ ├── Theme.h/cpp +│ │ ├── Core/ +│ │ │ ├── Event.h +│ │ │ ├── AssetItem.h +│ │ │ └── LogEntry.h +│ │ ├── Managers/ +│ │ │ ├── SelectionManager.h +│ │ │ ├── LogSystem.h/cpp +│ │ │ ├── ProjectManager.h/cpp +│ │ │ └── EditorSceneManager.h/cpp +│ │ ├── Panels/ +│ │ │ ├── Panel.h/cpp +│ │ │ ├── MenuBar.h/cpp +│ │ │ ├── HierarchyPanel.h/cpp +│ │ │ ├── InspectorPanel.h/cpp +│ │ │ ├── SceneViewPanel.h/cpp +│ │ │ ├── GameViewPanel.h/cpp +│ │ │ ├── ProjectPanel.h/cpp +│ │ │ ├── ConsolePanel.h/cpp +│ │ │ ├── AssetsBrowserPanel.h/cpp +│ │ │ ├── AnimationPanel.h/cpp +│ │ │ ├── ProfilerPanel.h/cpp +│ │ │ └── SettingsPanel.h/cpp +│ │ ├── Windows/ +│ │ │ ├── AssetImporter.h/cpp +│ │ │ ├── SceneHierarchyWindow.h/cpp +│ │ │ ├── ShaderEditor.h/cpp +│ │ │ ├── MaterialEditor.h/cpp +│ │ │ ├── AnimationEditor.h/cpp +│ │ │ └── PreferenceWindow.h/cpp +│ │ ├── Tools/ +│ │ │ ├── Gizmo.h/cpp +│ │ │ ├── SelectionTool.h/cpp +│ │ │ ├── MoveTool.h/cpp +│ │ │ ├── RotateTool.h/cpp +│ │ │ ├── ScaleTool.h/cpp +│ │ │ └── EditorCamera.h/cpp +│ │ ├── Editor/ +│ │ │ ├── EditorEngineLink.h/cpp +│ │ │ ├── EditorRenderView.h/cpp +│ │ │ ├── EditorModes.h +│ │ │ └── UndoRedo.h/cpp +│ │ └── ImGui/ +│ │ ├── ImGuiRenderer.h/cpp +│ │ ├── ImGuiTheme.h/cpp +│ │ └── ImGuiWidgets.h/cpp +│ └── assets/ +│ ├── fonts/ +│ ├── icons/ +│ └── themes/ +│ +├── runtime/ # 游戏运行时(独立可执行文件) +│ ├── CMakeLists.txt +│ ├── src/ +│ │ ├── GameMain.cpp +│ │ ├── RuntimeConfig.h +│ │ └── EntryPoint.cpp +│ └── resources/ +│ └── (烘焙后的场景和资源) +│ +├── tools/ # 工具链 +│ ├── AssetProcessor/ # 资源处理器 +│ ├── ShaderCompiler/ # 着色器编译器 +│ ├── SceneCooker/ # 场景烘焙工具 +│ ├── TextureConverter/ # 纹理转换工具 +│ ├── MeshOptimizer/ # 网格优化工具 +│ ├── AudioImporter/ # 音频导入工具 +│ ├── BuildTool/ # 构建打包工具 +│ └── ShaderDebugger/ # 着色器调试工具 +│ +├── content/ # 资源内容 +│ ├── Assets/ +│ │ ├── Scenes/ +│ │ ├── Materials/ +│ │ ├── Meshes/ +│ │ ├── Textures/ +│ │ ├── Audio/ +│ │ ├── Scripts/ +│ │ ├── Shaders/ +│ │ ├── Animations/ +│ │ ├── Prefabs/ +│ │ └── UI/ +│ ├── Packages/ # 包管理 +│ └── Library/ # 引擎库缓存 +│ ├── ShaderLibrary/ +│ ├── ShaderCache/ +│ ├── AssetDatabase/ +│ ├── SourceAssets/ +│ └── ImportCache/ +│ +└── docs/ # 文档 + ├── Architecture.md + ├── ComponentReference.md + ├── ShaderGuide.md + └── APIReference.md +``` + +--- + +## 第二章 核心层 (Core Layer) + +核心层提供引擎所有其他部分依赖的基础功能,是整个引擎的基石。 + +### 2.1 数学库 (Math Library) + +#### 2.1.1 设计目标 + +- **高性能**: SIMD 优化,支持 SSE/AVX/NEON +- **精确性**: 满足游戏精度需求,避免浮点误差 +- **完整性**: 覆盖游戏开发所需的所有数学类型 +- **可读性**: 简洁清晰的 API 设计 + +#### 2.1.2 核心类型 + +```cpp +namespace XCEngine { +namespace Math { + +// 向量类型 +struct Vector2 { float x, y; }; +struct Vector3 { float x, y, z; }; +struct Vector4 { float x, y, z, w; }; + +// 矩阵类型 +struct Matrix3x3; // 3D变换 +struct Matrix4x4; // 4D变换 +struct Matrix2x2; // 2D变换 + +// 四元数 - 避免欧拉角万向节锁 +struct Quaternion { + float x, y, z, w; + + // 旋转变换 + static Quaternion FromAxisAngle(const Vector3& axis, float radians); + static Quaternion FromEulerAngles(float pitch, float yaw, float roll); + static Quaternion FromRotationMatrix(const Matrix4x4& matrix); + static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float t); + + Vector3 ToEulerAngles() const; + Matrix4x4 ToMatrix4x4() const; + Vector3 operator*(const Vector3& v) const; // 旋转向量 +}; + +// 变换 - 组合位置、旋转、缩放 +struct Transform { + Vector3 position = Vector3::Zero(); + Quaternion rotation = Quaternion::Identity(); + Vector3 scale = Vector3::One(); + + Matrix4x4 ToMatrix() const; + Transform Inverse() const; + Transform operator*(const Transform& other) const; // 组合变换 + Vector3 TransformPoint(const Vector3& point) const; + Vector3 TransformDirection(const Vector3& direction) const; +}; + +// 空间参照 +enum class Space { + Self, // 自身局部空间 + World // 世界空间 +}; + +// 颜色 +struct Color { float r, g, b, a; }; +struct LinearColor; // 线性空间颜色 +struct HDRColor; // HDR颜色 + +// 射线 - 用于射线检测和选择 +struct Ray { + Vector3 origin; + Vector3 direction; + + Vector3 GetPoint(float t) const; + bool Intersects(const Sphere& sphere, float& t) const; + bool Intersects(const Box& box, float& t) const; + bool Intersects(const Plane& plane, float& t) const; +}; + +// 包围体 +struct Sphere { Vector3 center; float radius; }; +struct Box { Vector3 center; Vector3 extents; Matrix4x4 transform; }; +struct Frustum; // 视锥体 +struct OBB; // 定向包围盒 +struct AABB; // 轴对齐包围盒 + +} // namespace Math +} // namespace XCEngine +``` + +#### 2.1.3 SIMD 优化示例 + +```cpp +// 使用 SIMD 进行向量运算 +struct alignas(16) Vector3_SIMD { + union { + __m128 simd; + struct { float x, y, z, w; }; + }; + + Vector3_SIMD operator+(const Vector3_SIMD& other) const { + Vector3_SIMD result; + result.simd = _mm_add_ps(simd, other.simd); + return result; + } + + float Dot(const Vector3_SIMD& other) const { + __m128 dot = _mm_mul_ps(simd, other.simd); + __m128 temp = _mm_movehl_ps(dot, dot); + dot = _mm_add_ss(dot, temp); + return _mm_cvtss_f32(dot); + } + + Vector3_SIMD Cross(const Vector3_SIMD& other) const { + Vector3_SIMD result; + __m128 a = _mm_shuffle_ps(simd, simd, _MM_SHUFFLE(3,0,2,1)); + __m128 b = _mm_shuffle_ps(other.simd, other.simd, _MM_SHUFFLE(3,1,0,2)); + result.simd = _mm_sub_ps(_mm_mul_ps(simd, a), _mm_mul_ps(other.simd, b)); + result.simd = _mm_shuffle_ps(result.simd, result.simd, _MM_SHUFFLE(3,0,2,1)); + return result; + } +}; +``` + +### 2.2 内存管理 (Memory Management) + +```cpp +namespace XCEngine { +namespace Memory { + +// 分配器基类 +class IAllocator { +public: + virtual ~IAllocator() = default; + + virtual void* Allocate(size_t size, size_t alignment = 0) = 0; + virtual void Free(void* ptr) = 0; + virtual void* Reallocate(void* ptr, size_t newSize) = 0; + + virtual size_t GetTotalAllocated() const = 0; + virtual size_t GetTotalFreed() const = 0; + virtual size_t GetPeakAllocated() const = 0; + virtual size_t GetAllocationCount() const = 0; + + virtual const char* GetName() const = 0; +}; + +// 线性分配器 - 快速分配和批量释放 +class LinearAllocator : public IAllocator { +public: + explicit LinearAllocator(size_t size, IAllocator* parent = nullptr); + ~LinearAllocator(); + + void* Allocate(size_t size, size_t alignment = 8) override; + void Free(void* ptr) override; // 只重置,不真正释放 + void Clear(); // 清空所有内存 + + void* GetMarker() const; + void SetMarker(void* marker); + +private: + byte* m_buffer = nullptr; + size_t m_capacity = 0; + size_t m_offset = 0; + IAllocator* m_parent = nullptr; +}; + +// 池分配器 - 高频小对象分配 +class PoolAllocator : public IAllocator { +public: + PoolAllocator(size_t blockSize, size_t poolSize, size_t alignment = 8); + ~PoolAllocator(); + + void* Allocate(size_t size, size_t alignment = 0) override; + void Free(void* ptr) override; + + bool Contains(void* ptr) const; + size_t GetBlockSize() const { return m_blockSize; } + size_t GetFreeBlockCount() const; + +private: + struct FreeNode { + FreeNode* next; + }; + + size_t m_blockSize = 0; + size_t m_alignment = 0; + void* m_memory = nullptr; + FreeNode* m_freeList = nullptr; + size_t m_totalBlocks = 0; + size_t m_freeBlocks = 0; +}; + +// 代理分配器 - 用于追踪和调试 +class ProxyAllocator : public IAllocator { +public: + ProxyAllocator(IAllocator* underlying, const char* name); + + void* Allocate(size_t size, size_t alignment = 0) override; + void Free(void* ptr) override; + void* Reallocate(void* ptr, size_t newSize) override; + + struct Stats { + size_t totalAllocated; + size_t totalFreed; + size_t peakAllocated; + size_t allocationCount; + size_t memoryOverhead; + }; + const Stats& GetStats() const; + +private: + IAllocator* m_underlying; + const char* m_name; + Stats m_stats; + Mutex m_mutex; +}; + +// 全局内存管理器 +class MemoryManager { +public: + static MemoryManager& Get(); + + void Initialize(); + void Shutdown(); + + IAllocator* GetSystemAllocator(); + IAllocator* GetPhysicsAllocator(); + IAllocator* GetRenderingAllocator(); + IAllocator* GetAudioAllocator(); + + std::unique_ptr CreateLinearAllocator(size_t size); + std::unique_ptr CreatePoolAllocator(size_t blockSize, size_t count); + std::unique_ptr CreateProxyAllocator(const char* name); + + void SetTrackAllocations(bool track); + void DumpMemoryLeaks(); + void GenerateMemoryReport(); +}; + +#define XE_ALLOC(allocator, size, ...) allocator->Allocate(size, ##__VA_ARGS__) +#define XE_FREE(allocator, ptr) allocator->Free(ptr) + +} +} +``` + +### 2.3 线程系统 (Threading) + +```cpp +namespace XCEngine { +namespace Threading { + +enum class TaskPriority : uint8_t { + Critical = 0, + High = 1, + Normal = 2, + Low = 3, + Idle = 4 +}; + +enum class TaskStatus : uint8_t { + Pending, + Scheduled, + Running, + Completed, + Failed, + Canceled +}; + +template +using Func = std::function; + +// 任务接口 +class ITask { +public: + virtual ~ITask() = default; + + virtual void Execute() = 0; + virtual void OnComplete() {} + virtual void OnCancel() {} + + TaskPriority GetPriority() const { return m_priority; } + TaskStatus GetStatus() const { return m_status; } + uint64 GetId() const { return m_id; } + +protected: + TaskPriority m_priority = TaskPriority::Normal; + TaskStatus m_status = TaskStatus::Pending; + uint64 m_id = 0; + std::atomic m_refCount{1}; +}; + +// Lambda 任务包装器 +template +class LambdaTask : public ITask { +public: + explicit LambdaTask(Func&& func, TaskPriority priority = TaskPriority::Normal) + : m_func(std::move(func)), m_priority(priority) {} + + void Execute() override { + m_func(); + } + +private: + Func m_func; +}; + +// 任务组 - 用于批量管理任务 +class TaskGroup { +public: + using Callback = std::function; + + TaskGroup(); + ~TaskGroup(); + + uint64 AddTask(std::unique_ptr task); + uint64 AddTask(Func&& func, TaskPriority priority = TaskPriority::Normal); + + void AddDependency(uint64 taskId, uint64 dependsOn); + void Wait(); + bool WaitFor(std::chrono::milliseconds timeout); + + void SetCompleteCallback(Callback&& callback); + bool IsComplete() const; + float GetProgress() const; +}; + +// 任务系统主类 +class TaskSystem { +public: + static TaskSystem& Get(); + + void Initialize(const TaskSystemConfig& config); + void Shutdown(); + + uint64 Submit(std::unique_ptr task); + uint64 Submit(Func&& func, TaskPriority priority = TaskPriority::Normal); + + TaskGroup* CreateTaskGroup(); + void DestroyTaskGroup(TaskGroup* group); + + void Wait(uint64 taskId); + uint32 GetWorkerThreadCount() const; + + void Update(); + + // 并行 For 循环 + template + void ParallelFor(int32 start, int32 end, Func&& func); + + void RunOnMainThread(Func&& func); +}; + +} +} +``` + +### 2.4 容器库 (Containers) + +```cpp +namespace XCEngine { +namespace Containers { + +// 动态数组 +template +class Array { +public: + using Iterator = T*; + using ConstIterator = const T*; + + Array() = default; + explicit Array(size_t capacity); + Array(size_t count, const T& value); + Array(std::initializer_list init); + ~Array(); + + Array(const Array& other); + Array(Array&& other) noexcept; + Array& operator=(const Array& other); + Array& operator=(Array&& other) noexcept; + + T& operator[](size_t index); + const T& operator[](size_t index) const; + + T* Data() { return m_data; } + const T* Data() const { return m_data; } + + size_t Size() const { return m_size; } + size_t Capacity() const { return m_capacity; } + + void Clear(); + void PushBack(const T& value); + void PushBack(T&& value); + template + T& EmplaceBack(Args&&... args); + void PopBack(); + +private: + T* m_data = nullptr; + size_t m_size = 0; + size_t m_capacity = 0; + IAllocator* m_allocator = nullptr; +}; + +// 字符串 +class String { +public: + String(); + String(const char* str); + String(const char* str, size_t len); + ~String(); + + String& operator+=(const String& other); + String& operator+=(const char* str); + + String Substring(size_t pos, size_t len = npos) const; + String Trim() const; + String ToLower() const; + String ToUpper() const; + + size_t Find(const char* str, size_t pos = 0) const; + bool StartsWith(const String& prefix) const; + bool EndsWith(const String& suffix) const; + + const char* CStr() const { return m_data; } + size_t Length() const { return m_length; } + +private: + char* m_data = nullptr; + size_t m_length = 0; + size_t m_capacity = 0; +}; + +// 哈希映射 +template +class HashMap { +public: + struct Pair { + Key first; + Value second; + }; + + HashMap() = default; + explicit HashMap(size_t bucketCount, IAllocator* allocator = nullptr); + + Value& operator[](const Key& key); + Value* Find(const Key& key); + const Value* Find(const Key& key) const; + bool Contains(const Key& key) const; + + bool Insert(const Key& key, const Value& value); + bool Erase(const Key& key); + void Clear(); + + size_t Size() const { return m_size; } + +private: + size_t GetBucketIndex(const Key& key) const; + void Resize(); + + struct Bucket { + Array pairs; + }; + Array m_buckets; + size_t m_bucketCount = 0; + size_t m_size = 0; + float m_loadFactor = 0.75f; + IAllocator* m_allocator = nullptr; +}; + +} // namespace Containers +} // namespace XCEngine +``` + +### 2.5 日志与调试系统 + +```cpp +namespace XCEngine { +namespace Core { + +// 事件系统 - 基础事件系统(线程安全版本) +template +class Event { +public: + using Callback = std::function; + using Listener = std::pair; + using Iterator = typename std::vector::iterator; + + uint64_t Subscribe(Callback callback) { + std::lock_guard lock(m_mutex); + uint64_t id = ++m_nextId; + m_listeners.emplace_back(id, std::move(callback)); + return id; + } + + void Unsubscribe(uint64_t id) { + std::lock_guard lock(m_mutex); + m_pendingUnsubscribes.push_back(id); + } + + void ProcessUnsubscribes() { + std::lock_guard lock(m_mutex); + for (uint64_t id : m_pendingUnsubscribes) { + m_listeners.erase( + std::remove_if(m_listeners.begin(), m_listeners.end(), + [id](const auto& pair) { return pair.first == id; }), + m_listeners.end() + ); + } + m_pendingUnsubscribes.clear(); + } + + void Invoke(Args... args) const { + // 注意:这里不加锁以避免回调中调用Unsubscribe导致的死锁 + // 实际使用时应在调用前确保没有并发的Unsubscribe + // 或者使用副本进行调用 + + if (!m_pendingUnsubscribes.empty()) { + std::vector listenersCopy; + { + std::lock_guard lock(m_mutex); + listenersCopy = m_listeners; + m_pendingUnsubscribes.clear(); + } + for (const auto& [id, callback] : listenersCopy) { + callback(args...); + } + } else { + for (const auto& [id, callback] : m_listeners) { + callback(args...); + } + } + } + + void Clear() { + std::lock_guard lock(m_mutex); + m_listeners.clear(); + } + + Iterator begin() { return m_listeners.begin(); } + Iterator end() { return m_listeners.end(); } + +private: + mutable std::mutex m_mutex; + std::vector m_listeners; + std::vector m_pendingUnsubscribes; + uint64_t m_nextId = 0; +}; + +// 基础类型定义 +// 注意:String 定义在 Containers 命名空间中,避免与 Core::String 冲突 +using int8 = int8_t; +using int16 = int16_t; +using int32 = int32_t; +using int64 = int64_t; +using uint8 = uint8_t; +using uint16 = uint16_t; +using uint32 = uint32_t; +using uint64 = uint64_t; +using byte = uint8_t; + +// 引用计数基类 +class RefCounted { +public: + RefCounted() : m_refCount(1) {} + virtual ~RefCounted() = default; + + void AddRef() { ++m_refCount; } + void Release() { + if (--m_refCount == 0) { + delete this; + } + } + + uint32_t GetRefCount() const { return m_refCount.load(); } + +protected: + std::atomic m_refCount; +}; + +// 智能指针别名 +template +using Ref = std::shared_ptr; + +template +using UniqueRef = std::unique_ptr; + +} // namespace Core +} + +namespace XCEngine { +namespace Debug { + +enum class LogLevel : uint8_t { + Verbose = 0, + Debug = 1, + Info = 2, + Warning = 3, + Error = 4, + Fatal = 5 +}; + +enum class LogCategory { + General, + Rendering, + Physics, + Audio, + Scripting, + Network, + Memory, + Threading, + FileSystem, + Custom +}; + +struct LogEntry { + LogLevel level; + LogCategory category; + String message; + String file; + int32 line; + String function; + uint64 timestamp; + uint32 threadId; +}; + +class ILogSink { +public: + virtual ~ILogSink() = default; + virtual void Log(const LogEntry& entry) = 0; + virtual void Flush() = 0; +}; + +class ConsoleLogSink : public ILogSink { +public: + void Log(const LogEntry& entry) override; + void Flush() override; + void SetColorOutput(bool enable); + void SetMinimumLevel(LogLevel level); +}; + +class FileLogSink : public ILogSink { +public: + explicit FileLogSink(const String& filePath); + ~FileLogSink(); + void Log(const LogEntry& entry) override; + void Flush() override; +private: + String m_filePath; + FileWriter m_writer; +}; + +class Logger { +public: + static Logger& Get(); + + void Initialize(); + void Shutdown(); + + void AddSink(std::unique_ptr sink); + void RemoveSink(ILogSink* sink); + + void Log(LogLevel level, LogCategory category, + const String& message, const char* file = nullptr, + int32 line = 0, const char* function = nullptr); + + void Verbose(LogCategory category, const String& message); + void Debug(LogCategory category, const String& message); + void Info(LogCategory category, const String& message); + void Warning(LogCategory category, const String& message); + void Error(LogCategory category, const String& message); + void Fatal(LogCategory category, const String& message); + + void SetMinimumLevel(LogLevel level); + void SetCategoryEnabled(LogCategory category, bool enabled); +}; + +#define XE_LOG(category, level, message) \ + XCEngine::Debug::Logger::Get().Log(level, category, message, __FILE__, __LINE__, __FUNCTION__) + +#define XE_ASSERT(condition, message) \ + if (!(condition)) { \ + XCEngine::Debug::Logger::Get().Fatal(XCEngine::Debug::LogCategory::General, message); \ + __debugbreak(); \ + } + +// 性能分析器 +class Profiler { +public: + static Profiler& Get(); + + void Initialize(); + void Shutdown(); + + void BeginProfile(const char* name); + void EndProfile(); + + void BeginFrame(); + void EndFrame(); + + void MarkEvent(const char* name, uint64_t timestamp, uint32_t threadId); + void SetMarker(const char* name, uint32_t color); + + void ExportChromeTracing(const String& filePath); +}; + +#define XE_PROFILE_BEGIN(name) XCEngine::Debug::Profiler::Get().BeginProfile(name) +#define XE_PROFILE_END() XCEngine::Debug::Profiler::Get().EndProfile() +#define XE_PROFILE_FUNCTION() XE_PROFILE_BEGIN(__FUNCTION__) + +} +} +``` + +--- + +## 第三章 组件系统 (GameObject + Component) + +> 本架构参考**传统Unity的GameObject + Component模式**。 +> - GameObject是实体容器,包含Transform等内置组件 +> - Component是挂载在GameObject上的class(引用类型),包含数据和行为 +> - Component有完整的生命周期(Awake, Start, Update, OnDestroy等) +> - Scene直接管理GameObject列表,没有World中间层 + +### 3.1 组件系统架构 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ GameObject + Component Architecture │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────────────────────────────────────────────────────────────┐ │ +│ │ Scene (场景) │ │ +│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ Scene │ │ +│ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ +│ │ │ │ GameObject List │ │ │ +│ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ +│ │ │ │ │ GameObject │ │ GameObject │ │ GameObject │ │ │ │ +│ │ │ │ │ - name │ │ - name │ │ - name │ │ │ │ +│ │ │ │ │ - transform│ │ - transform│ │ - transform│ │ │ │ +│ │ │ │ │ - components│ │ - components│ │ - components│ │ │ │ +│ │ │ │ │ └ Renderer│ │ └ Camera │ │ └ Script │ │ │ │ +│ │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │ +│ │ │ └─────────────────────────────────────────────────────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### 3.2 游戏对象 (GameObject) + +```cpp +namespace XCEngine { + +class Scene; +class Transform; +class Component; + +// GameObject: 游戏对象(类Unity GameObject) +// 传统Unity风格的GameObject,包含内置组件和用户组件 +// 生命周期由 Scene 的 unique_ptr 管理,不需要引用计数 +class GameObject { +public: + GameObject(); + ~GameObject(); + + // 内部构造 - 用于Scene创建GameObject时设置初始属性 + struct ConstructParams { + String name = "GameObject"; + GameObject* parent = nullptr; + bool active = true; + }; + + // 工厂方法(替代公有构造函数) + static GameObject* Create(const ConstructParams& params = {}); + static void Destroy(GameObject* obj); + + String name; // 对象名称 + bool active = true; // 激活状态 + + TransformComponent& GetTransform() { return m_transform; } + const TransformComponent& GetTransform() const { return m_transform; } + + Scene* GetScene() const { return m_scene; } + + // 组件管理 + template + T* AddComponent(); + + template + void RemoveComponent(); + + template + T* GetComponent() const; + + template + std::vector GetComponents() const; + + template + T* GetComponentInChildren() const; + + template + std::vector GetComponentsInChildren() const; + + template + T* GetComponentInParent() const; + + // 层级管理 + GameObject* GetParent() const; + void SetParent(GameObject* parent); + void SetParent(GameObject* parent, bool worldPositionStays); + const std::vector& GetChildren() const; + GameObject* GetChild(int index) const; + int GetChildCount() const; + int GetSiblingIndex() const; + void SetSiblingIndex(int index); + + // 激活状态 + void SetActive(bool active); + bool IsActive() const; + bool IsActiveInHierarchy() const; + + // 场景查找(静态方法,内部使用SceneManager::GetActiveScene) + static GameObject* Find(const String& name); + static std::vector FindObjectsOfType(); + static std::vector FindGameObjectsWithTag(const String& tag); + + // 生命周期 + void Destroy(); + +private: + void AddComponentInternal(Component* component); + void RemoveComponentInternal(Component* component); + + std::vector> m_components; + + // 组件类型索引 - 用于O(1)查询(类型ID -> 组件索引) + // 每个 AddComponent/RemoveComponent 时更新 + std::unordered_map m_componentTypeIndex; + + std::vector m_children; + GameObject* m_parent = nullptr; + Scene* m_scene = nullptr; + + // TransformComponent是GameObject的内置组件 + // 注意:TransformComponent继承自Component,需要在构造后设置m_gameObject + TransformComponent m_transform; + + void Initialize(const ConstructParams& params); + + friend class Scene; + friend class TransformComponent; +}; + +// GameObject实现 +inline GameObject::GameObject() { + // m_transform需要在构造后初始化m_gameObject +} + +inline GameObject::~GameObject() { + // 销毁所有子对象 + for (auto* child : m_children) { + delete child; + } +} + +inline GameObject* GameObject::Create(const ConstructParams& params) { + GameObject* obj = new GameObject(); + obj->Initialize(params); + return obj; +} + +inline void GameObject::Destroy(GameObject* obj) { + delete obj; +} + +inline void GameObject::Initialize(const ConstructParams& params) { + name = params.name; + active = params.active; + + // 设置TransformComponent的m_gameObject指针 + m_transform.m_gameObject = this; + + // 设置父子关系 + if (params.parent) { + params.parent->m_children.push_back(this); + m_parent = params.parent; + } +} + +inline void GameObject::Destroy() { + if (m_scene) { + m_scene->DestroyGameObject(this); + } else { + delete this; + } +} + +// 静态方法实现 +inline GameObject* GameObject::Find(const String& name) { + return SceneManager::Get().GetActiveScene()->Find(name); +} + +inline std::vector GameObject::FindObjectsOfType() { + return SceneManager::Get().GetActiveScene()->FindObjectsOfType(); +} + +inline std::vector GameObject::FindGameObjectsWithTag(const String& tag) { + return SceneManager::Get().GetActiveScene()->FindGameObjectsWithTag(tag); +} + +// GameObject创建辅助类 +class GameObjectBuilder { +public: + explicit GameObjectBuilder(const String& name = "GameObject"); + ~GameObjectBuilder() = default; + + template + GameObjectBuilder& AddComponent(Args&&... args); + + GameObject* Build(); + +private: + String m_name; + std::vector> m_components; +}; + +} +``` + +### 3.3 组件 (Component) + +```cpp +namespace XCEngine { + +class GameObject; + +// 组件基类(类Unity MonoBehaviour) +// 包含完整的生命周期方法,用户组件继承此类 +// 注意:组件由GameObject拥有和管理生命周期,不需要引用计数 +class Component { +public: + Component(); + virtual ~Component(); + + // 所属GameObject + GameObject* gameObject() const { return m_gameObject; } + TransformComponent& transform() const { return m_gameObject->GetTransform(); } + + // 激活状态 + bool IsEnabled() const { return m_enabled; } + void SetEnabled(bool enabled) { m_enabled = enabled; } + + // 场景引用 + Scene* GetScene() const; + + // 组件查找 + template + T* GetComponent() const { return m_gameObject->GetComponent(); } + + template + std::vector GetComponents() const { return m_gameObject->GetComponents(); } + + // ======================================== + // 生命周期(类Unity MonoBehaviour) + // ======================================== + + // 创建时调用(即使组件被禁用也会调用) + virtual void Awake() {} + + // 首次启用时调用(当对象和组件都被启用时) + virtual void Start() {} + + // 每帧调用(当组件启用时) + virtual void Update(float deltaTime) {} + + // 物理更新(固定时间间隔) + virtual void FixedUpdate() {} + + // 在Update之后每帧调用 + virtual void LateUpdate(float deltaTime) {} + + // 销毁时调用 + virtual void OnDestroy() {} + + // 当组件被启用时调用 + virtual void OnEnable() {} + + // 当组件被禁用时调用 + virtual void OnDisable() {} + + // ======================================== + // 物理回调(类Unity) + // ======================================== + + virtual void OnCollisionEnter(const Collision& collision) {} + virtual void OnCollisionStay(const Collision& collision) {} + virtual void OnCollisionExit(const Collision& collision) {} + + virtual void OnTriggerEnter(Collider* other) {} + virtual void OnTriggerStay(Collider* other) {} + virtual void OnTriggerExit(Collider* other) {} + + virtual void OnMouseDown() {} + virtual void OnMouseDrag() {} + virtual void OnMouseEnter() {} + virtual void OnMouseExit() {} + virtual void OnMouseOver() {} + virtual void OnMouseUp() {} + virtual void OnMouseUpAsButton() {} + + virtual void OnTriggerEnter2D(Collider2D* other) {} + virtual void OnTriggerExit2D(Collider2D* other) {} + virtual void OnCollisionEnter2D(Collision2D* collision) {} + virtual void OnCollisionExit2D(Collision2D* collision) {} + + // ======================================== + // 消息发送 + // ======================================== + + // 发送消息到同GameObject上的其他组件 + void SendMessage(const String& methodName, const void* value = nullptr); + void SendMessageUpwards(const String& methodName, const void* value = nullptr); + void BroadcastMessage(const String& methodName, const void* value = nullptr); + +protected: + GameObject* m_gameObject = nullptr; + bool m_enabled = true; + + friend class GameObject; +}; + +// 组件类型注册(用于运行时类型识别) +class ComponentTypeRegistry { +public: + static ComponentTypeRegistry& Get(); + + template + static uint32_t GetTypeId() { + static uint32_t id = Get().Register(typeid(T).name(), static_cast(-1)); + return id; + } + + template + static uint32_t GetTypeId(const char* typeName) { + static uint32_t id = Get().Register(typeName, static_cast(-1)); + return id; + } + + static uint32_t GetTypeIdFromName(const char* typeName) { + return Get().GetIdByName(typeName); + } + + static const char* GetTypeName(uint32_t typeId) { + return Get().GetNameById(typeId); + } + +private: + uint32_t Register(const char* typeName, uint32_t suggestedId); + uint32_t GetIdByName(const char* typeName) const; + const char* GetNameById(uint32_t typeId) const; + + std::atomic m_nextTypeId{0}; + std::unordered_map m_idToName; + std::unordered_map m_nameToId; + Mutex m_mutex; +}; + +// ============================================================================ +// ============================================================================ +// TransformComponent - GameObject的内置组件(类Unity Transform) +// 继承自 Component,包含父子层级关系 +// ============================================================================ + +class TransformComponent : public Component { +public: + // 局部变换 + Vector3 GetLocalPosition() const { return m_localPosition; } + void SetLocalPosition(const Vector3& position) { m_localPosition = position; SetDirty(); } + + Quaternion GetLocalRotation() const { return m_localRotation; } + void SetLocalRotation(const Quaternion& rotation) { m_localRotation = rotation; SetDirty(); } + + Vector3 GetLocalScale() const { return m_localScale; } + void SetLocalScale(const Vector3& scale) { m_localScale = scale; SetDirty(); } + + // 世界变换(通过计算得出) + Vector3 GetPosition() const; + void SetPosition(const Vector3& position); + + Quaternion GetRotation() const; + void SetRotation(const Quaternion& rotation); + + Vector3 GetScale() const; + void SetScale(const Vector3& scale); + + // 方向向量 + Vector3 GetForward() const { return GetRotation() * Vector3::Forward(); } + Vector3 GetRight() const { return GetRotation() * Vector3::Right(); } + Vector3 GetUp() const { return GetRotation() * Vector3::Up(); } + + // 矩阵 + const Matrix4x4& GetLocalToWorldMatrix() const; + Matrix4x4 GetWorldToLocalMatrix() const; + + // 层级操作 + TransformComponent* GetParent() const { return m_parent; } + void SetParent(TransformComponent* parent, bool worldPositionStays = true); + + int GetChildCount() const { return static_cast(m_children.size()); } + TransformComponent* GetChild(int index) const; + TransformComponent* Find(const String& name) const; + + void DetachChildren(); + void SetAsFirstSibling(); + void SetAsLastSibling(); + void SetSiblingIndex(int index); + int GetSiblingIndex() const; + + // 变换操作 + void LookAt(const Vector3& target); + void LookAt(const Vector3& target, const Vector3& up); + void Rotate(const Vector3& eulers); + void Rotate(const Vector3& axis, float angle); + void Translate(const Vector3& translation); + void Translate(const Vector3& translation, Math::Space relativeTo); + + // 点变换 + Vector3 TransformPoint(const Vector3& point) const; + Vector3 InverseTransformPoint(const Vector3& point) const; + Vector3 TransformDirection(const Vector3& direction) const; + Vector3 InverseTransformDirection(const Vector3& direction) const; + + // 设为脏(需要重新计算世界变换) + void SetDirty() { m_dirty = true; } + +private: + Vector3 m_localPosition = Vector3::Zero(); + Quaternion m_localRotation = Quaternion::Identity(); + Vector3 m_localScale = Vector3::One(); + + TransformComponent* m_parent = nullptr; + std::vector m_children; + + mutable Matrix4x4 m_localToWorldMatrix; + mutable Matrix4x4 m_worldToLocalMatrix; + mutable Vector3 m_worldPosition; + mutable Quaternion m_worldRotation; + mutable Vector3 m_worldScale; + mutable bool m_dirty = true; + + void UpdateWorldTransform() const; + + friend class GameObject; +}; + +// 渲染组件(继承Component) +class RenderMeshComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + + ResourceGUID GetMesh() const { return m_meshGuid; } + void SetMesh(const ResourceGUID& guid); + + ResourceGUID GetMaterial() const { return m_materialGuid; } + void SetMaterial(const ResourceGUID& guid); + + bool GetCastShadows() const { return m_castShadows; } + void SetCastShadows(bool cast) { m_castShadows = cast; } + + bool GetReceiveShadows() const { return m_receiveShadows; } + void SetReceiveShadows(bool receive) { m_receiveShadows = receive; } + +private: + ResourceGUID m_meshGuid; + ResourceGUID m_materialGuid; + bool m_castShadows = true; + bool m_receiveShadows = true; +}; + +// 光源组件 - 继承Component(类Unity Light) +class RenderLightComponent : public Component { +public: + void Awake() override; + void Update(float deltaTime) override; + + enum class LightType : uint8_t { + Directional, + Point, + Spot, + Area + }; + + void SetLightType(LightType type) { m_type = type; } + LightType GetLightType() const { return m_type; } + + void SetColor(const Vector3& color) { m_color = color; } + Vector3 GetColor() const { return m_color; } + + void SetIntensity(float intensity) { m_intensity = intensity; } + float GetIntensity() const { return m_intensity; } + + void SetRange(float range) { m_range = range; } + float GetRange() const { return m_range; } + + void SetSpotAngle(float angle) { m_spotAngle = angle; } + float GetSpotAngle() const { return m_spotAngle; } + + void SetCastShadows(bool cast) { m_castShadows = cast; } + bool GetCastShadows() const { return m_castShadows; } + + void SetShadowResolution(uint32_t resolution) { m_shadowResolution = resolution; } + uint32_t GetShadowResolution() const { return m_shadowResolution; } + + void SetCullingMask(int32_t mask) { m_cullingMask = mask; } + int32_t GetCullingMask() const { return m_cullingMask; } + +private: + LightType m_type = LightType::Point; + Vector3 m_color = Vector3::One(); + float m_intensity = 1.0f; + float m_range = 10.0f; + float m_spotAngle = 30.0f; + float m_penumbraAngle = 5.0f; + bool m_castShadows = true; + uint32_t m_shadowResolution = 1024; + float m_shadowBias = 0.005f; + float m_normalOffsetBias = 0.001f; + float m_nearPlane = 0.1f; + int32_t m_cullingMask = -1; + float m_intensityVariation = 0.0f; + ResourceGUID m_cookieTextureGuid = ResourceGUID::Invalid; + float m_cookieSize = 5.0f; +}; + +// 相机组件 - 继承Component(类Unity Camera) +class CameraComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + + enum class ProjectionType : uint8_t { + Perspective, + Orthographic + }; + + void SetProjectionType(ProjectionType type) { m_projectionType = type; } + ProjectionType GetProjectionType() const { return m_projectionType; } + + void SetFieldOfView(float fov) { m_fieldOfView = fov; } + float GetFieldOfView() const { return m_fieldOfView; } + + void SetOrthographicSize(float size) { m_orthographicSize = size; } + float GetOrthographicSize() const { return m_orthographicSize; } + + void SetNearClipPlane(float near) { m_nearPlane = near; } + float GetNearClipPlane() const { return m_nearPlane; } + + void SetFarClipPlane(float far) { m_farPlane = far; } + float GetFarClipPlane() const { return m_farPlane; } + + void SetViewport(const Rect& rect) { m_viewportRect = rect; } + const Rect& GetViewport() const { return m_viewportRect; } + + void SetCullingMask(int32_t mask) { m_cullingMask = mask; } + int32_t GetCullingMask() const { return m_cullingMask; } + + void SetDepth(float depth) { m_depth = depth; } + float GetDepth() const { return m_depth; } + + Matrix4x4 GetViewMatrix() const; + Matrix4x4 GetProjectionMatrix() const; + Matrix4x4 GetViewProjectionMatrix() const; + + Vector3 ScreenToWorldPoint(const Vector3& screenPoint) const; + Vector3 WorldToScreenPoint(const Vector3& worldPoint) const; + Ray ScreenPointToRay(const Vector2& screenPoint) const; + + Frustum& GetFrustum() { return m_frustum; } + +private: + ProjectionType m_projectionType = ProjectionType::Perspective; + float m_fieldOfView = 60.0f; + float m_orthographicSize = 5.0f; + float m_nearPlane = 0.1f; + float m_farPlane = 1000.0f; + float m_aspectRatio = 16.0f / 9.0f; + Rect m_viewportRect = Rect(0, 0, 1, 1); + float m_depth = 0.0f; + int32_t m_cullingMask = -1; + Frustum m_frustum; +}; + +// 物理组件 - 继承Component(类Unity Rigidbody) +class RigidBodyComponent : public Component { +public: + void Awake() override; + void Start() override; + void FixedUpdate() override; + void OnEnable() override; + void OnDisable() override; + void OnDestroy() override; + + // 物理回调(类Unity) + void OnCollisionEnter(const Collision& collision) override; + void OnCollisionStay(const Collision& collision) override; + void OnCollisionExit(const Collision& collision) override; + void OnTriggerEnter(Collider* other) override; + void OnTriggerStay(Collider* other) override; + void OnTriggerExit(Collider* other) override; + + enum class BodyType : uint8_t { + Dynamic, + Kinematic, + Static + }; + + void SetBodyType(BodyType type) { m_bodyType = type; } + BodyType GetBodyType() const { return m_bodyType; } + + void SetMass(float mass) { m_mass = mass; } + float GetMass() const { return m_mass; } + + void SetLinearDamping(float damping) { m_linearDamping = damping; } + float GetLinearDamping() const { return m_linearDamping; } + + void SetAngularDamping(float damping) { m_angularDamping = damping; } + float GetAngularDamping() const { return m_angularDamping; } + + void AddForce(const Vector3& force, ForceMode mode = ForceMode::Force); + void AddForceAtPosition(const Vector3& force, const Vector3& position, ForceMode mode = ForceMode::Force); + void AddTorque(const Vector3& torque, ForceMode mode = ForceMode::Force); + + void SetVelocity(const Vector3& velocity); + Vector3 GetVelocity() const; + + void SetAngularVelocity(const Vector3& velocity); + Vector3 GetAngularVelocity() const; + + void SetUseGravity(bool use) { m_useGravity = use; } + bool IsUsingGravity() const { return m_useGravity; } + + void SetIsKinematic(bool kinematic); + bool IsKinematic() const; + + enum class InterpolateMode : uint8_t { + None, + Interpolate, + Extrapolate + }; + + void SetInterpolate(InterpolateMode mode); + InterpolateMode GetInterpolate() const { return m_interpolateMode; } + + // 获取物理引擎内部句柄(用于 PhysicsWorld 调用,避免 GameObject* 悬空指针) + void* GetPhysicsHandle() const { return m_physicsHandle; } + void SetPhysicsHandle(void* handle) { m_physicsHandle = handle; } + +private: + BodyType m_bodyType = BodyType::Dynamic; + float m_mass = 1.0f; + float m_linearDamping = 0.0f; + float m_angularDamping = 0.05f; + Vector3 m_velocity; + Vector3 m_angularVelocity; + bool m_useGravity = true; + InterpolateMode m_interpolateMode = InterpolateMode::None; + + // 物理引擎内部句柄(由 PhysicsWorld 设置) + void* m_physicsHandle = nullptr; +}; + +// 碰撞组件 - 继承Component(类Unity Collider) +class ColliderComponent : public Component { +public: + void Awake() override; + void Start() override; + + enum class ShapeType : uint8_t { + Box, + Sphere, + Capsule, + Mesh, + ConvexHull + }; + + void SetShapeType(ShapeType type) { m_shapeType = type; } + ShapeType GetShapeType() const { return m_shapeType; } + + void SetCenter(const Vector3& center) { m_center = center; } + Vector3 GetCenter() const { return m_center; } + + void SetSize(const Vector3& size) { m_boxSize = size; } + Vector3 GetSize() const { return m_boxSize; } + + void SetRadius(float radius) { m_sphereRadius = radius; } + float GetRadius() const { return m_sphereRadius; } + + void SetIsTrigger(bool trigger) { m_isTrigger = trigger; } + bool IsTrigger() const { return m_isTrigger; } + + void SetMaterial(const ResourceGUID& guid); + ResourceGUID GetMaterial() const { return m_materialGuid; } + +private: + ShapeType m_shapeType = ShapeType::Box; + Vector3 m_boxSize = Vector3::One(); + float m_sphereRadius = 0.5f; + float m_capsuleRadius = 0.5f; + float m_capsuleHeight = 2.0f; + + Vector3 m_center = Vector3::Zero(); + Quaternion m_rotation = Quaternion::Identity(); + + int32_t m_layer = 0; + int32_t m_mask = -1; + + float m_friction = 0.5f; + float m_restitution = 0.0f; + + bool m_isTrigger = false; + bool m_convex = true; + + ResourceGUID m_materialGuid = ResourceGUID::Invalid; + ResourceGUID m_meshGuid = ResourceGUID::Invalid; + + // 物理引擎内部句柄(由 PhysicsWorld 设置) + void* m_physicsHandle = nullptr; +}; + +// 关节组件 - 继承Component(类Unity Joint) +class JointComponent : public Component { +public: + void Awake() override; + void OnDestroy() override; + + enum class Type : uint8_t { + Hinge, // 铰链关节 + Slider, // 滑块关节 + Spring, // 弹簧关节 + Fixed, // 固定关节 + Configurable, // 可配置关节 + Character // 角色关节 + }; + + enum class Axis { + X, Y, Z + }; + + void SetJointType(Type type) { m_jointType = type; } + Type GetJointType() const { return m_jointType; } + + void SetConnectedBody(GameObject* body) { m_connectedBody = body; } + GameObject* GetConnectedBody() const { return m_connectedBody; } + + void SetAnchor(const Vector3& anchor) { m_anchor = anchor; } + Vector3 GetAnchor() const { return m_anchor; } + + void SetAxis(const Vector3& axis) { m_axis = axis; } + Vector3 GetAxis() const { return m_axis; } + + void SetBreakForce(float force) { m_breakForce = force; } + float GetBreakForce() const { return m_breakForce; } + + void SetBreakTorque(float torque) { m_breakTorque = torque; } + float GetBreakTorque() const { return m_breakTorque; } + + void SetEnableCollision(bool enable) { m_enableCollision = enable; } + bool GetEnableCollision() const { return m_enableCollision; } + + bool IsBroken() const { return m_broken; } + +private: + Type m_jointType = Type::Fixed; + GameObject* m_connectedBody = nullptr; + + Vector3 m_anchor = Vector3::Zero(); + Vector3 m_axis = Vector3::Up(); + Vector3 m_secondaryAxis = Vector3::Right(); + + float m_breakForce = INFINITY; + float m_breakTorque = INFINITY; + bool m_enableCollision = false; + bool m_broken = false; + + void* m_physicsJoint = nullptr; +}; + +// 音频源组件(继承Component) +class AudioSourceComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + void OnEnable() override; + void OnDisable() override; + void OnDestroy() override; + + void Play(); + void Stop(); + void Pause(); + + bool IsPlaying() const; + bool IsPaused() const; + + void SetClip(const ResourceGUID& guid); + ResourceGUID GetClip() const { return m_clipGuid; } + + void SetLoop(bool loop) { m_loop = loop; } + bool GetLoop() const { return m_loop; } + + void SetVolume(float volume) { m_volume = volume; } + float GetVolume() const { return m_volume; } + + void SetPitch(float pitch) { m_pitch = pitch; } + float GetPitch() const { return m_pitch; } + + void SetSpatialBlend(float blend) { m_spatialBlend = blend; } + float GetSpatialBlend() const { return m_spatialBlend; } + +private: + ResourceGUID m_clipGuid; + bool m_playOnAwake = false; + bool m_loop = false; + bool m_isPlaying = false; + bool m_isPaused = false; + float m_volume = 1.0f; + float m_pitch = 1.0f; + float m_spatialBlend = 1.0f; + float m_minDistance = 1.0f; + float m_maxDistance = 500.0f; +}; + +// 音频监听器组件(继承Component) +class AudioListenerComponent : public Component { +public: + void Awake() override; + + void SetDopplerFactor(float factor) { m_dopplerFactor = factor; } + float GetDopplerFactor() const { return m_dopplerFactor; } + + void SetMasterVolume(float volume) { m_masterVolume = volume; } + float GetMasterVolume() const { return m_masterVolume; } + +private: + float m_dopplerFactor = 1.0f; + float m_masterVolume = 1.0f; +}; + +} // namespace XCEngine +``` + +### 3.5 场景 (Scene) + +> 说明:传统Unity的Scene直接管理GameObject列表,没有World中间层。 + +```cpp +namespace XCEngine { + +// 场景(类Unity Scene) +// 直接管理GameObject列表,不需要World +class Scene { +public: + Scene(); + ~Scene(); + + // 场景名称 + const String& GetName() const { return m_name; } + void SetName(const String& name) { m_name = name; } + + // GameObject管理(类Unity Scene API) + GameObject* CreateGameObject(const String& name = "GameObject") { + GameObject::ConstructParams params; + params.name = name; + params.parent = nullptr; + params.active = true; + + GameObject* obj = GameObject::Create(params); + obj->m_scene = this; + AddGameObject(obj); + return obj; + } + + GameObject* CreateGameObject(const String& name, GameObject* parent) { + GameObject::ConstructParams params; + params.name = name; + params.parent = parent; + params.active = true; + + GameObject* obj = GameObject::Create(params); + obj->m_scene = this; + AddGameObject(obj); + return obj; + } + + void DestroyGameObject(GameObject* obj); + + // 根GameObject(没有父对象的顶层GameObject,从所有GameObject中筛选) + // 注意:此方法为O(n)复杂度,与Unity的Scene.GetRootGameObjects行为一致 + // Unity也不缓存根对象,因为GameObject层级变化频繁,缓存维护成本可能更高 + std::vector GetRootGameObjects() const { + std::vector roots; + roots.reserve(m_gameObjects.size() / 2); // 预分配合理容量 + for (auto& obj : m_gameObjects) { + if (obj->GetParent() == nullptr) { + roots.push_back(obj.get()); + } + } + return roots; + } + + // 查找 + GameObject* Find(const String& name) const; + GameObject* FindGameObjectWithTag(const String& tag) const; + std::vector FindGameObjectsWithTag(const String& tag) const; + template + std::vector FindObjectsOfType() const; + T* FindObjectOfType() const; + + // 激活状态 + bool IsActive() const { return m_isActive; } + void SetActive(bool active); + + // 生命周期 + void Load(const String& filePath); + void LoadAsync(const String& filePath, std::function callback); + void Save(const String& filePath); + + // 更新(内部调用) + void Update(float deltaTime); + void FixedUpdate(float fixedDeltaTime); + void LateUpdate(float deltaTime); + + // 调试 + void DebugDraw(); + int GetObjectCount() const { return m_gameObjects.size(); } + +private: + void AddGameObject(GameObject* obj); + void RemoveGameObject(GameObject* obj); + + String m_name; + std::vector> m_gameObjects; + bool m_isActive = true; + + friend class GameObject; + friend class SceneManager; +}; + +// 场景管理器 +class SceneManager { +public: + static SceneManager& Get(); + + void Initialize(); + void Shutdown(); + + // 场景操作 + Scene* CreateScene(const String& name); + void LoadScene(const String& filePath); + void LoadSceneAsync(const String& filePath, std::function callback); + void UnloadScene(Scene* scene); + void UnloadScene(const String& sceneName); + + // 活动场景 + void SetActiveScene(Scene* scene); + void SetActiveScene(const String& sceneName); + Scene* GetActiveScene() const; + + // 查找 + Scene* GetScene(const String& name) const; + std::vector GetAllScenes() const; + + // 更新 + void Update(float deltaTime); + void FixedUpdate(float fixedDeltaTime); + void LateUpdate(float deltaTime); + + // 事件 + Event OnSceneLoaded; + Event OnSceneUnloaded; + Event OnActiveSceneChanged; + +private: + SceneManager() = default; + + std::vector> m_scenes; + Scene* m_activeScene = nullptr; + Scene* m_loadingScene = nullptr; + + std::unordered_map m_sceneNameMap; + std::function m_loadCallback; + bool m_loading = false; +}; + +} // namespace XCEngine +``` + +--- + +## 第四章 渲染系统 (Renderer) + +> **架构说明**: +> - **RenderGraph** - 高级渲染管线抽象,定义 Pass 之间的依赖关系和资源流 +> - **RenderContext** - 低级渲染上下文,管理 GPU 资源和执行具体的渲染命令 +> - 关系:RenderGraph 是声明式的渲染描述,RenderContext 是执行层 + +### 4.1 渲染系统架构 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Rendering Pipeline │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────────────────────────────────────────────────────────────┐ │ +│ │ Render Pipeline Manager │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ Render Graph Builder │ │ +│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ +│ │ │ Pass 1 │ │ Pass 2 │ │ Pass 3 │ │ Pass N │ │ │ +│ │ │ G-Buffer │ │ Lighting │ │ Shadow │ │ Post │ │ │ +│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ Render Passes │ │ +│ │ │ │ +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ +│ │ │ GBuffer │→ │ Shadow │→ │ Deferred │→ │ Forward │ │ │ +│ │ │ Pass │ │ Pass │ │ Lighting │ │ Pass │ │ │ +│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ +│ │ ↓ ↓ ↓ ↓ │ │ +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ +│ │ │ Depth │ │ Shadow │ │ SSAO │ │ Alpha │ │ │ +│ │ │ Pre-Pass │ │ Update │ │ Pass │ │ Blend │ │ │ +│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ +│ │ ↓ │ │ +│ │ ┌────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ Post-Processing │ │ │ +│ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ +│ │ │ │ SSAO │ │ SSR │ │ Bloom │ │ Tone │ │ FXAA │ │ │ │ +│ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │ +│ │ └────────────────────────────────────────────────────────────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ GPU Resources │ │ +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ +│ │ │ Vertex │ │ Index │ │ Uniform │ │ Texture │ │ Render │ │ │ +│ │ │ Buffer │ │ Buffer │ │ Buffer │ │ Sampler │ │ Target │ │ │ +│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### 4.2 渲染抽象层 + +```cpp +namespace XCEngine { +namespace Rendering { + +enum class ResourceState { + Undefined, + RenderTarget, + DepthStencil, + ShaderResource, + UnorderedAccess, + CopySrc, + CopyDst, + Present +}; + +struct ResourceDesc { + ResourceType type; + uint32_t width = 1; + uint32_t height = 1; + uint32_t depth = 1; + uint32_t mipLevels = 1; + uint32_t arraySize = 1; + Format format = Format::Unknown; + SampleCount sampleCount = SampleCount::Count1; + ResourceState initialState = ResourceState::Undefined; + bool cpuAccessible = false; + bool randomAccess = false; + + MemoryUsage memoryUsage = MemoryUsage::Default; + + String name; +}; + +class IRenderDevice { +public: + virtual ~IRenderDevice() = default; + + virtual const char* GetApiName() const = 0; + virtual const char* GetDriverVersion() const = 0; + virtual uint64_t GetDeviceId() const = 0; + virtual uint64_t GetVendorId() const = 0; + + virtual bool SupportsRaytracing() const = 0; + virtual bool SupportsMeshShaders() const = 0; + virtual bool SupportsVariableRateShading() const = 0; + virtual bool SupportsSamplerFeedback() const = 0; + virtual uint32_t GetMaxTextureSize() const = 0; + virtual uint32_t GetMaxUBOSize() const = 0; + virtual uint32_t GetMaxMSAA() const = 0; + + virtual std::unique_ptr CreateTexture(const ResourceDesc& desc) = 0; + virtual std::unique_ptr CreateBuffer(const ResourceDesc& desc, const void* initialData = nullptr) = 0; + virtual std::unique_ptr CreateShader(const ShaderDesc& desc) = 0; + virtual std::unique_ptr CreatePipeline(const PipelineDesc& desc) = 0; + virtual std::unique_ptr CreateRenderPass(const RenderPassDesc& desc) = 0; + + virtual ICommandQueue* GetGraphicsQueue() = 0; + virtual ICommandQueue* GetComputeQueue() = 0; + virtual ICommandQueue* GetCopyQueue() = 0; + + virtual std::unique_ptr CreateFence() = 0; + virtual IDescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc) = 0; + virtual std::unique_ptr CreateQueryHeap(const QueryHeapDesc& desc) = 0; +}; + +class ICommandList { +public: + virtual ~ICommandList() = default; + + virtual void TransitionBarrier(const IResource* resource, ResourceState newState) = 0; + virtual void UAVBarrier(const IResource* resource) = 0; + virtual void FlushBarriers() = 0; + + virtual void SetPipeline(const IPipeline* pipeline) = 0; + virtual void SetVertexBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0; + virtual void SetIndexBuffer(const IBuffer* buffer, IndexType indexType, uint64_t offset = 0) = 0; + virtual void SetConstantBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0; + virtual void SetShaderResource(uint32_t slot, const IResource* resource) = 0; + virtual void SetSampler(uint32_t slot, const ISampler* sampler) = 0; + + virtual void Draw(uint32_t vertexCount, uint32_t firstVertex = 0) = 0; + virtual void DrawIndexed(uint32_t indexCount, uint32_t firstIndex = 0, int32_t baseVertex = 0) = 0; + virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, + uint32_t firstVertex = 0, uint32_t firstInstance = 0) = 0; + virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, + uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) = 0; + + virtual void Dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0; + + virtual void BuildAccelerationStructure(const RaytracingBuildDesc& desc) = 0; + virtual void SetRaytracingPipeline(const IPipeline* pipeline) = 0; + virtual void DispatchRays(const DispatchRaysDesc& desc) = 0; + + virtual void BeginRenderPass(const RenderPassBeginDesc& desc) = 0; + virtual void EndRenderPass() = 0; + + virtual void CopyResource(IResource* dst, const IResource* src) = 0; + virtual void CopyBuffer(IBuffer* dst, uint64_t dstOffset, const IBuffer* src, uint64_t srcOffset, uint64_t size) = 0; + + virtual void BeginQuery(IQueryHeap* heap, uint32_t index) = 0; + virtual void EndQuery(IQueryHeap* heap, uint32_t index) = 0; + + virtual void SetMarker(const char* name, uint32_t color) = 0; + virtual void BeginEvent(const char* name, uint32_t color) = 0; + virtual void EndEvent() = 0; +}; + +class RenderContext { +public: + // 前向声明 + class GBufferPass; + class LightingPass; + class ShadowPass; + class PostProcessPass; + + // 创建和销毁(支持多实例) + static RenderContext* Create(const RenderContextDesc& desc); + static void Destroy(RenderContext* context); + + // 获取主上下文(默认上下文,用于单窗口场景) + static RenderContext* GetMain(); + + void Initialize(const RenderContextDesc& desc); + void Shutdown(); + + IRenderDevice* GetDevice() { return m_device.get(); } + + void BeginFrame(); + void EndFrame(); + + ICommandList* GetMainCommandList() { return m_mainCommandList.get(); } + + void SetRenderTarget(const RenderTarget& target); + void SetViewport(const Viewport& viewport); + void SetScissorRect(const Rect& rect); + + void RenderScene(const SceneRenderDesc& desc); + void ApplyPostProcessing(const PostProcessDesc& desc); + + void CaptureFrame(const String& filePath); + void ToggleDebugView(); + +private: + std::unique_ptr m_device; + std::unique_ptr m_mainCommandList; + std::unique_ptr m_swapChain; + + std::unique_ptr m_gBufferPass; + std::unique_ptr m_lightingPass; + std::unique_ptr m_shadowPass; + std::unique_ptr m_postProcessPass; + + uint32_t m_frameIndex = 0; + uint64_t m_frameCount = 0; + + // 静态主上下文(用于 GetMain()) + static RenderContext* s_mainContext; +}; + +class RenderTexture : public IResource { +public: + uint32_t GetWidth() const { return m_width; } + uint32_t GetHeight() const { return m_height; } + uint32_t GetMipLevels() const { return m_mipLevels; } + Format GetFormat() const { return m_format; } + + void* GetNativeHandle() const { return m_nativeHandle; } + + IShaderResourceView* GetSRV() { return m_srv.get(); } + IRenderTargetView* GetRTV() { return m_rtv.get(); } + IDepthStencilView* GetDSV() { return m_dsv.get(); } + + void* Map(); + void Unmap(); + +private: + uint32_t m_width, m_height; + uint32_t m_mipLevels; + Format m_format; + void* m_nativeHandle = nullptr; + + std::unique_ptr m_srv; + std::unique_ptr m_rtv; + std::unique_ptr m_dsv; +}; + +class RenderBuffer : public IResource { +public: + uint64_t GetSize() const { return m_size; } + BufferUsage GetUsage() const { return m_usage; } + + void* GetNativeHandle() const { return m_nativeHandle; } + + void SetData(const void* data, uint64_t size, uint64_t offset = 0); + void* Map(); + void Unmap(); + +private: + uint64_t m_size; + BufferUsage m_usage; + void* m_nativeHandle = nullptr; +}; + +} +} +``` + +### 4.3 渲染图 (Render Graph) + +```cpp +namespace XCEngine { +namespace Rendering { + +class RenderGraphResource { +public: + RenderGraphResource() = default; + RenderGraphResource(const String& name); + + const String& GetName() const { return m_name; } + uint32_t GetIndex() const { return m_index; } + + bool IsValid() const { return m_index != UINT32_MAX; } + operator bool() const { return IsValid(); } + +private: + String m_name; + uint32_t m_index = UINT32_MAX; + friend class RenderGraph; +}; + +class RenderGraphPass { +public: + using ExecuteFn = std::function; + + RenderGraphPass(const String& name, PassType type); + + RenderGraphResource Read(const String& resourceName); + RenderGraphResource Write(const String& resourceName); + RenderGraphResource ReadWrite(const String& resourceName, ResourceState initialState, ResourceState finalState); + + void Execute(ExecuteFn&& fn); + void Execute() const; + + void SetDebugColor(const Color& color); + + const String& GetName() const { return m_name; } + PassType GetType() const { return m_type; } + const std::vector& GetReads() const { return m_reads; } + const std::vector& GetWrites() const { return m_writes; } + +private: + String m_name; + PassType m_type; + std::vector m_reads; + std::vector m_writes; + ExecuteFn m_executeFn; + Color m_debugColor; + + friend class RenderGraph; +}; + +class RenderGraph { +public: + RenderGraph(); + ~RenderGraph(); + + RenderGraphResource CreateTexture(const String& name, const TextureDesc& desc); + RenderGraphResource CreateBuffer(const String& name, const BufferDesc& desc); + + RenderGraphPass& AddPass(const String& name, PassType type); + + void Build(); + void Execute(ICommandList* commandList); + + void SetName(const String& name); + void Print() const; + void ExportToDot(const String& filePath) const; + + void Clear(); + +private: + void Compile(); + void Validate(); + void SortPasses(); + void AllocateResources(); + + struct ResourceInfo { + String name; + ResourceDesc desc; + ResourceState currentState; + uint32_t firstPassWrite = UINT32_MAX; + uint32_t lastPassRead = UINT32_MAX; + bool imported = false; + }; + + struct PassInfo { + String name; + PassType type; + std::vector reads; + std::vector writes; + std::function executeFn; + }; + + std::vector m_resources; + std::vector m_passes; + std::unordered_map m_resourceIndex; + + bool m_built = false; +}; + +} +} +``` + +--- + +## 第五章 资源系统 (Resource System) + +### 5.1 资源管理架构 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Resource Management │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────────────────────────────────────────────────────────────┐ │ +│ │ Asset Database │ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ +│ │ │ GUID │ │ Path │ │ Meta │ │ │ +│ │ │ 映射表 │ │ 索引 │ │ 数据 │ │ │ +│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ Resource Manager │ │ +│ │ ┌───────────────────────────────────────────────────────────────┐ │ │ +│ │ │ Resource Loader Registry │ │ │ +│ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ +│ │ │ │ Mesh │ │ Texture│ │ Audio │ │ Material│ │ Shader │ │ │ │ +│ │ │ │ Loader │ │ Loader │ │ Loader │ │ Loader │ │ Loader │ │ │ │ +│ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │ +│ │ └───────────────────────────────────────────────────────────────┘ │ │ +│ │ │ │ │ +│ │ ┌──────────────────────────▼────────────────────────────────────┐ │ │ +│ │ │ Resource Cache │ │ │ +│ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ +│ │ │ │ LRU Cache │ │ │ │ +│ │ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ │ +│ │ │ │ │ Resource│ │ Resource│ │ Resource│ │ Resource│ │ │ │ │ +│ │ │ │ │ 1 │ │ 2 │ │ 3 │ │ N │ │ │ │ │ +│ │ │ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │ │ +│ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ +│ │ └───────────────────────────────────────────────────────────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌────────────────────────────────▼───────────────────────────────────────┐ │ +│ │ Import Pipeline │ │ +│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ +│ │ │ Import │→ │ Process │→ │ Cook │→ │ Package │→ │ Index │ │ │ +│ │ │ 导入 │ │ 处理 │ │ 烘焙 │ │ 打包 │ │ 索引 │ │ │ +│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### 5.2 资源系统实现 + +```cpp +namespace XCEngine { +namespace Resources { + +enum class ResourceType { + Unknown, + Mesh, + Texture, + Material, + Shader, + Audio, + Animation, + Skeleton, + Font, + Prefab, + Scene, + Script, + PhysicsMaterial, + NavMesh, + Video, + Custom +}; + +struct ResourceGUID { + static constexpr uint64_t INVALID = 0; + + uint64_t value = INVALID; + + bool IsValid() const { return value != INVALID; } + bool operator==(const ResourceGUID& other) const { return value == other.value; } + bool operator!=(const ResourceGUID& other) const { return value != other.value; } + + String ToString() const; + static ResourceGUID FromString(const String& str); + + struct Hash { + size_t operator()(const ResourceGUID& guid) const { + return std::hash{}(guid.value); + } + }; +}; + +class IResource { +public: + virtual ~IResource() = default; + + virtual ResourceType GetType() const = 0; + virtual const String& GetName() const = 0; + virtual ResourceGUID GetGUID() const = 0; + + virtual bool IsLoaded() const = 0; + virtual bool IsLoading() const = 0; + virtual float GetLoadingProgress() const = 0; + + virtual void AddRef() = 0; + virtual void Release() = 0; + virtual uint32_t GetRefCount() const = 0; + + virtual void Unload() = 0; +}; + +struct LoadRequest { + ResourceGUID guid; + ResourceType type; + std::function callback; + std::function progressCallback; + bool async = true; + uint32_t priority = 0; +}; + +class IResourceLoader { +public: + virtual ~IResourceLoader() = default; + + virtual ResourceType GetResourceType() const = 0; + virtual std::vector GetSupportedExtensions() const = 0; + + virtual bool CanLoad(const String& filePath) const = 0; + virtual bool Load(const String& filePath, IResource* resource) = 0; + virtual bool Save(const String& filePath, const IResource* resource) = 0; + + virtual std::unique_ptr CreateResource() = 0; +}; + +class ResourceRepository { +public: + void Initialize(const String& basePath); + void Shutdown(); + + std::unique_ptr LoadRaw(const String& filePath, size_t& outSize); + std::unique_ptr OpenStream(const String& filePath); + + bool FileExists(const String& filePath); + bool DirectoryExists(const String& dirPath); + std::vector GetFiles(const String& dirPath, const String& extension = ""); + + String GetFullPath(const String& relativePath); + String GetCachePath(); + String GetSourcePath(); + +private: + String m_basePath; + String m_cachePath; + String m_sourcePath; +}; + +class ResourceCache { +public: + explicit ResourceCache(size_t maxMemory); + ~ResourceCache(); + + void Initialize(); + void Shutdown(); + + void Add(const ResourceGUID& guid, IResource* resource); + IResource* Find(const ResourceGUID& guid); + void Remove(const ResourceGUID& guid); + void Clear(); + + void SetMaxMemory(size_t bytes); + size_t GetCurrentMemory() const; + size_t GetMaxMemory() const; + + void Touch(const ResourceGUID& guid); + void Evict(size_t bytesToFree); + + struct Stats { + uint32_t hitCount; + uint32_t missCount; + size_t memoryUsed; + size_t memoryReserved; + }; + const Stats& GetStats() const; + +private: + struct CacheEntry { + IResource* resource; + size_t memorySize; + uint64_t lastAccess; + }; + + std::unordered_map m_cache; + size_t m_maxMemory; + size_t m_currentMemory; + Stats m_stats; +}; + +class ResourceManager { +public: + static ResourceManager& Get(); + + void Initialize(const ResourceManagerConfig& config); + void Shutdown(); + + void RegisterLoader(std::unique_ptr loader); + IResourceLoader* GetLoader(ResourceType type) const; + IResourceLoader* GetLoaderForFile(const String& filePath) const; + + ResourceGUID Load(const String& filePath); + ResourceGUID LoadAsync(const String& filePath, const std::function& callback); + + template + std::shared_ptr Get(const ResourceGUID& guid); + + template + std::shared_ptr Get(const String& filePath); + + void AddRef(const ResourceGUID& guid); + void Release(const ResourceGUID& guid); + + ResourceGUID FindByPath(const String& path) const; + String GetPath(const ResourceGUID& guid) const; + + bool Reload(const ResourceGUID& guid); + void Unload(const ResourceGUID& guid); + void UnloadUnused(); + + void PrintStatistics(); + + void RebuildDatabase(); + void ScanDirectory(const String& dirPath); + +private: + ResourceManager() = default; + + std::unordered_map> m_loaders; + std::unordered_map, ResourceGUID::Hash> m_resources; + std::unordered_map m_pathToGUID; + std::unordered_map m_guidToPath; + + std::unique_ptr m_cache; + std::unique_ptr m_repository; + + std::unique_ptr m_assetDatabase; + + std::atomic m_nextGuid{1}; +}; + +template +class ResourcePtr { +public: + ResourcePtr() = default; + + explicit ResourcePtr(const ResourceGUID& guid) + : m_guid(guid), m_resource(ResourceManager::Get().Get(guid)) {} + + ResourcePtr(const ResourcePtr& other) + : m_guid(other.m_guid), m_resource(other.m_resource) {} + + ~ResourcePtr() { + if (m_guid.IsValid()) { + ResourceManager::Get().Release(m_guid); + } + } + + T* Get() const { return m_resource.get(); } + T* operator->() const { return m_resource.get(); } + T& operator*() const { return *m_resource; } + + bool IsValid() const { return m_resource != nullptr; } + explicit operator bool() const { return IsValid(); } + + const ResourceGUID& GetGUID() const { return m_guid; } + +private: + ResourceGUID m_guid; + std::shared_ptr m_resource; +}; + +} +} +``` + +--- + +## 第六章 场景系统 (Scene System) + +> **架构说明**: Scene是Unity风格的场景,直接管理GameObject列表(没有World中间层),负责场景生命周期管理、资源加载和序列化。 + +### 6.1 场景管理 + +```cpp +namespace XCEngine { +namespace Scene { + +// 注意:GameObject和Transform定义在Components命名空间中 +// Transform是GameObject的内置组件,包含父子层级关系 + +enum class SceneLoadFlags { + None = 0, + Async = 1 << 0, + Additive = 1 << 1, + Single = 1 << 2, + DontLoadAudio = 1 << 3, + DontCreatePhysics = 1 << 4, + SubScene = 1 << 5 +}; + +inline SceneLoadFlags operator|(SceneLoadFlags a, SceneLoadFlags b) { + return static_cast(static_cast(a) | static_cast(b)); +} + +inline SceneLoadFlags& operator|=(SceneLoadFlags& a, SceneLoadFlags b) { + a = a | b; + return a; +} + +inline SceneLoadFlags operator&(SceneLoadFlags a, SceneLoadFlags b) { + return static_cast(static_cast(a) & static_cast(b)); +} + +inline SceneLoadFlags& operator&=(SceneLoadFlags& a, SceneLoadFlags b) { + a = a & b; + return a; +} + +inline bool HasFlag(SceneLoadFlags flags, SceneLoadFlags flag) { + return (static_cast(flags) & static_cast(flag)) != 0; +} + +// 注意:SceneManager 定义在 XCEngine 命名空间中(第三章 3.5 节) +// 此处只保留场景相关的辅助类型和序列化器 + +// 场景序列化器 +// 支持 JSON 和 Binary 两种格式 +class SceneSerializer { +public: + // 序列化格式 + enum class Format { + JSON, + Binary + }; + + // 序列化到文件 + static void Serialize(const Scene& scene, const String& filePath, Format format = Format::JSON); + static std::unique_ptr Deserialize(const String& filePath); + + // JSON 序列化 (使用已存在的 Core 命名空间中的 JSON 库) + static void SerializeToJson(const Scene& scene, Core::JsonDocument& doc); + static void DeserializeFromJson(Scene& scene, const Core::JsonDocument& doc); + + // Binary 序列化 (使用 Core::IStream) + static void SerializeToBinary(const Scene& scene, Core::IStream& stream); + static std::unique_ptr DeserializeFromBinary(Core::IStream& stream); + +private: + static void SerializeGameObject(const GameObject& gameObject, Core::JsonValue& parent); + static void DeserializeGameObject(GameObject& gameObject, const Core::JsonValue& data); + + static void SerializeComponent(uint32_t componentTypeId, const void* component, Core::JsonValue& parent); + static void DeserializeComponent(uint32_t componentTypeId, const GameObject& gameObject, const Core::JsonValue& data); +}; + +// ============================================================================ +// 序列化辅助类型 (需要在 Core 命名空间中定义) +// ============================================================================ + +namespace Core { + +// 流接口 +class IStream { +public: + virtual ~IStream() = default; + + virtual bool IsValid() const = 0; + virtual size_t GetPosition() const = 0; + virtual size_t GetSize() const = 0; + + virtual size_t Read(void* buffer, size_t size) = 0; + virtual size_t Write(const void* buffer, size_t size) = 0; + + virtual void Seek(size_t position) = 0; + virtual void Skip(size_t bytes) = 0; + virtual void Flush() = 0; + + virtual bool IsReading() const = 0; + virtual bool IsWriting() const = 0; +}; + +// JSON 文档 +class JsonDocument { +public: + JsonDocument(); + ~JsonDocument(); + + void Parse(const String& json); + void Parse(const char* json, size_t length); + + JsonValue& GetRoot(); + const JsonValue& GetRoot() const; + + String ToString() const; + + bool HasParseError() const; + String GetParseError() const; +}; + +// JSON 值 +class JsonValue { +public: + enum class Type { + Null, + Bool, + Int, + Float, + String, + Array, + Object + }; + + JsonValue(); + JsonValue(bool value); + JsonValue(int32_t value); + JsonValue(int64_t value); + JsonValue(float value); + JsonValue(double value); + JsonValue(const String& value); + JsonValue(const char* value); + ~JsonValue(); + + Type GetType() const { return m_type; } + + // 值的获取 + bool GetBool() const; + int32_t GetInt() const; + int64_t GetInt64() const; + float GetFloat() const; + double GetDouble() const; + const String& GetString() const; + + // 数组/对象访问 + size_t GetSize() const; + JsonValue& operator[](size_t index); + const JsonValue& operator[](size_t index) const; + JsonValue& operator[](const String& key); + const JsonValue& operator[](const String& key) const; + + bool Has(const String& key) const; + + // 修改 + JsonValue& SetBool(bool value); + JsonValue& SetInt(int32_t value); + JsonValue& SetFloat(float value); + JsonValue& SetString(const String& value); + + JsonValue& AddArrayElement(); + JsonValue& AddObjectMember(const String& key); + + void Clear(); + +private: + Type m_type = Type::Null; + // ... 具体成员 +}; + +} // namespace Core + +} +} +``` + +--- + +## 第七章 物理系统 (Physics) + +### 7.1 物理系统 + +```cpp +namespace XCEngine { +namespace Physics { + +// 碰撞检测查询标志 +enum class QueryFlags : uint32_t { + None = 0, + Colliders = 1 << 0, + Rigidodies = 1 << 1, + Transforms = 1 << 2, + All = Colliders | Rigidodies | Transforms +}; + +// 力学模式 (类Unity ForceMode) +enum class ForceMode : uint8_t { + Force = 0, // 持续力 (质量单位) + Acceleration = 1, // 加速度 (无质量单位) + Impulse = 2, // 瞬时冲量 (质量单位) + VelocityChange = 3 // 速度变化 (无质量单位) +}; + +enum class CollisionShapeType { + Sphere, + Box, + Capsule, + ConvexMesh, + ConcaveMesh, + Heightfield, + Compound +}; + +struct CollisionLayer { + static constexpr uint32_t MaxLayers = 32; + static constexpr uint32_t Default = 0; + + uint32_t id; + String name; + uint32_t mask; +}; + +struct PhysicsMaterial { + float friction = 0.5f; + float restitution = 0.0f; + float frictionCombine = 0; + float restitutionCombine = 0; + bool isTrigger = false; + + float staticFriction = 0.5f; + float dynamicFriction = 0.5f; +}; + +struct RaycastHit { + GameObject* gameObject; + Vector3 point; + Vector3 normal; + float distance; + Vector2 uv; + int32_t faceIndex; + float fraction; + + ColliderComponent* collider = nullptr; +}; + +// 碰撞信息 (类Unity Collision) +struct Collision { + GameObject* gameObject = nullptr; + ColliderComponent* collider = nullptr; + RigidBodyComponent* rigidBody = nullptr; + + Vector3 relativeVelocity; + Vector3 contactPoint; + Vector3 contactNormal; + + std::vector contacts; + std::vector normals; +}; + +// 2D碰撞信息 (类Unity Collision2D) +struct Collision2D { + GameObject* gameObject = nullptr; + Collider2DComponent* collider = nullptr; + RigidBody2DComponent* rigidBody = nullptr; + + Vector2 relativeVelocity; + Vector2 contactPoint; + Vector2 contactNormal; + + std::vector contacts; + std::vector normals; + + float fraction = 0.0f; + int32_t faceID = 0; +}; + +// 2D碰撞体组件 (类Unity Collider2D) +class Collider2DComponent : public Component { +public: + void Awake() override; + void Start() override; + + enum class ShapeType : uint8_t { + Box, + Circle, + Capsule, + Polygon, + Edge + }; + + void SetShapeType(ShapeType type) { m_shapeType = type; } + ShapeType GetShapeType() const { return m_shapeType; } + + void SetOffset(const Vector2& offset) { m_offset = offset; } + Vector2 GetOffset() const { return m_offset; } + + void SetDensity(float density) { m_density = density; } + float GetDensity() const { return m_density; } + + void SetIsTrigger(bool trigger) { m_isTrigger = trigger; } + bool IsTrigger() const { return m_isTrigger; } + + void SetUsedByEffector(bool use) { m_usedByEffector = use; } + bool IsUsedByEffector() const { return m_usedByEffector; } + +private: + ShapeType m_shapeType = ShapeType::Box; + Vector2 m_offset = Vector2::Zero(); + float m_density = 1.0f; + bool m_isTrigger = false; + bool m_usedByEffector = false; + + void* m_physicsHandle = nullptr; +}; + +// 2D刚体组件 (类Unity Rigidbody2D) +class RigidBody2DComponent : public Component { +public: + void Awake() override; + void Start() override; + void FixedUpdate() override; + + enum class BodyType : uint8_t { + Dynamic, + Kinematic, + Static + }; + + enum class InterpolateMode : uint8_t { + None, + Interpolate, + Extrapolate + }; + + void SetBodyType(BodyType type) { m_bodyType = type; } + BodyType GetBodyType() const { return m_bodyType; } + + void SetMass(float mass) { m_mass = mass; } + float GetMass() const { return m_mass; } + + void SetLinearVelocity(const Vector2& velocity); + Vector2 GetLinearVelocity() const; + + void SetAngularVelocity(float velocity); + float GetAngularVelocity() const; + + void AddForce(const Vector2& force, ForceMode mode = ForceMode::Force); + void AddForceAtPosition(const Vector2& force, const Vector2& position, ForceMode mode = ForceMode::Force); + + void SetGravityScale(float scale) { m_gravityScale = scale; } + float GetGravityScale() const { return m_gravityScale; } + + void SetIsKinematic(bool kinematic) { m_kinematic = kinematic; } + bool IsKinematic() const { return m_kinematic; } + + void SetInterpolateMode(InterpolateMode mode) { m_interpolateMode = mode; } + InterpolateMode GetInterpolateMode() const { return m_interpolateMode; } + + void* GetPhysicsHandle() const { return m_physicsHandle; } + void SetPhysicsHandle(void* handle) { m_physicsHandle = handle; } + +private: + BodyType m_bodyType = BodyType::Dynamic; + float m_mass = 1.0f; + Vector2 m_linearVelocity; + float m_angularVelocity = 0.0f; + float m_gravityScale = 1.0f; + bool m_kinematic = false; + InterpolateMode m_interpolateMode = InterpolateMode::None; + + void* m_physicsHandle = nullptr; +}; + +struct CollisionEvent { + GameObject* gameObjectA; + GameObject* gameObjectB; + Vector3 point; + Vector3 normal; + Vector3 relativeVelocity; + + enum class Type { + Enter, + Stay, + Exit + }; + Type type; +}; + +class PhysicsWorld { +public: + PhysicsWorld(); + ~PhysicsWorld(); + + void Initialize(const PhysicsWorldDesc& desc); + void Shutdown(); + + void Simulate(float deltaTime); + void SetGravity(const Vector3& gravity); + Vector3 GetGravity() const { return m_gravity; } + + // 物理组件注册(替代直接 SyncWithScene,通过组件系统同步) + void RegisterRigidBody(RigidBodyComponent* component); + void UnregisterRigidBody(RigidBodyComponent* component); + void RegisterCollider(ColliderComponent* component); + void UnregisterCollider(ColliderComponent* component); + + bool Raycast(const Ray& ray, float maxDistance, RaycastHit& hit, + uint32_t layerMask = 0xFFFFFFFF, QueryFlags flags = QueryFlags::None); + bool RaycastMultiple(const Ray& ray, float maxDistance, std::vector& hits, + uint32_t layerMask = 0xFFFFFFFF, QueryFlags flags = QueryFlags::None); + + bool CheckSphere(const Sphere& sphere, uint32_t layerMask = 0xFFFFFFFF); + bool CheckBox(const Box& box, uint32_t layerMask = 0xFFFFFFFF); + bool CheckCapsule(const Vector3& start, const Vector3& end, float radius, + uint32_t layerMask = 0xFFFFFFFF); + + bool SphereCast(const Sphere& sphere, const Vector3& direction, float maxDistance, + RaycastHit& hit, uint32_t layerMask = 0xFFFFFFFF); + + std::vector OverlapSphere(const Sphere& sphere, uint32_t layerMask = 0xFFFFFFFF); + std::vector OverlapBox(const Box& box, uint32_t layerMask = 0xFFFFFFFF); + + // 使用 RigidBodyComponent* 代替 GameObject*,通过组件内部的句柄操作,避免悬空指针 + void AddForce(RigidBodyComponent* component, const Vector3& force, ForceMode mode = ForceMode::Force); + void AddForceAtPosition(RigidBodyComponent* component, const Vector3& force, const Vector3& position, + ForceMode mode = ForceMode::Force); + void AddTorque(RigidBodyComponent* component, const Vector3& torque, ForceMode mode = ForceMode::Force); + + void SetLinearVelocity(RigidBodyComponent* component, const Vector3& velocity); + void SetAngularVelocity(RigidBodyComponent* component, const Vector3& velocity); + Vector3 GetLinearVelocity(RigidBodyComponent* component) const; + Vector3 GetAngularVelocity(RigidBodyComponent* component) const; + + void SetKinematic(RigidBodyComponent* component, bool kinematic); + + // Joint 由 JointComponent 组件管理,不再由 PhysicsWorld 直接创建 + + Event OnCollisionEnter; + Event OnCollisionStay; + Event OnCollisionExit; + Event OnTriggerEnter; + Event OnTriggerStay; + Event OnTriggerExit; + + void DebugDraw(); + void SetDebugDrawEnabled(bool enabled); + +private: + void* m_physicsBackend = nullptr; + + Vector3 m_gravity = Vector3(0, -9.81f, 0); + + std::vector m_collisionEvents; + std::vector m_triggerEvents; + + bool m_debugDrawEnabled = false; +}; + +class CharacterControllerComponent : public Component { +public: + void Awake() override; + void Update(float deltaTime) override; + void OnDestroy() override; + + void Initialize(const CharacterControllerDesc& desc); + + void Move(const Vector3& displacement); + void SetVelocity(const Vector3& velocity); + Vector3 GetVelocity() const { return m_velocity; } + + bool IsGrounded() const { return m_grounded; } + Vector3 GetGroundNormal() const { return m_groundNormal; } + GameObject* GetGroundObject() const { return m_groundObject; } + + void Jump(const Vector3& jumpForce); + void SetJumpEnabled(bool enabled); + + void SetSlopeLimit(float angle); + void SetStepOffset(float height); + void SetSkinWidth(float width); + + bool DetectCollision(const Vector3& position, const Vector3& direction, float distance); + +private: + void UpdateGroundStatus(); + void HandleCollision(); + + Vector3 m_velocity = Vector3::Zero(); + Vector3 m_pendingForces = Vector3::Zero(); + + float m_slopeLimit = 45.0f; + float m_stepOffset = 0.5f; + float m_skinWidth = 0.02f; + float m_minDistance = 0.1f; + + bool m_grounded = false; + bool m_jumpEnabled = true; + Vector3 m_groundNormal = Vector3::Up(); + GameObject* m_groundObject = nullptr; + + uint32_t m_layer = 0; + uint32_t m_collisionMask = 0xFFFFFFFF; +}; + +} +} +``` + +--- + +## 第八章 音频系统 (Audio) + +> **架构说明**: Unity风格的音频系统。音频源和监听器都是挂载在GameObject上的组件。 +> AudioEngine是底层实现,提供音频解码、混音、空间化等功能。 + +### 8.1 音频系统 + +```cpp +namespace XCEngine { +namespace Audio { + +// 音频格式 +enum class AudioFormat { + Unknown, + WAV, + OGG, + MP3, + FLAC, + AAC +}; + +// 音频片段 (资源) +class AudioClip : public IResource { +public: + AudioClip(); + ~AudioClip(); + + const String& GetName() const override { return m_name; } + ResourceType GetType() const override { return ResourceType::Audio; } + ResourceGUID GetGUID() const override { return m_guid; } + + bool IsLoaded() const override { return m_loaded; } + bool IsLoading() const override { return m_loading; } + float GetLoadingProgress() const override { return m_loadProgress; } + + const uint8_t* GetData() const { return m_data.get(); } + size_t GetDataSize() const { return m_dataSize; } + uint32_t GetSampleRate() const { return m_sampleRate; } + uint32_t GetChannels() const { return m_channels; } + uint32_t GetBitsPerSample() const { return m_bitsPerSample; } + float GetDuration() const { return m_duration; } + + AudioFormat GetFormat() const { return m_format; } + +private: + String m_name; + ResourceGUID m_guid; + + std::unique_ptr m_data; + size_t m_dataSize = 0; + + uint32_t m_sampleRate = 44100; + uint32_t m_channels = 2; + uint32_t m_bitsPerSample = 16; + float m_duration = 0.0f; + + AudioFormat m_format = AudioFormat::Unknown; + + bool m_loaded = false; + bool m_loading = false; + float m_loadProgress = 0.0f; + + friend class AudioEngine; +}; + +// 音频总线 (混音器) +class AudioBus { +public: + AudioBus(const String& name, AudioBus* parent = nullptr); + + void SetVolume(float volume); + float GetVolume() const { return m_volume; } + + void SetMute(bool mute); + bool IsMuted() const { return m_muted; } + + void SetBypassEffects(bool bypass); + bool IsBypassingEffects() const { return m_bypassEffects; } + + void AddEffect(AudioEffect* effect); + void RemoveEffect(AudioEffect* effect); + +private: + String m_name; + AudioBus* m_parent = nullptr; + std::vector m_children; + std::vector> m_effects; + + float m_volume = 1.0f; + bool m_muted = false; + bool m_bypassEffects = false; +}; + +// 音频引擎 - 底层实现 (不对外直接使用) +class AudioEngine { +public: + static AudioEngine& Get(); + + void Initialize(const AudioEngineConfig& config); + void Shutdown(); + + const char* GetDeviceName() const; + uint32_t GetSpeakerCount() const; + + void Update(float deltaTime); + + // 资源管理 + std::shared_ptr LoadClip(const String& filePath); + void UnloadClip(AudioClip* clip); + + // 混音器 + AudioBus* GetMasterBus() { return m_masterBus.get(); } + AudioBus* GetBus(const String& path); + AudioBus* CreateBus(const String& path); + + // 内部音频源管理 (由 AudioSystem 使用) + struct InternalSource { + uint64_t id = 0; + void* handle = nullptr; // 底层音频引擎句柄 + }; + + InternalSource CreateInternalSource(); + void DestroyInternalSource(InternalSource source); + void SetSourceClip(InternalSource source, AudioClip* clip); + void PlaySource(InternalSource source); + void StopSource(InternalSource source); + void PauseSource(InternalSource source); + void SetSourceVolume(InternalSource source, float volume); + void SetSourcePitch(InternalSource source, float pitch); + void SetSourcePosition(InternalSource source, const Vector3& position); + void SetSourceLoop(InternalSource source, bool loop); + bool IsSourcePlaying(InternalSource source); + + // 监听器管理 - Unity 限制只能有一个 AudioListener + void SetListenerComponent(AudioListenerComponent* listener); + AudioListenerComponent* GetListenerComponent() const { return m_listenerComponent; } + + void SetListenerPosition(const Vector3& position); + void SetListenerVelocity(const Vector3& velocity); + void SetListenerOrientation(const Vector3& forward, const Vector3& up); + void SetListenerDopplerFactor(float factor); + + struct Stats { + uint32_t activeVoices; + uint32_t totalVoices; + uint32_t playingSources; + uint32_t cpuUsage; + size_t memoryUsage; + }; + const Stats& GetStats() const { return m_stats; } + +private: + AudioEngine() = default; + + std::unique_ptr m_masterBus; + + std::unordered_map> m_loadedClips; + std::vector m_activeSources; + uint64_t m_nextSourceId = 1; + + // 监听器状态 + Vector3 m_listenerPosition; + Vector3 m_listenerVelocity; + Vector3 m_listenerForward = Vector3::Forward(); + Vector3 m_listenerUp = Vector3::Up(); + float m_listenerDopplerFactor = 1.0f; + + // 限制只能有一个 AudioListener + AudioListenerComponent* m_listenerComponent = nullptr; + + Stats m_stats; + + void* m_backend = nullptr; // FMOD / Wwise / OpenAL +}; + +} // namespace Audio +} // namespace XCEngine +``` + +--- + +## 第十章 动画系统 (Animation) + +### 10.1 动画系统架构 + +```cpp +namespace XCEngine { +namespace Animation { + +// 动画曲线 +struct AnimationCurve { + std::vector> floatKeys; + std::vector> vector3Keys; + std::vector> quaternionKeys; + std::vector> colorKeys; + + // 具体类型的求值方法 + float EvaluateFloat(float time, float defaultValue = 0.0f) const; + Vector3 EvaluateVector3(float time, const Vector3& defaultValue = Vector3::Zero()) const; + Quaternion EvaluateQuaternion(float time, const Quaternion& defaultValue = Quaternion::Identity()) const; + Color EvaluateColor(float time, const Color& defaultValue = Color::White) const; + + // 具体类型的 Key 操作 + void AddKeyFloat(float time, float value); + void AddKeyVector3(float time, const Vector3& value); + void AddKeyQuaternion(float time, const Quaternion& value); + void AddKeyColor(float time, const Color& value); + + void RemoveKeyFloat(float time); + void RemoveKeyVector3(float time); + void RemoveKeyQuaternion(float time); + void RemoveKeyColor(float time); +}; + +// 动画片段 +struct AnimationClip : public IResource { + float duration = 0.0f; + float sampleRate = 30.0f; + bool loop = false; + + // 轨道 + struct Track { + String path; // 目标路径 e.g., "Root/Child/Arm" + enum Type { Position, Rotation, Scale, Float, Int, Bool, Trigger } type; + AnimationCurve curve; + }; + + std::vector tracks; + + // 事件 + struct Event { + float time; + String functionName; + String stringParameter; + float floatParameter; + int intParameter; + }; + std::vector events; +}; + +// 骨骼 +struct Bone { + String name; + int32 parentIndex = -1; + Matrix4x4 localMatrix; + Matrix4x4 worldMatrix; + Vector3 position; + Quaternion rotation; + Vector3 scale; +}; + +// 骨架 +struct Skeleton : public IResource { + std::vector bones; + int32 rootBoneIndex = -1; + + int32 FindBone(const String& name) const; + const Bone& GetBone(int32 index) const; + Matrix4x4 GetBoneMatrix(int32 index) const; +}; + +// 蒙皮数据 +struct SkinningData { + std::vector bindPoses; + std::vector boneIndices; + std::vector boneWeights; +}; + +// 动画状态机 +class AnimatorStateMachine { +public: + struct State { + String name; + AnimationClip* clip = nullptr; + float speed = 1.0f; + float cycleOffset = 0.0f; + + std::vector transitions; + }; + + struct Transition { + String targetState; + float exitTime = 0.0f; + float duration = 0.0f; + + enum class ConditionMode { + If, + IfNot, + Greater, + Less, + Equals + }; + + struct Condition { + String parameter; + ConditionMode mode; + float threshold; + }; + std::vector conditions; + }; + + struct Parameter { + enum Type { Float, Int, Bool, Trigger } type; + String name; + }; + + // 状态管理 + void AddState(const String& name); + void AddTransition(const String& from, const String& to, const Transition& transition); + void AddParameter(const Parameter& param); + + // 播放控制 + void Play(const String& stateName); + void CrossFade(const String& stateName, float duration); + void Stop(); + + // 参数 + void SetFloat(const String& name, float value); + void SetInt(const String& name, int32 value); + void SetBool(const String& name, bool value); + void SetTrigger(const String& name); + + float GetFloat(const String& name) const; + int32 GetInt(const String& name) const; + bool GetBool(const String& name) const; + + // 动画层级 + void AddLayer(const String& name, float weight = 1.0f); + void SetLayerWeight(const String& name, float weight); + +private: + std::vector m_states; + std::vector m_parameters; + std::unordered_map m_stateIndices; + + String m_currentState; + String m_previousState; + float m_currentTime = 0.0f; +}; + +// 动画器组件 - 继承Component(类Unity Animator) +class AnimatorComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + void OnDestroy() override; + + void SetSkeleton(Skeleton* skeleton); + Skeleton* GetSkeleton() const { return m_skeleton; } + + // 播放控制 + void Play(const String& stateName); + void CrossFade(const String& stateName, float duration); + void PlayInFixedTime(const String& stateName, float normalizedTime); + + bool IsPlaying() const; + float GetCurrentAnimationTime() const; + float GetCurrentAnimationLength() const; + + // 层 + void AddLayer(const String& name, float weight); + void SetLayerWeight(const String& name, float weight); + + // 参数 + void SetFloat(const String& name, float value); + void SetInteger(const String& name, int32 value); + void SetBool(const String& name, bool value); + void SetTrigger(const String& name); + + // 根运动 + void SetApplyRootMotion(bool apply) { m_applyRootMotion = apply; } + bool GetApplyRootMotion() const { return m_applyRootMotion; } + + Vector3 GetRootPosition() const { return m_rootPosition; } + Quaternion GetRootRotation() const { return m_rootRotation; } + +private: + Skeleton* m_skeleton = nullptr; + std::unique_ptr m_stateMachine; + bool m_useGPUAnimation = false; + Buffer* m_boneMatricesBuffer = nullptr; + bool m_applyRootMotion = false; + Vector3 m_rootPosition; + Quaternion m_rootRotation; +}; + +// 动画系统管理器 (处理GPU蒙皮、事件等) +class AnimationSystem { +public: + static AnimationSystem& Get(); + + void Initialize(); + void Shutdown(); + + void Update(float deltaTime); + + void UpdateGPUBuffers(AnimatorComponent* animator); + void ProcessAnimationEvents(AnimatorComponent* animator, float prevTime, float currentTime); + +private: + void EvaluateState(AnimatorComponent* animator, float time, + std::vector& boneMatrices); + void BlendStates(AnimatorComponent* animator, float blendWeight, + const std::vector& from, + const std::vector& to, + std::vector& output); +}; + + // GPU 蒙皮 + void UpdateGPUBuffers(AnimatorComponent* animator); + + // 事件触发 + void ProcessAnimationEvents(AnimatorComponent* animator, float prevTime, float currentTime); + +private: + void EvaluateState(AnimatorComponent* animator, float time, + std::vector& boneMatrices); + void BlendStates(AnimatorComponent* animator, float blendWeight, + const std::vector& from, + const std::vector& to, + std::vector& output); +}; + +// Blend Shape +struct BlendShape { + String name; + std::vector vertices; + std::vector normals; + std::vector tangents; +}; + +struct BlendShapeFrame { + float weight = 0.0f; + std::vector deltaVertices; + std::vector deltaNormals; + std::vector deltaTangents; +}; + +struct BlendShapeData { + std::vector shapes; + std::vector frames; +}; + +// 程序化动画 +namespace ProceduralAnimation { + +class IKChain { +public: + void SetJoints(const std::vector& joints); + void Solve(const Vector3& target); + + void SetPoleVector(const Vector3& pole); + void SetIterations(int32 iterations); + +private: + std::vector m_joints; + Vector3 m_poleVector; + int32_t m_iterations = 10; +}; + +class CCDIK : public IKChain { +public: + void Solve(const Vector3& target) override; +}; + +class FABRIK : public IKChain { +public: + void Solve(const Vector3& target) override; + +private: + void ForwardReach(const Vector3& target); + void BackwardReach(const Vector3& base); + void SolveConstraints(); +}; + +} // namespace ProceduralAnimation +} // namespace Animation +} // namespace XCEngine +``` + +--- + +## 第十一章 粒子系统 (Particle System) + +### 11.1 粒子系统架构 + +```cpp +namespace XCEngine { +namespace Particles { + +// 粒子数据 - 粒子系统使用SoA布局以优化SIMD性能(这是性能关键路径的例外) +struct Particle { + Vector3 position; + Vector3 velocity; + Vector3 acceleration; + + Quaternion rotation; + float rotationSpeed; + + float size; + float lifetime; + float age; + + Color color; + float alpha; + + uint32_t seed; + bool alive; +}; + +// 粒子发射器 +class ParticleEmitter { +public: + // 发射模式 + enum class EmitMode { + Continuous, + Burst, + Distance + }; + + // 形状 + enum class ShapeType { + Sphere, + Box, + Cone, + Circle, + Edge, + MeshSurface, + MeshVolume + }; + + // 发射参数 + float rate = 10.0f; + int maxParticles = 1000; + float lifetime = 5.0f; + + // 初始速度 + Vector3 velocityMin = Vector3(-1, 1, -1); + Vector3 velocityMax = Vector3(1, 1, 1); + float speedMin = 1.0f; + float speedMax = 5.0f; + + // 初始变换 + float startSizeMin = 0.1f; + float startSizeMax = 0.5f; + float startRotationMin = 0.0f; + float startRotationMax = 360.0f; + Color startColor = Color::White; + + // 形状 + ShapeType shape = ShapeType::Sphere; + float shapeRadius = 1.0f; + float shapeAngle = 25.0f; + Vector3 shapeBoxSize = Vector3::One(); + + // 发射 + EmitMode emitMode = EmitMode::Continuous; + int burstCount = 10; + float burstInterval = 1.0f; +}; + +// 粒子系统组件 - 继承Component(类Unity ParticleSystem) +class ParticleSystemComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + void OnDestroy() override; + + // 播放控制(Unity 风格) + void Play(); + void Stop(); + void Pause(); + void Resume(); + void Clear(); + + bool IsPlaying() const { return m_isPlaying && !m_isPaused; } + bool IsPaused() const { return m_isPaused; } + bool IsStopped() const { return !m_isPlaying; } + + void SetLoop(bool loop) { m_loop = loop; } + bool GetLoop() const { return m_loop; } + + void SetEmitRate(float rate) { m_emitter.rate = rate; } + float GetEmitRate() const { return m_emitter.rate; } + + void SetLifetime(float lifetime) { m_emitter.lifetime = lifetime; } + float GetLifetime() const { return m_emitter.lifetime; } + + void SetStartSpeed(float speed) { m_emitter.speedMin = m_emitter.speedMax = speed; } + float GetStartSpeed() const { return m_emitter.speedMin; } + + void SetStartSize(float size) { m_emitter.startSizeMin = m_emitter.startSizeMax = size; } + float GetStartSize() const { return m_emitter.startSizeMin; } + + void SetStartColor(const Color& color) { m_emitter.startColor = color; } + Color GetStartColor() const { return m_emitter.startColor; } + +private: + ParticleEmitter m_emitter; + bool m_isPlaying = false; + bool m_isPaused = false; + bool m_loop = true; + float m_simulationSpeed = 1.0f; + float m_startDelay = 0.0f; + uint32_t m_randomSeed = 0; +}; + +// GPU 粒子系统 +class GPUParticleSystem { +public: + void Initialize(uint32_t maxParticles); + void Shutdown(); + + void Update(float deltaTime, const ParticleSystemComponent& config); + void Render(RenderContext& context); + + // GPU 缓冲区 + Buffer* GetPositionBuffer() { return m_positionBuffer.get(); } + Buffer* GetVelocityBuffer() { return m_velocityBuffer.get(); } + Buffer* GetColorBuffer() { return m_colorBuffer.get(); } + +private: + struct GPUParticle { + Vector4 position; // w = size + Vector4 velocity; // w = lifetime + Vector4 color; // w = rotation + }; + + uint32_t m_maxParticles = 0; + + std::unique_ptr m_positionBuffer; + std::unique_ptr m_velocityBuffer; + std::unique_ptr m_colorBuffer; + std::unique_ptr m_indexBuffer; + + ComputePipeline m_updatePipeline; +}; + +// 粒子系统管理器 +class ParticleSystemManager { +public: + static ParticleSystemManager& Get(); + + void Initialize(); + void Shutdown(); + + void Update(float deltaTime); + void Render(RenderContext& context); + + // 发射器 + ParticleEmitter* CreateEmitter(); + void DestroyEmitter(ParticleEmitter* emitter); + + // GPU 粒子 + GPUParticleSystem* GetGPUParticleSystem() { return &m_gpuSystem; } + +private: + std::vector> m_emitters; + GPUParticleSystem m_gpuSystem; +}; + +// VFX Graph 集成 +namespace VFXGraph { + +class VFXGraphAsset : public IResource { +public: + // VFX Graph 描述 +}; + +class VFXGraphComponent : public Component { +public: + void Update(float deltaTime) override; + + VFXGraphAsset* asset = nullptr; + + std::unordered_map floatParameters; + std::unordered_map vector3Parameters; + std::unordered_map colorParameters; + std::unordered_map boolParameters; + + void SetFloat(const String& name, float value); + void SetVector3(const String& name, const Vector3& value); + void SetColor(const String& name, const Color& value); + void SetBool(const String& name, bool value); + + void Play(); + void Stop(); + void Pause(); + void SetSeed(uint32_t seed); +}; + +} // namespace VFXGraph +} // namespace Particles +} // namespace XCEngine +``` + +--- + +## 第十二章 网络系统 (Networking) + +### 12.1 网络系统架构 + +```cpp +namespace XCEngine { +namespace Networking { + +// 网络模式 +enum class NetworkMode { + Offline, + Host, + Client, + Server +}; + +// 传输层 +enum class TransportProtocol { + UDP, + TCP, + WebSocket +}; + +// 网络消息 +struct NetworkMessage { + uint32_t type; + uint32_t channel; + uint32_t senderId; + uint64_t sequence; + uint64_t timestamp; + std::vector data; +}; + +// 消息类型 +enum class MessageType : uint32_t { + // 内置 + Connect = 1, + Disconnect = 2, + Heartbeat = 3, + Ack = 4, + + // 游戏 + Spawn = 100, + Despawn = 101, + TransformUpdate = 102, + ComponentUpdate = 103, + RPC = 104, + SceneChange = 105, +}; + +// 网络通道 +enum class NetworkChannel { + Reliable, + Unreliable, + Voice, + Raw +}; + +// 网络连接 +class NetworkConnection { +public: + uint32_t GetId() const { return m_id; } + const String& GetAddress() const { return m_address; } + float GetRoundTripTime() const { return m_rtt; } + + bool IsConnected() const { return m_connected; } + + void Send(uint32_t type, const void* data, size_t size, NetworkChannel channel); + void Disconnect(); + +private: + uint32_t m_id = 0; + String m_address; + bool m_connected = false; + float m_rtt = 0.0f; +}; + +// 网络玩家 +struct NetworkPlayer { + uint32_t id; + String name; + NetworkConnection* connection = nullptr; + GameObject* avatar = nullptr; + bool isLocal = false; + bool isReady = false; +}; + +// 网络管理器 +class NetworkManager { +public: + static NetworkManager& Get(); + + void Initialize(const NetworkConfig& config); + void Shutdown(); + + // 模式 + NetworkMode GetMode() const { return m_mode; } + + // 主机 + bool StartHost(uint16_t port); + void StopHost(); + + // 客户端 + bool Connect(const String& address, uint16_t port); + void Disconnect(); + + // 玩家 + uint32_t GetLocalPlayerId() const { return m_localPlayerId; } + NetworkPlayer* GetPlayer(uint32_t id); + const std::vector& GetPlayers(); + + // 消息 + void Send(uint32_t playerId, uint32_t type, const void* data, size_t size, + NetworkChannel channel = NetworkChannel::Reliable); + void SendToAll(uint32_t type, const void* data, size_t size, + NetworkChannel channel = NetworkChannel::Reliable); + + // RPC + template + void RegisterRPC(const String& name, T* obj, void (T::*func)(NetworkReader&)); + + // 场景同步 + void SetNetworkedScene(Scene* scene); + void AddNetworkedObject(GameObject* gameObject); + void RemoveNetworkedObject(GameObject* gameObject); + + // 同步 + void Update(float deltaTime); + + // 事件 + Event OnPlayerConnected; + Event OnPlayerDisconnected; + Event OnMessageReceived; + +private: + NetworkMode m_mode = NetworkMode::Offline; + uint32_t m_localPlayerId = 0; + std::vector m_players; + + void* m_transport = nullptr; // ENet / LiteNetLib / custom +}; + +// 网络组件 +class NetworkIdentityComponent : public Component { +public: + void Update(float deltaTime) override; + + uint32_t networkId = 0; + bool isLocalPlayer = false; + bool isOwnedByClient = false; + bool canSpawn = true; + bool syncTransform = true; + bool syncComponents = true; +}; + +class NetworkTransformComponent : public Component { +public: + void Update(float deltaTime) override; + + enum class SyncMode { + None, + SyncTransform, + SyncPosition, + SyncPositionAndRotation, + SyncPositionRotationScale + }; + + SyncMode syncMode = SyncMode::SyncPositionRotationScale; + float snapThreshold = 0.5f; + float interpolationDelay = 0.1f; + + float syncInterval = 0.05f; + + bool enablePrediction = true; + float predictionTime = 0.1f; + + bool quantizePosition = true; + int positionPrecision = 0.01f; + bool quantizeRotation = true; + int rotationPrecision = 1; +}; + +// 远程过程调用 +namespace RPC { + +// RPC 属性 +enum class RpcTarget { + Server, + Others, + All, + Specific +}; + +enum class RpcMode { + Normal, + Buffered, + Unbuffered +}; + +// RPC 调用 +struct RpcCall { + String methodName; + std::vector args; + RpcTarget target; + uint32_t targetPlayer; + float timestamp; +}; + +// 注册 RPC +#define XE_RPC(methodName, target) \ + void methodName(NetworkReader& reader); \ + static void _RPC_##methodName(NetworkIdentityComponent* identity, NetworkReader& reader) { \ + auto* comp = identity->GetComponent(); \ + if (comp && comp->isOwnedByClient) { \ + auto* obj = static_cast(identity); \ + obj->methodName(reader); \ + } \ + } + +// 服务器/客户端 RPC +class RpcHandler { +public: + void Register(uint32_t hash, std::function handler); + void Call(NetworkIdentityComponent* identity, uint32_t methodHash, NetworkWriter& writer, + RpcTarget target, uint32_t targetPlayer = 0); + void Handle(NetworkMessage& msg); +}; + +} // namespace RPC + +// 网络序列化 +class NetworkSerializer { +public: + void Serialize(NetworkWriter& writer, const GameObject& gameObject); + void Deserialize(NetworkReader& reader, GameObject& gameObject); + + void SerializeTransform(NetworkWriter& writer, const TransformComponent& transform); + void DeserializeTransform(NetworkReader& reader, TransformComponent& transform); + + // 组件同步 + void SerializeComponent(NetworkWriter& writer, uint32_t componentTypeId, const void* component); + void* DeserializeComponent(NetworkReader& reader, uint32_t componentTypeId, GameObject* gameObject); +}; + +// 网络预测 +class ClientPrediction { +public: + struct PredictedState { + Vector3 position; + Quaternion rotation; + Vector3 velocity; + float timestamp; + }; + + void StorePredictedState(const Vector3& position, const Quaternion& rotation, + const Vector3& velocity); + void ApplyServerCorrection(const Vector3& serverPosition, const Quaternion& serverRotation); + + bool HasPredictionError() const; + void Reconcile(); + +private: + std::deque m_predictedStates; + std::deque m_unconfirmedStates; + + Vector3 m_lastServerPosition; + Quaternion m_lastServerRotation; +}; + +// 延迟补偿 +class LagCompensation { +public: + struct ServerFrame { + float timestamp; + std::vector entities; + }; + + void RecordFrame(const std::vector& entities); + EntitySnapshot GetInterpolatedSnapshot(float timestamp); + + bool Raycast(Ray& ray, float maxDistance, RaycastHit& hit); + +private: + std::deque m_frames; + float m_recordDuration = 1.0f; // 记录1秒 +}; + +} // namespace Networking +} // namespace XCEngine +``` + +--- + +## 第十三章 UI 系统 (In-Game UI / UGUI) + +> **架构说明**: Unity UGUI风格的UI系统。UI元素作为组件挂载在GameObject上。 +> 每个UI元素GameObject必须挂载RectTransform组件。 + +### 13.1 UI 系统架构 + +```cpp +namespace XCEngine { +namespace UI { + +// ============================================================================ +// UI 组件 (Unity UGUI风格) +// ============================================================================ + +// 矩形变换组件 (Unity RectTransform,继承 Transform) +class RectTransformComponent : public TransformComponent { +public: + void Update(float deltaTime) override; + + // 锚点 + Vector2 anchorMin = Vector2(0, 0); + Vector2 anchorMax = Vector2(0, 0); + Vector2 pivot = Vector2(0.5f, 0.5f); + + // 位置和大小 + Vector2 anchoredPosition = Vector2::Zero(); + Vector2 sizeDelta = Vector2(100, 100); + + // 偏移 (相对于锚点) + Vector2 offsetMin = Vector2::Zero(); + Vector2 offsetMax = Vector2::Zero(); + + // 计算属性 + Vector3 GetWorldPosition() const; + Vector2 GetWorldSize() const; + void SetSize(const Vector2& size); + +private: + // 父子层级由基类 TransformComponent 管理 + mutable Matrix4x4 m_worldMatrix; + mutable bool m_dirty = true; +}; + +// 图像组件 (Unity Image) +class ImageComponent : public Component { +public: + void Update(float deltaTime) override; + + ResourceGUID spriteGuid; + + enum class Type { + Simple, + Sliced, + Tiled, + Filled + }; + Type type = Type::Simple; + + float fillAmount = 1.0f; + enum class FillMethod { Horizontal, Vertical, Radial90, Radial180, Radial360 }; + FillMethod fillMethod = FillMethod::Horizontal; + bool fillClockwise = true; + int fillOrigin = 0; + + Color color = Color::White; + bool raycastTarget = true; + + Event<> OnSpriteChanged; +}; + +// 文本组件 (Unity Text / TextMeshPro) +class TextComponent : public Component { +public: + void Update(float deltaTime) override; + + String text; + ResourceGUID fontGuid; + + int fontSize = 14; + enum class FontStyle { Normal, Bold, Italic, BoldAndItalic }; + FontStyle fontStyle = FontStyle::Normal; + + Color color = Color::White; + Color outlineColor = Color::Black; + float outlineWidth = 0.0f; + + enum class Alignment { + UpperLeft, UpperCenter, UpperRight, + MiddleLeft, MiddleCenter, MiddleRight, + LowerLeft, LowerCenter, LowerRight + }; + Alignment alignment = Alignment::MiddleCenter; + + float lineSpacing = 1.0f; + bool richText = true; + bool horizontalOverflow = false; + bool verticalOverflow = true; + bool raycastTarget = true; +}; + +// 按钮组件 (Unity Button) +class ButtonComponent : public Component { +public: + void Update(float deltaTime) override; + + enum class Transition { + None, + ColorTint, + SpriteSwap, + Animation + }; + Transition transition = Transition::ColorTint; + + // 颜色状态 + Color normalColor = Color::White; + Color highlightedColor = Color(1, 1, 1, 0.8f); + Color pressedColor = Color(1, 1, 1, 0.6f); + Color disabledColor = Color(1, 1, 1, 0.5f); + + // 精灵状态 + ResourceGUID normalSpriteGuid; + ResourceGUID highlightedSpriteGuid; + ResourceGUID pressedSpriteGuid; + ResourceGUID disabledSpriteGuid; + + // 事件 + Event<> OnClick; + Event<> OnPointerDown; + Event<> OnPointerUp; + Event<> OnPointerEnter; + Event<> OnPointerExit; +}; + +// 输入字段组件 (Unity InputField / TMP_InputField) +class InputFieldComponent : public Component { +public: + void Update(float deltaTime) override; + + String text; + String placeholder; + + int characterLimit = 0; + bool multiLine = false; + bool isPassword = false; + char passwordChar = '*'; + + enum class ContentType { + Standard, + Autocorrected, + DecimalNumber, + IntegerNumber, + Name, + EmailAddress, + Password, + PIN, + MobileTelephoneNumber, + TelephoneNumber, + URL, + Alphabet + }; + ContentType contentType = ContentType::Standard; + + Color color = Color::White; + bool raycastTarget = true; + + // 事件 + Event OnValueChanged; + Event OnEndEdit; + Event<> OnSubmit; +}; + +// 滑动条组件 (Unity Slider) +class SliderComponent : public Component { +public: + void Update(float deltaTime) override; + + float value = 0.5f; + float minValue = 0.0f; + float maxValue = 1.0f; + bool wholeNumbers = false; + + enum class Direction { + LeftToRight, + RightToLeft, + BottomToTop, + TopToBottom + }; + Direction direction = Direction::LeftToRight; + + Color color = Color::White; + bool raycastTarget = true; + + // 事件 + Event OnValueChanged; + Event OnPointerDown; + Event OnPointerUp; +}; + +// 滚动视图组件 (Unity ScrollRect) +class ScrollViewComponent : public Component { +public: + void Update(float deltaTime) override; + + GameObject* contentGameObject = nullptr; + + enum class MovementType { + Elastic, + Clamped, + Unrestricted + }; + MovementType movementType = MovementType::Elastic; + + float elasticity = 0.1f; + float decelerationRate = 0.135f; + + GameObject* horizontalScrollbar = nullptr; + GameObject* verticalScrollbar = nullptr; + + bool enabled = true; + bool raycastTarget = true; +}; + +// 画布组件 (Unity Canvas) +class CanvasComponent : public Component { +public: + void Update(float deltaTime) override; + + enum class RenderMode { + ScreenSpaceOverlay, + ScreenSpaceCamera, + WorldSpace + }; + RenderMode renderMode = RenderMode::ScreenSpaceOverlay; + + GameObject* targetCamera = nullptr; + float planeDistance = 100.0f; + + float scaleFactor = 1.0f; + + int32_t renderOrder = 0; +}; + +// 画布缩放器组件 (Unity CanvasScaler) +class CanvasScalerComponent : public Component { +public: + void Update(float deltaTime) override; + + enum class ScaleMode { + ConstantPixelSize, + ScaleWithScreenSize, + ConstantPhysicalSize + }; + ScaleMode uiScaleMode = ScaleMode::ScaleWithScreenSize; + + Vector2 referenceResolution = Vector2(800, 600); + float referencePixelsPerUnit = 100.0f; + + enum class ScreenMatchMode { + Width, + Height, + Expand, + Shrink + }; + ScreenMatchMode screenMatchMode = ScreenMatchMode::Expand; + + float matchWidthOrHeight = 0.0f; +}; + +// 布局元素组件 (用于布局组) +class LayoutElementComponent : public Component { +public: + void Update(float deltaTime) override; + + float minWidth = 0.0f; + float minHeight = 0.0f; + float preferredWidth = 0.0f; + float preferredHeight = 0.0f; + float flexibleWidth = 0.0f; + float flexibleHeight = 0.0f; + int32_t layoutPriority = 0; +}; + +// 水平布局组组件 (Unity HorizontalLayoutGroupComponent) +class HorizontalLayoutGroupComponent : public Component { +public: + void Update(float deltaTime) override; + + float spacing = 0.0f; + bool childForceExpandWidth = true; + bool childForceExpandHeight = false; + bool childControlWidth = true; + bool childControlHeight = true; + int32_t childAlignment = 4; +}; + +// 垂直布局组组件 (Unity VerticalLayoutGroupComponent) +class VerticalLayoutGroupComponent : public Component { +public: + void Update(float deltaTime) override; + + float spacing = 0.0f; + bool childForceExpandWidth = false; + bool childForceExpandHeight = true; + bool childControlWidth = true; + bool childControlHeight = true; + int32_t childAlignment = 4; +}; + +// 网格布局组组件 (Unity GridLayoutGroupComponent) +class GridLayoutGroupComponent : public Component { +public: + void Update(float deltaTime) override; + + Vector2 cellSize = Vector2(100, 100); + Vector2 spacing = Vector2::Zero(); + int32_t startCorner = 0; + int32_t startAxis = 0; + int32_t constraint = 0; + int32_t constraintCount = 2; +}; + +// ============================================================================ +// UI 系统 (处理布局、事件等 - 传统Unity风格) +// ============================================================================ + +class UISystem { +public: + void Initialize(); + void Shutdown(); + void Update(float deltaTime); + + // 射线检测 + GameObject* Raycast(const Vector2& screenPosition); + std::vector RaycastAll(const Vector2& screenPosition); + + // 焦点管理 + void SetFocus(GameObject* element); + GameObject* GetFocusedElement(); + void ClearFocus(); + +private: + void ProcessLayoutGroups(); + void ProcessRaycasts(); + void ProcessEvents(); + + GameObject* m_focusedElement = nullptr; + GameObject* m_hoveredElement = nullptr; +}; + +// ============================================================================ +// UI 渲染器 (底层实现) +// ============================================================================ + +class UIRenderer { +public: + void Initialize(); + void Shutdown(); + + void Render(Scene& scene); + + // 批处理 + void BeginBatch(); + void AddToBatch(GameObject* gameObject, const Matrix4x4& transform, const Mesh* mesh, const Material* material); + void EndBatch(); + + // 默认材质 + Material* defaultMaterial = nullptr; + Material* defaultSpriteMaterial = nullptr; +}; + +// ============================================================================ +// 画布渲染器组件 (挂载在 Canvas 上) +class CanvasRendererComponent : public Component { +public: + void Update(float deltaTime) override; + + bool renderMode = true; + uint32_t vertexCount = 0; + uint32_t indexCount = 0; + bool hasPopulateMesh = false; + + std::function onPopulateMesh; +}; + +// ============================================================================ +// UI 事件系统 +// ============================================================================ + +class UIEventSystem { +public: + static UIEventSystem& Get(); + + // 指针事件 + void OnPointerDown(PointerEvent& event); + void OnPointerUp(PointerEvent& event); + void OnPointerMove(PointerEvent& event); + void OnPointerClick(PointerEvent& event); + + // 键盘事件 + void OnKeyDown(KeyEvent& event); + void OnKeyUp(KeyEvent& event); + void OnTextInput(TextInputEvent& event); + + // 拖放事件 + void OnDragStart(DragEvent& event); + void OnDrag(DragEvent& event); + void OnDragEnd(DragEvent& event); + +private: + GameObject* m_currentPointerOver = nullptr; + GameObject* m_draggedElement = nullptr; + GameObject* m_focusedElement = nullptr; +}; + +} // namespace UI +} // namespace XCEngine +``` + +--- + +## 第十四章 编辑器架构 (Editor) + +### 14.1 编辑器整体架构 + +```cpp +namespace XCEngine { +namespace Editor { + +// 编辑器应用 +class EditorApplication { +public: + static EditorApplication& Get(); + + void Initialize(); + void Shutdown(); + void Run(); + + // 主循环 + void Update(); + void Render(); + + // 项目 + Project* GetCurrentProject() { return m_currentProject.get(); } + void NewProject(const String& path); + void OpenProject(const String& path); + void SaveProject(); + void CloseProject(); + + // 编辑器状态 + enum class Mode { + Stopped, + Playing, + Paused, + Step + }; + Mode GetMode() const { return m_mode; } + void Play(); + void Pause(); + void Stop(); + void Step(); + + // 场景操作 + void NewScene(); + void OpenScene(const String& path); + void SaveScene(); + void SaveSceneAs(const String& path); + + // 窗口 + void RegisterWindow(EditorWindow* window); + void UnregisterWindow(EditorWindow* window); + +private: + std::unique_ptr m_currentProject; + Mode m_mode = Mode::Stopped; + std::vector> m_windows; +}; + +// 编辑器窗口基类 +class EditorWindow { +public: + virtual ~EditorWindow() = default; + + virtual void OnOpen() {} + virtual void OnClose() {} + virtual void Update(float deltaTime) {} + virtual void OnGUI() {} + + virtual bool IsOpen() const { return m_open; } + void SetOpen(bool open) { m_open = open; } + + virtual ImVec2 GetSize() const { return ImVec2(400, 300); } + virtual ImVec2 GetPosition() const { return ImVec2(0, 0); } + +protected: + String m_title; + bool m_open = true; +}; + +// 项目 +class Project { +public: + String name; + String path; + String assemblyName; + + // 设置 + ProjectSettings settings; + + // 资源(使用编辑器专用的资源数据库) + EditorAssetDatabase* GetAssetDatabase() { return m_assetDatabase.get(); } + + // 场景 + std::vector GetScenes(); + void AddScene(const String& scenePath); + void RemoveScene(const String& scenePath); + + // 构建 + void Build(const BuildSettings& settings); + +private: + std::unique_ptr m_assetDatabase; + std::vector m_scenes; +}; + +// 编辑器资源数据库(继承自 Resources::AssetDatabase) +class EditorAssetDatabase { +public: + void Initialize(const String& projectPath); + void Shutdown(); + + // 资源查找 + Resources::ResourceGUID FindAsset(const String& guid) const; + Resources::ResourceGUID FindAssetByPath(const String& path) const; + String GetAssetPath(const Resources::ResourceGUID& guid) const; + + // 资源操作 + void ImportAsset(const String& sourcePath); + void ReimportAsset(const Resources::ResourceGUID& guid); + void DeleteAsset(const Resources::ResourceGUID& guid); + + // 刷新 + void Refresh(); + + // GUID 生成 + Resources::ResourceGUID GenerateGUID(); + + // 编辑器特定功能 + void SelectAsset(const Resources::ResourceGUID& guid); + std::vector GetSelectedAssets() const; + void OpenInExternalEditor(const Resources::ResourceGUID& guid); + + // 资源变换监听 + Core::Event OnAssetRenamed; + Core::Event OnAssetDeleted; + +private: + void ScanDirectory(const String& dirPath); + void ImportAssetInternal(const String& sourcePath, const String& destPath); + + struct AssetMetadata { + Resources::ResourceGUID guid; + String path; + String extension; + int64_t fileSize; + int64_t lastModified; + String importerType; + JsonObject metadata; + }; + + std::unordered_map m_guidToAsset; + std::unordered_map m_pathToGuid; + + std::vector m_selectedAssets; +}; + +// 资源导入器 +class AssetImporter { +public: + virtual ~AssetImporter() = default; + + virtual bool CanImport(const String& extension) const = 0; + virtual void Import(const String& sourcePath, const ResourceGUID& guid, + const ImportSettings& settings) = 0; + virtual ImportSettings* GetDefaultSettings() const = 0; + +protected: + String GetOutputPath(const String& sourcePath, const ResourceGUID& guid); +}; + +// 具体导入器 +class TextureImporter : public AssetImporter { +public: + bool CanImport(const String& extension) const override; + void Import(const String& sourcePath, const ResourceGUID& guid, + const ImportSettings& settings) override; + + struct Settings : ImportSettings { + TextureType textureType = TextureType::Texture2D; + int maxSize = 2048; + TextureFormat format = TextureFormat::RGBA; + bool generateMipmaps = true; + bool sRGB = true; + FilterMode filterMode = FilterMode::Bilinear; + WrapMode wrapMode = WrapMode::Repeat; + }; +}; + +class MeshImporter : public AssetImporter { +public: + bool CanImport(const String& extension) const override; + void Import(const String& sourcePath, const ResourceGUID& guid, + const ImportSettings& settings) override; +}; + +class MaterialImporter : public AssetImporter { +public: + bool CanImport(const String& extension) const override; + void Import(const String& sourcePath, const ResourceGUID& guid, + const ImportSettings& settings) override; +}; + +// 编辑器场景管理 (Unity Editor 风格) +// +// 编辑器/运行时模式切换机制: +// - Stop (编辑模式): 编辑器直接操作 m_editingScene +// - Play (运行模式): +// 1. 深拷贝 m_editingScene -> m_runtimeScene (包括所有Entity和Component) +// 2. 运行 m_runtimeScene +// 3. 用户在运行时对Scene的修改都在 m_runtimeScene 中 +// - Stop -> Play 循环: +// 1. 销毁旧的 m_runtimeScene (如果存在) +// 2. 深拷贝 m_editingScene -> m_runtimeScene +// - Play -> Stop: +// 1. 销毁 m_runtimeScene +// 2. 如果用户选择了 "Apply Changes",将 runtime 改动的 GameObject 同步回 editing +// 3. 恢复编辑模式 +class EditorSceneManager { +public: + static EditorSceneManager& Get(); + + // 编辑场景 (编辑模式下使用) + Scene* GetEditingScene() { return m_editingScene.get(); } + + // 运行时场景 (Play 模式下使用) + // 注意:运行时场景是编辑场景的副本,不是同一个对象 + Scene* GetRuntimeScene() { return m_runtimeScene.get(); } + + // Play/Stop 控制 + enum class Mode { + Stopped, // 编辑模式 + Playing, // 播放模式 + Paused // 暂停模式 + }; + + void Play(); // 开始播放:从 editing 拷贝到 runtime + void Pause(); // 暂停 + void Unpause(); // 继续 + void Stop(); // 停止播放:销毁 runtime,可选 Apply Changes + void Step(); // 单步执行一帧 + + Mode GetMode() const { return m_mode; } + + // Apply Changes (Play -> Stop 时可选) + // 将 runtime 场景中的运行时数据同步回 editing 场景 + enum class ApplyChangesMode { + None, // 不应用任何更改 + All, // 应用所有更改 + Selected // 只应用选中的GameObject + }; + void SetApplyChangesMode(ApplyChangesMode mode); + void ApplyRuntimeChanges(); + + // 场景操作 + void CreateNewScene(); + void OpenScene(const String& path); + void SaveScene(const String& path); + + // 撤销/重做 + void Undo(); + void Redo(); + bool CanUndo() const; + bool CanRedo() const; + + // GameObject操作 + void DuplicateGameObject(GameObject* gameObject); + void DeleteGameObject(GameObject* gameObject); + void PasteGameObject(); + void CopyGameObject(GameObject* gameObject); + + // 预制件 + void CreatePrefab(GameObject* gameObject, const String& path); + GameObject* InstantiatePrefab(const String& path); + void UnpackPrefab(GameObject* gameObject); + +private: + void CopySceneToRuntime(); // 深拷贝编辑场景到运行时场景 + void SyncRuntimeToEditing(); // 同步运行时更改回编辑场景 + + std::unique_ptr m_editingScene; + std::unique_ptr m_runtimeScene; + + Mode m_mode = Mode::Stopped; + ApplyChangesMode m_applyChangesMode = ApplyChangesMode::None; + + std::deque m_undoStack; + std::deque m_redoStack; +}; + +// 撤销/重做 +class UndoRedoSystem { +public: + void PushAction(std::unique_ptr action); + void Undo(); + void Redo(); + + bool CanUndo() const { return !m_undoStack.empty(); } + bool CanRedo() const { return !m_redoStack.empty(); } + + void Clear(); + +private: + std::deque> m_undoStack; + std::deque> m_redoStack; + size_t m_maxStackSize = 100; +}; + +// 编辑器工具 +namespace Tools { + +class EditorTool { +public: + virtual ~EditorTool() = default; + virtual void OnActivate() {} + virtual void OnDeactivate() {} + virtual void Update(float deltaTime) {} + virtual void OnSceneGUI() {} + virtual void OnObjectGUI(GameObject* gameObject) {} + + virtual const char* GetName() const = 0; + virtual const char* GetIcon() const = 0; + +protected: + bool m_active = false; +}; + +class SelectionTool : public EditorTool { +public: + const char* GetName() const override { return "Select"; } + void Update(float deltaTime) override; + void OnSceneGUI() override; +}; + +class MoveTool : public EditorTool { +public: + const char* GetName() const override { return "Move"; } + void Update(float deltaTime) override; + void OnSceneGUI() override; +}; + +class RotateTool : public EditorTool { +public: + const char* GetName() const override { return "Rotate"; } + void Update(float deltaTime) override; + void OnSceneGUI() override; +}; + +class ScaleTool : public EditorTool { +public: + const char* GetName() const override { return "Scale"; } + void Update(float deltaTime) override; + void OnSceneGUI() override; +}; + +class Gizmo { +public: + enum class Mode { + Translate, + Rotate, + Scale, + Rect, + Transform + }; + + enum class Space { + World, + Local + }; + + enum class PivotMode { + Center, + Pivot + }; + + void SetMode(Mode mode); + void SetSpace(Space space); + void SetPivot(PivotMode pivot); + + void BeginManipulation(GameObject* gameObject); + void Draw(GameObject* gameObject); + void EndManipulation(); + + bool IsManipulating() const { return m_manipulating; } + Matrix4x4 GetManipulationDelta() const; + +private: + Mode m_mode = Mode::Translate; + Space m_space = Space::World; + PivotMode m_pivot = PivotMode::Center; + bool m_manipulating = false; + GameObject* m_selectedGameObject = nullptr; + Matrix4x4 m_startMatrix; +}; + +// 编辑器相机 +class EditorCamera { +public: + void Initialize(); + void Shutdown(); + + void Update(float deltaTime); + + void SetProjection(float fov, float aspect, float near, float far); + void SetOrthographic(float size, float near, float far); + + Matrix4x4 GetViewMatrix() const; + Matrix4x4 GetProjectionMatrix() const; + + // 控制 + void Orbit(const Vector2& delta); + void Pan(const Vector2& delta); + void Zoom(float delta); + + void FocusOn(GameObject* gameObject); + void FocusOn(const BoundingBox& bounds); + + // 状态 + float GetDistance() const { return m_distance; } + void SetDistance(float distance); + + Vector3 GetPosition() const; + Vector3 GetForward() const; + Vector3 GetTarget() const { return m_target; } + +private: + Vector3 m_target = Vector3::Zero(); + float m_distance = 10.0f; + float m_pitch = 0.0f; + float m_yaw = 0.0f; + + float m_fov = 60.0f; + float m_near = 0.1f; + float m_far = 1000.0f; + bool m_orthographic = false; + + // 交互 + bool m_isOrbiting = false; + bool m_isPanning = false; +}; + +} // namespace Tools + +// 编辑器面板 +namespace Panels { + +class HierarchyPanel { +public: + void OnGUI(); + + void SetSearchFilter(const String& filter); + void DrawGameObjectTree(GameObject* parent, int& idCounter); + +private: + String m_searchFilter; + GameObject* m_contextMenuGameObject = nullptr; +}; + +class InspectorPanel { +public: + void OnGUI(); + + void DrawGameObject(GameObject* gameObject); + void DrawComponent(uint32_t componentTypeId, void* component); + void DrawAddComponentMenu(); + +private: + GameObject* m_selectedGameObject = nullptr; +}; + +class SceneViewPanel { +public: + void OnGUI(); + void Render(); + + Tools::EditorCamera& GetCamera() { return m_camera; } + +private: + Tools::EditorCamera m_camera; + bool m_gridVisible = true; + bool m_gizmosVisible = true; +}; + +class GameViewPanel { +public: + void OnGUI(); + void Render(); + + void SetResolution(int width, int height); + void SetFullscreen(bool fullscreen); + +private: + int m_width = 1280; + int m_height = 720; + bool m_fullscreen = false; + bool m_vsync = true; +}; + +class ProjectPanel { +public: + void OnGUI(); + + void DrawAssetBrowser(); + void DrawFolderTree(); + + void OnAssetSelected(ResourceGUID guid); + +private: + String m_currentPath; + std::vector m_selectedAssets; + ViewMode m_viewMode = ViewMode::Grid; +}; + +class ConsolePanel { +public: + void OnGUI(); + + void Log(const String& message, LogLevel level); + void Clear(); + void Filter(LogLevel minLevel); + +private: + struct LogEntry { + String message; + LogLevel level; + String source; + int64_t timestamp; + }; + + std::vector m_logs; + LogLevel m_filterLevel = LogLevel::Info; +}; + +// 动画曲线编辑器 +class AnimationCurveEditor { +public: + void OnGUI(); + + void SetCurve(AnimationCurve* curve); + void AddKey(float time, float value); + void RemoveKey(int index); + +private: + AnimationCurve* m_curve = nullptr; + int m_selectedKey = -1; +}; + +// 着色器编辑器 +class ShaderEditor { +public: + void OnGUI(); + + void OpenShader(const String& path); + void SaveShader(); + void CompileShader(); + + void SetPreviewMesh(Mesh* mesh); + void SetPreviewRotation(const Vector3& rotation); + +private: + String m_shaderPath; + bool m_compileErrors = false; + String m_errorMessage; +}; + +// 材质编辑器 +class MaterialEditor { +public: + void OnGUI(); + + void OpenMaterial(Material* material); + void SaveMaterial(); + + void DrawProperty(MaterialProperty* property); + +private: + Material* m_material = nullptr; +}; + +// 偏好设置 +class PreferencesWindow : public EditorWindow { +public: + void OnGUI() override; + +private: + void DrawGeneralSettings(); + void DrawThemeSettings(); + void DrawInputSettings(); + void DrawShortcutSettings(); +}; + +} // namespace Panels + +// 编辑器渲染 +class EditorRenderView { +public: + void Initialize(); + void Shutdown(); + + void RenderSceneView(Panels::SceneViewPanel* panel); + void RenderGameView(Panels::GameViewPanel* panel); + + void SetRenderTarget(RenderTexture* target); + +private: + void SetupCamera(EditorCamera& camera); + void RenderGizmos(); + + RenderTexture* m_renderTarget = nullptr; +}; + +} // namespace Editor +} // namespace XCEngine +``` + +--- + +## 第十五章 工具链 (Toolchain) + +### 15.1 资源处理管道 + +```cpp +namespace XCEngine { +namespace Tools { + +// 资源处理器 +class AssetProcessor { +public: + static AssetProcessor& Get(); + + void Initialize(const String& projectPath); + void Shutdown(); + + // 导入 + void ImportAsset(const String& sourcePath); + void ImportAllAssets(); + + // 烘焙 + void CookScene(Scene* scene, const String& outputPath); + void CookMaterial(Material* material, const String& outputPath); + void CookTexture(Texture* texture, const String& outputPath); + + // 构建 + void BuildProject(const BuildSettings& settings); + +private: + void ProcessImportQueue(); + void WriteCookedData(const String& path, const void* data, size_t size); + + std::queue m_importQueue; +}; + +// 着色器编译器 +class ShaderCompiler { +public: + void Initialize(); + void Shutdown(); + + // 编译 + CompiledShader Compile(const ShaderSource& source, const ShaderCompileOptions& options); + bool CompileFile(const String& inputPath, const String& outputPath, + const ShaderCompileOptions& options); + + // 工具 + void GenerateShaderIncludes(); + void StripDebugInfo(CompiledShader& shader); + + // 工具链 + enum class ShaderProfile { + DXIL, // DirectX 12 + SPIRV, // Vulkan + MSL, // Metal + GLSL, // OpenGL + WGSL // WebGPU + }; + + void SetProfile(ShaderProfile profile); + void AddPreprocessorDefine(const String& define); + +private: + struct CompilerConfig { + ShaderProfile profile; + std::vector defines; + bool generateDebugInfo = false; + bool optimize = true; + int optimizationLevel = 3; + }; + + CompilerConfig m_config; +}; + +// 场景烘焙器 +class SceneCooker { +public: + void Cook(Scene* scene, const CookSettings& settings); + + // 灯光烘焙 + void BakeLightmaps(Scene* scene); + void BakeReflectionProbes(Scene* scene); + void BakeAmbientOcclusion(Scene* scene); + + // 导航烘焙 + void BakeNavigationMesh(Scene* scene); + + // 遮挡剔除 + void BakeOcclusionCulling(Scene* scene); + + // 静态批处理 + void BakeStaticBatches(Scene* scene); + +private: + void CookGameObject(GameObject* gameObject); + void WriteCookedScene(const String& path, const CookedScene& data); +}; + +// 构建工具 +class BuildTool { +public: + struct BuildSettings { + String outputPath; + String projectName; + + // 平台 + BuildPlatform platform; + BuildConfiguration config = BuildConfiguration::Release; + + // 脚本 + bool compileScripts = true; + bool generateDebugSymbols = false; + + // 资源 + bool compressAssets = true; + bool stripUnusedResources = true; + + // 目标 + bool buildExe = true; + bool buildDLC = false; + bool bundleResources = true; + }; + + void Build(const BuildSettings& settings); + void BuildPlayer(const BuildSettings& settings); + void BuildAssetBundle(const BuildSettings& settings); + +private: + void PrepareBuildDirectory(const BuildSettings& settings); + void CompileScripts(const BuildSettings& settings); + void CookResources(const BuildSettings& settings); + void CopyEngineFiles(const BuildSettings& settings); + void LinkExecutable(const BuildSettings& settings); +}; + +// 性能分析器工具 +class ProfilerCapture { +public: + void StartCapture(); + void StopCapture(); + + void SaveCapture(const String& path); + void LoadCapture(const String& path); + + // 分析 + void GenerateReport(); + float GetTotalFrameTime() const; + float GetCPUFrameTime() const; + float GetGPUFrameTime() const; + +private: + struct FrameData { + uint64_t timestamp; + std::vector events; + }; + + std::vector m_frames; + bool m_capturing = false; +}; + +} // namespace Tools +} // namespace XCEngine +``` + +--- + +## 第十六章 平台层 (Platform) + +### 16.1 跨平台抽象 + +```cpp +namespace XCEngine { +namespace Platform { + +// 平台类型 +enum class PlatformType { + Windows, + Linux, + macOS, + Android, + iOS, + Web, + PlayStation, + Xbox, + Nintendo +}; + +// 键码 +enum class KeyCode { + None = 0, + A = 4, B = 5, C = 6, D = 7, E = 8, F = 9, G = 10, + H = 11, I = 12, J = 13, K = 14, L = 15, M = 16, N = 17, + O = 18, P = 19, Q = 20, R = 21, S = 22, T = 23, U = 24, + V = 25, W = 26, X = 27, Y = 28, Z = 29, + F1 = 122, F2 = 120, F3 = 99, F4 = 118, F5 = 96, F6 = 97, + F7 = 98, F8 = 100, F9 = 101, F10 = 109, F11 = 103, F12 = 111, + Space = 49, Tab = 48, Enter = 36, Escape = 53, + LeftShift = 56, RightShift = 60, LeftCtrl = 59, RightCtrl = 62, + LeftAlt = 58, RightAlt = 61, + Up = 126, Down = 125, Left = 123, Right = 124, + Home = 115, End = 119, PageUp = 116, PageDown = 121, + Delete = 51, Backspace = 51 +}; + +// 鼠标按钮 +enum class MouseButton { + Left = 0, + Right = 1, + Middle = 2, + Button4 = 3, + Button5 = 4 +}; + +// 触摸状态 +struct TouchState { + int touchId; + Vector2 position; + Vector2 deltaPosition; + float deltaTime; + int tapCount; + enum Phase { Began, Moved, Stationary, Ended, Canceled } phase; +}; + +// 指针事件 +struct PointerEvent { + int pointerId; + Vector2 position; + Vector2 deltaPosition; + float pressure; + MouseButton button; + enum Type { Pressed, Released, Moved, Wheel, Hover } type; +}; + +// 按键事件 +struct KeyEvent { + KeyCode keyCode; + bool alt; + bool ctrl; + bool shift; + bool meta; + enum Type { Down, Up, Repeat } type; +}; + +// 文本输入事件 +struct TextInputEvent { + char character; + String text; +}; + +// 拖放事件 +struct DragEvent { + Vector2 position; + Vector2 delta; + int pointerId; +}; + +// 文件变化事件 +struct FileChangeEvent { + String path; + enum Type { Created, Modified, Deleted, Renamed } type; +}; + +// 手势事件 +struct GestureEvent { + Vector2 position; + float deltaScale; + float deltaRotation; + int tapCount; + enum Type { None, Tap, DoubleTap, Pinch, Rotate, Pan } type; +}; + +// 窗口 +class Window { +public: + virtual ~Window() = default; + + virtual void Create(const WindowDesc& desc) = 0; + virtual void Destroy() = 0; + + virtual void Show() = 0; + virtual void Hide() = 0; + virtual void Minimize() = 0; + virtual void Maximize() = 0; + virtual void Restore() = 0; + virtual void SetFullscreen(bool fullscreen) = 0; + + virtual void SetTitle(const String& title) = 0; + virtual void SetSize(int width, int height) = 0; + virtual void SetPosition(int x, int y) = 0; + + virtual bool IsClosed() const = 0; + virtual bool IsFocused() const = 0; + virtual bool IsMinimized() const = 0; + virtual bool IsMaximized() const = 0; + virtual bool IsFullscreen() const = 0; + + virtual void* GetNativeHandle() const = 0; + + // 事件 + Event OnResize; + Event OnMove; + Event<> OnClose; + Event<> OnFocus; + Event<> OnBlur; + Event<> OnMinimize; + Event<> OnMaximize; + Event<> OnRestore; +}; + +// 输入 +class InputSystem { +public: + // 键盘 + bool IsKeyDown(KeyCode key) const; + bool IsKeyUp(KeyCode key) const; + bool IsKeyPressed(KeyCode key) const; + + // 鼠标 + Vector2 GetMousePosition() const; + Vector2 GetMouseDelta() const; + float GetMouseScrollDelta() const; + bool IsMouseButtonDown(MouseButton button) const; + bool IsMouseButtonUp(MouseButton button) const; + bool IsMouseButtonClicked(MouseButton button) const; + + // 手柄 + int GetJoystickCount() const; + bool IsJoystickConnected(int joystick) const; + Vector2 GetJoystickAxis(int joystick, int axis) const; + bool IsJoystickButtonDown(int joystick, int button) const; + + // 触摸 + int GetTouchCount() const; + TouchState GetTouch(int index) const; + + // 手势 + Event OnGesture; +}; + +// 注意:FileSystem 定义在 Platform 命名空间中 +// Core::IO 只保留流抽象 (IStream, FileReader, FileWriter) +} + +namespace XCEngine { +namespace Platform { + +// 文件系统 - 统一的跨平台文件系统抽象 +class FileSystem { +public: + static FileSystem& Get(); + + // 路径操作 + String GetWorkingDirectory(); + String GetExecutablePath(); + String GetUserDirectory(); + String GetAppDataDirectory(); + String GetTempDirectory(); + + // 文件操作 + bool FileExists(const String& path); + bool DirectoryExists(const String& path); + bool CreateDirectory(const String& path); + bool DeleteFile(const String& path); + bool DeleteDirectory(const String& path); + + // 读写 + std::unique_ptr OpenRead(const String& path); + std::unique_ptr OpenWrite(const String& path); + std::unique_ptr OpenAppend(const String& path); + + // 遍历 + void EnumerateFiles(const String& directory, const String& pattern, + std::vector& results); + void EnumerateDirectories(const String& directory, + std::vector& results); + + // 观察 + void WatchDirectory(const String& directory, + std::function callback); +}; + +// 时间 + +// 时间 +class Time { +public: + static float GetTime(); + static float GetUnscaledTime(); + static float GetDeltaTime(); + static float GetUnscaledDeltaTime(); + + static void SetTimeScale(float scale); + static float GetTimeScale() { return m_timeScale; } + + static uint64_t GetFrameCount() { return m_frameCount; } + static int GetFrameRate() { return m_frameRate; } + + static void SetTargetFrameRate(int rate); + static void BeginFrame(); + static void EndFrame(); + +private: + static float m_timeScale; + static uint64_t m_frameCount; + static int m_frameRate; +}; + +// 内存映射文件 +class MemoryMappedFile { +public: + bool Open(const String& path); + void Close(); + + void* GetData() const { return m_data; } + size_t GetSize() const { return m_size; } + +private: + void* m_handle = nullptr; + void* m_data = nullptr; + size_t m_size = 0; +}; + +// 进程 +class Process { +public: + bool Launch(const String& command, const std::vector& args); + void Terminate(); + bool IsRunning() const; + + int GetExitCode() const; + int WaitForExit(); + + void Write(const void* data, size_t size); + String ReadOutput(); + String ReadError(); + +private: + void* m_handle = nullptr; +}; + +// 动态库 +class DynamicLibrary { +public: + bool Load(const String& path); + void Unload(); + + void* GetFunction(const String& name); + bool IsLoaded() const; + +private: + void* m_handle = nullptr; +}; + +// 系统信息 +class SystemInfo { +public: + static String GetOSName(); + static String GetOSVersion(); + static String GetMachineName(); + static String GetUserName(); + + static int GetProcessorCount(); + static int GetProcessorCoreCount(); + static int GetThreadCount(); + + static uint64_t GetTotalMemory(); + static uint64_t GetAvailableMemory(); + + static String GetGPUName(); + static uint64_t GetGPUMemory(); + static int GetGPUMonitorCount(); + + static bool HasNvidiaGPU(); + static bool HasAmdGPU(); + static bool HasIntelGPU(); +}; + +} // namespace Platform +} // namespace XCEngine +``` + +--- + +## 第十七章 构建与部署 + +### 17.1 CMake 项目结构 + +``` +XCVolumeRenderer/ +├── CMakeLists.txt # 根 CMake 配置 +├── cmake/ +│ ├── FindXXX.cmake # 第三方库查找 +│ ├── XCEngineDefaults.cmake # 默认设置 +│ └── Utils.cmake # 工具宏 +│ +├── engine/ # 引擎核心 +│ ├── CMakeLists.txt +│ ├── include/ +│ └── src/ +│ +├── editor/ # 编辑器 +│ ├── CMakeLists.txt +│ └── src/ +│ +├── runtime/ # 运行时 +│ ├── CMakeLists.txt +│ └── src/ +│ +├── tools/ # 工具链 +│ ├── AssetProcessor/ +│ ├── ShaderCompiler/ +│ └── SceneCooker/ +│ +└── third_party/ # 第三方库 + ├── CMakeLists.txt + ├── imgui/ + ├── stb/ + └── ... +``` + +### 17.2 CMake 配置示例 + +```cmake +# 根 CMakeLists.txt +cmake_minimum_required(VERSION 3.20) +project(XCGameEngine VERSION 1.0.0) + +# 选项 +option(BUILD_EDITOR "Build editor" ON) +option(BUILD_RUNTIME "Build runtime" ON) +option(BUILD_TOOLS "Build tools" ON) +option(BUILD_SHADERS "Build shaders" ON) + +# 加载工具 +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +include(XCEngineDefaults) + +# 依赖 +find_package(Threads REQUIRED) +find_package(D3D12 REQUIRED) +find_package(Vulkan REQUIRED) + +# 子目录 +add_subdirectory(third_party) +add_subdirectory(engine) + +if(BUILD_EDITOR) + add_subdirectory(editor) +endif() + +if(BUILD_RUNTIME) + add_subdirectory(runtime) +endif() + +if(BUILD_TOOLS) + add_subdirectory(tools) +endif() +``` + +### 17.3 构建流程 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Build Pipeline │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Source Code ──► Compile ──► Link ──► Engine Library │ +│ │ │ +│ │ │ +│ ▼ │ +│ Assets ──► Import ──► Cook ──► Pack ──► Resource Bundle │ +│ │ +│ │ │ +│ │ │ +│ ▼ │ +│ Shaders ──► Compile ──► Pack ──► Shader Cache │ +│ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────────┐ │ +│ │ Final Output │ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │ │ +│ │ │ Executable │ │ Resources │ │ Engine Libraries │ │ │ +│ │ │ (EXE/DLL) │ │ (.pak) │ │ (.lib/.dll) │ │ │ +│ │ └──────────────┘ └──────────────┘ └──────────────────────────┘ │ │ +│ └─────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 第十八章 总结与实现建议 + +### 18.1 架构核心要点 + +1. **分层设计**: Platform → Core → Engine → Editor/Runtime +2. **组件系统**: 类Unity的GameObject+Component模式 +3. **渲染抽象**: 跨 API 的渲染接口,便于扩展 +4. **资源管理**: 完整的导入→处理→缓存→加载管道 +5. **工具链**: 从源代码到最终产品的完整构建系统 + +### 18.2 实现优先级建议 + +#### 第一阶段 (基础框架) +- [ ] 数学库 (Vector, Matrix, Quaternion, Transform) +- [ ] 基础容器 (Array, String, HashMap) +- [ ] 内存管理 (Allocator, Pool) +- [ ] 线程系统 (Thread, Mutex, TaskSystem) +- [ ] 日志系统 +- [ ] 文件系统抽象 + +#### 第二阶段 (组件系统 + 渲染) +- [ ] 组件系统核心 (GameObject, Component) +- [ ] 基础组件 (Transform, RenderMesh) +- [ ] 渲染抽象层 (Device, CommandList) +- [ ] D3D12/Vulkan 后端 +- [ ] 基础渲染管线 (GBuffer, Lighting) + +#### 第三阶段 (功能系统) +- [ ] 资源系统 (ResourceManager, AssetDatabase) +- [ ] 场景系统 (Scene, SceneManager) +- [ ] 物理系统 (基础碰撞检测) +- [ ] 输入系统 +- [ ] UI 框架 + +#### 第四阶段 (编辑器) +- [ ] 编辑器 UI (ImGui) +- [ ] 场景视图/游戏视图 +- [ ] 层级面板/检视面板 +- [ ] 资源浏览器 +- [ ] 工具 (Gizmo, 编辑器相机) + +#### 第五阶段 (高级功能) +- [ ] 动画系统 +- [ ] 粒子系统 +- [ ] 音频系统 +- [ ] 网络系统 +- [ ] 脚本系统 + +### 18.3 代码组织建议 + +``` +engine/src/ +├── Core/ # 1-2周 +│ ├── Math/ +│ ├── Containers/ +│ ├── Memory/ +│ ├── Threading/ +│ └── Debug/ +├── Components/ # 2-3周 +│ ├── GameObject.cpp +│ ├── Component.cpp +│ └── System.cpp +├── Renderer/ # 3-4周 +│ ├── Device.cpp +│ ├── CommandList.cpp +│ ├── Pipeline.cpp +│ └── Passes/ +├── Resources/ # 2周 +│ ├── ResourceManager.cpp +│ ├── AssetDatabase.cpp +│ └── Loaders/ +├── Scene/ # 1周 +├── Physics/ # 2-3周 +├── Scripting/ # 3-4周 (可选) +└── Platform/ # 1周 + ├── Windows.cpp + └── ... + +editor/src/ +├── Application.cpp # 1周 +├── Panels/ # 2周 +├── Tools/ # 2周 +├── Windows/ # 2周 +└── ImGui/ # 1周 +``` + +### 18.4 技术选型建议 + +| 子系统 | 推荐方案 | 备选 | +|--------|----------|------| +| 图形 API | D3D12 + Vulkan | Metal, OpenGL | +| 物理 | PhysX | Bullet, Box2D | +| 脚本 | C# (Mono/.NET) | Lua, AngelScript | +| UI (编辑器) | ImGui | Qt, Custom | +| UI (运行时) | 自研 Canvas | DearImgui, RmlUI | +| 资源格式 | 自研 Binary + JSON | glTF, USD | +| 压缩 | LZ4 + ZSTD | LZMA, LZHAM | +| 网络 | 自研 / ENet | LiteNetLib | + +### 18.5 性能目标 + +- 60 FPS 稳定运行 (1080p, 中等画质) +- 10000+ 实体同屏 +- 加载时间 < 3秒 (典型场景) +- 编辑器响应 < 16ms + +--- + +*文档版本: 1.15* +*最后更新: 2026-03-13* diff --git a/docs/XCVolumeRenderer渲染引擎架构设计.md b/docs/XCVolumeRenderer渲染引擎架构设计.md new file mode 100644 index 00000000..799315e4 --- /dev/null +++ b/docs/XCVolumeRenderer渲染引擎架构设计.md @@ -0,0 +1,1845 @@ +# XCVolumeRenderer - 渲染引擎架构设计文档 + +> **基于 XCGameEngine 架构提取的渲染引擎子集** +> 版本: 1.0 +> 日期: 2026-03-13 +> 目标: 构建专业级实时体积渲染引擎 + +--- + +## 第一章 核心基础层 + +### 1.1 数学库 (Math Library) + +```cpp +namespace XCEngine { +namespace Math { + +struct Vector2 { + float x, y; + + static Vector2 Zero() { return Vector2{0, 0}; } + static Vector2 One() { return Vector2{1, 1}; } + static Vector2 Up() { return Vector2{0, 1}; } + static Vector2 Down() { return Vector2{0, -1}; } + static Vector2 Right() { return Vector2{1, 0}; } + static Vector2 Left() { return Vector2{-1, 0}; } + + static float Dot(const Vector2& a, const Vector2& b); + static float Cross(const Vector2& a, const Vector2& b); + static Vector2 Normalize(const Vector2& v); + static float Magnitude(const Vector2& v); + static Vector2 Lerp(const Vector2& a, const Vector2& b, float t); +}; + +struct Vector3 { + float x, y, z; + + static Vector3 Zero() { return Vector3{0, 0, 0}; } + static Vector3 One() { return Vector3{1, 1, 1}; } + static Vector3 Forward() { return Vector3{0, 0, 1}; } + static Vector3 Back() { return Vector3{0, 0, -1}; } + static Vector3 Up() { return Vector3{0, 1, 0}; } + static Vector3 Down() { return Vector3{0, -1, 0}; } + static Vector3 Right() { return Vector3{1, 0, 0}; } + static Vector3 Left() { return Vector3{-1, 0, 0}; } + + static Vector3 Cross(const Vector3& a, const Vector3& b); + static float Dot(const Vector3& a, const Vector3& b); + static Vector3 Normalize(const Vector3& v); + static float Magnitude(const Vector3& v); + static float SqrMagnitude(const Vector3& v); + static Vector3 Lerp(const Vector3& a, const Vector3& b, float t); + static Vector3 MoveTowards(const Vector3& current, const Vector3& target, float maxDistance); +}; + +struct Vector4 { float x, y, z, w; }; + +struct Matrix3x3; +struct Matrix4x4; + +struct Quaternion { + float x, y, z, w; + + static Quaternion Identity() { return Quaternion{0, 0, 0, 1}; } + + static Quaternion FromAxisAngle(const Vector3& axis, float radians); + static Quaternion FromEulerAngles(float pitch, float yaw, float roll); + static Quaternion FromRotationMatrix(const Matrix4x4& matrix); + static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float t); + static Quaternion LookRotation(const Vector3& forward, const Vector3& up = Vector3::Up()); + + Vector3 ToEulerAngles() const; + Matrix4x4 ToMatrix4x4() const; + Vector3 operator*(const Vector3& v) const; + + Quaternion operator*(const Quaternion& other) const; + Quaternion Inverse() const; + float Dot(const Quaternion& other) const; +}; + +struct Transform { + Vector3 position = Vector3::Zero(); + Quaternion rotation = Quaternion::Identity(); + Vector3 scale = Vector3::One(); + + Matrix4x4 ToMatrix() const; + Transform Inverse() const; + Transform operator*(const Transform& other) const; + Vector3 TransformPoint(const Vector3& point) const; + Vector3 TransformDirection(const Vector3& direction) const; +}; + +enum class Space { + Self, + World +}; + +struct Color { + float r, g, b, a; + + static Color White() { return Color{1, 1, 1, 1}; } + static Color Black() { return Color{0, 0, 0, 1}; } + static Color Red() { return Color{1, 0, 0, 1}; } + static Color Green() { return Color{0, 1, 0, 1}; } + static Color Blue() { return Color{0, 0, 1, 1}; } + static Color Yellow() { return Color{1, 1, 0, 1}; } + static Color Cyan() { return Color{0, 1, 1, 1}; } + static Color Magenta() { return Color{1, 0, 1, 1}; } + static Color Clear() { return Color{0, 0, 0, 0}; } + + static Color Lerp(const Color& a, const Color& b, float t); +}; + +struct Rect { + float x, y, width, height; + + Rect() : x(0), y(0), width(0), height(0) {} + Rect(float x, float y, float w, float h) : x(x), y(y), width(w), height(h) {} + + float GetLeft() const { return x; } + float GetRight() const { return x + width; } + float GetTop() const { return y; } + float GetBottom() const { return y + height; } + + Vector2 GetPosition() const { return Vector2{x, y}; } + Vector2 GetSize() const { return Vector2{width, height}; } + + bool Contains(float px, float py) const { + return px >= x && px < x + width && py >= y && py < y + height; + } +}; + +struct RectInt { + int32_t x, y, width, height; + + RectInt() : x(0), y(0), width(0), height(0) {} + RectInt(int32_t x, int32_t y, int32_t w, int32_t h) : x(x), y(y), width(w), height(h) {} +}; + +struct Viewport { + float x, y, width, height; + float minDepth = 0.0f; + float maxDepth = 1.0f; + + Viewport() : x(0), y(0), width(0), height(0) {} + Viewport(float x, float y, float w, float h) : x(x), y(y), width(w), height(h) {} +}; + +struct Ray { + Vector3 origin; + Vector3 direction; + + Vector3 GetPoint(float t) const; + bool Intersects(const Sphere& sphere, float& t) const; + bool Intersects(const Box& box, float& t) const; + bool Intersects(const Plane& plane, float& t) const; +}; + +struct Sphere { Vector3 center; float radius; }; +struct Box { Vector3 center; Vector3 extents; Matrix4x4 transform; }; +struct Plane { Vector3 normal; float distance; }; +struct Frustum; +struct OBB; +struct AABB; + +} // namespace Math +} // namespace XCEngine +``` + +### 1.2 内存管理 (Memory Management) + +```cpp +namespace XCEngine { +namespace Memory { + +class IAllocator { +public: + virtual ~IAllocator() = default; + + virtual void* Allocate(size_t size, size_t alignment = 0) = 0; + virtual void Free(void* ptr) = 0; + virtual void* Reallocate(void* ptr, size_t newSize) = 0; + + virtual size_t GetTotalAllocated() const = 0; + virtual size_t GetTotalFreed() const = 0; + virtual size_t GetPeakAllocated() const = 0; + virtual size_t GetAllocationCount() const = 0; + + virtual const char* GetName() const = 0; +}; + +class LinearAllocator : public IAllocator { +public: + explicit LinearAllocator(size_t size, IAllocator* parent = nullptr); + ~LinearAllocator(); + + void* Allocate(size_t size, size_t alignment = 8) override; + void Free(void* ptr) override; + void Clear(); + + void* GetMarker() const; + void SetMarker(void* marker); + +private: + byte* m_buffer = nullptr; + size_t m_capacity = 0; + size_t m_offset = 0; + IAllocator* m_parent = nullptr; +}; + +class PoolAllocator : public IAllocator { +public: + PoolAllocator(size_t blockSize, size_t poolSize, size_t alignment = 8); + ~PoolAllocator(); + + void* Allocate(size_t size, size_t alignment = 0) override; + void Free(void* ptr) override; + + bool Contains(void* ptr) const; + size_t GetBlockSize() const { return m_blockSize; } + size_t GetFreeBlockCount() const; + +private: + struct FreeNode { + FreeNode* next; + }; + + size_t m_blockSize = 0; + size_t m_alignment = 0; + void* m_memory = nullptr; + FreeNode* m_freeList = nullptr; + size_t m_totalBlocks = 0; + size_t m_freeBlocks = 0; +}; + +class ProxyAllocator : public IAllocator { +public: + ProxyAllocator(IAllocator* underlying, const char* name); + + void* Allocate(size_t size, size_t alignment = 0) override; + void Free(void* ptr) override; + void* Reallocate(void* ptr, size_t newSize) override; + + struct Stats { + size_t totalAllocated; + size_t totalFreed; + size_t peakAllocated; + size_t allocationCount; + size_t memoryOverhead; + }; + const Stats& GetStats() const; + +private: + IAllocator* m_underlying; + const char* m_name; + Stats m_stats; + Mutex m_mutex; +}; + +class MemoryManager { +public: + static MemoryManager& Get(); + + void Initialize(); + void Shutdown(); + + IAllocator* GetSystemAllocator(); + + std::unique_ptr CreateLinearAllocator(size_t size); + std::unique_ptr CreatePoolAllocator(size_t blockSize, size_t count); + std::unique_ptr CreateProxyAllocator(const char* name); + + void SetTrackAllocations(bool track); + void DumpMemoryLeaks(); + void GenerateMemoryReport(); +}; + +#define XE_ALLOC(allocator, size, ...) allocator->Allocate(size, ##__VA_ARGS__) +#define XE_FREE(allocator, ptr) allocator->Free(ptr) + +} // namespace Memory +} // namespace XCEngine +``` + +### 1.3 容器库 (Containers) + +```cpp +namespace XCEngine { +namespace Containers { + +template +class Array { +public: + using Iterator = T*; + using ConstIterator = const T*; + + Array() = default; + explicit Array(size_t capacity); + Array(size_t count, const T& value); + Array(std::initializer_list init); + ~Array(); + + Array(const Array& other); + Array(Array&& other) noexcept; + Array& operator=(const Array& other); + Array& operator=(Array&& other) noexcept; + + T& operator[](size_t index); + const T& operator[](size_t index) const; + + T* Data() { return m_data; } + const T* Data() const { return m_data; } + + size_t Size() const { return m_size; } + size_t Capacity() const { return m_capacity; } + + void Clear(); + void PushBack(const T& value); + void PushBack(T&& value); + template + T& EmplaceBack(Args&&... args); + void PopBack(); + +private: + T* m_data = nullptr; + size_t m_size = 0; + size_t m_capacity = 0; + IAllocator* m_allocator = nullptr; +}; + +class String { +public: + String(); + String(const char* str); + String(const char* str, size_t len); + ~String(); + + String& operator+=(const String& other); + String& operator+=(const char* str); + + String Substring(size_t pos, size_t len = npos) const; + String Trim() const; + String ToLower() const; + String ToUpper() const; + + size_t Find(const char* str, size_t pos = 0) const; + bool StartsWith(const String& prefix) const; + bool EndsWith(const String& suffix) const; + + const char* CStr() const { return m_data; } + size_t Length() const { return m_length; } + +private: + char* m_data = nullptr; + size_t m_length = 0; + size_t m_capacity = 0; +}; + +template +class HashMap { +public: + struct Pair { + Key first; + Value second; + }; + + HashMap() = default; + explicit HashMap(size_t bucketCount, IAllocator* allocator = nullptr); + + Value& operator[](const Key& key); + Value* Find(const Key& key); + const Value* Find(const Key& key) const; + bool Contains(const Key& key) const; + + bool Insert(const Key& key, const Value& value); + bool Erase(const Key& key); + void Clear(); + + size_t Size() const { return m_size; } + +private: + size_t GetBucketIndex(const Key& key) const; + void Resize(); + + struct Bucket { + Array pairs; + }; + Array m_buckets; + size_t m_bucketCount = 0; + size_t m_size = 0; + float m_loadFactor = 0.75f; + IAllocator* m_allocator = nullptr; +}; + +} // namespace Containers +} // namespace XCEngine +``` + +### 1.4 线程系统 (Threading) + +```cpp +namespace XCEngine { +namespace Threading { + +enum class TaskPriority : uint8_t { + Critical = 0, + High = 1, + Normal = 2, + Low = 3, + Idle = 4 +}; + +enum class TaskStatus : uint8_t { + Pending, + Scheduled, + Running, + Completed, + Failed, + Canceled +}; + +template +using Func = std::function; + +class ITask { +public: + virtual ~ITask() = default; + + virtual void Execute() = 0; + virtual void OnComplete() {} + virtual void OnCancel() {} + + TaskPriority GetPriority() const { return m_priority; } + TaskStatus GetStatus() const { return m_status; } + uint64 GetId() const { return m_id; } + +protected: + TaskPriority m_priority = TaskPriority::Normal; + TaskStatus m_status = TaskStatus::Pending; + uint64 m_id = 0; + std::atomic m_refCount{1}; +}; + +template +class LambdaTask : public ITask { +public: + explicit LambdaTask(Func&& func, TaskPriority priority = TaskPriority::Normal) + : m_func(std::move(func)), m_priority(priority) {} + + void Execute() override { + m_func(); + } + +private: + Func m_func; +}; + +class TaskGroup { +public: + using Callback = std::function; + + TaskGroup(); + ~TaskGroup(); + + uint64 AddTask(std::unique_ptr task); + uint64 AddTask(Func&& func, TaskPriority priority = TaskPriority::Normal); + + void AddDependency(uint64 taskId, uint64 dependsOn); + void Wait(); + bool WaitFor(std::chrono::milliseconds timeout); + + void SetCompleteCallback(Callback&& callback); + bool IsComplete() const; + float GetProgress() const; +}; + +class TaskSystem { +public: + static TaskSystem& Get(); + + void Initialize(const TaskSystemConfig& config); + void Shutdown(); + + uint64 Submit(std::unique_ptr task); + uint64 Submit(Func&& func, TaskPriority priority = TaskPriority::Normal); + + TaskGroup* CreateTaskGroup(); + void DestroyTaskGroup(TaskGroup* group); + + void Wait(uint64 taskId); + uint32 GetWorkerThreadCount() const; + + void Update(); + + template + void ParallelFor(int32 start, int32 end, Func&& func); + + void RunOnMainThread(Func&& func); +}; + +} // namespace Threading +} // namespace XCEngine +``` + +### 1.5 日志与调试系统 + +```cpp +namespace XCEngine { +namespace Core { + +template +class Event { +public: + using Callback = std::function; + using Listener = std::pair; + using Iterator = typename std::vector::iterator; + + uint64_t Subscribe(Callback callback) { + std::lock_guard lock(m_mutex); + uint64_t id = ++m_nextId; + m_listeners.emplace_back(id, std::move(callback)); + return id; + } + + void Unsubscribe(uint64_t id) { + std::lock_guard lock(m_mutex); + m_pendingUnsubscribes.push_back(id); + } + + void ProcessUnsubscribes() { + std::lock_guard lock(m_mutex); + for (uint64_t id : m_pendingUnsubscribes) { + m_listeners.erase( + std::remove_if(m_listeners.begin(), m_listeners.end(), + [id](const auto& pair) { return pair.first == id; }), + m_listeners.end() + ); + } + m_pendingUnsubscribes.clear(); + } + + void Invoke(Args... args) const { + if (!m_pendingUnsubscribes.empty()) { + std::vector listenersCopy; + { + std::lock_guard lock(m_mutex); + listenersCopy = m_listeners; + m_pendingUnsubscribes.clear(); + } + for (const auto& [id, callback] : listenersCopy) { + callback(args...); + } + } else { + for (const auto& [id, callback] : m_listeners) { + callback(args...); + } + } + } + + void Clear() { + std::lock_guard lock(m_mutex); + m_listeners.clear(); + } + + Iterator begin() { return m_listeners.begin(); } + Iterator end() { return m_listeners.end(); } + +private: + mutable std::mutex m_mutex; + std::vector m_listeners; + std::vector m_pendingUnsubscribes; + uint64_t m_nextId = 0; +}; + +using int8 = int8_t; +using int16 = int16_t; +using int32 = int32_t; +using int64 = int64_t; +using uint8 = uint8_t; +using uint16 = uint16_t; +using uint32 = uint32_t; +using uint64 = uint64_t; +using byte = uint8_t; + +class RefCounted { +public: + RefCounted() : m_refCount(1) {} + virtual ~RefCounted() = default; + + void AddRef() { ++m_refCount; } + void Release() { + if (--m_refCount == 0) { + delete this; + } + } + + uint32_t GetRefCount() const { return m_refCount.load(); } + +protected: + std::atomic m_refCount; +}; + +template +using Ref = std::shared_ptr; + +template +using UniqueRef = std::unique_ptr; + +} // namespace Core +} // namespace XCEngine + +namespace XCEngine { +namespace Debug { + +enum class LogLevel : uint8_t { + Verbose = 0, + Debug = 1, + Info = 2, + Warning = 3, + Error = 4, + Fatal = 5 +}; + +enum class LogCategory { + General, + Rendering, + Physics, + Audio, + Scripting, + Network, + Memory, + Threading, + FileSystem, + Custom +}; + +struct LogEntry { + LogLevel level; + LogCategory category; + String message; + String file; + int32 line; + String function; + uint64 timestamp; + uint32 threadId; +}; + +class ILogSink { +public: + virtual ~ILogSink() = default; + virtual void Log(const LogEntry& entry) = 0; + virtual void Flush() = 0; +}; + +class ConsoleLogSink : public ILogSink { +public: + void Log(const LogEntry& entry) override; + void Flush() override; + void SetColorOutput(bool enable); + void SetMinimumLevel(LogLevel level); +}; + +class FileLogSink : public ILogSink { +public: + explicit FileLogSink(const String& filePath); + ~FileLogSink(); + void Log(const LogEntry& entry) override; + void Flush() override; +private: + String m_filePath; + FileWriter m_writer; +}; + +class Logger { +public: + static Logger& Get(); + + void Initialize(); + void Shutdown(); + + void AddSink(std::unique_ptr sink); + void RemoveSink(ILogSink* sink); + + void Log(LogLevel level, LogCategory category, + const String& message, const char* file = nullptr, + int32 line = 0, const char* function = nullptr); + + void Verbose(LogCategory category, const String& message); + void Debug(LogCategory category, const String& message); + void Info(LogCategory category, const String& message); + void Warning(LogCategory category, const String& message); + void Error(LogCategory category, const String& message); + void Fatal(LogCategory category, const String& message); + + void SetMinimumLevel(LogLevel level); + void SetCategoryEnabled(LogCategory category, bool enabled); +}; + +#define XE_LOG(category, level, message) \ + XCEngine::Debug::Logger::Get().Log(level, category, message, __FILE__, __LINE__, __FUNCTION__) + +#define XE_ASSERT(condition, message) \ + if (!(condition)) { \ + XCEngine::Debug::Logger::Get().Fatal(XCEngine::Debug::LogCategory::General, message); \ + __debugbreak(); \ + } + +class Profiler { +public: + static Profiler& Get(); + + void Initialize(); + void Shutdown(); + + void BeginProfile(const char* name); + void EndProfile(); + + void BeginFrame(); + void EndFrame(); + + void MarkEvent(const char* name, uint64_t timestamp, uint32_t threadId); + void SetMarker(const char* name, uint32_t color); + + void ExportChromeTracing(const String& filePath); +}; + +#define XE_PROFILE_BEGIN(name) XCEngine::Debug::Profiler::Get().BeginProfile(name) +#define XE_PROFILE_END() XCEngine::Debug::Profiler::Get().EndProfile() +#define XE_PROFILE_FUNCTION() XE_PROFILE_BEGIN(__FUNCTION__) + +} // namespace Debug +} // namespace XCEngine +``` + +--- + +## 第二章 组件系统 + +### 2.1 组件基类 + +```cpp +namespace XCEngine { + +class Scene; +class GameObject; +class TransformComponent; + +// 组件类型注册(用于运行时类型识别) +class ComponentTypeRegistry { +public: + static ComponentTypeRegistry& Get(); + + template + static uint32_t GetTypeId() { + static uint32_t id = Get().Register(typeid(T).name(), static_cast(-1)); + return id; + } + + template + static uint32_t GetTypeId(const char* typeName) { + static uint32_t id = Get().Register(typeName, static_cast(-1)); + return id; + } + + static uint32_t GetTypeIdFromName(const char* typeName) { + return Get().GetIdByName(typeName); + } + + static const char* GetTypeName(uint32_t typeId) { + return Get().GetNameById(typeId); + } + +private: + uint32_t Register(const char* typeName, uint32_t suggestedId); + uint32_t GetIdByName(const char* typeName) const; + const char* GetNameById(uint32_t typeId) const; + + std::atomic m_nextTypeId{0}; + std::unordered_map m_idToName; + std::unordered_map m_nameToId; + Mutex m_mutex; +}; + +// 组件基类(类Unity MonoBehaviour) +class Component { +public: + Component(); + virtual ~Component(); + + GameObject* gameObject() const { return m_gameObject; } + TransformComponent& transform() const { return m_gameObject->GetTransform(); } + + bool IsEnabled() const { return m_enabled; } + void SetEnabled(bool enabled) { m_enabled = enabled; } + + Scene* GetScene() const; + + template + T* GetComponent() const { return m_gameObject->GetComponent(); } + + template + std::vector GetComponents() const { return m_gameObject->GetComponents(); } + + virtual void Awake() {} + virtual void Start() {} + virtual void Update(float deltaTime) {} + virtual void FixedUpdate() {} + virtual void LateUpdate(float deltaTime) {} + virtual void OnDestroy() {} + virtual void OnEnable() {} + virtual void OnDisable() {} + +protected: + GameObject* m_gameObject = nullptr; + bool m_enabled = true; + + friend class GameObject; +}; + +} // namespace XCEngine +``` + +### 2.2 Transform组件 + +```cpp +namespace XCEngine { + +class TransformComponent : public Component { +public: + Vector3 GetLocalPosition() const { return m_localPosition; } + void SetLocalPosition(const Vector3& position) { m_localPosition = position; SetDirty(); } + + Quaternion GetLocalRotation() const { return m_localRotation; } + void SetLocalRotation(const Quaternion& rotation) { m_localRotation = rotation; SetDirty(); } + + Vector3 GetLocalScale() const { return m_localScale; } + void SetLocalScale(const Vector3& scale) { m_localScale = scale; SetDirty(); } + + Vector3 GetPosition() const; + void SetPosition(const Vector3& position); + + Quaternion GetRotation() const; + void SetRotation(const Quaternion& rotation); + + Vector3 GetScale() const; + void SetScale(const Vector3& scale); + + Vector3 GetForward() const { return GetRotation() * Vector3::Forward(); } + Vector3 GetRight() const { return GetRotation() * Vector3::Right(); } + Vector3 GetUp() const { return GetRotation() * Vector3::Up(); } + + const Matrix4x4& GetLocalToWorldMatrix() const; + Matrix4x4 GetWorldToLocalMatrix() const; + + TransformComponent* GetParent() const { return m_parent; } + void SetParent(TransformComponent* parent, bool worldPositionStays = true); + + int GetChildCount() const { return static_cast(m_children.size()); } + TransformComponent* GetChild(int index) const; + TransformComponent* Find(const String& name) const; + + void DetachChildren(); + void SetAsFirstSibling(); + void SetAsLastSibling(); + void SetSiblingIndex(int index); + int GetSiblingIndex() const; + + void LookAt(const Vector3& target); + void LookAt(const Vector3& target, const Vector3& up); + void Rotate(const Vector3& eulers); + void Rotate(const Vector3& axis, float angle); + void Translate(const Vector3& translation); + void Translate(const Vector3& translation, Math::Space relativeTo); + + Vector3 TransformPoint(const Vector3& point) const; + Vector3 InverseTransformPoint(const Vector3& point) const; + Vector3 TransformDirection(const Vector3& direction) const; + Vector3 InverseTransformDirection(const Vector3& direction) const; + + void SetDirty() { m_dirty = true; } + +private: + Vector3 m_localPosition = Vector3::Zero(); + Quaternion m_localRotation = Quaternion::Identity(); + Vector3 m_localScale = Vector3::One(); + + TransformComponent* m_parent = nullptr; + std::vector m_children; + + mutable Matrix4x4 m_localToWorldMatrix; + mutable Matrix4x4 m_worldToLocalMatrix; + mutable Vector3 m_worldPosition; + mutable Quaternion m_worldRotation; + mutable Vector3 m_worldScale; + mutable bool m_dirty = true; + + void UpdateWorldTransform() const; + + friend class GameObject; +}; + +} // namespace XCEngine +``` + +### 2.3 GameObject + +```cpp +namespace XCEngine { + +class Scene; + +class GameObject { +public: + GameObject(); + ~GameObject(); + + struct ConstructParams { + String name = "GameObject"; + GameObject* parent = nullptr; + bool active = true; + }; + + static GameObject* Create(const ConstructParams& params = {}); + static void Destroy(GameObject* obj); + + String name; + bool active = true; + + TransformComponent& GetTransform() { return m_transform; } + const TransformComponent& GetTransform() const { return m_transform; } + + Scene* GetScene() const { return m_scene; } + + template + T* AddComponent(); + + template + void RemoveComponent(); + + template + T* GetComponent() const; + + template + std::vector GetComponents() const; + + template + T* GetComponentInChildren() const; + + template + std::vector GetComponentsInChildren() const; + + template + T* GetComponentInParent() const; + + GameObject* GetParent() const; + void SetParent(GameObject* parent); + void SetParent(GameObject* parent, bool worldPositionStays); + const std::vector& GetChildren() const; + GameObject* GetChild(int index) const; + int GetChildCount() const; + int GetSiblingIndex() const; + void SetSiblingIndex(int index); + + void SetActive(bool active); + bool IsActive() const; + bool IsActiveInHierarchy() const; + + static GameObject* Find(const String& name); + static std::vector FindObjectsOfType(); + static std::vector FindGameObjectsWithTag(const String& tag); + + void Destroy(); + +private: + void AddComponentInternal(Component* component); + void RemoveComponentInternal(Component* component); + + std::vector> m_components; + std::unordered_map m_componentTypeIndex; + + std::vector m_children; + GameObject* m_parent = nullptr; + Scene* m_scene = nullptr; + + TransformComponent m_transform; + + void Initialize(const ConstructParams& params); + + friend class Scene; + friend class TransformComponent; +}; + +inline GameObject::GameObject() { +} + +inline GameObject::~GameObject() { + for (auto* child : m_children) { + delete child; + } +} + +inline GameObject* GameObject::Create(const ConstructParams& params) { + GameObject* obj = new GameObject(); + obj->Initialize(params); + return obj; +} + +inline void GameObject::Destroy(GameObject* obj) { + delete obj; +} + +inline void GameObject::Initialize(const ConstructParams& params) { + name = params.name; + active = params.active; + + m_transform.m_gameObject = this; + + if (params.parent) { + params.parent->m_children.push_back(this); + m_parent = params.parent; + } +} + +inline void GameObject::Destroy() { + if (m_scene) { + m_scene->DestroyGameObject(this); + } else { + delete this; + } +} + +inline GameObject* GameObject::Find(const String& name) { + return SceneManager::Get().GetActiveScene()->Find(name); +} + +inline std::vector GameObject::FindObjectsOfType() { + return SceneManager::Get().GetActiveScene()->FindObjectsOfType(); +} + +inline std::vector GameObject::FindGameObjectsWithTag(const String& tag) { + return SceneManager::Get().GetActiveScene()->FindGameObjectsWithTag(tag); +} + +} // namespace XCEngine +``` + +--- + +## 第三章 场景系统 + +### 3.1 Scene + +```cpp +namespace XCEngine { + +class Scene { +public: + Scene(); + ~Scene(); + + const String& GetName() const { return m_name; } + void SetName(const String& name) { m_name = name; } + + GameObject* CreateGameObject(const String& name = "GameObject") { + GameObject::ConstructParams params; + params.name = name; + params.parent = nullptr; + params.active = true; + + GameObject* obj = GameObject::Create(params); + obj->m_scene = this; + AddGameObject(obj); + return obj; + } + + GameObject* CreateGameObject(const String& name, GameObject* parent) { + GameObject::ConstructParams params; + params.name = name; + params.parent = parent; + params.active = true; + + GameObject* obj = GameObject::Create(params); + obj->m_scene = this; + AddGameObject(obj); + return obj; + } + + void DestroyGameObject(GameObject* obj); + + std::vector GetRootGameObjects() const { + std::vector roots; + roots.reserve(m_gameObjects.size() / 2); + for (auto& obj : m_gameObjects) { + if (obj->GetParent() == nullptr) { + roots.push_back(obj.get()); + } + } + return roots; + } + + GameObject* Find(const String& name) const; + GameObject* FindGameObjectWithTag(const String& tag) const; + std::vector FindGameObjectsWithTag(const String& tag) const; + template + std::vector FindObjectsOfType() const; + T* FindObjectOfType() const; + + bool IsActive() const { return m_isActive; } + void SetActive(bool active); + + void Load(const String& filePath); + void LoadAsync(const String& filePath, std::function callback); + void Save(const String& filePath); + + void Update(float deltaTime); + void FixedUpdate(float fixedDeltaTime); + void LateUpdate(float deltaTime); + + void DebugDraw(); + int GetObjectCount() const { return m_gameObjects.size(); } + +private: + void AddGameObject(GameObject* obj); + void RemoveGameObject(GameObject* obj); + + String m_name; + std::vector> m_gameObjects; + bool m_isActive = true; + + friend class GameObject; + friend class SceneManager; +}; + +class SceneManager { +public: + static SceneManager& Get(); + + void Initialize(); + void Shutdown(); + + Scene* CreateScene(const String& name); + void LoadScene(const String& filePath); + void LoadSceneAsync(const String& filePath, std::function callback); + void UnloadScene(Scene* scene); + void UnloadScene(const String& sceneName); + + void SetActiveScene(Scene* scene); + void SetActiveScene(const String& sceneName); + Scene* GetActiveScene() const; + + Scene* GetScene(const String& name) const; + std::vector GetAllScenes() const; + + void Update(float deltaTime); + void FixedUpdate(float fixedDeltaTime); + void LateUpdate(float deltaTime); + + Event OnSceneLoaded; + Event OnSceneUnloaded; + Event OnActiveSceneChanged; + +private: + SceneManager() = default; + + std::vector> m_scenes; + Scene* m_activeScene = nullptr; + Scene* m_loadingScene = nullptr; + + std::unordered_map m_sceneNameMap; + std::function m_loadCallback; + bool m_loading = false; +}; + +// GameObject创建辅助类 +class GameObjectBuilder { +public: + explicit GameObjectBuilder(const String& name = "GameObject"); + ~GameObjectBuilder() = default; + + template + GameObjectBuilder& AddComponent(Args&&... args); + + GameObject* Build(); + +private: + String m_name; + std::vector> m_components; +}; + +} // namespace XCEngine +``` + +--- + +## 第四章 渲染系统 + +### 4.1 渲染抽象层 + +```cpp +namespace XCEngine { +namespace Rendering { + +enum class ResourceState { + Undefined, + RenderTarget, + DepthStencil, + ShaderResource, + UnorderedAccess, + CopySrc, + CopyDst, + Present +}; + +struct ResourceDesc { + ResourceType type; + uint32_t width = 1; + uint32_t height = 1; + uint32_t depth = 1; + uint32_t mipLevels = 1; + uint32_t arraySize = 1; + Format format = Format::Unknown; + SampleCount sampleCount = SampleCount::Count1; + ResourceState initialState = ResourceState::Undefined; + bool cpuAccessible = false; + bool randomAccess = false; + + MemoryUsage memoryUsage = MemoryUsage::Default; + + String name; +}; + +class IRenderDevice { +public: + virtual ~IRenderDevice() = default; + + virtual const char* GetApiName() const = 0; + virtual const char* GetDriverVersion() const = 0; + virtual uint64_t GetDeviceId() const = 0; + virtual uint64_t GetVendorId() const = 0; + + virtual bool SupportsRaytracing() const = 0; + virtual bool SupportsMeshShaders() const = 0; + virtual bool SupportsVariableRateShading() const = 0; + virtual bool SupportsSamplerFeedback() const = 0; + virtual uint32_t GetMaxTextureSize() const = 0; + virtual uint32_t GetMaxUBOSize() const = 0; + virtual uint32_t GetMaxMSAA() const = 0; + + virtual std::unique_ptr CreateTexture(const ResourceDesc& desc) = 0; + virtual std::unique_ptr CreateBuffer(const ResourceDesc& desc, const void* initialData = nullptr) = 0; + virtual std::unique_ptr CreateShader(const ShaderDesc& desc) = 0; + virtual std::unique_ptr CreatePipeline(const PipelineDesc& desc) = 0; + virtual std::unique_ptr CreateRenderPass(const RenderPassDesc& desc) = 0; + + virtual ICommandQueue* GetGraphicsQueue() = 0; + virtual ICommandQueue* GetComputeQueue() = 0; + virtual ICommandQueue* GetCopyQueue() = 0; + + virtual std::unique_ptr CreateFence() = 0; + virtual IDescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc) = 0; + virtual std::unique_ptr CreateQueryHeap(const QueryHeapDesc& desc) = 0; +}; + +class ICommandList { +public: + virtual ~ICommandList() = default; + + virtual void TransitionBarrier(const IResource* resource, ResourceState newState) = 0; + virtual void UAVBarrier(const IResource* resource) = 0; + virtual void FlushBarriers() = 0; + + virtual void SetPipeline(const IPipeline* pipeline) = 0; + virtual void SetVertexBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0; + virtual void SetIndexBuffer(const IBuffer* buffer, IndexType indexType, uint64_t offset = 0) = 0; + virtual void SetConstantBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0; + virtual void SetShaderResource(uint32_t slot, const IResource* resource) = 0; + virtual void SetSampler(uint32_t slot, const ISampler* sampler) = 0; + + virtual void Draw(uint32_t vertexCount, uint32_t firstVertex = 0) = 0; + virtual void DrawIndexed(uint32_t indexCount, uint32_t firstIndex = 0, int32_t baseVertex = 0) = 0; + virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, + uint32_t firstVertex = 0, uint32_t firstInstance = 0) = 0; + virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, + uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) = 0; + + virtual void Dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0; + + virtual void BuildAccelerationStructure(const RaytracingBuildDesc& desc) = 0; + virtual void SetRaytracingPipeline(const IPipeline* pipeline) = 0; + virtual void DispatchRays(const DispatchRaysDesc& desc) = 0; + + virtual void BeginRenderPass(const RenderPassBeginDesc& desc) = 0; + virtual void EndRenderPass() = 0; + + virtual void CopyResource(IResource* dst, const IResource* src) = 0; + virtual void CopyBuffer(IBuffer* dst, uint64_t dstOffset, const IBuffer* src, uint64_t srcOffset, uint64_t size) = 0; + + virtual void BeginQuery(IQueryHeap* heap, uint32_t index) = 0; + virtual void EndQuery(IQueryHeap* heap, uint32_t index) = 0; + + virtual void SetMarker(const char* name, uint32_t color) = 0; + virtual void BeginEvent(const char* name, uint32_t color) = 0; + virtual void EndEvent() = 0; +}; + +class RenderContext { +public: + class GBufferPass; + class LightingPass; + class ShadowPass; + class PostProcessPass; + + static RenderContext* Create(const RenderContextDesc& desc); + static void Destroy(RenderContext* context); + + static RenderContext* GetMain(); + + void Initialize(const RenderContextDesc& desc); + void Shutdown(); + + IRenderDevice* GetDevice() { return m_device.get(); } + + void BeginFrame(); + void EndFrame(); + + ICommandList* GetMainCommandList() { return m_mainCommandList.get(); } + + void SetRenderTarget(const RenderTarget& target); + void SetViewport(const Viewport& viewport); + void SetScissorRect(const Rect& rect); + + void RenderScene(const SceneRenderDesc& desc); + void ApplyPostProcessing(const PostProcessDesc& desc); + + void CaptureFrame(const String& filePath); + void ToggleDebugView(); + +private: + std::unique_ptr m_device; + std::unique_ptr m_mainCommandList; + std::unique_ptr m_swapChain; + + std::unique_ptr m_gBufferPass; + std::unique_ptr m_lightingPass; + std::unique_ptr m_shadowPass; + std::unique_ptr m_postProcessPass; + + uint32_t m_frameIndex = 0; + uint64_t m_frameCount = 0; + + static RenderContext* s_mainContext; +}; + +// 资源类型 +enum class ResourceType { + Unknown, + Mesh, + Texture, + Material, + Shader, + Audio, + Animation, + Skeleton, + Font, + Prefab, + Scene, + Script, + PhysicsMaterial, + NavMesh, + Video, + Custom +}; + +// 资源GUID +struct ResourceGUID { + static constexpr uint64_t INVALID = 0; + + uint64_t value = INVALID; + + bool IsValid() const { return value != INVALID; } + bool operator==(const ResourceGUID& other) const { return value == other.value; } + bool operator!=(const ResourceGUID& other) const { return value != other.value; } + + String ToString() const; + static ResourceGUID FromString(const String& str); + + struct Hash { + size_t operator()(const ResourceGUID& guid) const { + return std::hash{}(guid.value); + } + }; +}; + +// 资源基类 +class IResource { +public: + virtual ~IResource() = default; + + virtual ResourceType GetType() const = 0; + virtual const String& GetName() const = 0; + virtual ResourceGUID GetGUID() const = 0; + + virtual bool IsLoaded() const = 0; + virtual bool IsLoading() const = 0; + virtual float GetLoadingProgress() const = 0; + + virtual void AddRef() = 0; + virtual void Release() = 0; + virtual uint32_t GetRefCount() const = 0; + + virtual void Unload() = 0; +}; + +class RenderTexture : public IResource { +public: + uint32_t GetWidth() const { return m_width; } + uint32_t GetHeight() const { return m_height; } + uint32_t GetMipLevels() const { return m_mipLevels; } + Format GetFormat() const { return m_format; } + + void* GetNativeHandle() const { return m_nativeHandle; } + + IShaderResourceView* GetSRV() { return m_srv.get(); } + IRenderTargetView* GetRTV() { return m_rtv.get(); } + IDepthStencilView* GetDSV() { return m_dsv.get(); } + + void* Map(); + void Unmap(); + +private: + uint32_t m_width, m_height; + uint32_t m_mipLevels; + Format m_format; + void* m_nativeHandle = nullptr; + + std::unique_ptr m_srv; + std::unique_ptr m_rtv; + std::unique_ptr m_dsv; +}; + +class RenderBuffer : public IResource { +public: + uint64_t GetSize() const { return m_size; } + BufferUsage GetUsage() const { return m_usage; } + + void* GetNativeHandle() const { return m_nativeHandle; } + + void SetData(const void* data, uint64_t size, uint64_t offset = 0); + void* Map(); + void Unmap(); + +private: + uint64_t m_size; + BufferUsage m_usage; + void* m_nativeHandle = nullptr; +}; + +} // namespace Rendering +} // namespace XCEngine +``` + +### 4.2 渲染图 (Render Graph) + +```cpp +namespace XCEngine { +namespace Rendering { + +class RenderGraphResource { +public: + RenderGraphResource() = default; + RenderGraphResource(const String& name); + + const String& GetName() const { return m_name; } + uint32_t GetIndex() const { return m_index; } + + bool IsValid() const { return m_index != UINT32_MAX; } + operator bool() const { return IsValid(); } + +private: + String m_name; + uint32_t m_index = UINT32_MAX; + friend class RenderGraph; +}; + +class RenderGraphPass { +public: + using ExecuteFn = std::function; + + RenderGraphPass(const String& name, PassType type); + + RenderGraphResource Read(const String& resourceName); + RenderGraphResource Write(const String& resourceName); + RenderGraphResource ReadWrite(const String& resourceName, ResourceState initialState, ResourceState finalState); + + void Execute(ExecuteFn&& fn); + void Execute() const; + + void SetDebugColor(const Color& color); + + const String& GetName() const { return m_name; } + PassType GetType() const { return m_type; } + const std::vector& GetReads() const { return m_reads; } + const std::vector& GetWrites() const { return m_writes; } + +private: + String m_name; + PassType m_type; + std::vector m_reads; + std::vector m_writes; + ExecuteFn m_executeFn; + Color m_debugColor; + + friend class RenderGraph; +}; + +class RenderGraph { +public: + RenderGraph(); + ~RenderGraph(); + + RenderGraphResource CreateTexture(const String& name, const TextureDesc& desc); + RenderGraphResource CreateBuffer(const String& name, const BufferDesc& desc); + + RenderGraphPass& AddPass(const String& name, PassType type); + + void Build(); + void Execute(ICommandList* commandList); + + void SetName(const String& name); + void Print() const; + void ExportToDot(const String& filePath) const; + + void Clear(); + +private: + void Compile(); + void Validate(); + void SortPasses(); + void AllocateResources(); + + struct ResourceInfo { + String name; + ResourceDesc desc; + ResourceState currentState; + uint32_t firstPassWrite = UINT32_MAX; + uint32_t lastPassRead = UINT32_MAX; + bool imported = false; + }; + + struct PassInfo { + String name; + PassType type; + std::vector reads; + std::vector writes; + std::function executeFn; + }; + + std::vector m_resources; + std::vector m_passes; + std::unordered_map m_resourceIndex; + + bool m_built = false; +}; + +} // namespace Rendering +} // namespace XCEngine +``` + +### 4.3 相机组件 + +```cpp +namespace XCEngine { + +class CameraComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + + enum class ProjectionType : uint8_t { + Perspective, + Orthographic + }; + + void SetProjectionType(ProjectionType type) { m_projectionType = type; } + ProjectionType GetProjectionType() const { return m_projectionType; } + + void SetFieldOfView(float fov) { m_fieldOfView = fov; } + float GetFieldOfView() const { return m_fieldOfView; } + + void SetOrthographicSize(float size) { m_orthographicSize = size; } + float GetOrthographicSize() const { return m_orthographicSize; } + + void SetNearClipPlane(float near) { m_nearPlane = near; } + float GetNearClipPlane() const { return m_nearPlane; } + + void SetFarClipPlane(float far) { m_farPlane = far; } + float GetFarClipPlane() const { return m_farPlane; } + + void SetViewport(const Rect& rect) { m_viewportRect = rect; } + const Rect& GetViewport() const { return m_viewportRect; } + + void SetCullingMask(int32_t mask) { m_cullingMask = mask; } + int32_t GetCullingMask() const { return m_cullingMask; } + + void SetDepth(float depth) { m_depth = depth; } + float GetDepth() const { return m_depth; } + + Matrix4x4 GetViewMatrix() const; + Matrix4x4 GetProjectionMatrix() const; + Matrix4x4 GetViewProjectionMatrix() const; + + Vector3 ScreenToWorldPoint(const Vector3& screenPoint) const; + Vector3 WorldToScreenPoint(const Vector3& worldPoint) const; + Ray ScreenPointToRay(const Vector2& screenPoint) const; + + Frustum& GetFrustum() { return m_frustum; } + +private: + ProjectionType m_projectionType = ProjectionType::Perspective; + float m_fieldOfView = 60.0f; + float m_orthographicSize = 5.0f; + float m_nearPlane = 0.1f; + float m_farPlane = 1000.0f; + float m_aspectRatio = 16.0f / 9.0f; + Rect m_viewportRect = Rect(0, 0, 1, 1); + float m_depth = 0.0f; + int32_t m_cullingMask = -1; + Frustum m_frustum; +}; + +} // namespace XCEngine +``` + +### 4.4 光照组件 + +```cpp +namespace XCEngine { + +class RenderLightComponent : public Component { +public: + void Awake() override; + void Update(float deltaTime) override; + + enum class LightType : uint8_t { + Directional, + Point, + Spot, + Area + }; + + void SetLightType(LightType type) { m_type = type; } + LightType GetLightType() const { return m_type; } + + void SetColor(const Vector3& color) { m_color = color; } + Vector3 GetColor() const { return m_color; } + + void SetIntensity(float intensity) { m_intensity = intensity; } + float GetIntensity() const { return m_intensity; } + + void SetRange(float range) { m_range = range; } + float GetRange() const { return m_range; } + + void SetSpotAngle(float angle) { m_spotAngle = angle; } + float GetSpotAngle() const { return m_spotAngle; } + + void SetCastShadows(bool cast) { m_castShadows = cast; } + bool GetCastShadows() const { return m_castShadows; } + + void SetShadowResolution(uint32_t resolution) { m_shadowResolution = resolution; } + uint32_t GetShadowResolution() const { return m_shadowResolution; } + + void SetCullingMask(int32_t mask) { m_cullingMask = mask; } + int32_t GetCullingMask() const { return m_cullingMask; } + +private: + LightType m_type = LightType::Point; + Vector3 m_color = Vector3::One(); + float m_intensity = 1.0f; + float m_range = 10.0f; + float m_spotAngle = 30.0f; + float m_penumbraAngle = 5.0f; + bool m_castShadows = true; + uint32_t m_shadowResolution = 1024; + float m_shadowBias = 0.005f; + float m_normalOffsetBias = 0.001f; + float m_nearPlane = 0.1f; + int32_t m_cullingMask = -1; + float m_intensityVariation = 0.0f; + ResourceGUID m_cookieTextureGuid = ResourceGUID::Invalid; + float m_cookieSize = 5.0f; +}; + +} // namespace XCEngine +``` + +### 4.5 渲染网格组件 + +```cpp +namespace XCEngine { + +class RenderMeshComponent : public Component { +public: + void Awake() override; + void Start() override; + void Update(float deltaTime) override; + + ResourceGUID GetMesh() const { return m_meshGuid; } + void SetMesh(const ResourceGUID& guid); + + ResourceGUID GetMaterial() const { return m_materialGuid; } + void SetMaterial(const ResourceGUID& guid); + + bool GetCastShadows() const { return m_castShadows; } + void SetCastShadows(bool cast) { m_castShadows = cast; } + + bool GetReceiveShadows() const { return m_receiveShadows; } + void SetReceiveShadows(bool receive) { m_receiveShadows = receive; } + +private: + ResourceGUID m_meshGuid; + ResourceGUID m_materialGuid; + bool m_castShadows = true; + bool m_receiveShadows = true; +}; + +} // namespace XCEngine +``` + +--- + +## 第五章 目录结构 + +``` +XCVolumeRenderer/ +├── engine/ # 引擎核心库(静态库) +│ ├── CMakeLists.txt +│ ├── include/ +│ │ └── XCGameEngine/ +│ │ ├── Core/ # 核心基础 +│ │ │ ├── Assert.h +│ │ │ ├── Event.h +│ │ │ ├── TypeTraits.h +│ │ │ └── UniquePtr.h +│ │ ├── Math/ # 数学库 +│ │ │ ├── Vector2.h +│ │ │ ├── Vector3.h +│ │ │ ├── Vector4.h +│ │ │ ├── Matrix3.h +│ │ │ ├── Matrix4.h +│ │ │ ├── Quaternion.h +│ │ │ ├── Transform.h +│ │ │ ├── Color.h +│ │ │ ├── Ray.h +│ │ │ ├── Plane.h +│ │ │ ├── Sphere.h +│ │ │ ├── Box.h +│ │ │ └── Frustum.h +│ │ ├── Containers/ # 容器 +│ │ │ ├── Array.h +│ │ │ ├── String.h +│ │ │ └── HashMap.h +│ │ ├── Memory/ # 内存管理 +│ │ │ ├── Allocator.h +│ │ │ ├── LinearAllocator.h +│ │ │ ├── PoolAllocator.h +│ │ │ └── ProxyAllocator.h +│ │ ├── Threading/ # 线程 +│ │ │ ├── Thread.h +│ │ │ ├── Mutex.h +│ │ │ ├── TaskSystem.h +│ │ │ └── Atomic.h +│ │ ├── Debug/ # 调试 +│ │ │ ├── Logger.h +│ │ │ └── Profiler.h +│ │ ├── Components/ # 组件系统 +│ │ │ ├── GameObject.h +│ │ │ ├── Component.h +│ │ │ ├── TransformComponent.h +│ │ │ ├── RenderMeshComponent.h +│ │ │ ├── RenderLightComponent.h +│ │ │ └── CameraComponent.h +│ │ ├── Scene/ # 场景系统 +│ │ │ ├── Scene.h +│ │ │ └── SceneManager.h +│ │ ├── Renderer/ # 渲染系统 +│ │ │ ├── Device.h +│ │ │ ├── Context.h +│ │ │ ├── SwapChain.h +│ │ │ ├── Buffer.h +│ │ │ ├── Texture.h +│ │ │ ├── Shader.h +│ │ │ ├── Pipeline.h +│ │ │ ├── RenderPass.h +│ │ │ ├── CommandList.h +│ │ │ ├── RenderGraph.h +│ │ │ └── RenderModule.h +│ │ └── XCGameEngine.h # 主头文件 +│ ├── src/ +│ │ ├── Core/ +│ │ ├── Math/ +│ │ ├── Components/ +│ │ ├── Scene/ +│ │ ├── Renderer/ +│ │ └── ... +│ └── third_party/ +│ ├── stb/ +│ └── json/ +│ +├── runtime/ # 游戏运行时(独立可执行文件) +│ ├── CMakeLists.txt +│ ├── src/ +│ │ ├── GameMain.cpp +│ │ └── EntryPoint.cpp +│ └── resources/ +│ +├── tools/ # 工具链 +│ ├── ShaderCompiler/ # 着色器编译器 +│ └── BuildTool/ # 构建打包工具 +│ +├── content/ # 资源内容 +│ ├── Assets/ +│ │ ├── Scenes/ +│ │ ├── Materials/ +│ │ ├── Meshes/ +│ │ ├── Textures/ +│ │ └── Shaders/ +│ └── Library/ +│ +└── docs/ # 文档 +``` + +--- + +## 附录:待扩展功能 + +以下功能将在后续迭代中添加: + +1. **物理系统** - RigidBodyComponent, ColliderComponent, PhysicsWorld +2. **音频系统** - AudioSourceComponent, AudioListenerComponent, AudioEngine +3. **动画系统** - AnimatorComponent, AnimationClip, Skeleton +4. **粒子系统** - ParticleSystemComponent, GPUParticles +5. **UI系统** - CanvasComponent, ImageComponent, TextComponent, ButtonComponent +6. **网络系统** - NetworkIdentityComponent, NetworkTransformComponent +7. **完整编辑器** - HierarchyPanel, InspectorPanel, SceneViewPanel diff --git a/imgui.ini b/imgui.ini new file mode 100644 index 00000000..bf18ac4f --- /dev/null +++ b/imgui.ini @@ -0,0 +1,24 @@ +[Window][Scene View] +Pos=0,20 +Size=880,480 + +[Window][Hierarchy] +Pos=0,20 +Size=200,480 + +[Window][Inspector] +Pos=1080,20 +Size=200,480 + +[Window][Project] +Pos=0,500 +Size=640,150 + +[Window][Console] +Pos=640,500 +Size=640,150 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +