98 lines
3 KiB
C++
98 lines
3 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <glm/ext.hpp>
|
|
#include <glm/glm.hpp>
|
|
|
|
using glm::mat4;
|
|
|
|
// we do not define std::vector<Node*> 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<mat4> localTransform; // indexed by node
|
|
std::vector<mat4> globalTransform; // indexed by node
|
|
|
|
// list of nodes that need their global transforms recalculated
|
|
std::vector<int> changedAtThisFrame[MAX_NODE_LEVEL];
|
|
|
|
// Hierarchy component
|
|
std::vector<Hierarchy> hierarchy;
|
|
|
|
// Mesh component: which Mesh belongs to which node (Node -> Mesh)
|
|
std::unordered_map<uint32_t, uint32_t> meshForNode;
|
|
|
|
// Material component: which material belongs to which node (Node -> Material)
|
|
std::unordered_map<uint32_t, uint32_t> materialForNode;
|
|
|
|
// Node name component: which name is assigned to the node (Node -> Name)
|
|
std::unordered_map<uint32_t, uint32_t> nameForNode;
|
|
|
|
// List of scene node names
|
|
std::vector<std::string> nodeNames;
|
|
|
|
// Debug list of material names
|
|
std::vector<std::string> 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<Scene *> &scenes,
|
|
const std::vector<glm::mat4> &rootTransforms,
|
|
const std::vector<uint32_t> &meshCounts,
|
|
bool mergeMeshes = true, bool mergeMaterials = true);
|
|
|
|
// Delete a collection of nodes from a scenegraph
|
|
void deleteSceneNodes(Scene &scene, const std::vector<uint32_t> &nodesToDelete);
|