Bladeren bron

- fbx: read Geometry -> Skin and Model -> Cluster connections. Improve logging, some refactoring.

Alexander Gessler 13 jaren geleden
bovenliggende
commit
05ec3c2e90
5 gewijzigde bestanden met toevoegingen van 113 en 33 verwijderingen
  1. 17 16
      code/FBXDeformer.cpp
  2. 0 15
      code/FBXDocument.cpp
  3. 26 1
      code/FBXDocument.h
  4. 44 0
      code/FBXDocumentUtil.h
  5. 26 1
      code/FBXMeshGeometry.cpp

+ 17 - 16
code/FBXDeformer.cpp

@@ -78,6 +78,7 @@ Deformer::~Deformer()
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
 Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
 : Deformer(id,element,doc,name)
 : Deformer(id,element,doc,name)
+, node()
 {
 {
 	const Scope& sc = GetRequiredScope(element);
 	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(indices,Indexes);
 	ReadVectorDataArray(weights,Weights);
 	ReadVectorDataArray(weights,Weights);
+
+	// read assigned node
+	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
+	BOOST_FOREACH(const Connection* con, conns) {
+		const Model* const mod = ProcessSimpleConnection<Model>(*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));
 		accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0));
 	}
 	}
 
 
-	const char* const arr[] = {"Deformer"};
-
 	// resolve assigned clusters 
 	// resolve assigned clusters 
-	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),arr, 1);
+	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
 
 
 	clusters.reserve(conns.size());
 	clusters.reserve(conns.size());
 	BOOST_FOREACH(const Connection* con, conns) {
 	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<const Cluster*>(ob);
+		const Cluster* const cluster = ProcessSimpleConnection<Cluster>(*con, false, "Cluster -> Skin", element);
 		if(cluster) {
 		if(cluster) {
 			clusters.push_back(cluster);
 			clusters.push_back(cluster);
 			continue;
 			continue;
 		}
 		}
-
 	}
 	}
 }
 }
 
 

+ 0 - 15
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)
 Document::Document(const Parser& parser, const ImportSettings& settings)
 : settings(settings)
 : settings(settings)

+ 26 - 1
code/FBXDocument.h

@@ -60,6 +60,14 @@ namespace FBX {
 	class Material;
 	class Material;
 	class Geometry;
 	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
 /** Represents a delay-parsed FBX objects. Many objects in the scene
  *  are not needed by assimp, so it makes no sense to parse them
  *  are not needed by assimp, so it makes no sense to parse them
@@ -363,8 +371,19 @@ class Geometry : public Object
 {
 {
 public:
 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();
 	~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;
 		return transformLink;
 	}
 	}
 
 
+	const Model* const TargetNode() const {
+		return node;
+	}
+
 private:
 private:
 
 
 	WeightList weights;
 	WeightList weights;
@@ -702,6 +725,8 @@ private:
 
 
 	aiMatrix4x4 transform;
 	aiMatrix4x4 transform;
 	aiMatrix4x4 transformLink;
 	aiMatrix4x4 transformLink;
+
+	const Model* node;
 };
 };
 
 
 
 

+ 44 - 0
code/FBXDocumentUtil.h

@@ -108,6 +108,50 @@ boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
 	const Element &element, 
 	const Element &element, 
 	const Scope& sc);
 	const Scope& sc);
 
 
+
+
+
+// ------------------------------------------------------------------------------------------------
+template <typename T>
+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<const T*>(ob);
+}
+
+
 } //!Util
 } //!Util
 } //!FBX
 } //!FBX
 } //!Assimp
 } //!Assimp

+ 26 - 1
code/FBXMeshGeometry.cpp

@@ -57,9 +57,34 @@ namespace FBX {
 
 
 	using namespace Util;
 	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<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
+	BOOST_FOREACH(const Connection* con, conns) {
+		const Skin* const sk = ProcessSimpleConnection<Skin>(*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)
 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();
 	const Scope* sc = element.Compound();
 	if (!sc) {
 	if (!sc) {