[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50232] branches/soc-2012-bratwurst: *POST-GSOC-FROM-HERE!-TAG* - ext_assimp: merge https://github.com/ acgessler/assimp-gsoc2012-fbx proper framerate conversion, fixes crash when assigning animations to root node, keep Null node info, support scenes with no geometry in them, massive logging cleanup ( fewer but more concise warnings), performance improvements.

Alexander Gessler alexander.gessler at gmx.net
Mon Aug 27 01:34:39 CEST 2012


Revision: 50232
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50232
Author:   aramis_acg
Date:     2012-08-26 23:34:38 +0000 (Sun, 26 Aug 2012)
Log Message:
-----------
*POST-GSOC-FROM-HERE!-TAG* - ext_assimp: merge https://github.com/acgessler/assimp-gsoc2012-fbx proper framerate conversion, fixes crash when assigning animations to root node, keep Null node info, support scenes with no geometry in them, massive logging cleanup (fewer  but more concise warnings), performance improvements.

Modified Paths:
--------------
    branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDeformer.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocument.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocument.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXModel.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXNodeAttribute.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp	2012-08-26 23:17:50 UTC (rev 50231)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp	2012-08-26 23:34:38 UTC (rev 50232)
@@ -98,17 +98,18 @@
 
 
 // ------------------------------------------------------------------------------------------------
-AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc)
+AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, 
+	const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
 : Object(id, element, name)
 , target()
+, doc(doc)
 {
 	const Scope& sc = GetRequiredScope(element);
-	props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc);
+	
+	// find target node
+	const char* whitelist[] = {"Model","NodeAttribute"};
+	const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
 
-	{
-	// resolve attached animation curves
-	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
-
 	BOOST_FOREACH(const Connection* con, conns) {
 
 		// link should go for a property
@@ -116,34 +117,21 @@
 			continue;
 		}
 
-		const Object* const ob = con->SourceObject();
-		if(!ob) {
-			DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
-			continue;
-		}
+		if(target_prop_whitelist) {
+			const char* const s = con->PropertyName().c_str();
+			bool ok = false;
+			for (size_t i = 0; i < whitelist_size; ++i) {
+				if (!strcmp(s, target_prop_whitelist[i])) {
+					ok = true;
+					break;
+				}
+			}
 
-		const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
-		if(!anim) {
-			DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
-			continue;
+			if (!ok) {
+				throw std::range_error("AnimationCurveNode target property is not in whitelist");
+			}
 		}
-		
-		curves[con->PropertyName()] = anim;
-	}
 
-	}{
-
-	// find target node
-	const char* whitelist[] = {"Model","NodeAttribute"};
-	const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
-
-	BOOST_FOREACH(const Connection* con, conns) {
-
-		// link should go for a property
-		if (!con->PropertyName().length()) {
-			continue;
-		}
-
 		const Object* const ob = con->DestinationObject();
 		if(!ob) {
 			DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
@@ -160,10 +148,12 @@
 		prop = con->PropertyName();
 		break;
 	}
-	}
+
 	if(!target) {
 		DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
 	}
+
+	props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
 }
 
 
@@ -175,12 +165,64 @@
 
 
 // ------------------------------------------------------------------------------------------------
+const AnimationCurveMap& AnimationCurveNode::Curves() const
+{
+	if(curves.empty()) {
+		// resolve attached animation curves
+		const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
+
+		BOOST_FOREACH(const Connection* con, conns) {
+
+			// link should go for a property
+			if (!con->PropertyName().length()) {
+				continue;
+			}
+
+			const Object* const ob = con->SourceObject();
+			if(!ob) {
+				DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
+				continue;
+			}
+
+			const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
+			if(!anim) {
+				DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
+				continue;
+			}
+
+			curves[con->PropertyName()] = anim;
+		}
+	}
+
+	return curves;
+}
+
+
+// ------------------------------------------------------------------------------------------------
 AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
 : Object(id, element, name)
+, doc(doc)
 {
 	const Scope& sc = GetRequiredScope(element);
-	props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc);
 
+	// note: the props table here bears little importance and is usually absent
+	props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+AnimationLayer::~AnimationLayer()
+{
+
+}
+
+
+// ------------------------------------------------------------------------------------------------
+AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, 
+	size_t whitelist_size /*= 0*/) const
+{
+	AnimationCurveNodeList nodes;
+
 	// resolve attached animation nodes
 	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
 	nodes.reserve(conns.size());
@@ -203,15 +245,24 @@
 			DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
 			continue;
 		}
+
+		if(target_prop_whitelist) {
+			const char* s = anim->TargetProperty().c_str();
+			bool ok = false;
+			for (size_t i = 0; i < whitelist_size; ++i) {
+				if (!strcmp(s, target_prop_whitelist[i])) {
+					ok = true;
+					break;
+				}
+			}
+			if(!ok) {
+				continue;
+			}
+		}
 		nodes.push_back(anim);
 	}
-}
 
-
-// ------------------------------------------------------------------------------------------------
-AnimationLayer::~AnimationLayer()
-{
-
+	return nodes; // pray for NRVO
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -219,8 +270,10 @@
 : Object(id, element, name)
 {
 	const Scope& sc = GetRequiredScope(element);
-	props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc);
 
+	// note: we don't currently use any of these properties so we shouldn't bother if it is missing
+	props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
+
 	// resolve attached animation layers
 	const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
 	layers.reserve(conns.size());

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp	2012-08-26 23:17:50 UTC (rev 50231)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp	2012-08-26 23:34:38 UTC (rev 50232)
@@ -61,8 +61,10 @@
 
 
 #define MAGIC_NODE_TAG "_$AssimpFbx$"
-#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158
+#define MAGIC_NULL_TAG "_$AssimpFbxNull$"
 
+#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
+
 	// XXX vc9's debugger won't step into anonymous namespaces
 //namespace {
 
@@ -124,6 +126,13 @@
 		}
 
 		TransferDataToScene();
+
+		// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
+		// to make sure the scene passes assimp's validation. FBX files
+		// need not contain geometry (i.e. camera animations, raw armatures).
+		if (out->mNumMeshes == 0) {
+			out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
+		}
 	}
 
 
@@ -197,16 +206,17 @@
 					// is supposed to have. If there is none, add another node to 
 					// preserve the name - people might have scripts etc. that rely
 					// on specific node names.
-					bool has_name = false;
+					aiNode* name_carrier = NULL;
 					BOOST_FOREACH(aiNode* prenode, nodes_chain) {
 						if ( !strcmp(prenode->mName.C_Str(), original_name.c_str()) ) {
-							has_name = true;
+							name_carrier = prenode;
 							break;
 						}
 					}
 
-					if(!has_name) {
+					if(!name_carrier) {
 						nodes_chain.push_back(new aiNode(original_name));
+						name_carrier = nodes_chain.back();
 					}
 
 					// link all nodes in a row
@@ -240,6 +250,14 @@
 						ConvertCameras(*model);
 					}
 
+					// preserve the info that a node was marked as Null node
+					// in the original file.
+					if(model->IsNull()) {
+						const std::string& new_name = original_name + MAGIC_NULL_TAG;
+						RenameNode(original_name, new_name);
+						name_carrier->mName.Set( new_name.c_str() );
+					}
+
 					nodes.push_back(nodes_chain.front());	
 					nodes_chain.clear();
 				}
@@ -1545,9 +1563,66 @@
 
 
 	// ------------------------------------------------------------------------------------------------
+	// get the number of fps for a FrameRate enumerated value
+	static double FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0)
+	{
+		switch(fp) {
+			case FileGlobalSettings::FrameRate_DEFAULT:
+				return 1.0;
+
+			case FileGlobalSettings::FrameRate_120:
+				return 120.0;
+
+			case FileGlobalSettings::FrameRate_100:
+				return 100.0;
+
+			case FileGlobalSettings::FrameRate_60:
+				return 60.0;
+
+			case FileGlobalSettings::FrameRate_50:
+				return 50.0;
+
+			case FileGlobalSettings::FrameRate_48:
+				return 48.0;
+
+			case FileGlobalSettings::FrameRate_30:
+			case FileGlobalSettings::FrameRate_30_DROP:
+				return 30.0;
+
+			case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
+			case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
+				return 29.9700262;
+
+			case FileGlobalSettings::FrameRate_PAL:
+				return 25.0;
+
+			case FileGlobalSettings::FrameRate_CINEMA:
+				return 24.0;
+
+			case FileGlobalSettings::FrameRate_1000:
+				return 1000.0;
+
+			case FileGlobalSettings::FrameRate_CINEMA_ND:
+				return 23.976;
+
+			case FileGlobalSettings::FrameRate_CUSTOM:
+				return customFPSVal;
+		}
+
+		ai_assert(false);
+		return -1.0f;
+	}
+
+
+	// ------------------------------------------------------------------------------------------------
 	// convert animation data to aiAnimation et al
 	void ConvertAnimations() 
 	{
+		// first of all determine framerate
+		const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
+		const float custom = doc.GlobalSettings().CustomFrameRate();
+		anim_fps = FrameRateToDouble(fps, custom);
+
 		const std::vector<const AnimationStack*>& animations = doc.AnimationStacks();
 		BOOST_FOREACH(const AnimationStack* stack, animations) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list