kopia lustrzana https://github.com/jameshball/osci-render
Use tinyobjloader instead of custom obj reader
rodzic
ece67ce7ee
commit
56efe597cb
|
@ -41,10 +41,10 @@ std::vector<Vector2> Camera::sampleVerticesInRender(WorldObject& object) {
|
|||
double oldRotateZ = object.rotateZ;
|
||||
|
||||
for (int i = 0; i < SAMPLE_RENDER_SAMPLES - 1; i++) {
|
||||
for (size_t j = 0; j < std::min(VERTEX_SAMPLES, object.vertices.size()); j++) {
|
||||
double x = object.vertices[j].v[0];
|
||||
double y = object.vertices[j].v[1];
|
||||
double z = object.vertices[j].v[2];
|
||||
for (size_t j = 0; j < std::min(VERTEX_SAMPLES, object.numVertices); j++) {
|
||||
double x = object.vs[j * 3];
|
||||
double y = object.vs[j * 3 + 1];
|
||||
double z = object.vs[j * 3 + 2];
|
||||
vertices.push_back(project(object.rotateX, object.rotateY, object.rotateZ, x, y, z));
|
||||
}
|
||||
object.rotateY += rotation;
|
||||
|
|
|
@ -15,7 +15,7 @@ private:
|
|||
const double VERTEX_VALUE_THRESHOLD = 1.0;
|
||||
const double CAMERA_MOVE_INCREMENT = -0.1;
|
||||
const int SAMPLE_RENDER_SAMPLES = 50;
|
||||
const size_t VERTEX_SAMPLES = 1000;
|
||||
const int VERTEX_SAMPLES = 1000;
|
||||
const int MAX_NUM_STEPS = 1000;
|
||||
|
||||
double focalLength;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#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 {
|
||||
|
@ -8,87 +9,32 @@ struct pair_hash {
|
|||
};
|
||||
|
||||
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;
|
||||
tinyobj::ObjReaderConfig reader_config;
|
||||
tinyobj::ObjReader reader;
|
||||
|
||||
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
|
||||
/*vertex v; float x;
|
||||
while (!stringstream.eof()) {
|
||||
stringstream >> x >> std::ws;
|
||||
v.v.push_back(x);
|
||||
}
|
||||
parameters.push_back(v);*/
|
||||
}
|
||||
else if (key == "vt") { // texture coordinate
|
||||
/*vertex v; float x;
|
||||
while (!stringstream.eof()) {
|
||||
stringstream >> x >> std::ws;
|
||||
v.v.push_back(x);
|
||||
}
|
||||
texcoords.push_back(v);*/
|
||||
}
|
||||
else if (key == "vn") { // normal
|
||||
/*vertex v; float x;
|
||||
while (!stringstream.eof()) {
|
||||
stringstream >> x >> std::ws;
|
||||
v.v.push_back(x);
|
||||
}
|
||||
v.normalize();
|
||||
normals.push_back(v);*/
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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& 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));
|
||||
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;
|
||||
|
||||
|
@ -96,39 +42,46 @@ WorldObject::WorldObject(juce::InputStream& stream) {
|
|||
edge_list.push_back(edge);
|
||||
}
|
||||
|
||||
Graph graph(vertices.size(), edge_list);
|
||||
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 (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();
|
||||
|
||||
for (auto& v : vertices) {
|
||||
v.v[0] = (v.v[0] - x) / max;
|
||||
v.v[1] = (v.v[1] - y) / max;
|
||||
v.v[2] = (v.v[2] - z) / max;
|
||||
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 = vertices[prevVertex].v[0];
|
||||
double y1 = vertices[prevVertex].v[1];
|
||||
double z1 = vertices[prevVertex].v[2];
|
||||
double x2 = vertices[vertex].v[0];
|
||||
double y2 = vertices[vertex].v[1];
|
||||
double z2 = vertices[vertex].v[2];
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -3,52 +3,6 @@
|
|||
#include <JuceHeader.h>
|
||||
#include "Line3D.h"
|
||||
|
||||
// from https://www.keithlantz.net/2011/10/a-preliminary-wavefront-obj-loader-in-c/
|
||||
struct vertex {
|
||||
std::vector<float> v;
|
||||
void normalize() {
|
||||
float magnitude = 0.0f;
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
magnitude += pow(v[i], 2.0f);
|
||||
magnitude = sqrt(magnitude);
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
v[i] /= magnitude;
|
||||
}
|
||||
vertex operator-(vertex v2) {
|
||||
vertex v3;
|
||||
if (v.size() != v2.v.size()) {
|
||||
v3.v.push_back(0.0f);
|
||||
v3.v.push_back(0.0f);
|
||||
v3.v.push_back(0.0f);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
v3.v.push_back(v[i] - v2.v[i]);
|
||||
}
|
||||
return v3;
|
||||
}
|
||||
vertex cross(vertex v2) {
|
||||
vertex v3;
|
||||
if (v.size() != 3 || v2.v.size() != 3) {
|
||||
v3.v.push_back(0.0f);
|
||||
v3.v.push_back(0.0f);
|
||||
v3.v.push_back(0.0f);
|
||||
}
|
||||
else {
|
||||
v3.v.push_back(v[1] * v2.v[2] - v[2] * v2.v[1]);
|
||||
v3.v.push_back(v[2] * v2.v[0] - v[0] * v2.v[2]);
|
||||
v3.v.push_back(v[0] * v2.v[1] - v[1] * v2.v[0]);
|
||||
}
|
||||
return v3;
|
||||
}
|
||||
};
|
||||
|
||||
struct face {
|
||||
std::vector<int> vertex;
|
||||
std::vector<int> texture;
|
||||
std::vector<int> normal;
|
||||
};
|
||||
|
||||
class WorldObject {
|
||||
public:
|
||||
WorldObject(juce::InputStream&);
|
||||
|
@ -56,10 +10,7 @@ public:
|
|||
double rotateX = 0.0, rotateY = 0.0, rotateZ = 0.0;
|
||||
|
||||
std::vector<Line3D> edges;
|
||||
std::vector<vertex> vertices;
|
||||
std::vector<float> vs;
|
||||
int numVertices;
|
||||
private:
|
||||
std::vector<vertex> texcoords;
|
||||
std::vector<vertex> normals;
|
||||
std::vector<vertex> parameters;
|
||||
std::vector<face> faces;
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "tiny_obj_loader.h"
|
Plik diff jest za duży
Load Diff
|
@ -51,6 +51,10 @@
|
|||
<FILE id="ix12FT" name="Camera.h" compile="0" resource="0" file="Source/obj/Camera.h"/>
|
||||
<FILE id="JJTNO9" name="Line3D.cpp" compile="1" resource="0" file="Source/obj/Line3D.cpp"/>
|
||||
<FILE id="TMrur0" name="Line3D.h" compile="0" resource="0" file="Source/obj/Line3D.h"/>
|
||||
<FILE id="a4ILpa" name="tiny_obj_loader.cpp" compile="1" resource="0"
|
||||
file="Source/obj/tiny_obj_loader.cpp"/>
|
||||
<FILE id="YdfYbM" name="tiny_obj_loader.h" compile="0" resource="0"
|
||||
file="Source/obj/tiny_obj_loader.h"/>
|
||||
<FILE id="YNsbe9" name="WorldObject.cpp" compile="1" resource="0" file="Source/obj/WorldObject.cpp"/>
|
||||
<FILE id="SZBVI9" name="WorldObject.h" compile="0" resource="0" file="Source/obj/WorldObject.h"/>
|
||||
</GROUP>
|
||||
|
|
Ładowanie…
Reference in New Issue