#ifndef MODEL_COMPONENT_H #define MODEL_COMPONENT_H #include #include #include #include #include // Structure representing a single vertex. struct Vertex { glm::vec3 Position; glm::vec3 Normal; glm::vec2 TexCoords; glm::vec3 Tangent; }; // Structure representing a sub-mesh (a group of faces sharing the same material) struct SubMesh { std::vector vertices; std::vector indices; glm::vec3 diffuseColor; glm::vec3 specularColor; float shininess; GLuint diffuseTexture; // (Optional) If you add a normal texture per submesh. // GLuint normalTexture; GLuint VAO, VBO, EBO; SubMesh() : diffuseColor(1.0f,1.0f,1.0f), specularColor(1.0f,1.0f,1.0f), shininess(32.0f), diffuseTexture(0), VAO(0), VBO(0), EBO(0) {} }; class ModelComponent { public: ModelComponent(); ~ModelComponent(); // Base model file path. std::string modelPath; // Submeshes. std::vector meshes; // Global material overrides (if any). glm::vec3 diffuseColor; glm::vec3 specularColor; float shininess; // Functions. bool LoadModel(const std::string &filepath); void Draw(); // Texture loading. bool LoadDiffuseTexture(const std::string &filepath, GLuint &textureID); bool LoadNormalTexture(const std::string &filepath); // Setup mesh for a submesh. void SetupMesh(SubMesh &mesh); // --- YAML Serialization Functions (Globals Only) --- // Save the global ModelComponent state to a YAML node. YAML::Node Save() const { YAML::Node node; node["modelPath"] = modelPath; node["globalDiffuseColor"] = YAML::Node(); node["globalDiffuseColor"].push_back(diffuseColor.x); node["globalDiffuseColor"].push_back(diffuseColor.y); node["globalDiffuseColor"].push_back(diffuseColor.z); node["globalSpecularColor"] = YAML::Node(); node["globalSpecularColor"].push_back(specularColor.x); node["globalSpecularColor"].push_back(specularColor.y); node["globalSpecularColor"].push_back(specularColor.z); node["globalShininess"] = shininess; return node; } // Load the global ModelComponent state from a YAML node. void Load(const YAML::Node &node) { if (node["modelPath"]) { modelPath = node["modelPath"].as(); } if (node["globalDiffuseColor"]) { diffuseColor.x = node["globalDiffuseColor"][0].as(); diffuseColor.y = node["globalDiffuseColor"][1].as(); diffuseColor.z = node["globalDiffuseColor"][2].as(); } if (node["globalSpecularColor"]) { specularColor.x = node["globalSpecularColor"][0].as(); specularColor.y = node["globalSpecularColor"][1].as(); specularColor.z = node["globalSpecularColor"][2].as(); } if (node["globalShininess"]) { shininess = node["globalShininess"].as(); } // Reload the model (populates meshes based on the modelPath). LoadModel(modelPath); } }; #endif // MODEL_COMPONENT_H