- 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.
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)
{
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
const Scope& GetRequiredScope(const Element& el, const Element* element = NULL)
const Scope& GetRequiredScope(const Element& el)
{
const Scope* const s = el.Compound();
if(!s) {
DOMError("expected compound scope",element);
DOMError("expected compound scope",&el);
}
return *s;
@ -90,11 +99,11 @@ namespace {
// ------------------------------------------------------------------------------------------------
// 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();
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];
@ -189,12 +198,12 @@ namespace FBX {
// ------------------------------------------------------------------------------------------------
// 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 uint64_t i = ParseTokenAsID(t,err);
if(err) {
DOMError(err,element);
DOMError(err,t);
}
return i;
}
@ -202,12 +211,12 @@ uint64_t ParseTokenAsID(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------
// 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 size_t i = ParseTokenAsDim(t,err);
if(err) {
DOMError(err,element);
DOMError(err,t);
}
return i;
}
@ -215,12 +224,12 @@ size_t ParseTokenAsDim(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsFloat() with DOMError handling
float ParseTokenAsFloat(const Token& t, const Element* element = NULL)
float ParseTokenAsFloat(const Token& t)
{
const char* err;
const float i = ParseTokenAsFloat(t,err);
if(err) {
DOMError(err,element);
DOMError(err,t);
}
return i;
}
@ -228,12 +237,12 @@ float ParseTokenAsFloat(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt() with DOMError handling
int ParseTokenAsInt(const Token& t, const Element* element = NULL)
int ParseTokenAsInt(const Token& t)
{
const char* err;
const int i = ParseTokenAsInt(t,err);
if(err) {
DOMError(err,element);
DOMError(err,t);
}
return i;
}
@ -241,12 +250,12 @@ int ParseTokenAsInt(const Token& t, const Element* element = NULL)
// ------------------------------------------------------------------------------------------------
// 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 std::string& i = ParseTokenAsString(t,err);
if(err) {
DOMError(err,element);
DOMError(err,t);
}
return i;
}
@ -371,20 +380,8 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name)
}
if(index == 0) {
const Scope& layer = GetRequiredScope(*(*it).second,&element);
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);
}
const Scope& layer = GetRequiredScope(*(*it).second);
ReadLayer(layer);
}
else {
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()
{

View File

@ -146,8 +146,8 @@ public:
/** Get a UV coordinate slot, returns an empty array if
* the requested slot does not exist. */
const std::vector<aiVector3D>& GetTextureCoords(unsigned int index) const {
static const std::vector<aiVector3D> empty;
const std::vector<aiVector2D>& GetTextureCoords(unsigned int index) const {
static const std::vector<aiVector2D> empty;
return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
}
@ -166,6 +166,12 @@ 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:
// cached data arrays
@ -174,7 +180,7 @@ private:
std::vector<unsigned int> faces;
std::vector<aiVector3D> tangents;
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];
};