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

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();
}
}
}