- fbx: work on reading vertex data.

pull/14/head
Alexander Gessler 2012-06-27 23:02:00 +02:00
parent f354d8d7c7
commit f9e310edfb
2 changed files with 95 additions and 32 deletions

View File

@ -57,9 +57,18 @@ namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError. // signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError.
void DOMError(const std::string& message, const Token& token)
{
throw DeadlyImportError(Util::AddTokenText("FBX-DOM",message,&token));
}
// ------------------------------------------------------------------------------------------------
void DOMError(const std::string& message, const Element* element = NULL) void DOMError(const std::string& message, const Element* element = NULL)
{ {
throw DeadlyImportError(element ? Util::AddTokenText("FBX-DOM",message,&element->KeyToken()) : ("FBX-DOM " + message)); if(element) {
DOMError(message,element->KeyToken());
}
throw DeadlyImportError("FBX-DOM " + message);
} }
@ -77,11 +86,11 @@ namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// extract required compound scope // extract required compound scope
const Scope& GetRequiredScope(const Element& el, const Element* element = NULL) const Scope& GetRequiredScope(const Element& el)
{ {
const Scope* const s = el.Compound(); const Scope* const s = el.Compound();
if(!s) { if(!s) {
DOMError("expected compound scope",element); DOMError("expected compound scope",&el);
} }
return *s; return *s;
@ -90,11 +99,11 @@ namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// get token at a particular index // get token at a particular index
const Token& GetRequiredToken(const Element& el, unsigned int index, const Element* element = NULL) const Token& GetRequiredToken(const Element& el, unsigned int index)
{ {
const TokenList& t = el.Tokens(); const TokenList& t = el.Tokens();
if(t.size() > index) { if(t.size() > index) {
DOMError(Formatter::format( "missing token at index " ) << index,element); DOMError(Formatter::format( "missing token at index " ) << index,&el);
} }
return *t[index]; return *t[index];
@ -189,12 +198,12 @@ namespace FBX {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsID() with DOMError handling // wrapper around ParseTokenAsID() with DOMError handling
uint64_t ParseTokenAsID(const Token& t, const Element* element = NULL) uint64_t ParseTokenAsID(const Token& t)
{ {
const char* err; const char* err;
const uint64_t i = ParseTokenAsID(t,err); const uint64_t i = ParseTokenAsID(t,err);
if(err) { if(err) {
DOMError(err,element); DOMError(err,t);
} }
return i; return i;
} }
@ -202,12 +211,12 @@ uint64_t ParseTokenAsID(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsDim() with DOMError handling // wrapper around ParseTokenAsDim() with DOMError handling
size_t ParseTokenAsDim(const Token& t, const Element* element = NULL) size_t ParseTokenAsDim(const Token& t)
{ {
const char* err; const char* err;
const size_t i = ParseTokenAsDim(t,err); const size_t i = ParseTokenAsDim(t,err);
if(err) { if(err) {
DOMError(err,element); DOMError(err,t);
} }
return i; return i;
} }
@ -215,12 +224,12 @@ size_t ParseTokenAsDim(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsFloat() with DOMError handling // wrapper around ParseTokenAsFloat() with DOMError handling
float ParseTokenAsFloat(const Token& t, const Element* element = NULL) float ParseTokenAsFloat(const Token& t)
{ {
const char* err; const char* err;
const float i = ParseTokenAsFloat(t,err); const float i = ParseTokenAsFloat(t,err);
if(err) { if(err) {
DOMError(err,element); DOMError(err,t);
} }
return i; return i;
} }
@ -228,12 +237,12 @@ float ParseTokenAsFloat(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt() with DOMError handling // wrapper around ParseTokenAsInt() with DOMError handling
int ParseTokenAsInt(const Token& t, const Element* element = NULL) int ParseTokenAsInt(const Token& t)
{ {
const char* err; const char* err;
const int i = ParseTokenAsInt(t,err); const int i = ParseTokenAsInt(t,err);
if(err) { if(err) {
DOMError(err,element); DOMError(err,t);
} }
return i; return i;
} }
@ -241,12 +250,12 @@ int ParseTokenAsInt(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsString() with DOMError handling // wrapper around ParseTokenAsString() with DOMError handling
std::string ParseTokenAsString(const Token& t, const Element* element = NULL) std::string ParseTokenAsString(const Token& t)
{ {
const char* err; const char* err;
const std::string& i = ParseTokenAsString(t,err); const std::string& i = ParseTokenAsString(t,err);
if(err) { if(err) {
DOMError(err,element); DOMError(err,t);
} }
return i; return i;
} }
@ -371,20 +380,8 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name)
} }
if(index == 0) { if(index == 0) {
const Scope& layer = GetRequiredScope(*(*it).second,&element); const Scope& layer = GetRequiredScope(*(*it).second);
ReadLayer(layer);
const ElementCollection& LayerElement = sc->GetCollection("LayerElement");
for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) {
const Scope& elayer = GetRequiredScope(*(*eit).second,&element);
const Element& Type = GetRequiredElement(elayer,"Type",&element);
const Element& TypedIndex = GetRequiredElement(elayer,"TypedIndex",&element);
const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0),&Type);
const std::string& typedIndex = ParseTokenAsString(GetRequiredToken(TypedIndex,0),&Type);
}
} }
else { else {
FBXImporter::LogWarn("ignoring additional geometry layers"); FBXImporter::LogWarn("ignoring additional geometry layers");
@ -392,6 +389,66 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name)
} }
} }
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadLayer(const Scope& layer)
{
const ElementCollection& LayerElement = layer.GetCollection("LayerElement");
for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) {
const Scope& elayer = GetRequiredScope(*(*eit).second);
ReadLayerElement(elayer);
}
}
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadLayerElement(const Scope& layerElement)
{
const Element& Type = GetRequiredElement(layerElement,"Type");
const Element& TypedIndex = GetRequiredElement(layerElement,"TypedIndex");
const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0));
const int typedIndex = ParseTokenAsInt(GetRequiredToken(TypedIndex,0));
const Scope& top = GetRequiredScope(element);
const ElementCollection candidates = top.GetCollection(type);
for (ElementMap::const_iterator it = candidates.first; it != candidates.second; ++it) {
const int index = ParseTokenAsInt(GetRequiredToken(*(*it).second,0));
if(index == typedIndex) {
ReadVertexData(type,typedIndex,GetRequiredScope(*(*it).second));
return;
}
}
FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ")
<< type << ", index: " << typedIndex);
}
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source)
{
const std::string& MappingInformationType = ParseTokenAsString(GetRequiredToken(GetRequiredElement(source,"MappingInformationType"),0));
const std::string& ReferenceInformationType = ParseTokenAsString(GetRequiredToken(GetRequiredElement(source,"ReferenceInformationType"),0));
if (type == "LayerElementUV") {
if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum UV number exceeded: ")
<< index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" );
return;
}
const std::vector<aiVector2D>& uv = uvs[index];
}
else if (type == "LayerElementMaterial") {
}
else if (type == "LayerElementNormal") {
ReadVectorDataArray(normals,GetRequiredElement(source,"Normals"));
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
MeshGeometry::~MeshGeometry() MeshGeometry::~MeshGeometry()
{ {

View File

@ -146,8 +146,8 @@ public:
/** Get a UV coordinate slot, returns an empty array if /** Get a UV coordinate slot, returns an empty array if
* the requested slot does not exist. */ * the requested slot does not exist. */
const std::vector<aiVector3D>& GetTextureCoords(unsigned int index) const { const std::vector<aiVector2D>& GetTextureCoords(unsigned int index) const {
static const std::vector<aiVector3D> empty; static const std::vector<aiVector2D> empty;
return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index]; return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
} }
@ -166,6 +166,12 @@ public:
public: public:
private:
void ReadLayer(const Scope& layer);
void ReadLayerElement(const Scope& layerElement);
void ReadVertexData(const std::string& type, int index, const Scope& source);
private: private:
// cached data arrays // cached data arrays
@ -174,7 +180,7 @@ private:
std::vector<unsigned int> faces; std::vector<unsigned int> faces;
std::vector<aiVector3D> tangents; std::vector<aiVector3D> tangents;
std::vector<aiVector3D> normals; std::vector<aiVector3D> normals;
std::vector<aiVector3D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS]; std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS];
std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS]; std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS];
}; };