init
This commit is contained in:
106
engine/include/hd2d/Model.h
Normal file
106
engine/include/hd2d/Model.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
#include "hd2d/GL.h"
|
||||
#include "hd2d/Texture.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace hd2d {
|
||||
|
||||
// Material of a glTF primitive. Materials whose name starts with "foliage"
|
||||
// get alpha testing, two-sided wrap lighting and sun translucency.
|
||||
struct ModelMaterial {
|
||||
std::string name;
|
||||
const Texture* texture = nullptr; // base color (sRGB); null = white
|
||||
glm::vec4 baseColor{1.0f};
|
||||
bool alphaMask = false;
|
||||
float alphaCutoff = 0.5f;
|
||||
bool doubleSided = false;
|
||||
bool foliage = false;
|
||||
glm::vec3 emissive{0.0f}; // linear HDR (factor x strength)
|
||||
const Texture* emissiveTexture = nullptr; // multiplies `emissive`; null = white
|
||||
};
|
||||
|
||||
struct ModelPrimitive {
|
||||
GLuint vbo = 0, ibo = 0;
|
||||
GLsizei indexCount = 0;
|
||||
const ModelMaterial* material = nullptr; // owned by the ModelLibrary
|
||||
};
|
||||
|
||||
// Static mesh made of primitives (one per material). Vertex layout: position,
|
||||
// normal, uv, color (rgb = tint/AO, a = wind weight). Built from one root
|
||||
// node of a glTF file with the node's world transform baked in.
|
||||
struct Model {
|
||||
std::string name;
|
||||
std::vector<ModelPrimitive> primitives;
|
||||
glm::vec3 boundsMin{0.0f}, boundsMax{0.0f};
|
||||
// Named attachment points from child empties of the glTF node (model space),
|
||||
// e.g. "fire_0" on the bridge braziers.
|
||||
std::unordered_map<std::string, glm::vec3> sockets;
|
||||
};
|
||||
|
||||
// Loads a .glb/.gltf once (textures shared by all its models) and exposes each
|
||||
// root node with a mesh as a named Model.
|
||||
class ModelLibrary {
|
||||
public:
|
||||
ModelLibrary() = default;
|
||||
ModelLibrary(const ModelLibrary&) = delete;
|
||||
ModelLibrary& operator=(const ModelLibrary&) = delete;
|
||||
~ModelLibrary();
|
||||
|
||||
bool load(const std::string& path);
|
||||
const Model* get(const std::string& name) const;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Texture>> textures_;
|
||||
std::vector<std::unique_ptr<ModelMaterial>> materials_;
|
||||
std::unordered_map<std::string, std::unique_ptr<Model>> models_;
|
||||
};
|
||||
|
||||
// Per-instance placement: rotation about +Y, non-uniform scale, brightness tint.
|
||||
struct ModelInstance {
|
||||
glm::vec3 pos{0.0f};
|
||||
float yaw = 0.0f;
|
||||
glm::vec3 scale{1.0f};
|
||||
float tint = 1.0f;
|
||||
|
||||
glm::vec3 toWorld(const glm::vec3& local) const { // matches mesh.vert
|
||||
glm::vec3 p = local * scale;
|
||||
float c = std::cos(yaw), s = std::sin(yaw);
|
||||
return pos + glm::vec3(c * p.x + s * p.z, p.y, -s * p.x + c * p.z);
|
||||
}
|
||||
};
|
||||
|
||||
// Instanced draw of one model.
|
||||
class ModelBatch {
|
||||
public:
|
||||
explicit ModelBatch(const Model* model = nullptr) : model(model) {}
|
||||
ModelBatch(const ModelBatch&) = delete;
|
||||
ModelBatch& operator=(const ModelBatch&) = delete;
|
||||
~ModelBatch();
|
||||
|
||||
void upload(); // call after editing `instances`
|
||||
// Draws primitive `i` (the renderer binds its material first).
|
||||
void drawPrimitive(size_t i) const;
|
||||
|
||||
const Model* model = nullptr;
|
||||
std::vector<ModelInstance> instances;
|
||||
bool castShadows = true;
|
||||
bool inReflections = true;
|
||||
float windScale = 1.0f; // multiplies the per-vertex wind weight
|
||||
// Strength of the contact shadow baked into the ground under each instance
|
||||
// (see GroundOcclusion); 0 disables. Its size follows the model's footprint.
|
||||
float groundOcclusion = 0.0f;
|
||||
|
||||
private:
|
||||
std::vector<GLuint> vaos_;
|
||||
GLuint instanceVbo_ = 0;
|
||||
size_t capacity_ = 0;
|
||||
GLsizei count_ = 0;
|
||||
};
|
||||
|
||||
} // namespace hd2d
|
||||
Reference in New Issue
Block a user