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

pull/14/head
Alexander Gessler 2012-07-03 16:50:58 +02:00
parent 23914685f9
commit fd451f7ba6
3 changed files with 146 additions and 0 deletions

View File

@ -433,6 +433,7 @@ Object::~Object()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Geometry::Geometry(const Element& element, const std::string& name) Geometry::Geometry(const Element& element, const std::string& name)
: Object(element,name) : Object(element,name)
@ -440,6 +441,7 @@ Geometry::Geometry(const Element& element, const std::string& name)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Geometry::~Geometry() Geometry::~Geometry()
{ {
@ -454,8 +456,10 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
{ {
ReadPropertyTemplates(); ReadPropertyTemplates();
ReadObjects(); ReadObjects();
ReadConnections();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Document::~Document() Document::~Document()
{ {
@ -464,6 +468,7 @@ Document::~Document()
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Document::ReadObjects() void Document::ReadObjects()
{ {
@ -497,6 +502,7 @@ void Document::ReadObjects()
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Document::ReadPropertyTemplates() 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 } // !FBX
} // !Assimp } // !Assimp

View File

@ -333,6 +333,41 @@ private:
std::vector<unsigned int> mappings; 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 // XXX again, unique_ptr would be useful. shared_ptr is too
// bloated since the objects have a well-defined single owner // bloated since the objects have a well-defined single owner
// during their entire lifetime (Document). FBX files have // during their entire lifetime (Document). FBX files have
@ -341,6 +376,9 @@ private:
typedef std::map<uint64_t, LazyObject*> ObjectMap; typedef std::map<uint64_t, LazyObject*> ObjectMap;
typedef std::fbx_unordered_map<std::string, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap; 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 */ /** DOM root for a FBX file */
class Document class Document
{ {
@ -351,6 +389,8 @@ public:
public: public:
LazyObject* GetObject(uint64_t id) const;
const PropertyTemplateMap& Templates() const { const PropertyTemplateMap& Templates() const {
return templates; return templates;
} }
@ -363,10 +403,19 @@ public:
return settings; return settings;
} }
const ConnectionMap& ConnectionsBySource() const {
return src_connections;
}
const ConnectionMap& ConnectionsByDestination() const {
return dest_connections;
}
private: private:
void ReadObjects(); void ReadObjects();
void ReadPropertyTemplates(); void ReadPropertyTemplates();
void ReadConnections();
private: private:
@ -376,6 +425,8 @@ private:
const Parser& parser; const Parser& parser;
PropertyTemplateMap templates; PropertyTemplateMap templates;
ConnectionMap src_connections;
ConnectionMap dest_connections;
}; };
} }

View File

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