summaryrefslogtreecommitdiff
path: root/obj_loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'obj_loader.cpp')
-rw-r--r--obj_loader.cpp118
1 files changed, 75 insertions, 43 deletions
diff --git a/obj_loader.cpp b/obj_loader.cpp
index b3cb517..7611a2c 100644
--- a/obj_loader.cpp
+++ b/obj_loader.cpp
@@ -1,8 +1,10 @@
#include "obj_loader.h"
#include <algorithm>
#include <fstream>
-#include <iostream>
#include <map>
+#include <memory>
+#include <stdexcept>
+#include <utility>
static bool CompareOBJIndexPtr(const OBJIndex * a, const OBJIndex * b);
static inline unsigned int FindNextChar(unsigned int start, const char * str, unsigned int length, char token);
@@ -24,19 +26,25 @@ OBJModel::OBJModel(const std::string & fileName)
unsigned int lineLength = line.length();
- if (lineLength < 2)
+ if (lineLength < 2) {
continue;
+ }
const char * lineCStr = line.c_str();
switch (lineCStr[0]) {
case 'v':
- if (lineCStr[1] == 't')
- this->uvs.push_back(ParseOBJVec2(line));
- else if (lineCStr[1] == 'n')
- this->normals.push_back(ParseOBJVec3(line));
- else if (lineCStr[1] == ' ' || lineCStr[1] == '\t')
- this->vertices.push_back(ParseOBJVec3(line));
+ switch (lineCStr[1]) {
+ case 't':
+ this->uvs.push_back(ParseOBJVec2(line));
+ break;
+ case 'n':
+ this->normals.push_back(ParseOBJVec3(line));
+ break;
+ case ' ':
+ case '\t':
+ this->vertices.push_back(ParseOBJVec3(line));
+ }
break;
case 'f':
CreateOBJFace(line);
@@ -47,7 +55,7 @@ OBJModel::OBJModel(const std::string & fileName)
}
}
else {
- std::cerr << "Unable to load mesh: " << fileName << std::endl;
+ throw std::runtime_error {"Unable to load mesh: " + fileName};
}
}
@@ -69,8 +77,9 @@ IndexedModel::CalcNormals()
normals[i2] += normal;
}
- for (unsigned int i = 0; i < positions.size(); i++)
+ for (unsigned int i = 0; i < positions.size(); i++) {
normals[i] = glm::normalize(normals[i]);
+ }
}
IndexedModel
@@ -83,8 +92,9 @@ OBJModel::ToIndexedModel()
std::vector<OBJIndex *> indexLookup;
- for (unsigned int i = 0; i < numIndices; i++)
+ for (unsigned int i = 0; i < numIndices; i++) {
indexLookup.push_back(&OBJIndices[i]);
+ }
std::sort(indexLookup.begin(), indexLookup.end(), CompareOBJIndexPtr);
@@ -98,21 +108,25 @@ OBJModel::ToIndexedModel()
glm::vec2 currentTexCoord;
glm::vec3 currentNormal;
- if (hasUVs)
+ if (hasUVs) {
currentTexCoord = uvs[currentIndex->uvIndex];
- else
+ }
+ else {
currentTexCoord = glm::vec2(0, 0);
+ }
- if (hasNormals)
+ if (hasNormals) {
currentNormal = normals[currentIndex->normalIndex];
- else
+ }
+ else {
currentNormal = glm::vec3(0, 0, 0);
+ }
unsigned int normalModelIndex;
unsigned int resultModelIndex;
// Create model to properly generate normals on
- std::map<OBJIndex, unsigned int>::iterator it = normalModelIndexMap.find(*currentIndex);
+ const auto it = normalModelIndexMap.find(*currentIndex);
if (it == normalModelIndexMap.end()) {
normalModelIndex = normalModel.positions.size();
@@ -121,8 +135,9 @@ OBJModel::ToIndexedModel()
normalModel.texCoords.push_back(currentTexCoord);
normalModel.normals.push_back(currentNormal);
}
- else
+ else {
normalModelIndex = it->second;
+ }
// Create model which properly separates texture coordinates
unsigned int previousVertexLocation = FindLastVertexIndex(indexLookup, currentIndex, result);
@@ -134,8 +149,9 @@ OBJModel::ToIndexedModel()
result.texCoords.push_back(currentTexCoord);
result.normals.push_back(currentNormal);
}
- else
+ else {
resultModelIndex = previousVertexLocation;
+ }
normalModel.indices.push_back(normalModelIndex);
result.indices.push_back(resultModelIndex);
@@ -145,8 +161,9 @@ OBJModel::ToIndexedModel()
if (!hasNormals) {
normalModel.CalcNormals();
- for (unsigned int i = 0; i < result.positions.size(); i++)
+ for (unsigned int i = 0; i < result.positions.size(); i++) {
result.normals[i] = normalModel.normals[indexMap[i]];
+ }
}
return result;
@@ -170,11 +187,13 @@ OBJModel::FindLastVertexIndex(
for (unsigned int i = 0; i < current; i++) {
OBJIndex * possibleIndex = indexLookup[current - i];
- if (possibleIndex == currentIndex)
+ if (possibleIndex == currentIndex) {
continue;
+ }
- if (possibleIndex->vertexIndex != currentIndex->vertexIndex)
+ if (possibleIndex->vertexIndex != currentIndex->vertexIndex) {
break;
+ }
countStart--;
}
@@ -182,26 +201,32 @@ OBJModel::FindLastVertexIndex(
for (unsigned int i = countStart; i < indexLookup.size() - countStart; i++) {
OBJIndex * possibleIndex = indexLookup[current + i];
- if (possibleIndex == currentIndex)
+ if (possibleIndex == currentIndex) {
continue;
+ }
- if (possibleIndex->vertexIndex != currentIndex->vertexIndex)
+ if (possibleIndex->vertexIndex != currentIndex->vertexIndex) {
break;
+ }
else if ((!hasUVs || possibleIndex->uvIndex == currentIndex->uvIndex)
&& (!hasNormals || possibleIndex->normalIndex == currentIndex->normalIndex)) {
glm::vec3 currentPosition = vertices[currentIndex->vertexIndex];
glm::vec2 currentTexCoord;
glm::vec3 currentNormal;
- if (hasUVs)
+ if (hasUVs) {
currentTexCoord = uvs[currentIndex->uvIndex];
- else
+ }
+ else {
currentTexCoord = glm::vec2(0, 0);
+ }
- if (hasNormals)
+ if (hasNormals) {
currentNormal = normals[currentIndex->normalIndex];
- else
+ }
+ else {
currentNormal = glm::vec3(0, 0, 0);
+ }
for (unsigned int j = 0; j < result.positions.size(); j++) {
if (currentPosition == result.positions[j]
@@ -216,10 +241,12 @@ OBJModel::FindLastVertexIndex(
return -1;
}
else {
- if (testIndex->vertexIndex < currentIndex->vertexIndex)
+ if (testIndex->vertexIndex < currentIndex->vertexIndex) {
start = current;
- else
+ }
+ else {
end = current;
+ }
}
previous = current;
@@ -254,13 +281,15 @@ OBJModel::ParseOBJIndex(const std::string & token, bool * hasUVs, bool * hasNorm
unsigned int vertIndexStart = 0;
unsigned int vertIndexEnd = FindNextChar(vertIndexStart, tokenString, tokenLength, '/');
- OBJIndex result;
- result.vertexIndex = ParseOBJIndexValue(token, vertIndexStart, vertIndexEnd);
- result.uvIndex = 0;
- result.normalIndex = 0;
+ OBJIndex result {
+ .vertexIndex = ParseOBJIndexValue(token, vertIndexStart, vertIndexEnd),
+ .uvIndex = 0,
+ .normalIndex = 0,
+ };
- if (vertIndexEnd >= tokenLength)
+ if (vertIndexEnd >= tokenLength) {
return result;
+ }
vertIndexStart = vertIndexEnd + 1;
vertIndexEnd = FindNextChar(vertIndexStart, tokenString, tokenLength, '/');
@@ -268,8 +297,9 @@ OBJModel::ParseOBJIndex(const std::string & token, bool * hasUVs, bool * hasNorm
result.uvIndex = ParseOBJIndexValue(token, vertIndexStart, vertIndexEnd);
*hasUVs = true;
- if (vertIndexEnd >= tokenLength)
+ if (vertIndexEnd >= tokenLength) {
return result;
+ }
vertIndexStart = vertIndexEnd + 1;
vertIndexEnd = FindNextChar(vertIndexStart, tokenString, tokenLength, '/');
@@ -289,8 +319,9 @@ OBJModel::ParseOBJVec3(const std::string & line)
unsigned int vertIndexStart = 2;
while (vertIndexStart < tokenLength) {
- if (tokenString[vertIndexStart] != ' ')
+ if (tokenString[vertIndexStart] != ' ') {
break;
+ }
vertIndexStart++;
}
@@ -309,8 +340,6 @@ OBJModel::ParseOBJVec3(const std::string & line)
float z = ParseOBJFloatValue(line, vertIndexStart, vertIndexEnd);
return glm::vec3(x, y, z);
-
- // glm::vec3(atof(tokens[1].c_str()), atof(tokens[2].c_str()), atof(tokens[3].c_str()))
}
glm::vec2
@@ -322,8 +351,9 @@ OBJModel::ParseOBJVec2(const std::string & line)
unsigned int vertIndexStart = 3;
while (vertIndexStart < tokenLength) {
- if (tokenString[vertIndexStart] != ' ')
+ if (tokenString[vertIndexStart] != ' ') {
break;
+ }
vertIndexStart++;
}
@@ -351,8 +381,9 @@ FindNextChar(unsigned int start, const char * str, unsigned int length, char tok
unsigned int result = start;
while (result < length) {
result++;
- if (str[result] == token)
+ if (str[result] == token) {
break;
+ }
}
return result;
@@ -361,13 +392,13 @@ FindNextChar(unsigned int start, const char * str, unsigned int length, char tok
static inline unsigned int
ParseOBJIndexValue(const std::string & token, unsigned int start, unsigned int end)
{
- return atoi(token.substr(start, end - start).c_str()) - 1;
+ return std::stoul(token.substr(start, end - start)) - 1;
}
static inline float
ParseOBJFloatValue(const std::string & token, unsigned int start, unsigned int end)
{
- return atof(token.substr(start, end - start).c_str());
+ return std::stof(token.substr(start, end - start));
}
static inline std::vector<std::string>
@@ -382,8 +413,9 @@ SplitString(const std::string & s, char delim)
while (end <= strLength) {
while (end <= strLength) {
- if (cstr[end] == delim)
+ if (cstr[end] == delim) {
break;
+ }
end++;
}