ThreeLab/Engine/Components/ModelComponent.h
2025-04-01 19:19:53 -05:00

110 lines
3.2 KiB
C++

#ifndef MODEL_COMPONENT_H
#define MODEL_COMPONENT_H
#include <string>
#include <vector>
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <yaml-cpp/yaml.h>
// 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<Vertex> vertices;
std::vector<GLuint> 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<SubMesh> 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<std::string>();
}
if (node["globalDiffuseColor"]) {
diffuseColor.x = node["globalDiffuseColor"][0].as<float>();
diffuseColor.y = node["globalDiffuseColor"][1].as<float>();
diffuseColor.z = node["globalDiffuseColor"][2].as<float>();
}
if (node["globalSpecularColor"]) {
specularColor.x = node["globalSpecularColor"][0].as<float>();
specularColor.y = node["globalSpecularColor"][1].as<float>();
specularColor.z = node["globalSpecularColor"][2].as<float>();
}
if (node["globalShininess"]) {
shininess = node["globalShininess"].as<float>();
}
// Reload the model (populates meshes based on the modelPath).
LoadModel(modelPath);
}
};
#endif // MODEL_COMPONENT_H