98 lines
5.4 KiB
C++
98 lines
5.4 KiB
C++
#include "Models.hpp"
|
|
#include <fstream>
|
|
#include <map>
|
|
|
|
using namespace render;
|
|
|
|
std::unique_ptr<Model> (*Model::createFunc)(const Data&) = nullptr;
|
|
std::unique_ptr<LodModel> (*LodModel::createFunc)(const LodData&) = nullptr;
|
|
|
|
const std::vector<glm::vec3> Shape::SKY_CUBE = {
|
|
{-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f},
|
|
{-1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
|
|
{ 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f},
|
|
{-1.0f, -1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
|
|
{-1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, -1.0f},
|
|
{-1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}
|
|
};
|
|
const std::vector<glm::vec3> Shape::LINE_CUBE = {
|
|
{0, 0, 0}, {0, 0, 1}, {0, 0, 1}, {0, 1, 1}, {0, 1, 1}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {1, 0, 1}, {1, 1, 1},
|
|
{1, 1, 1}, {1, 1, 0}, {1, 1, 0}, {1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}, {0, 1, 0}, {1, 1, 0}
|
|
};
|
|
constexpr auto SINPIOVER4 = 0.853553391f;
|
|
const std::vector<glm::vec3> Shape::LINE_SPHERE = {
|
|
{1, .5f, .5f}, {SINPIOVER4, SINPIOVER4, .5f}, {SINPIOVER4, SINPIOVER4, .5f}, {.5f, 1, .5f},
|
|
{.5f, 1, .5f}, {1-SINPIOVER4, SINPIOVER4, .5f}, {1-SINPIOVER4, SINPIOVER4, .5f}, {0, .5f, .5f},
|
|
{1, .5f, .5f}, {SINPIOVER4, 1-SINPIOVER4, .5f}, {SINPIOVER4, 1-SINPIOVER4, .5f}, {.5f, 0, .5f},
|
|
{.5f, 0, .5f}, {1-SINPIOVER4, 1-SINPIOVER4, .5f}, {1-SINPIOVER4, 1-SINPIOVER4, .5f}, {0, .5f, .5f},
|
|
{1, .5f, .5f}, {SINPIOVER4, .5f, SINPIOVER4}, {SINPIOVER4, .5f, SINPIOVER4}, {.5f, .5f, 1},
|
|
{.5f, .5f, 1}, {1-SINPIOVER4, .5f, SINPIOVER4}, {1-SINPIOVER4, .5f, SINPIOVER4}, {0, .5f, .5f},
|
|
{1, .5f, .5f}, {SINPIOVER4, .5f, 1-SINPIOVER4}, {SINPIOVER4, .5f, 1-SINPIOVER4}, {.5f, .5f, 0},
|
|
{.5f, .5f, 0}, {1-SINPIOVER4, .5f, 1-SINPIOVER4}, {1-SINPIOVER4, .5f, 1-SINPIOVER4}, {0, .5f, .5f},
|
|
{.5f, 1, .5f}, {.5f, SINPIOVER4, SINPIOVER4}, {.5f, SINPIOVER4, SINPIOVER4}, {.5f, .5f, 1},
|
|
{.5f, .5f, 1}, {.5f, 1-SINPIOVER4, SINPIOVER4}, {.5f, 1-SINPIOVER4, SINPIOVER4}, {.5f, 0, .5f},
|
|
{.5f, 1, .5f}, {.5f, SINPIOVER4, 1-SINPIOVER4}, {.5f, SINPIOVER4, 1-SINPIOVER4}, {.5f, .5f, 0},
|
|
{.5f, .5f, 0}, {.5f, 1-SINPIOVER4, 1-SINPIOVER4}, {.5f, 1-SINPIOVER4, 1-SINPIOVER4}, {.5f, 0, .5f}
|
|
};
|
|
const std::pair<std::vector<glm::vec3>, std::vector<glm::vec4>> ColoredShape::LINE_CUBE = {Shape::LINE_CUBE,
|
|
{
|
|
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
|
|
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
|
|
}};
|
|
|
|
void indexVBO(const std::vector<PackedVertexData> &in_vertices, std::vector<glm::u16> &out_indices, std::vector<PackedVertexData> &out_vertices);
|
|
|
|
Model::Data::Data(const std::vector<PackedVertexData> &vs, const std::vector<glm::u16> &indices): indices(indices), vertices(vs) { }
|
|
Model::Data::Data(std::istream& in) {
|
|
{
|
|
size_t i_size;
|
|
in.read(reinterpret_cast<char *>(&i_size), sizeof(i_size));
|
|
indices.resize(i_size);
|
|
in.read(reinterpret_cast<char *>(indices.data()), sizeof(glm::u16) * i_size);
|
|
}
|
|
size_t v_size;
|
|
in.read(reinterpret_cast<char *>(&v_size), sizeof(v_size));
|
|
vertices.resize(v_size, PackedVertexData(0, 0, 0, 0, 0, 0, 0, 0));
|
|
in.read(reinterpret_cast<char *>(vertices.data()), sizeof(PackedVertexData) * v_size);
|
|
}
|
|
void Model::Data::serialize(std::ostream& out) {
|
|
{
|
|
size_t i_size = indices.size();
|
|
out.write(reinterpret_cast<char *>(&i_size), sizeof(i_size));
|
|
out.write(reinterpret_cast<char *>(indices.data()), sizeof(glm::u16) * i_size);
|
|
}
|
|
size_t v_size = vertices.size();
|
|
out.write(reinterpret_cast<char *>(&v_size), sizeof(v_size));
|
|
out.write(reinterpret_cast<char *>(vertices.data()), sizeof(PackedVertexData) * v_size);
|
|
}
|
|
void Model::Data::index(const std::vector<PackedVertexData>& vs) {
|
|
indexVBO(vs, indices, vertices);
|
|
}
|
|
|
|
void indexVBO(const std::vector<PackedVertexData> &in_vertices, std::vector<glm::u16> &out_indices,
|
|
std::vector<PackedVertexData> &out_vertices)
|
|
{
|
|
std::map<PackedVertexData, glm::u16> VertexToOutIndex;
|
|
|
|
auto getSimilarVertexIndex_fast = [&] (const PackedVertexData &packed, glm::u16 &out) {
|
|
auto it = VertexToOutIndex.find(packed);
|
|
if (it == VertexToOutIndex.end()) {
|
|
return false;
|
|
}else{
|
|
out = it->second;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
out_indices.reserve(in_vertices.size());
|
|
for (const auto& vertex: in_vertices) {
|
|
glm::u16 index;
|
|
if (getSimilarVertexIndex_fast(vertex, index)) {
|
|
out_indices.push_back(index);
|
|
} else {
|
|
out_vertices.push_back(vertex);
|
|
out_indices.push_back(out_vertices.size() - 1);
|
|
VertexToOutIndex[vertex] = out_indices.back();
|
|
}
|
|
}
|
|
} |