Skip to content

Instantly share code, notes, and snippets.

@JossWhittle
Last active February 26, 2016 16:26
Show Gist options
  • Select an option

  • Save JossWhittle/642d1aeb0569f00afa21 to your computer and use it in GitHub Desktop.

Select an option

Save JossWhittle/642d1aeb0569f00afa21 to your computer and use it in GitHub Desktop.
struct Vec {
float x,y,z;
};
static inline bool hasPrefix(const std::string &str, const std::string &prefix) {
return (str.size() >= prefix.size())
&& (std::mismatch(prefix.cbegin(), prefix.cend(), str.cbegin()).first == prefix.cend());
};
static inline std::vector<std::string> split(const std::string &str, const char delim) {
std::vector<std::string> result; result.reserve(16);
size_t start{}, end;
while ((end = str.find(delim, start)) != std::string::npos) {
if (str[start] != ' ') result.push_back(str.substr(start, (end - start)));
start = end + 1;
}
result.push_back(str.substr(start));
return result;
};
inline std::vector<float> loadOBJ(const std::string &path) {
const std::string V_PRE = "v ";
const std::string VN_PRE = "vn ";
const std::string VT_PRE = "vt ";
const std::string F_PRE = "f ";
std::vector<float> mesh;
std::vector<Vec> LIST_VERTEX;
std::vector<Vec> LIST_NORMAL;
std::vector<Vec> LIST_UV;
// Open File
std::ifstream inFile(path, ios::in);
if (inFile.is_open()) {
std::string line;
while (std::getline(inFile, line)) {
if (hasPrefix(line, V_PRE)) {
std::vector<std::string> sm = split(line, ' ');
//assert(sm.size() >= 4);
// Vertex
real x, y, z;
x = stod(sm[1]);
y = stod(sm[2]);
z = stod(sm[3]);
Vec v = Vec{ x, y, z };
LIST_VERTEX.push_back(v);
continue;
}
if (hasPrefix(line, VN_PRE)) {
std::vector<std::string> sm = split(line, ' ');
//assert(sm.size() >= 4);
// Vertex
real x, y, z;
x = stod(sm[1]);
y = stod(sm[2]);
z = stod(sm[3]);
Vec v = Vec{ x, y, z }.normal();
LIST_NORMAL.push_back(v);
continue;
}
if (hasPrefix(line, VT_PRE)) {
std::vector<std::string> sm = split(line, ' ');
//assert(sm.size() >= 3);
// Vertex
real x, y;
x = stod(sm[1]);
y = stod(sm[2]);
Vec v{ x, y, 0.0 };
LIST_UV.push_back(v);
continue;
}
if (hasPrefix(line, F_PRE)) {
std::vector<std::string> fm = split(line, ' '), sm;
//assert(fm.size() >= 4);
sm = split(fm[1], '/');
//assert(sm.size() >= 3);
int v0, n0, t0;
v0 = stoi(sm[0]);
t0 = atoi(sm[1].c_str());
n0 = stoi(sm[2]);
sm = split(fm[2], '/');
//assert(sm.size() >= 3);
int v1, n1, t1;
v1 = stoi(sm[0]);
t1 = atoi(sm[1].c_str());
n1 = stoi(sm[2]);
sm = split(fm[3], '/');
//assert(sm.size() >= 3);
int v2, n2, t2;
v2 = stoi(sm[0]);
t2 = atoi(sm[1].c_str());
n2 = stoi(sm[2]);
Vec V0, V1, V2;
V0 = (v0 > 0) ? LIST_VERTEX[v0 - 1] : (v0 < 0) ? LIST_VERTEX[LIST_VERTEX.size() + v0] : Vec();
V1 = (v1 > 0) ? LIST_VERTEX[v1 - 1] : (v1 < 0) ? LIST_VERTEX[LIST_VERTEX.size() + v1] : Vec();
V2 = (v2 > 0) ? LIST_VERTEX[v2 - 1] : (v2 < 0) ? LIST_VERTEX[LIST_VERTEX.size() + v2] : Vec();
Vec N0, N1, N2;
N0 = (n0 > 0) ? LIST_NORMAL[n0 - 1] : (n0 < 0) ? LIST_NORMAL[LIST_NORMAL.size() + n0] : Vec();
N1 = (n1 > 0) ? LIST_NORMAL[n1 - 1] : (n1 < 0) ? LIST_NORMAL[LIST_NORMAL.size() + n1] : Vec();
N2 = (n2 > 0) ? LIST_NORMAL[n2 - 1] : (n2 < 0) ? LIST_NORMAL[LIST_NORMAL.size() + n2] : Vec();
Vec T0, T1, T2;
T0 = (t0 > 0) ? LIST_UV[t0 - 1] : (t0 < 0) ? LIST_UV[LIST_UV.size() + t0] : Vec();
T1 = (t1 > 0) ? LIST_UV[t1 - 1] : (t1 < 0) ? LIST_UV[LIST_UV.size() + t1] : Vec();
T2 = (t2 > 0) ? LIST_UV[t2 - 1] : (t2 < 0) ? LIST_UV[LIST_UV.size() + t2] : Vec();
mesh.push_back(V0.x);
mesh.push_back(V0.y);
mesh.push_back(V0.z);
mesh.push_back(N0.x);
mesh.push_back(N0.y);
mesh.push_back(N0.z);
mesh.push_back(V1.x);
mesh.push_back(V1.y);
mesh.push_back(V1.z);
mesh.push_back(N1.x);
mesh.push_back(N1.y);
mesh.push_back(N1.z);
mesh.push_back(V2.x);
mesh.push_back(V2.y);
mesh.push_back(V2.z);
mesh.push_back(N2.x);
mesh.push_back(N2.y);
mesh.push_back(N2.z);
continue;
}
}
inFile.close();
}
else {
std::exit(1);
}
return mesh;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment