1
0
Fork 0
Univerxel/src/client/render/api/Models.hpp

122 lines
3.1 KiB
C++

/**
* Application specific vertex objects.
*/
#pragma once
#include "common.hpp"
#include <glm/glm.hpp>
#include <string.h>
#include <vector>
#include <iosfwd>
namespace render {
/// Vertex properties
struct VertexData {
VertexData(const glm::vec3 &position, glm::u16 material, const glm::vec3 &normal):
Position(position), Material(material), Normal(normal) { }
glm::vec3 Position;
glm::u16 Material;
glm::vec3 Normal;
};
/// Quantized vertex properties
struct PackedVertexData {
PackedVertexData(glm::u16 x, glm::u16 y, glm::u16 z, glm::u16 mat, glm::u16 nx, glm::u16 ny, glm::u16 nz, glm::u16 nw = 0) {
PosMat[0] = x;
PosMat[1] = y;
PosMat[2] = z;
PosMat[3] = mat;
Nrm[0] = nx;
Nrm[1] = ny;
Nrm[2] = nz;
Nrm[3] = nw;
}
glm::u16 PosMat[4];
glm::u16 Nrm[4]; //NOTE: Triplanar does not handle 10_10_10_2_REV
bool operator<(const PackedVertexData that) const {
return memcmp((void *)this, (void *)&that, sizeof(PackedVertexData)) > 0;
};
};
/// Position only buffer
class Shape {
public:
virtual ~Shape() { }
static const std::vector<glm::vec3> SKY_CUBE;
static const std::vector<glm::vec3> LINE_CUBE;
static const std::vector<glm::vec3> LINE_SPHERE;
};
/// Color lines model
class ColoredShape {
public:
virtual ~ColoredShape() { }
static const std::pair<std::vector<glm::vec3>, std::vector<glm::vec4>> LINE_CUBE;
};
/// VertexData model with index
class Model {
public:
virtual ~Model() { }
/// Preindexed buffer data
struct Data {
using indices_t = std::vector<glm::u16>;
indices_t indices;
std::vector<PackedVertexData> vertices;
Data() { }
Data(const std::vector<PackedVertexData> &vertices, const indices_t &indices);
Data(const std::vector<PackedVertexData> &vertices) { index(vertices); }
Data(std::istream &in);
void index(const std::vector<PackedVertexData> &vertices);
bool empty() const {
return indices.empty();
}
void clear() {
indices.clear();
vertices.clear();
}
void serialize(std::ostream &out);
};
static _FORCE_INLINE_ std::unique_ptr<Model> Create(const Data& data) {
assert(createFunc != nullptr && "Uninitialized renderer");
return createFunc(data);
}
protected:
static std::unique_ptr<Model> (*createFunc)(const Data&);
};
/// VertexData model with Level Of Detail indices
class LodModel {
public:
virtual ~LodModel() { }
using LodData = std::pair<Model::Data, std::vector<size_t>>;
static _FORCE_INLINE_ std::unique_ptr<LodModel> Create(const LodData& data) {
assert(createFunc != nullptr && "Uninitialized renderer");
return createFunc(data);
}
void inline setLevel(size_t l) { level = l; }
protected:
size_t level = 0;
size_t indexSize;
std::vector<size_t> offsets;
constexpr inline size_t getOffset(size_t level) const {
return level <= 0 ? 0 : (level-1 < offsets.size() ? offsets[level-1] : indexSize);
}
static std::unique_ptr<LodModel> (*createFunc)(const LodData&);
};
}