2013-09-25 09:05:18 +01:00
|
|
|
#pragma once
|
|
|
|
#ifndef _MODEL_HPP_
|
|
|
|
#define _MODEL_HPP_
|
2016-09-09 21:13:21 +01:00
|
|
|
#include <algorithm>
|
2014-02-09 03:14:43 +00:00
|
|
|
#include <glm/glm.hpp>
|
2013-09-25 09:05:18 +01:00
|
|
|
#include <memory>
|
2016-09-09 21:13:21 +01:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2013-09-25 09:05:18 +01:00
|
|
|
|
2016-04-07 01:13:46 +01:00
|
|
|
#include <gl/DrawBuffer.hpp>
|
|
|
|
#include <gl/GeometryBuffer.hpp>
|
|
|
|
#include <gl/TextureData.hpp>
|
2016-09-09 21:13:21 +01:00
|
|
|
#include <loaders/RWBinaryStream.hpp>
|
2013-09-25 09:05:18 +01:00
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
// Forward Declerations
|
|
|
|
class ModelFrame;
|
|
|
|
struct Geometry;
|
|
|
|
class Atomic;
|
|
|
|
class Clump;
|
|
|
|
|
|
|
|
// Pointer types
|
|
|
|
using ModelFramePtr = std::shared_ptr<ModelFrame>;
|
|
|
|
using GeometryPtr = std::shared_ptr<Geometry>;
|
|
|
|
using AtomicPtr = std::shared_ptr<Atomic>;
|
|
|
|
using AtomicList = std::vector<AtomicPtr>;
|
|
|
|
using ClumpPtr = std::shared_ptr<Clump>;
|
|
|
|
|
2014-02-13 10:55:11 +00:00
|
|
|
/**
|
2017-01-04 21:08:21 +00:00
|
|
|
* ModelFrame stores transformation hierarchy
|
2014-02-13 10:55:11 +00:00
|
|
|
*/
|
2014-02-09 03:14:43 +00:00
|
|
|
class ModelFrame {
|
2016-09-09 21:13:21 +01:00
|
|
|
unsigned int index;
|
|
|
|
glm::mat3 defaultRotation;
|
|
|
|
glm::vec3 defaultTranslation;
|
|
|
|
glm::mat4 matrix;
|
2017-01-04 21:08:21 +00:00
|
|
|
glm::mat4 worldtransform_;
|
|
|
|
ModelFrame* parent_;
|
2016-09-09 21:13:21 +01:00
|
|
|
std::string name;
|
2017-01-04 21:08:21 +00:00
|
|
|
std::vector<ModelFramePtr> children_;
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2014-02-09 03:14:43 +00:00
|
|
|
public:
|
2017-01-04 21:08:21 +00:00
|
|
|
ModelFrame(unsigned int index = 0, glm::mat3 dR = glm::mat3(),
|
|
|
|
glm::vec3 dT = glm::vec3());
|
2016-09-09 21:13:21 +01:00
|
|
|
|
|
|
|
void reset();
|
2017-01-04 21:08:21 +00:00
|
|
|
|
|
|
|
void setTransform(const glm::mat4& m) {
|
|
|
|
matrix = m;
|
|
|
|
updateHierarchyTransform();
|
|
|
|
}
|
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
const glm::mat4& getTransform() const {
|
|
|
|
return matrix;
|
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
void setName(const std::string& fname) {
|
|
|
|
name = fname;
|
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
unsigned int getIndex() const {
|
|
|
|
return index;
|
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
glm::vec3 getDefaultTranslation() const {
|
|
|
|
return defaultTranslation;
|
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
glm::mat3 getDefaultRotation() const {
|
|
|
|
return defaultRotation;
|
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
void setTranslation(const glm::vec3& t) {
|
|
|
|
matrix[3] = glm::vec4(t, matrix[3][3]);
|
|
|
|
updateHierarchyTransform();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setRotation(const glm::mat3& r) {
|
|
|
|
for (unsigned int i = 0; i < 3; i++) {
|
|
|
|
matrix[i] = glm::vec4(r[i], matrix[i][3]);
|
|
|
|
}
|
|
|
|
updateHierarchyTransform();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the cached matrix
|
|
|
|
*/
|
|
|
|
void updateHierarchyTransform();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the cached world transformation for this Frame
|
|
|
|
*/
|
|
|
|
const glm::mat4& getWorldTransform() const {
|
|
|
|
return worldtransform_;
|
2016-09-09 21:13:21 +01:00
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
ModelFrame* getParent() const {
|
2017-01-04 21:08:21 +00:00
|
|
|
return parent_;
|
2016-09-09 21:13:21 +01:00
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
void addChild(ModelFramePtr& child);
|
|
|
|
|
|
|
|
const std::vector<ModelFramePtr>& getChildren() const {
|
|
|
|
return children_;
|
2016-09-09 21:13:21 +01:00
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
const std::string& getName() const {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
ModelFrame* findDescendant(const std::string& name) const;
|
2014-02-09 03:14:43 +00:00
|
|
|
};
|
|
|
|
|
2014-02-13 10:55:11 +00:00
|
|
|
/**
|
2017-01-03 16:21:21 +00:00
|
|
|
* Subgeometry
|
2014-02-13 10:55:11 +00:00
|
|
|
*/
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
struct SubGeometry {
|
|
|
|
GLuint start = 0;
|
|
|
|
size_t material = 0;
|
|
|
|
std::vector<uint32_t> indices;
|
|
|
|
size_t numIndices = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct GeometryVertex {
|
|
|
|
glm::vec3 position; /* 0 */
|
|
|
|
glm::vec3 normal; /* 24 */
|
|
|
|
glm::vec2 texcoord; /* 48 */
|
|
|
|
glm::u8vec4 colour; /* 64 */
|
|
|
|
|
|
|
|
/** @see GeometryBuffer */
|
|
|
|
static const AttributeList vertex_attributes() {
|
|
|
|
return {{ATRS_Position, 3, sizeof(GeometryVertex), 0ul},
|
|
|
|
{ATRS_Normal, 3, sizeof(GeometryVertex), sizeof(float) * 3},
|
|
|
|
{ATRS_TexCoord, 2, sizeof(GeometryVertex), sizeof(float) * 6},
|
|
|
|
{ATRS_Colour, 4, sizeof(GeometryVertex), sizeof(float) * 8,
|
|
|
|
GL_UNSIGNED_BYTE}};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Geometry
|
|
|
|
*/
|
|
|
|
struct Geometry {
|
|
|
|
enum FaceType { Triangles = 0, TriangleStrip = 1 };
|
2016-09-09 21:13:21 +01:00
|
|
|
|
|
|
|
struct Texture {
|
|
|
|
std::string name;
|
|
|
|
std::string alphaName;
|
|
|
|
TextureData::Handle texture;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum { MTF_PrimaryColour = 1 << 0, MTF_SecondaryColour = 1 << 1 };
|
|
|
|
|
|
|
|
struct Material {
|
|
|
|
std::vector<Texture> textures;
|
|
|
|
glm::u8vec4 colour;
|
|
|
|
|
|
|
|
uint8_t flags;
|
|
|
|
|
|
|
|
float diffuseIntensity;
|
|
|
|
float ambientIntensity;
|
|
|
|
};
|
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
DrawBuffer dbuff;
|
|
|
|
GeometryBuffer gbuff;
|
2013-09-25 09:05:18 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
GLuint EBO;
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
RW::BSGeometryBounds geometryBounds;
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
uint32_t clumpNum;
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
FaceType facetype;
|
2013-09-25 09:05:18 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
uint32_t flags;
|
2013-09-25 09:05:18 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
std::vector<Material> materials;
|
|
|
|
std::vector<SubGeometry> subgeom;
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
Geometry();
|
|
|
|
~Geometry();
|
|
|
|
};
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
/**
|
|
|
|
* @brief The Atomic struct
|
|
|
|
*/
|
2017-01-04 21:08:21 +00:00
|
|
|
class Atomic {
|
|
|
|
ModelFramePtr frame_;
|
|
|
|
GeometryPtr geometry_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
void setFrame(ModelFramePtr& frame) {
|
|
|
|
frame_ = frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ModelFramePtr& getFrame() const {
|
|
|
|
return frame_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setGeometry(GeometryPtr& geom) {
|
|
|
|
geometry_ = geom;
|
|
|
|
}
|
|
|
|
|
|
|
|
const GeometryPtr& getGeometry() const {
|
|
|
|
return geometry_;
|
|
|
|
}
|
2017-01-03 16:21:21 +00:00
|
|
|
};
|
2016-09-09 21:13:21 +01:00
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
/**
|
|
|
|
* A clump is a collection of Frames and Atomics
|
|
|
|
*/
|
|
|
|
class Clump {
|
|
|
|
public:
|
2017-01-04 21:08:21 +00:00
|
|
|
/**
|
|
|
|
* @brief findFrame Locates frame with name anywhere in the hierarchy
|
|
|
|
* @param name
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
ModelFrame* findFrame(const std::string& name) const;
|
2014-08-04 22:21:01 +01:00
|
|
|
|
2017-01-03 14:18:06 +00:00
|
|
|
~Clump();
|
2015-04-06 04:06:35 +01:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
void recalculateMetrics();
|
2016-04-19 01:20:54 +01:00
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
float getBoundingRadius() const {
|
|
|
|
return boundingRadius;
|
|
|
|
}
|
2016-04-19 01:20:54 +01:00
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
void addAtomic(AtomicPtr& atomic) {
|
|
|
|
atomics_.push_back(atomic);
|
|
|
|
}
|
|
|
|
|
|
|
|
const AtomicList& getAtomics() const {
|
|
|
|
return atomics_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setFrame(ModelFramePtr& root) {
|
|
|
|
rootframe_ = root;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ModelFramePtr& getFrame() const {
|
|
|
|
return rootframe_;
|
|
|
|
}
|
|
|
|
|
2016-04-19 01:20:54 +01:00
|
|
|
private:
|
2016-09-09 21:13:21 +01:00
|
|
|
float boundingRadius;
|
2017-01-04 21:08:21 +00:00
|
|
|
AtomicList atomics_;
|
|
|
|
ModelFramePtr rootframe_;
|
2013-09-25 09:05:18 +01:00
|
|
|
};
|
|
|
|
|
2014-03-01 04:12:35 +00:00
|
|
|
#endif
|