载入中...
搜索中...
未找到
SceneLoader.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
5#include "common/Module.h"
6#include "common/Result.h"
7
8#include <functional>
9#include <memory>
10#include <mutex>
11#include <string>
12#include <unordered_map>
13#include <unordered_set>
14#include <vector>
15
16struct aiScene;
17struct aiNode;
18struct aiMesh;
19
20namespace eve {
21namespace animation {
22class AnimSkeleton;
23class AnimClip;
24} // namespace animation
25namespace graphics {
26class Graphics;
27class Renderable3D;
28class Light3D;
29class Camera3D;
30class Texture;
31class Mesh;
32} // namespace graphics
33namespace model3d {
34class ModelData;
35} // namespace model3d
36namespace scene {
37struct NodeDesc;
38class SceneHost;
39} // namespace scene
40namespace thread {
41class ThreadPool;
42}
43
44namespace sceneloader {
45
62 enum class Action { Add, Remove, Modify, Move };
63
65 std::string id; // GameObject id (scene-object id).
66 std::string parent; // new parent id (Add / Move only).
67};
68
70struct SceneDiff {
71 std::vector<SceneDiffEntry> entries;
72 int added = 0;
73 int removed = 0;
74 int modified = 0;
75 int moved = 0;
76
78 bool empty() const { return entries.empty(); }
79};
80
84 int nodeCount = 0;
86 std::vector<std::string> warnings;
87 std::vector<std::string> sockets;
88 std::vector<std::string> collisions;
89};
90
98struct MeshSlot {
99 const aiScene *scene = nullptr;
100 const aiMesh *mesh = nullptr;
101 unsigned materialIndex = 0;
102};
103using MeshSlotMap = std::unordered_map<std::string, std::vector<MeshSlot>>;
104
116 bool triangulate = true;
119 bool flipUVs = true;
122 bool sharedMeshes = true;
124 bool mipmaps = true;
126 bool importLights = true;
128 bool importCameras = false;
130 bool importAnimations = true;
131};
132
154public:
156
158 SceneLoader();
160 ~SceneLoader() override;
161
163 scene::SceneHost *load(const std::string &path, bool linkRenderables = true,
164 const LoadOptions &options = {});
166 scene::SceneHost *load(const std::string &path, const LoadOptions &options);
168 scene::SceneHost *loadPreset(const std::string &path, const std::string &preset);
169
178 [[nodiscard("scene reload outcome must be checked")]] eve::Result<bool> reload(const std::string &path,
179 SceneDiff *out = nullptr,
180 const LoadOptions &options = {});
181
183 SceneDiff diff(const std::string &path);
185 [[nodiscard]] eve::Result<SceneInspection> inspect(const std::string &path,
186 const LoadOptions &options = {});
187
189 scene::SceneHost *host(const std::string &path);
190
192 void unload(const std::string &path);
193
195 int nodeCount(const std::string &path);
197 bool loaded(const std::string &path);
198
199 // ---- async loading (decode off-thread, mount on the main thread) ----
200
207 bool loadAsync(const std::string &path, const LoadOptions &options = {},
209 std::function<void(scene::SceneHost *)> done = nullptr);
210
212 bool loadAsyncDefault(const std::string &path) { return loadAsync(path); }
214 bool loadAsyncPreset(const std::string &path, const std::string &preset);
215
220 int pollAsync();
221
223 bool prewarmAsync(const std::string &path, const LoadOptions &options = {});
225 bool prewarm(const std::string &path) { return prewarmAsync(path); }
227 bool prewarmed(const std::string &path) const;
229 void clearPrewarm(const std::string &path);
230
232 int pendingAsyncCount() const;
233
235 int warningCount(const std::string &path) const;
237 std::string warning(const std::string &path, int index) const;
239 bool setLod(const std::string &path, int level);
241 int socketCount(const std::string &path) const;
243 std::string socketName(const std::string &path, int index) const;
245 int collisionCount(const std::string &path) const;
247 std::string collisionName(const std::string &path, int index) const;
248
249 // ---- imported scene extras ----
250
252 int lightCount(const std::string &path);
254 graphics::Light3D *light(const std::string &path, int index);
255
257 int cameraCount(const std::string &path);
259 graphics::Camera3D *camera(const std::string &path, int index);
260
262 int animationCount(const std::string &path);
264 animation::AnimSkeleton *skeleton(const std::string &path);
266 animation::AnimClip *clip(const std::string &path, int index);
267
268 // ---- pure tree helpers (no graphics required; unit-testable) ----
269
271 using TextureCache = std::unordered_map<std::string, graphics::Texture *>;
272 using MeshCache = std::unordered_map<const aiMesh *, graphics::Mesh *>;
274 struct CpuImage {
275 int w = 0;
276 int h = 0;
277 std::vector<uint8_t> rgba;
278 };
279 using CpuImageMap = std::unordered_map<std::string, CpuImage>;
280
282 static scene::NodeDesc buildNodeDesc(const aiScene *scene, MeshSlotMap *slotsOut = nullptr);
283
285 static SceneDiff diffTree(scene::SceneHost *host, const scene::NodeDesc &newRoot);
286
292 static bool applyTreeDiff(scene::SceneHost *host, const scene::NodeDesc &newRoot,
293 const SceneDiff &diff, graphics::Graphics *gfx,
294 const MeshSlotMap *slots);
295
301 static void fillSceneBounds(scene::SceneHost *host, const MeshSlotMap &slots);
302
303private:
304 struct Loaded {
305 std::string path;
306 scene::SceneHost *host = nullptr;
307 graphics::Graphics *gfx = nullptr;
309 std::vector<graphics::Light3D *> lights;
310 std::vector<graphics::Camera3D *> cameras;
311 animation::AnimSkeleton *skeleton = nullptr;
312 std::vector<animation::AnimClip *> clips;
313 };
314
315 struct DecodedScene {
317 DecodedScene();
319 ~DecodedScene();
321 DecodedScene(DecodedScene &&) noexcept;
323 DecodedScene &operator=(DecodedScene &&) noexcept;
324 DecodedScene(const DecodedScene &) = delete;
325 DecodedScene &operator=(const DecodedScene &) = delete;
326
327 std::string path;
328 model3d::ModelData *md = nullptr;
329 std::unique_ptr<scene::NodeDesc> root;
332 CpuImageMap cpuImages; // external textures pre-decoded off-thread
333 std::vector<graphics::Light3D *> lights;
334 std::vector<graphics::Camera3D *> cameras;
335 animation::AnimSkeleton *skeleton = nullptr;
336 std::vector<animation::AnimClip *> clips;
337 bool prewarmOnly = false;
339 std::function<void(scene::SceneHost *)> done;
340 };
341
342 bool decode(const std::string &path, const LoadOptions &options, DecodedScene *out);
343 scene::SceneHost *mount(DecodedScene &d);
345 void linkMeshNodes(scene::SceneHost *host, const MeshSlotMap &slots,
346 graphics::Graphics *gfx, const LoadOptions &options,
347 TextureCache &textures, MeshCache &shared,
348 const CpuImageMap *predecoded = nullptr);
350 void clearTextures();
352 std::string decodeErrorFor(const std::string &path) const;
353
354 std::unordered_map<std::string, Loaded> scenes_;
355 std::unordered_map<std::string, DecodedScene> prewarmed_;
356 TextureCache textures_;
357 std::shared_ptr<thread::ThreadPool> pool_;
358 std::vector<DecodedScene> pending_;
359 std::unordered_set<std::string> inFlight_;
360 // Internal async/decode diagnostics; public operations return structured Results.
361 std::unordered_map<std::string, std::string> lastErrors_;
362 std::unordered_map<std::string, std::vector<std::string>> warnings_;
363 mutable std::mutex pendingMu_;
364};
365
366} // namespace sceneloader
367} // namespace eve
float w
Definition AnimClip.cpp:738
int root
Definition AnimSmr.cpp:119
std::mutex mutex
#define EVENGINE_API_ORCHESTRATION
Definition Export.h:111
std::vector< eve::ProcgenProbeDesc > lights
float camera[2]
glm::vec4 clip
int h
int level
std::string path
Definition PlayHost.cpp:110
std::weak_ptr< PrimitiveScene > scene
float d
Move-only, checked operation results for the common layer.
MigrationFunction function
Light3D::Data * light
LocalPageCacheEntry slots[ShadowConfig::kLocalSlots]
const SquirrelValueOptions & options
UIHostHandle host
uint32_t index
EVENGINE_API_FOUNDATION public API.
Definition Module.h:46
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Keyframed skeletal animation clip (local TRS tracks per bone). Script type: AnimClip.
Definition AnimClip.h:145
3D bone hierarchy + bind-pose local TRS for skeletal animation. Independent of ik::Skeleton3D (FABRIK...
EVENGINE_API_BACKENDS public API.
Declarative 3D light. Collected by RenderSystem3D (max 8 per frame). type: "point" | "dir" | "spot" (...
Definition Light.h:191
ECS mount point for one scene graph (full scene or nested subtree root). Isomorphic to eve::ui::UIHos...
Definition SceneHost.h:89
Loads a 3D scene (glTF / OBJ / FBX / GLB ... via Assimp/medialoader) into the ECS scene tree.
std::unordered_map< const aiMesh *, graphics::Mesh * > MeshCache
bool prewarm(const std::string &path)
Script-friendly CPU prewarm using the default import preset.
std::unordered_map< std::string, CpuImage > CpuImageMap
bool loadAsyncDefault(const std::string &path)
Script-friendly async load using the default import preset.
std::unordered_map< std::string, graphics::Texture * > TextureCache
Caches shared across the loader: textures by source key, GPU meshes per aiMesh.
std::unordered_map< std::string, std::vector< MeshSlot > > MeshSlotMap
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16
Declarative scene-node description (build once / on dirty → flatten into SceneHost::Tree)....
Definition NodeDesc.h:19
Options controlling how a 3D scene file is decoded and mounted.
bool importLights
Import aiLight entries as graphics::Light3D entities.
bool mipmaps
Generate mipmaps + anisotropic filtering for imported textures.
bool sharedMeshes
Reuse one GPU mesh when several nodes reference the same aiMesh.
bool importAnimations
Import aiAnimation clips (skeleton + clips exposed via accessors).
bool importCameras
Import aiCamera entries as inactive graphics::Camera3D entities.
A GPU mesh reference for one Assimp mesh referenced by an aiNode. The loader uploads one Renderable3D...
Definition SceneLoader.h:98
SceneDiffEntry / SceneDiff
Definition SceneLoader.h:60
SceneDiff public API.
Definition SceneLoader.h:70
bool empty() const
Empty.
Definition SceneLoader.h:78
std::vector< SceneDiffEntry > entries
Definition SceneLoader.h:71
CPU-only import inspection result used by editor preflight.
Definition SceneLoader.h:82
std::vector< std::string > warnings
Definition SceneLoader.h:86
std::vector< std::string > collisions
Definition SceneLoader.h:88
std::vector< std::string > sockets
Definition SceneLoader.h:87
CPU-decoded texture (RGBA8) keyed by the same source+suffix key as TextureCache.