From e821988c648cd4ac91568b4ad9b447c1a9d81552 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Thu, 28 Jun 2012 16:51:55 +0200 Subject: [PATCH] - fbx: also read vertex colors, tangents and binormals. --- code/FBXDocument.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++- code/FBXDocument.h | 19 +++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index 014dd3016..d49a2a17d 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -204,6 +204,35 @@ void ReadVectorDataArray(std::vector& out, const Element& el) } +// ------------------------------------------------------------------------------------------------ +// read an array of color4 tuples +void ReadVectorDataArray(std::vector& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ReadVectorDataArray() above + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + if (a.Tokens().size() % 4 != 0) { + DOMError("number of floats is not a multiple of four (4)",&el); + } + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + aiColor4D v; + v.r = ParseTokenAsFloat(**it++); + v.g = ParseTokenAsFloat(**it++); + v.b = ParseTokenAsFloat(**it++); + v.a = ParseTokenAsFloat(**it++); + + out.push_back(v); + } +} + + // ------------------------------------------------------------------------------------------------ // read an array of float2 tuples void ReadVectorDataArray(std::vector& out, const Element& el) @@ -481,9 +510,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop if (type == "LayerElementUV") { if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { - FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum UV number exceeded: ") + FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" ); - return; } @@ -508,6 +536,21 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop else if (type == "LayerElementNormal") { ReadVertexDataNormals(normals,source,MappingInformationType,ReferenceInformationType); } + else if (type == "LayerElementTangent") { + ReadVertexDataTangents(tangents,source,MappingInformationType,ReferenceInformationType); + } + else if (type == "LayerElementBinormal") { + ReadVertexDataBinormals(binormals,source,MappingInformationType,ReferenceInformationType); + } + else if (type == "LayerElementColor") { + if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) { + FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") + << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" ); + return; + } + + ReadVertexDataColors(colors[index],source,MappingInformationType,ReferenceInformationType); + } } // ------------------------------------------------------------------------------------------------ @@ -622,6 +665,51 @@ void MeshGeometry::ReadVertexDataUV(std::vector& uv_out, const Scope } +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataColors(std::vector& colors_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(colors_out,source,MappingInformationType,ReferenceInformationType, + "Color", + "ColorIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataTangents(std::vector& tangents_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType, + "Tangent", + "TangentIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataBinormals(std::vector& binormals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, + "Binormal", + "BinormalIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + // ------------------------------------------------------------------------------------------------ Document::Document(const Parser& parser) : parser(parser) diff --git a/code/FBXDocument.h b/code/FBXDocument.h index ef3d39596..cb6192f70 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -136,6 +136,12 @@ public: const std::vector& GetTangents() const { return tangents; } + + /** Get a list of all vertex binormals or an empty array + * if no binormals are specified */ + const std::vector& GetBinormals() const { + return binormals; + } /** Return list of faces - each entry denotes a face and specifies * how many vertices it has. Vertices are taken from the @@ -180,6 +186,18 @@ private: const std::string& MappingInformationType, const std::string& ReferenceInformationType); + void ReadVertexDataColors(std::vector& colors_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataTangents(std::vector& tangents_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataBinormals(std::vector& binormals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + private: // cached data arrays @@ -187,6 +205,7 @@ private: std::vector vertices; std::vector faces; std::vector tangents; + std::vector binormals; std::vector normals; std::vector uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS]; std::vector colors[AI_MAX_NUMBER_OF_COLOR_SETS];