2023-01-15 22:34:02 +00:00
|
|
|
#include "WorldObject.h"
|
2023-01-19 15:36:33 +00:00
|
|
|
#include "../chinese_postman/ChinesePostman.h"
|
|
|
|
|
|
|
|
struct pair_hash {
|
|
|
|
inline std::size_t operator()(const std::pair<int, int>& v) const {
|
|
|
|
return v.first * 31 + v.second;
|
|
|
|
}
|
|
|
|
};
|
2023-01-15 22:34:02 +00:00
|
|
|
|
|
|
|
WorldObject::WorldObject(juce::InputStream& stream) {
|
|
|
|
std::string key;
|
|
|
|
while (!stream.isExhausted()) {
|
|
|
|
auto line = stream.readNextLine();
|
|
|
|
key = "";
|
|
|
|
std::stringstream stringstream(line.toStdString());
|
|
|
|
stringstream >> key >> std::ws;
|
|
|
|
|
|
|
|
if (key == "v") { // vertex
|
|
|
|
vertex v; float x;
|
|
|
|
while (!stringstream.eof()) {
|
|
|
|
stringstream >> x >> std::ws;
|
|
|
|
v.v.push_back(x);
|
|
|
|
}
|
|
|
|
vertices.push_back(v);
|
|
|
|
}
|
|
|
|
else if (key == "vp") { // parameter
|
2023-01-19 15:36:33 +00:00
|
|
|
/*vertex v; float x;
|
2023-01-15 22:34:02 +00:00
|
|
|
while (!stringstream.eof()) {
|
|
|
|
stringstream >> x >> std::ws;
|
|
|
|
v.v.push_back(x);
|
|
|
|
}
|
2023-01-19 15:36:33 +00:00
|
|
|
parameters.push_back(v);*/
|
2023-01-15 22:34:02 +00:00
|
|
|
}
|
|
|
|
else if (key == "vt") { // texture coordinate
|
2023-01-19 15:36:33 +00:00
|
|
|
/*vertex v; float x;
|
2023-01-15 22:34:02 +00:00
|
|
|
while (!stringstream.eof()) {
|
|
|
|
stringstream >> x >> std::ws;
|
|
|
|
v.v.push_back(x);
|
|
|
|
}
|
2023-01-19 15:36:33 +00:00
|
|
|
texcoords.push_back(v);*/
|
2023-01-15 22:34:02 +00:00
|
|
|
}
|
|
|
|
else if (key == "vn") { // normal
|
2023-01-19 15:36:33 +00:00
|
|
|
/*vertex v; float x;
|
2023-01-15 22:34:02 +00:00
|
|
|
while (!stringstream.eof()) {
|
|
|
|
stringstream >> x >> std::ws;
|
|
|
|
v.v.push_back(x);
|
|
|
|
}
|
|
|
|
v.normalize();
|
2023-01-19 15:36:33 +00:00
|
|
|
normals.push_back(v);*/
|
2023-01-15 22:34:02 +00:00
|
|
|
}
|
|
|
|
else if (key == "f") { // face
|
|
|
|
face f; int v, t, n;
|
|
|
|
while (!stringstream.eof()) {
|
|
|
|
stringstream >> v >> std::ws;
|
|
|
|
f.vertex.push_back(v - 1);
|
|
|
|
if (stringstream.peek() == '/') {
|
|
|
|
stringstream.get();
|
|
|
|
if (stringstream.peek() == '/') {
|
|
|
|
stringstream.get();
|
|
|
|
stringstream >> n >> std::ws;
|
|
|
|
f.normal.push_back(n - 1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
stringstream >> t >> std::ws;
|
|
|
|
f.texture.push_back(t - 1);
|
|
|
|
if (stringstream.peek() == '/') {
|
|
|
|
stringstream.get();
|
|
|
|
stringstream >> n >> std::ws;
|
|
|
|
f.normal.push_back(n - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
faces.push_back(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-19 15:36:33 +00:00
|
|
|
std::unordered_set<std::pair<int, int>, pair_hash> edge_set;
|
|
|
|
|
|
|
|
for (auto& f : faces) {
|
|
|
|
int num_vertices = f.vertex.size();
|
|
|
|
for (int i = 0; i < num_vertices; i++) {
|
|
|
|
int start = f.vertex[i];
|
|
|
|
int end = f.vertex[(i + 1) % num_vertices];
|
|
|
|
|
|
|
|
int first = start < end ? start : end;
|
|
|
|
int second = start < end ? end : start;
|
|
|
|
|
|
|
|
edge_set.insert(std::make_pair(first, second));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::list<std::pair<int, int>> edge_list;
|
|
|
|
|
|
|
|
for (auto& edge : edge_set) {
|
|
|
|
edge_list.push_back(edge);
|
|
|
|
}
|
|
|
|
|
|
|
|
Graph graph(vertices.size(), edge_list);
|
|
|
|
pair<list<int>, double> solution = ChinesePostman(graph);
|
|
|
|
list<int>& path = solution.first;
|
|
|
|
|
2023-01-15 22:34:02 +00:00
|
|
|
double x = 0.0, y = 0.0, z = 0.0;
|
|
|
|
double max = 0.0;
|
2023-01-19 15:36:33 +00:00
|
|
|
for (auto& v : vertices) {
|
|
|
|
x += v.v[0];
|
|
|
|
y += v.v[1];
|
|
|
|
z += v.v[2];
|
|
|
|
if (std::abs(v.v[0]) > max) max = std::abs(v.v[0]);
|
|
|
|
if (std::abs(v.v[1]) > max) max = std::abs(v.v[1]);
|
|
|
|
if (std::abs(v.v[2]) > max) max = std::abs(v.v[2]);
|
|
|
|
}
|
|
|
|
x /= vertices.size();
|
|
|
|
y /= vertices.size();
|
|
|
|
z /= vertices.size();
|
2023-01-15 22:34:02 +00:00
|
|
|
|
2023-01-19 15:36:33 +00:00
|
|
|
int prevVertex = -1;
|
|
|
|
for (auto& vertex : path) {
|
|
|
|
if (prevVertex != -1) {
|
|
|
|
double x1 = (vertices[prevVertex].v[0] - x) / max;
|
|
|
|
double y1 = (vertices[prevVertex].v[1] - y) / max;
|
|
|
|
double z1 = (vertices[prevVertex].v[2] - z) / max;
|
|
|
|
double x2 = (vertices[vertex].v[0] - x) / max;
|
|
|
|
double y2 = (vertices[vertex].v[1] - y) / max;
|
|
|
|
double z2 = (vertices[vertex].v[2] - z) / max;
|
2023-01-15 22:34:02 +00:00
|
|
|
|
2023-01-19 15:36:33 +00:00
|
|
|
edges.push_back(Line3D(x1, y1, z1, x2, y2, z2));
|
|
|
|
}
|
|
|
|
prevVertex = vertex;
|
|
|
|
}
|
2023-01-15 22:34:02 +00:00
|
|
|
}
|