diff --git a/code/FBXDeformer.cpp b/code/FBXDeformer.cpp index 0cfcde65a..561e9ebf4 100644 --- a/code/FBXDeformer.cpp +++ b/code/FBXDeformer.cpp @@ -78,6 +78,7 @@ Deformer::~Deformer() // ------------------------------------------------------------------------------------------------ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name) : Deformer(id,element,doc,name) +, node() { const Scope& sc = GetRequiredScope(element); @@ -91,6 +92,20 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const ReadVectorDataArray(indices,Indexes); ReadVectorDataArray(weights,Weights); + + // read assigned node + const std::vector& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); + BOOST_FOREACH(const Connection* con, conns) { + const Model* const mod = ProcessSimpleConnection(*con, false, "Model -> Cluster", element); + if(mod) { + node = mod; + break; + } + } + + if (!node) { + DOMError("failed to read target Node for Cluster",&element); + } } @@ -112,31 +127,17 @@ Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std:: accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0)); } - const char* const arr[] = {"Deformer"}; - // resolve assigned clusters - const std::vector& conns = doc.GetConnectionsByDestinationSequenced(ID(),arr, 1); + const std::vector& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); clusters.reserve(conns.size()); BOOST_FOREACH(const Connection* con, conns) { - // Cluster -> Skin links should be object-object connections - if (con->PropertyName().length()) { - continue; - } - - const Object* const ob = con->SourceObject(); - if(!ob) { - DOMWarning("failed to read source object for incoming Skin link, ignoring",&element); - continue; - } - - const Cluster* const cluster = dynamic_cast(ob); + const Cluster* const cluster = ProcessSimpleConnection(*con, false, "Cluster -> Skin", element); if(cluster) { clusters.push_back(cluster); continue; } - } } diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index a682d09c9..d02931bbb 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -579,21 +579,6 @@ Object::~Object() } -// ------------------------------------------------------------------------------------------------ -Geometry::Geometry(uint64_t id, const Element& element, const std::string& name) -: Object(id, element,name) -{ - -} - - -// ------------------------------------------------------------------------------------------------ -Geometry::~Geometry() -{ - -} - - // ------------------------------------------------------------------------------------------------ Document::Document(const Parser& parser, const ImportSettings& settings) : settings(settings) diff --git a/code/FBXDocument.h b/code/FBXDocument.h index bce541694..1d3bfc1ae 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -60,6 +60,14 @@ namespace FBX { class Material; class Geometry; + class AnimationCurve; + class AnimationCurveNode; + class AnimationLayer; + class AnimationStack; + + class Skin; + class Cluster; + /** Represents a delay-parsed FBX objects. Many objects in the scene * are not needed by assimp, so it makes no sense to parse them @@ -363,8 +371,19 @@ class Geometry : public Object { public: - Geometry(uint64_t id, const Element& element, const std::string& name); + Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc); ~Geometry(); + +public: + + /** Get the Skin attached to this geometry or NULL */ + const Skin* const DeformerSkin() const { + return skin; + } + +private: + + const Skin* skin; }; @@ -695,6 +714,10 @@ public: return transformLink; } + const Model* const TargetNode() const { + return node; + } + private: WeightList weights; @@ -702,6 +725,8 @@ private: aiMatrix4x4 transform; aiMatrix4x4 transformLink; + + const Model* node; }; diff --git a/code/FBXDocumentUtil.h b/code/FBXDocumentUtil.h index 35dbf7d22..8e395bfca 100644 --- a/code/FBXDocumentUtil.h +++ b/code/FBXDocumentUtil.h @@ -108,6 +108,50 @@ boost::shared_ptr GetPropertyTable(const Document& doc, const Element &element, const Scope& sc); + + + +// ------------------------------------------------------------------------------------------------ +template +inline const T* ProcessSimpleConnection(const Connection& con, + bool is_object_property_conn, + const char* name, + const Element& element, + const char** propNameOut = NULL) +{ + if (is_object_property_conn && con.PropertyName().length()) { + DOMWarning("expected incoming " + std::string(name) + + " link to be an object-object connection, ignoring", + &element + ); + return NULL; + } + else if (!is_object_property_conn && !con.PropertyName().length()) { + DOMWarning("expected incoming " + std::string(name) + + " link to be an object-property connection, ignoring", + &element + ); + return NULL; + } + + if(is_object_property_conn && propNameOut) { + // note: this is ok, the return value of PropertyValue() is guaranteed to + // remain valid and unchanged as long as the document exists. + *propNameOut = con.PropertyName().c_str(); + } + + const Object* const ob = con.SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for incoming" + std::string(name) + + " link, ignoring", + &element); + return NULL; + } + + return dynamic_cast(ob); +} + + } //!Util } //!FBX } //!Assimp diff --git a/code/FBXMeshGeometry.cpp b/code/FBXMeshGeometry.cpp index 111e6aa18..0586ab46c 100644 --- a/code/FBXMeshGeometry.cpp +++ b/code/FBXMeshGeometry.cpp @@ -57,9 +57,34 @@ namespace FBX { using namespace Util; + +// ------------------------------------------------------------------------------------------------ +Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) + : Object(id, element,name) + , skin() +{ + const std::vector& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); + BOOST_FOREACH(const Connection* con, conns) { + const Skin* const sk = ProcessSimpleConnection(*con, false, "Skin -> Geometry", element); + if(sk) { + skin = sk; + break; + } + } +} + + +// ------------------------------------------------------------------------------------------------ +Geometry::~Geometry() +{ + +} + + + // ------------------------------------------------------------------------------------------------ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) -: Geometry(id, element,name) +: Geometry(id, element,name, doc) { const Scope* sc = element.Compound(); if (!sc) {