Просмотр исходного кода

- fbx: add some utility functions to parse tokens to values and to handle errors automatically.

Alexander Gessler 13 лет назад
Родитель
Сommit
f354d8d7c7
1 измененных файлов с 108 добавлено и 10 удалено
  1. 108 10
      code/FBXDocument.cpp

+ 108 - 10
code/FBXDocument.cpp

@@ -65,7 +65,7 @@ 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& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL) 
 	{
 		const Element* el = sc[index];
 		if(!el) {
@@ -75,6 +75,32 @@ namespace {
 	}
 
 
+	// ------------------------------------------------------------------------------------------------
+	// extract required compound scope
+	const Scope& GetRequiredScope(const Element& el, const Element* element = NULL)
+	{
+		const Scope* const s = el.Compound();
+		if(!s) {
+			DOMError("expected compound scope",element);
+		}
+
+		return *s;
+	}
+
+
+	// ------------------------------------------------------------------------------------------------
+	// get token at a particular index
+	const Token& GetRequiredToken(const Element& el, unsigned int index, const Element* element = NULL)
+	{
+		const TokenList& t = el.Tokens();
+		if(t.size() > index) {
+			DOMError(Formatter::format( "missing token at index " ) << index,element);
+		}
+
+		return *t[index];
+	}
+
+
 	// ------------------------------------------------------------------------------------------------
 	// read an array of float3 tuples
 	void ReadVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
@@ -98,7 +124,7 @@ namespace {
 			DOMError("expected vector3 data",&el);
 		}
 
-		const Element& a = GetFixedElementFromScope(*scope,"a",&el);
+		const Element& a = GetRequiredElement(*scope,"a",&el);
 		if (a.Tokens().size() % 3 != 0) {
 			DOMError("number of floats is not a multiple of three",&el);
 		}
@@ -145,7 +171,7 @@ namespace {
 			DOMError("expected int data block",&el);
 		}
 
-		const Element& a = GetFixedElementFromScope(*scope,"a",&el);
+		const Element& a = GetRequiredElement(*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) {
@@ -161,6 +187,70 @@ namespace {
 namespace Assimp {
 namespace FBX {
 
+// ------------------------------------------------------------------------------------------------
+// wrapper around ParseTokenAsID() with DOMError handling
+uint64_t ParseTokenAsID(const Token& t, const Element* element = NULL) 
+{
+	const char* err;
+	const uint64_t i = ParseTokenAsID(t,err);
+	if(err) {
+		DOMError(err,element);
+	}
+	return i;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// wrapper around ParseTokenAsDim() with DOMError handling
+size_t ParseTokenAsDim(const Token& t, const Element* element = NULL)
+{
+	const char* err;
+	const size_t i = ParseTokenAsDim(t,err);
+	if(err) {
+		DOMError(err,element);
+	}
+	return i;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// wrapper around ParseTokenAsFloat() with DOMError handling
+float ParseTokenAsFloat(const Token& t, const Element* element = NULL)
+{
+	const char* err;
+	const float i = ParseTokenAsFloat(t,err);
+	if(err) {
+		DOMError(err,element);
+	}
+	return i;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// wrapper around ParseTokenAsInt() with DOMError handling
+int ParseTokenAsInt(const Token& t, const Element* element = NULL)
+{
+	const char* err;
+	const int i = ParseTokenAsInt(t,err);
+	if(err) {
+		DOMError(err,element);
+	}
+	return i;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// wrapper around ParseTokenAsString() with DOMError handling
+std::string ParseTokenAsString(const Token& t, const Element* element = NULL)
+{
+	const char* err;
+	const std::string& i = ParseTokenAsString(t,err);
+	if(err) {
+		DOMError(err,element);
+	}
+	return i;
+}
+
 // ------------------------------------------------------------------------------------------------
 LazyObject::LazyObject(const Element& element)
 : element(element)
@@ -256,8 +346,8 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name)
 	}
 
 	// must have Mesh elements:
-	const Element& Vertices = GetFixedElementFromScope(*sc,"Vertices",&element);
-	const Element& PolygonVertexIndex = GetFixedElementFromScope(*sc,"PolygonVertexIndex",&element);
+	const Element& Vertices = GetRequiredElement(*sc,"Vertices",&element);
+	const Element& PolygonVertexIndex = GetRequiredElement(*sc,"PolygonVertexIndex",&element);
 
 	// optional Mesh elements:
 	const ElementCollection& Layer = sc->GetCollection("Layer");
@@ -281,12 +371,20 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name)
 		}
 
 		if(index == 0) {
-			const Scope* const layer = (*it).second->Compound();
-			if (layer) {
-				DOMError("expected layer scope",&element);
-			}
+			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);
 
-			// XXX read layer data
+				const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0),&Type);
+				const std::string& typedIndex = ParseTokenAsString(GetRequiredToken(TypedIndex,0),&Type);
+
+
+			}
 		}
 		else {
 			FBXImporter::LogWarn("ignoring additional geometry layers");