kopia lustrzana https://github.com/jameshball/osci-render
91 wiersze
2.5 KiB
C++
91 wiersze
2.5 KiB
C++
#include "WorldObject.h"
|
|
#include "../chinese_postman/ChinesePostman.h"
|
|
#include "tiny_obj_loader.h"
|
|
|
|
struct pair_hash {
|
|
inline std::size_t operator()(const std::pair<int, int>& v) const {
|
|
return v.first * 31 + v.second;
|
|
}
|
|
};
|
|
|
|
WorldObject::WorldObject(juce::InputStream& stream) {
|
|
tinyobj::ObjReaderConfig reader_config;
|
|
tinyobj::ObjReader reader;
|
|
|
|
reader.ParseFromString(stream.readEntireStreamAsString().toStdString(), "", reader_config);
|
|
|
|
vs = reader.GetAttrib().vertices;
|
|
numVertices = vs.size() / 3;
|
|
std::vector<tinyobj::shape_t> shapes = reader.GetShapes();
|
|
|
|
std::unordered_set<std::pair<int, int>, pair_hash> edge_set;
|
|
for (auto& shape : shapes) {
|
|
int i = 0;
|
|
int face = 0;
|
|
while (i < shape.mesh.indices.size()) {
|
|
int prevVertex = -1;
|
|
for (int j = 0; j < shape.mesh.num_face_vertices[face]; j++) {
|
|
int vertex = shape.mesh.indices[i].vertex_index;
|
|
if (prevVertex != -1) {
|
|
edge_set.insert(std::make_pair(prevVertex, vertex));
|
|
}
|
|
prevVertex = vertex;
|
|
i++;
|
|
}
|
|
face++;
|
|
}
|
|
}
|
|
|
|
std::list<std::pair<int, int>> edge_list;
|
|
|
|
for (auto& edge : edge_set) {
|
|
edge_list.push_back(edge);
|
|
}
|
|
|
|
Graph graph(numVertices, edge_list);
|
|
pair<list<int>, double> solution = ChinesePostman(graph);
|
|
list<int>& path = solution.first;
|
|
|
|
double x = 0.0, y = 0.0, z = 0.0;
|
|
double max = 0.0;
|
|
|
|
for (int i = 0; i < numVertices; i++) {
|
|
x += vs[i * 3];
|
|
y += vs[i * 3 + 1];
|
|
z += vs[i * 3 + 2];
|
|
if (std::abs(vs[i * 3]) > max) {
|
|
max = std::abs(vs[i * 3]);
|
|
}
|
|
if (std::abs(vs[i * 3 + 1]) > max) {
|
|
max = std::abs(vs[i * 3 + 1]);
|
|
}
|
|
if (std::abs(vs[i * 3 + 2]) > max) {
|
|
max = std::abs(vs[i * 3 + 2]);
|
|
}
|
|
}
|
|
x /= numVertices;
|
|
y /= numVertices;
|
|
z /= numVertices;
|
|
|
|
for (int i = 0; i < numVertices; i++) {
|
|
vs[i * 3] = (vs[i * 3] - x) / max;
|
|
vs[i * 3 + 1] = (vs[i * 3 + 1] - y) / max;
|
|
vs[i * 3 + 2] = (vs[i * 3 + 2] - z) / max;
|
|
}
|
|
|
|
int prevVertex = -1;
|
|
for (auto& vertex : path) {
|
|
if (prevVertex != -1) {
|
|
double x1 = vs[prevVertex * 3];
|
|
double y1 = vs[prevVertex * 3 + 1];
|
|
double z1 = vs[prevVertex * 3 + 2];
|
|
double x2 = vs[vertex * 3];
|
|
double y2 = vs[vertex * 3 + 1];
|
|
double z2 = vs[vertex * 3 + 2];
|
|
|
|
edges.push_back(Line3D(x1, y1, z1, x2, y2, z2));
|
|
}
|
|
prevVertex = vertex;
|
|
}
|
|
}
|