Browse Source

- fbx: read object-object and object-property connections.

Alexander Gessler 13 years ago
parent
commit
fd451f7ba6
3 changed files with 146 additions and 0 deletions
  1. 94 0
      code/FBXDocument.cpp
  2. 51 0
      code/FBXDocument.h
  3. 1 0
      code/FBXMaterial.cpp

+ 94 - 0
code/FBXDocument.cpp

@@ -433,6 +433,7 @@ Object::~Object()
 
 }
 
+
 // ------------------------------------------------------------------------------------------------
 Geometry::Geometry(const Element& element, const std::string& name)
 : Object(element,name)
@@ -440,6 +441,7 @@ Geometry::Geometry(const Element& element, const std::string& name)
 
 }
 
+
 // ------------------------------------------------------------------------------------------------
 Geometry::~Geometry()
 {
@@ -454,8 +456,10 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
 {
 	ReadPropertyTemplates();
 	ReadObjects();
+	ReadConnections();
 }
 
+
 // ------------------------------------------------------------------------------------------------
 Document::~Document()
 {
@@ -464,6 +468,7 @@ Document::~Document()
 	}
 }
 
+
 // ------------------------------------------------------------------------------------------------
 void Document::ReadObjects()
 {
@@ -497,6 +502,7 @@ void Document::ReadObjects()
 	}
 }
 
+
 // ------------------------------------------------------------------------------------------------
 void Document::ReadPropertyTemplates()
 {
@@ -555,6 +561,94 @@ void Document::ReadPropertyTemplates()
 	}
 }
 
+
+
+// ------------------------------------------------------------------------------------------------
+void Document::ReadConnections()
+{
+	const Scope& sc = parser.GetRootScope();
+	// read property templates from "Definitions" section
+	const Element* const econns = sc["Connections"];
+	if(!econns || !econns->Compound()) {
+		DOMError("no Connections dictionary found");
+	}
+
+	uint64_t insertionOrder = 0l;
+
+	const Scope& sconns = *econns->Compound();
+	const ElementCollection conns = sconns.GetCollection("C");
+	for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) {
+		const Element& el = *(*it).second;
+		const std::string& type = ParseTokenAsString(GetRequiredToken(el,0));
+		const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1));
+		const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2));
+
+		// OO = object-object connection
+		// OP = object-property connection, in which case the destination property follows the object ID
+		const std::string& prop = (type == "OP" ? ParseTokenAsString(GetRequiredToken(el,3)) : "");
+
+		if(objects.find(src) == objects.end()) {
+			DOMWarning("source object for connection does not exist",&el);
+			continue;
+		}
+
+		if(objects.find(dest) == objects.end()) {
+			DOMWarning("destination object for connection does not exist",&el);
+			continue;
+		}
+
+		// add new connection
+		const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this);
+		src_connections.insert(ConnectionMap::value_type(src,c));  
+		dest_connections.insert(ConnectionMap::value_type(dest,c));  
+	}
+}
+
+
+// ------------------------------------------------------------------------------------------------
+LazyObject* Document::GetObject(uint64_t id) const
+{
+	ObjectMap::const_iterator it = objects.find(id);
+	return it == objects.end() ? NULL : (*it).second;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+Connection::Connection(uint64_t insertionOrder,  uint64_t src, uint64_t dest, const std::string& prop, const Document& doc)
+: insertionOrder(insertionOrder)
+, src(src)
+, dest(dest)
+, prop(prop)
+, doc(doc)
+{
+	ai_assert(doc.Objects().find(src) != doc.Objects().end());
+	ai_assert(doc.Objects().find(dest) != doc.Objects().end());
+}
+
+
+// ------------------------------------------------------------------------------------------------
+Connection::~Connection()
+{
+
+}
+
+
+// ------------------------------------------------------------------------------------------------
+const Object* Connection::SourceObject() const
+{
+	LazyObject* const lazy = doc.GetObject(src);
+	ai_assert(lazy);
+	return lazy->Get();
+}
+
+// ------------------------------------------------------------------------------------------------
+const Object* Connection::DestinationObject() const
+{
+	LazyObject* const lazy = doc.GetObject(dest);
+	ai_assert(lazy);
+	return lazy->Get();
+}
+
 } // !FBX
 } // !Assimp
 

+ 51 - 0
code/FBXDocument.h

@@ -333,6 +333,41 @@ private:
 	std::vector<unsigned int> mappings;
 };
 
+
+/** Represents a link between two FBX objects. */
+class Connection
+{
+public:
+
+	Connection(uint64_t insertionOrder,  uint64_t src, uint64_t dest, const std::string& prop, const Document& doc);
+	~Connection();
+
+	// note: a connection ensures that the source and dest objects exist, but
+	// not that they have DOM representations, so the return value of one of
+	// these functions can still be NULL.
+	const Object* SourceObject() const;
+	const Object* DestinationObject() const;
+
+	// return the name of the property the connection is attached to.
+	// this is an empty string for object to object (OO) connections.
+	const std::string& PropertyName() const {
+		return prop;
+	}
+
+	uint64_t InsertionOrder() const {
+		return insertionOrder;
+	}
+
+public:
+
+	uint64_t insertionOrder;
+	const std::string& prop;
+
+	uint64_t src, dest;
+	const Document& doc;
+};
+
+
 	// XXX again, unique_ptr would be useful. shared_ptr is too
 	// bloated since the objects have a well-defined single owner
 	// during their entire lifetime (Document). FBX files have
@@ -341,6 +376,9 @@ private:
 	typedef std::map<uint64_t, LazyObject*> ObjectMap; 
 	typedef std::fbx_unordered_map<std::string, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap;
 
+
+	typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
+
 /** DOM root for a FBX file */
 class Document 
 {
@@ -351,6 +389,8 @@ public:
 
 public:
 
+	LazyObject* GetObject(uint64_t id) const;
+
 	const PropertyTemplateMap& Templates() const {
 		return templates;
 	}
@@ -363,10 +403,19 @@ public:
 		return settings;
 	}
 
+	const ConnectionMap& ConnectionsBySource() const {
+		return src_connections;
+	}
+
+	const ConnectionMap& ConnectionsByDestination() const {
+		return dest_connections;
+	}
+
 private:
 
 	void ReadObjects();
 	void ReadPropertyTemplates();
+	void ReadConnections();
 
 private:
 
@@ -376,6 +425,8 @@ private:
 	const Parser& parser;
 
 	PropertyTemplateMap templates;
+	ConnectionMap src_connections;
+	ConnectionMap dest_connections;
 };
 
 }

+ 1 - 0
code/FBXMaterial.cpp

@@ -100,6 +100,7 @@ Material::~Material()
 {
 }
 
+
 // ------------------------------------------------------------------------------------------------
 Texture::Texture(const Element& element, const Document& doc, const std::string& name)
 : Object(element,name)