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 @@
#include <ACGL/OpenGL/Data/GeometryDataLoadStore.hh>
#include <ACGL/Math/Math.hh>
#include <ACGL/Utils/StringHelpers.hh>
#include <ACGL/Utils/MemoryMappedFile.hh>
#include <fstream>
#include <string>
......@@ -31,50 +32,62 @@ namespace
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
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);
float temp;
const char* it = _start;
if (*it == ' ')
{
it++;
}
const char* end = _end;
const char* found;
_dimension = 0;
while(stream >> temp && _dimension < _maxDimension)
while (_dimension < _maxDimension && it < end)
{
_data[_dimension] = temp;
_dimension++;
found = std::find(it, end, ' ');
_data[_dimension++] = std::atof(it);
it = found == end ? end : found + 1;
}
}
// 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) }
std::vector<IndexTuple> parseIndices(const std::string& _string)
std::vector<IndexTuple> parseIndices(const char* _start, const char* _end)
{
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;
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;
for(int i = 0; i < std::min<int>(componentsString.size(), 3); ++i)
indices.push_back(indexTuple);
//process the string now meaning we split by /
while (vsit < vsend)
{
std::string& componentString = componentsString[i];
int index = atoi(componentString.c_str());
if(i == 0) indexTuple.position = index-1;
if(i == 1) indexTuple.texCoord = index-1;
if(i == 2) indexTuple.normal = index-1;
foundSlash = std::find(vsit, vsend, '/');
index = std::atoi(vsit);
if (componentIndex == 0) indices.back().position = index - 1;
if (componentIndex == 1) indices.back().texCoord = index - 1;
if (componentIndex == 2) indices.back().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;
}
}
......@@ -89,13 +102,14 @@ namespace OpenGL{
SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _computeNormals)
{
SharedGeometryData data;
std::fstream file(_filename.c_str(), std::ios_base::in);
if(!file.good())
MemoryMappedFile mmf(_filename.c_str());
if(mmf.errorCode())
{
error() << "could not open file " << _filename << std::endl;
return data;
}
const char* pchBuf = mmf.data();
const char* pchEnd = pchBuf + mmf.length();
GLenum primitiveType = GL_INVALID_ENUM;
bool hasTexCoords = false;
......@@ -111,27 +125,30 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
std::vector<IndexTuple> indices;
std::string keyword;
std::string parameters;
while(file.good())
const char* parameters[2];
while (pchBuf < pchEnd)
{
// Parse the current line
const char* pchEOL = std::find(pchBuf, pchEnd, '\n');
// If the line starts with a #, it is a comment
if(file.peek() == '#')
if (*pchBuf == '#')
{
skipLine(file);
pchBuf = pchEOL + 1;
continue;
}
// Otherwise, extract the first word and the remainder
file >> keyword;
std::getline(file, parameters);
const char* pchKey = std::find(pchBuf, pchEnd, ' ');
keyword = std::string(pchBuf, pchKey);
parameters[0] = pchKey + 1;
parameters[1] = pchEOL;
if(keyword == "v") // vertex position
{
glm::vec4 position;
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 < 3)
......@@ -146,7 +163,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
{
glm::vec3 texCoord;
int dimension;
parseVector(parameters, 3, dimension, (float*)&texCoord);
parseVector(parameters[0], parameters[1], 3, dimension, (float*)&texCoord);
if(texCoordDimension < 0)
texCoordDimension = dimension;
......@@ -164,7 +181,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
{
glm::vec3 normal;
int dimension;
parseVector(parameters, 3, dimension, (float*)&normal);
parseVector(parameters[0], parameters[1], 3, dimension, (float*)&normal);
if(dimension < 3)
{
......@@ -186,7 +203,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
return data;
}
std::vector<IndexTuple> pointIndices = parseIndices(parameters);
std::vector<IndexTuple> pointIndices = parseIndices(parameters[0], parameters[1]);
// points are just added in order
for(size_t i = 0; i < pointIndices.size(); ++i)
{
......@@ -203,7 +220,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
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
for(size_t i = 0; i < lineIndices.size() - 1; ++i)
{
......@@ -221,7 +238,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
return data;
}
std::vector<IndexTuple> faceIndices = parseIndices(parameters);
std::vector<IndexTuple> faceIndices = parseIndices(parameters[0], parameters[1]);
// triangulate the polygon defined by the indices
for(size_t i = 1; i < faceIndices.size() - 1; ++i)
{
......@@ -256,6 +273,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
{
warning() << "unknown OBJ keyword ignored: " << keyword << std::endl;
}
pchBuf = pchEOL + 1;
}
if (!hasNormals && _computeNormals) {
......@@ -349,7 +367,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c
data->setStrideSize(strideSize);
data->setSize(abDataElements * sizeof(GLfloat));
data->setData((GLubyte*)abData);
std::exit(0);
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