From fd451f7ba6a4f20f8deb6e5f6c0217a3ca092087 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Tue, 3 Jul 2012 16:50:58 +0200 Subject: [PATCH] - fbx: read object-object and object-property connections. --- code/FBXDocument.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++ code/FBXDocument.h | 51 ++++++++++++++++++++++++ code/FBXMaterial.cpp | 1 + 3 files changed, 146 insertions(+) diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index cf3410c49..e66de9c58 100644 --- a/code/FBXDocument.cpp +++ b/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 diff --git a/code/FBXDocument.h b/code/FBXDocument.h index 5b99c1a94..2ad53ae94 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -333,6 +333,41 @@ private: std::vector 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 ObjectMap; typedef std::fbx_unordered_map > PropertyTemplateMap; + + typedef std::multimap 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; }; } diff --git a/code/FBXMaterial.cpp b/code/FBXMaterial.cpp index bbb00deba..bf2edded0 100644 --- a/code/FBXMaterial.cpp +++ b/code/FBXMaterial.cpp @@ -100,6 +100,7 @@ Material::~Material() { } + // ------------------------------------------------------------------------------------------------ Texture::Texture(const Element& element, const Document& doc, const std::string& name) : Object(element,name)