diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index 4a895d4a8..a34a7c191 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -64,7 +64,8 @@ namespace { // ------------------------------------------------------------------------------------------------ // extract a required element from a scope, abort if the element cannot be found - const Element& GetFixedElementFromScope(const Scope& sc, const std::string& index, const Element* element = NULL) { + const Element& GetFixedElementFromScope(const Scope& sc, const std::string& index, const Element* element = NULL) + { const Element* el = sc[index]; if(!el) { DOMError("did not find required element \"" + index + "\"",element); @@ -72,6 +73,88 @@ namespace { return *el; } + + // ------------------------------------------------------------------------------------------------ + // read an array of float3 tuples + void ReadVectorDataArray(std::vector& out, const Element& el) + { + out.clear(); + const TokenList& tok = el.Tokens(); + + const char* err; + const size_t dim = ParseTokenAsDim(*tok[0],err); + if(err) { + DOMError(err,&el); + } + + // may throw bad_alloc if the input is rubbish, but this need + // not to be prevented - importing would fail but we wouldn't + // crash since assimp handles this case properly. + out.reserve(dim); + + const Scope* const scope = el.Compound(); + if(!scope) { + DOMError("expected vector3 data",&el); + } + + const Element& a = GetFixedElementFromScope(*scope,"a",&el); + if (a.Tokens().size() % 3 != 0) { + DOMError("number of floats is not a multiple of three",&el); + } + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + aiVector3D v; + v.x = ParseTokenAsFloat(**it++,err); + if(err) { + DOMError(err,&el); + } + + v.y = ParseTokenAsFloat(**it++,err); + if(err) { + DOMError(err,&el); + } + + v.z = ParseTokenAsFloat(**it++,err); + if(err) { + DOMError(err,&el); + } + + out.push_back(v); + } + } + + + // ------------------------------------------------------------------------------------------------ + // read an array of ints + void ReadIntDataArray(std::vector& out, const Element& el) + { + out.clear(); + const TokenList& tok = el.Tokens(); + + const char* err; + const size_t dim = ParseTokenAsDim(*tok[0],err); + if(err) { + DOMError(err,&el); + } + + // see notes in ReadVectorDataArray() + out.reserve(dim); + + const Scope* const scope = el.Compound(); + if(!scope) { + DOMError("expected int data block",&el); + } + + const Element& a = GetFixedElementFromScope(*scope,"a",&el); + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + const int ival = ParseTokenAsInt(**it++,err); + if(err) { + DOMError(err,&el); + } + + out.push_back(ival); + } + } + } namespace Assimp { @@ -180,6 +263,11 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name) const ElementCollection& LayerElementMaterial = sc->GetCollection("LayerElementMaterial"); const ElementCollection& LayerElementUV = sc->GetCollection("LayerElementUV"); const ElementCollection& LayerElementNormal = sc->GetCollection("LayerElementNormal"); + + ReadVectorDataArray(vertices,Vertices); + + std::vector tempFaces; + ReadIntDataArray(tempFaces,PolygonVertexIndex); } // ------------------------------------------------------------------------------------------------ diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index 5918177b1..eca0f6609 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -233,33 +233,33 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) // ------------------------------------------------------------------------------------------------ -uint64_t ParseTokenAsDim(const Token& t, const char*& err_out) +size_t ParseTokenAsDim(const Token& t, const char*& err_out) { // same as ID parsing, except there is a trailing asterisk err_out = NULL; if (t.Type() != TokenType_DATA) { err_out = "expected TOK_DATA token"; - return 0L; + return 0; } if(*t.begin() != '*') { err_out = "expected asterisk before array dimension"; - return 0L; + return 0; } // XXX: should use size_t here unsigned int length = static_cast(t.end() - t.begin()); if(length == 0) { err_out = "expected valid integer number after asterisk"; - return 0L; + return 0; } const char* out; - const uint64_t id = strtoul10_64(t.begin() + 1,&out,&length); + const size_t id = static_cast(strtoul10_64(t.begin() + 1,&out,&length)); if (out != t.end()) { err_out = "failed to parse ID"; - return 0L; + return 0; } return id; diff --git a/code/FBXParser.h b/code/FBXParser.h index 385028954..9a708cabe 100644 --- a/code/FBXParser.h +++ b/code/FBXParser.h @@ -193,7 +193,7 @@ private: /* token parsing - this happens when building the DOM out of the parse-tree*/ uint64_t ParseTokenAsID(const Token& t, const char*& err_out); -uint64_t ParseTokenAsDim(const Token& t, const char*& err_out); +size_t ParseTokenAsDim(const Token& t, const char*& err_out); float ParseTokenAsFloat(const Token& t, const char*& err_out); int ParseTokenAsInt(const Token& t, const char*& err_out);