2025-04-01 20:03:18 +00:00
|
|
|
#ifndef MODEL_COMPONENT_H
|
|
|
|
#define MODEL_COMPONENT_H
|
|
|
|
|
2025-04-01 20:19:00 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <GL/glew.h>
|
2025-04-02 00:19:53 +00:00
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <yaml-cpp/yaml.h>
|
2025-04-01 20:19:00 +00:00
|
|
|
|
|
|
|
// Structure representing a single vertex.
|
|
|
|
struct Vertex {
|
|
|
|
glm::vec3 Position;
|
|
|
|
glm::vec3 Normal;
|
|
|
|
glm::vec2 TexCoords;
|
|
|
|
glm::vec3 Tangent;
|
|
|
|
};
|
2025-04-01 20:03:18 +00:00
|
|
|
|
2025-04-01 22:28:45 +00:00
|
|
|
// Structure representing a sub-mesh (a group of faces sharing the same material)
|
|
|
|
struct SubMesh {
|
|
|
|
std::vector<Vertex> vertices;
|
|
|
|
std::vector<GLuint> indices;
|
2025-04-01 20:03:18 +00:00
|
|
|
glm::vec3 diffuseColor;
|
|
|
|
glm::vec3 specularColor;
|
|
|
|
float shininess;
|
2025-04-01 22:28:45 +00:00
|
|
|
GLuint diffuseTexture;
|
2025-04-02 00:19:53 +00:00
|
|
|
// (Optional) If you add a normal texture per submesh.
|
|
|
|
// GLuint normalTexture;
|
2025-04-01 20:19:00 +00:00
|
|
|
GLuint VAO, VBO, EBO;
|
|
|
|
|
2025-04-01 22:28:45 +00:00
|
|
|
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)
|
|
|
|
{}
|
|
|
|
};
|
2025-04-01 20:19:00 +00:00
|
|
|
|
2025-04-01 22:28:45 +00:00
|
|
|
class ModelComponent {
|
|
|
|
public:
|
|
|
|
ModelComponent();
|
|
|
|
~ModelComponent();
|
2025-04-01 20:19:00 +00:00
|
|
|
|
2025-04-02 00:19:53 +00:00
|
|
|
// Base model file path.
|
2025-04-01 22:28:45 +00:00
|
|
|
std::string modelPath;
|
2025-04-02 00:19:53 +00:00
|
|
|
// Submeshes.
|
2025-04-01 22:28:45 +00:00
|
|
|
std::vector<SubMesh> meshes;
|
2025-04-01 20:19:00 +00:00
|
|
|
|
2025-04-02 00:19:53 +00:00
|
|
|
// Global material overrides (if any).
|
|
|
|
glm::vec3 diffuseColor;
|
|
|
|
glm::vec3 specularColor;
|
|
|
|
float shininess;
|
|
|
|
|
2025-04-01 22:28:45 +00:00
|
|
|
// Functions.
|
|
|
|
bool LoadModel(const std::string &filepath);
|
2025-04-01 20:19:00 +00:00
|
|
|
void Draw();
|
2025-04-01 22:28:45 +00:00
|
|
|
|
|
|
|
// 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);
|
2025-04-02 00:19:53 +00:00
|
|
|
|
|
|
|
// --- 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);
|
|
|
|
}
|
2025-04-01 20:03:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // MODEL_COMPONENT_H
|