Commit e4c4a3db authored by Martin Schultz's avatar Martin Schultz

* changed stream operations in objloader to be pointer operations

parent 02a18624
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <ACGL/OpenGL/Data/GeometryDataLoadStore.hh> #include <ACGL/OpenGL/Data/GeometryDataLoadStore.hh>
#include <ACGL/Math/Math.hh> #include <ACGL/Math/Math.hh>
#include <ACGL/Utils/StringHelpers.hh> #include <ACGL/Utils/StringHelpers.hh>
#include <ACGL/Utils/MemoryMappedFile.hh>
#include <fstream> #include <fstream>
#include <string> #include <string>
...@@ -31,50 +32,62 @@ namespace ...@@ -31,50 +32,62 @@ namespace
int normal; int normal;
}; };
void skipLine(std::fstream& _stream)
{
_stream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// Parses a string of space-separated numbers into a packed floating-point vector (_data) with a maximum number of _maxDimension elements // Parses a string of space-separated numbers into a packed floating-point vector (_data) with a maximum number of _maxDimension elements
void parseVector(const std::string& _string, int _maxDimension, int& _dimension, float* _data) void parseVector(const char* _start , const char* _end, int _maxDimension, int& _dimension, float* _data)
{ {
std::stringstream stream(_string); const char* it = _start;
float temp; if (*it == ' ')
{
it++;
}
const char* end = _end;
const char* found;
_dimension = 0; _dimension = 0;
while(stream >> temp && _dimension < _maxDimension) while (_dimension < _maxDimension && it < end)
{ {
_data[_dimension] = temp; found = std::find(it, end, ' ');
_dimension++; _data[_dimension++] = std::atof(it);
it = found == end ? end : found + 1;
} }
} }
// Turns an index parameter string into a std::vector of IndexTuples, e.g. // Turns an index parameter string into a std::vector of IndexTuples, e.g.
// "1//2 3//4 5//6" --> { IndexTuple(1, -1, 2), IndexTuple(3, -1, 4), IndexTuple(5, -1, 6) } // "1//2 3//4 5//6" --> { IndexTuple(1, -1, 2), IndexTuple(3, -1, 4), IndexTuple(5, -1, 6) }
std::vector<IndexTuple> parseIndices(const std::string& _string) std::vector<IndexTuple> parseIndices(const char* _start, const char* _end)
{ {
std::vector<IndexTuple> indices; std::vector<IndexTuple> indices;
std::stringstream stream(_string); const char* it = _start;
if (*it == ' ') //skip starting whitespace
it++;
const char* vsit;
const char* vsend;
const char* foundSlash;
std::string vertexString; std::string vertexString;
while(stream >> vertexString) std::string component;
int componentIndex;
int index;
while (it < _end)
{ {
std::vector<std::string> componentsString = ACGL::Utils::StringHelpers::split(vertexString, '/', false); vsit = it;
vsend = std::find(it, _end, ' ');
componentIndex = 0;
IndexTuple indexTuple; IndexTuple indexTuple;
indices.push_back(indexTuple);
for(int i = 0; i < std::min<int>(componentsString.size(), 3); ++i) //process the string now meaning we split by /
while (vsit < vsend)
{ {
std::string& componentString = componentsString[i]; foundSlash = std::find(vsit, vsend, '/');
int index = atoi(componentString.c_str()); index = std::atoi(vsit);
if (componentIndex == 0) indices.back().position = index - 1;
if(i == 0) indexTuple.position = index-1; if (componentIndex == 1) indices.back().texCoord = index - 1;
if(i == 1) indexTuple.texCoord = index-1; if (componentIndex == 2) indices.back().normal = index - 1;
if(i == 2) indexTuple.normal = index-1; componentIndex++;
vsit = foundSlash == vsend ? vsend : foundSlash + 1;
} }
//indices.push_back(indexTuple);
indices.push_back(indexTuple); it = vsend == _end ? _end : vsend + 1;
} }
return indices; return indices;
} }
} }
...@@ -89,13 +102,14 @@ namespace OpenGL{ ...@@ -89,13 +102,14 @@ namespace OpenGL{
SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _computeNormals) SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _computeNormals)
{ {
SharedGeometryData data; SharedGeometryData data;
MemoryMappedFile mmf(_filename.c_str());
std::fstream file(_filename.c_str(), std::ios_base::in); if(mmf.errorCode())
if(!file.good())
{ {
error() << "could not open file " << _filename << std::endl; error() << "could not open file " << _filename << std::endl;
return data; return data;
} }
const char* pchBuf = mmf.data();
const char* pchEnd = pchBuf + mmf.length();
GLenum primitiveType = GL_INVALID_ENUM; GLenum primitiveType = GL_INVALID_ENUM;
bool hasTexCoords = false; bool hasTexCoords = false;
...@@ -111,27 +125,30 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -111,27 +125,30 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
std::vector<IndexTuple> indices; std::vector<IndexTuple> indices;
std::string keyword; std::string keyword;
std::string parameters; const char* parameters[2];
while(file.good()) while (pchBuf < pchEnd)
{ {
// Parse the current line // Parse the current line
const char* pchEOL = std::find(pchBuf, pchEnd, '\n');
// If the line starts with a #, it is a comment // If the line starts with a #, it is a comment
if(file.peek() == '#') if (*pchBuf == '#')
{ {
skipLine(file); pchBuf = pchEOL + 1;
continue; continue;
} }
// Otherwise, extract the first word and the remainder // Otherwise, extract the first word and the remainder
file >> keyword; const char* pchKey = std::find(pchBuf, pchEnd, ' ');
std::getline(file, parameters); keyword = std::string(pchBuf, pchKey);
parameters[0] = pchKey + 1;
parameters[1] = pchEOL;
if(keyword == "v") // vertex position if(keyword == "v") // vertex position
{ {
glm::vec4 position; glm::vec4 position;
int dimension; int dimension;
parseVector(parameters, 4, dimension, (float*)&position); parseVector(parameters[0], parameters[1], 4, dimension, (float*)&position);
if(dimension < 4) position.w = 1.0; if(dimension < 4) position.w = 1.0;
if(dimension < 3) if(dimension < 3)
...@@ -146,7 +163,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -146,7 +163,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
{ {
glm::vec3 texCoord; glm::vec3 texCoord;
int dimension; int dimension;
parseVector(parameters, 3, dimension, (float*)&texCoord); parseVector(parameters[0], parameters[1], 3, dimension, (float*)&texCoord);
if(texCoordDimension < 0) if(texCoordDimension < 0)
texCoordDimension = dimension; texCoordDimension = dimension;
...@@ -164,7 +181,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -164,7 +181,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
{ {
glm::vec3 normal; glm::vec3 normal;
int dimension; int dimension;
parseVector(parameters, 3, dimension, (float*)&normal); parseVector(parameters[0], parameters[1], 3, dimension, (float*)&normal);
if(dimension < 3) if(dimension < 3)
{ {
...@@ -186,7 +203,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -186,7 +203,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
return data; return data;
} }
std::vector<IndexTuple> pointIndices = parseIndices(parameters); std::vector<IndexTuple> pointIndices = parseIndices(parameters[0], parameters[1]);
// points are just added in order // points are just added in order
for(size_t i = 0; i < pointIndices.size(); ++i) for(size_t i = 0; i < pointIndices.size(); ++i)
{ {
...@@ -203,7 +220,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -203,7 +220,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
return data; return data;
} }
std::vector<IndexTuple> lineIndices = parseIndices(parameters); std::vector<IndexTuple> lineIndices = parseIndices(parameters[0], parameters[1]);
// add line segments for the line strip defined by the vertices // add line segments for the line strip defined by the vertices
for(size_t i = 0; i < lineIndices.size() - 1; ++i) for(size_t i = 0; i < lineIndices.size() - 1; ++i)
{ {
...@@ -221,7 +238,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -221,7 +238,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
return data; return data;
} }
std::vector<IndexTuple> faceIndices = parseIndices(parameters); std::vector<IndexTuple> faceIndices = parseIndices(parameters[0], parameters[1]);
// triangulate the polygon defined by the indices // triangulate the polygon defined by the indices
for(size_t i = 1; i < faceIndices.size() - 1; ++i) for(size_t i = 1; i < faceIndices.size() - 1; ++i)
{ {
...@@ -256,6 +273,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -256,6 +273,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
{ {
warning() << "unknown OBJ keyword ignored: " << keyword << std::endl; warning() << "unknown OBJ keyword ignored: " << keyword << std::endl;
} }
pchBuf = pchEOL + 1;
} }
if (!hasNormals && _computeNormals) { if (!hasNormals && _computeNormals) {
...@@ -349,7 +367,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c ...@@ -349,7 +367,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
data->setStrideSize(strideSize); data->setStrideSize(strideSize);
data->setSize(abDataElements * sizeof(GLfloat)); data->setSize(abDataElements * sizeof(GLfloat));
data->setData((GLubyte*)abData); data->setData((GLubyte*)abData);
std::exit(0);
return data; return data;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment