#pragma once #include #include #include #include #include using glm::mat4; // we do not define std::vector Children - this is already present in the // aiNode from assimp constexpr const int MAX_NODE_LEVEL = 16; struct Hierarchy { // parent for this node (or -1 for root) int parent = -1; // first child for a node (or -1) int firstChild = -1; // next sibling for a node (or -1) int nextSibling = -1; // last added node (or -1) int lastSibling = -1; // cached node level int level = 0; }; /* This scene is converted into a descriptorSet(s) in MultiRenderer class This structure is also used as a storage type in SceneExporter tool */ struct Scene { // local transformations for each node and global transforms // + an array of 'dirty/changed' local transforms std::vector localTransform; // indexed by node std::vector globalTransform; // indexed by node // list of nodes that need their global transforms recalculated std::vector changedAtThisFrame[MAX_NODE_LEVEL]; // Hierarchy component std::vector hierarchy; // Mesh component: which Mesh belongs to which node (Node -> Mesh) std::unordered_map meshForNode; // Material component: which material belongs to which node (Node -> Material) std::unordered_map materialForNode; // Node name component: which name is assigned to the node (Node -> Name) std::unordered_map nameForNode; // List of scene node names std::vector nodeNames; // Debug list of material names std::vector materialNames; }; int addNode(Scene &scene, int parent, int level); void markAsChanged(Scene &scene, int node); int findNodeByName(const Scene &scene, const std::string &name); inline std::string getNodeName(const Scene &scene, int node) { int strID = scene.nameForNode.contains(node) ? scene.nameForNode.at(node) : -1; return (strID > -1) ? scene.nodeNames[strID] : std::string(); } inline void setNodeName(Scene &scene, int node, const std::string &name) { uint32_t stringID = (uint32_t)scene.nodeNames.size(); scene.nodeNames.push_back(name); scene.nameForNode[node] = stringID; } int getNodeLevel(const Scene &scene, int n); bool recalculateGlobalTransforms(Scene &scene); void loadScene(const char *fileName, Scene &scene); void saveScene(const char *fileName, const Scene &scene); void dumpTransforms(const char *fileName, const Scene &scene); void printChangedNodes(const Scene &scene); void dumpSceneToDot(const char *fileName, const Scene &scene, int *visited = nullptr); void mergeScenes(Scene &scene, const std::vector &scenes, const std::vector &rootTransforms, const std::vector &meshCounts, bool mergeMeshes = true, bool mergeMaterials = true); // Delete a collection of nodes from a scenegraph void deleteSceneNodes(Scene &scene, const std::vector &nodesToDelete);