[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50056] branches/soc-2012-bratwurst/extern /assimp/code: - ext_assimp: merge https://github.com/acgessler/ assimp-gsoc2012-fbx - fixes to cleanup the node hierarchy, animation/ armature bugfixes, binary reading bugfix.

Alexander Gessler alexander.gessler at gmx.net
Mon Aug 20 19:31:03 CEST 2012


Revision: 50056
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50056
Author:   aramis_acg
Date:     2012-08-20 17:31:03 +0000 (Mon, 20 Aug 2012)
Log Message:
-----------
- ext_assimp: merge https://github.com/acgessler/assimp-gsoc2012-fbx - fixes to cleanup the node hierarchy, animation/armature bugfixes, binary reading bugfix. 

Modified Paths:
--------------
    branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXTokenizer.h

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp	2012-08-20 17:25:04 UTC (rev 50055)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp	2012-08-20 17:31:03 UTC (rev 50056)
@@ -174,6 +174,11 @@
 
 	switch(type)
 	{
+		// 16 bit int
+	case 'Y':
+		cursor += 2;
+		break;
+
 		// 1 bit bool flag (yes/no)
 	case 'C':
 		cursor += 1;

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp	2012-08-20 17:25:04 UTC (rev 50055)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp	2012-08-20 17:31:03 UTC (rev 50056)
@@ -61,6 +61,7 @@
 
 
 #define MAGIC_NODE_TAG "_$AssimpFbx$"
+#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158
 
 	// XXX vc9's debugger won't step into anonymous namespaces
 //namespace {
@@ -542,9 +543,6 @@
 	/** checks if a node has more than just scaling, rotation and translation components */
 	bool NeedsComplexTransformationChain(const Model& model)
 	{
-		// XXX TEMPORARY
-		return true;
-
 		const PropertyTable& props = model.Props();
 		bool ok;
 
@@ -652,9 +650,6 @@
 			GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]);
 		}
 
-		// XXX TEMPORARY
-		is_complex = true;
-
 		// is_complex needs to be consistent with NeedsComplexTransformationChain()
 		// or the interplay between this code and the animation converter would
 		// not be guaranteed.
@@ -679,8 +674,7 @@
 				const TransformationComp comp = static_cast<TransformationComp>(i);
 				
 				if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) {
-					// XXX TEMPORARY
-					//continue;
+					continue;
 				}
 
 				aiNode* nd = new aiNode();
@@ -1785,7 +1779,8 @@
 				node_property_map.end(), 
 				layer_map,
 				max_time,
-				min_time
+				min_time,
+				true // input is TRS order, assimp is SRT
 				);
 
 			ai_assert(nd);
@@ -2056,7 +2051,8 @@
 		NodeMap::const_iterator iter_end,
 		const LayerMap& layer_map,
 		double& max_time,
-		double& min_time)
+		double& min_time,
+		bool reverse_order = false)
 
 	{
 		ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
@@ -2064,57 +2060,126 @@
 
 		const PropertyTable& props = target.Props();
 
-		// if a particular transformation is not given, grab it from
-		// the corresponding node to meet the semantics of aiNodeAnim,
-		// which requires all of rotation, scaling and translation
-		// to be set.
-		if(chain[TransformationComp_Scaling] != iter_end) {
-			ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second, 
-				layer_map, 
-				max_time, 
-				min_time);
-		}
-		else {
-			na->mScalingKeys = new aiVectorKey[1];
-			na->mNumScalingKeys = 1;
+		// need to convert from TRS order to SRT?
+		if(reverse_order) {
+		
+			aiVector3D def_scale, def_translate;
+			aiQuaternion def_rot;
 
-			na->mScalingKeys[0].mTime = 0.;
-			na->mScalingKeys[0].mValue = PropertyGet(props,"Lcl Scaling",
-				aiVector3D(1.f,1.f,1.f));
-		}
+			KeyFrameListList scaling;
+			KeyFrameListList translation;
+			KeyFrameListList rotation;
+			
+			if(chain[TransformationComp_Scaling] != iter_end) {
+				scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second);
+			}
+			else {
+				def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
+			}
 
-		if(chain[TransformationComp_Rotation] != iter_end) {
-			ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second, 
-				layer_map, 
+			if(chain[TransformationComp_Translation] != iter_end) {
+				translation = GetKeyframeList((*chain[TransformationComp_Translation]).second);
+			}
+			else {
+				def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
+			}
+			
+			if(chain[TransformationComp_Rotation] != iter_end) {
+				rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second);
+			}
+			else {
+				def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
+					target.RotationOrder());
+			}
+
+			KeyFrameListList joined;
+			joined.insert(joined.end(), scaling.begin(), scaling.end());
+			joined.insert(joined.end(), translation.begin(), translation.end());
+			joined.insert(joined.end(), rotation.begin(), rotation.end());
+
+			const KeyTimeList& times = GetKeyTimeList(joined);
+
+			aiQuatKey* out_quat = new aiQuatKey[times.size()];
+			aiVectorKey* out_scale = new aiVectorKey[times.size()];
+			aiVectorKey* out_translation = new aiVectorKey[times.size()];
+
+			ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation, 
+				scaling, 
+				translation, 
+				rotation, 
+				times,
 				max_time,
 				min_time,
-				target.RotationOrder());
-		}
-		else {
-			na->mRotationKeys = new aiQuatKey[1];
-			na->mNumRotationKeys = 1;
+				target.RotationOrder(),
+				def_scale,
+				def_translate,
+				def_rot);
 
-			na->mRotationKeys[0].mTime = 0.;
-			na->mRotationKeys[0].mValue = EulerToQuaternion(
-				PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
-				target.RotationOrder());
-		}
+			// XXX remove duplicates / redundant keys which this operation did
+			// likely produce if not all three channels were equally dense.
 
-		if(chain[TransformationComp_Translation] != iter_end) {
-			ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second, 
-				layer_map, 
-				max_time, 
-				min_time);
+			na->mNumScalingKeys = static_cast<unsigned int>(times.size());
+			na->mNumRotationKeys = na->mNumScalingKeys;
+			na->mNumPositionKeys = na->mNumScalingKeys;
+
+			na->mScalingKeys = out_scale;
+			na->mRotationKeys = out_quat;
+			na->mPositionKeys = out_translation;
 		}
 		else {
-			na->mPositionKeys = new aiVectorKey[1];
-			na->mNumPositionKeys = 1;
 
-			na->mPositionKeys[0].mTime = 0.;
-			na->mPositionKeys[0].mValue = PropertyGet(props,"Lcl Translation",
-				aiVector3D(0.f,0.f,0.f));
+			// if a particular transformation is not given, grab it from
+			// the corresponding node to meet the semantics of aiNodeAnim,
+			// which requires all of rotation, scaling and translation
+			// to be set.
+			if(chain[TransformationComp_Scaling] != iter_end) {
+				ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second, 
+					layer_map, 
+					max_time, 
+					min_time);
+			}
+			else {
+				na->mScalingKeys = new aiVectorKey[1];
+				na->mNumScalingKeys = 1;
+
+				na->mScalingKeys[0].mTime = 0.;
+				na->mScalingKeys[0].mValue = PropertyGet(props,"Lcl Scaling",
+					aiVector3D(1.f,1.f,1.f));
+			}
+
+			if(chain[TransformationComp_Rotation] != iter_end) {
+				ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second, 
+					layer_map, 
+					max_time,
+					min_time,
+					target.RotationOrder());
+			}
+			else {
+				na->mRotationKeys = new aiQuatKey[1];
+				na->mNumRotationKeys = 1;
+
+				na->mRotationKeys[0].mTime = 0.;
+				na->mRotationKeys[0].mValue = EulerToQuaternion(
+					PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
+					target.RotationOrder());
+			}
+
+			if(chain[TransformationComp_Translation] != iter_end) {
+				ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second, 
+					layer_map, 
+					max_time, 
+					min_time);
+			}
+			else {
+				na->mPositionKeys = new aiVectorKey[1];
+				na->mNumPositionKeys = 1;
+
+				na->mPositionKeys[0].mTime = 0.;
+				na->mPositionKeys[0].mValue = PropertyGet(props,"Lcl Translation",
+					aiVector3D(0.f,0.f,0.f));
+			}
+
 		}
-
 		return na.dismiss();
 	}
 
@@ -2267,7 +2332,7 @@
 			}
 
 			// magic value to convert fbx times to milliseconds
-			valOut->mTime = static_cast<double>(time) / 46186158;
+			valOut->mTime = CONVERT_FBX_TIME(time);
 
 			minTime = std::min(minTime, valOut->mTime);
 			maxTime = std::max(maxTime, valOut->mTime);
@@ -2282,7 +2347,8 @@
 
 
 	// ------------------------------------------------------------------------------------------------
-	void InterpolateKeys(aiQuatKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs, const bool geom,
+	void InterpolateKeys(aiQuatKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs, 
+		const bool geom,
 		double& maxTime,
 		double& minTime,
 		Model::RotOrder order)
@@ -2302,6 +2368,66 @@
 
 
 	// ------------------------------------------------------------------------------------------------
+	void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale,
+		aiVectorKey* out_translation, 
+		const KeyFrameListList& scaling, 
+		const KeyFrameListList& translation, 
+		const KeyFrameListList& rotation, 
+		const KeyTimeList& times,
+		double& maxTime,
+		double& minTime,
+		Model::RotOrder order,
+		const aiVector3D& def_scale,
+		const aiVector3D& def_translate,
+		const aiQuaternion& def_rotation)
+	{
+		if (rotation.size()) {
+			InterpolateKeys(out_quat, times, rotation, false, maxTime, minTime, order);
+		}
+		else {
+			for (size_t i = 0; i < times.size(); ++i) {
+				out_quat[i].mTime = CONVERT_FBX_TIME(times[i]);
+				out_quat[i].mValue = def_rotation;
+			}
+		}
+
+		if (scaling.size()) {
+			InterpolateKeys(out_scale, times, scaling, true, maxTime, minTime);
+		}
+		else {
+			for (size_t i = 0; i < times.size(); ++i) {
+				out_scale[i].mTime = CONVERT_FBX_TIME(times[i]);
+				out_scale[i].mValue = def_scale;
+			}
+		}
+
+		if (translation.size()) {
+			InterpolateKeys(out_translation, times, translation, false, maxTime, minTime);
+		}
+		else {
+			for (size_t i = 0; i < times.size(); ++i) {
+				out_translation[i].mTime = CONVERT_FBX_TIME(times[i]);
+				out_translation[i].mValue = def_translate;
+			}
+		}
+
+		const size_t count = times.size();
+		for (size_t i = 0; i < count; ++i) {
+			aiQuaternion& r = out_quat[i].mValue;
+			aiVector3D& s = out_scale[i].mValue;
+			aiVector3D& t = out_translation[i].mValue;
+
+			aiMatrix4x4 mat, temp;
+			aiMatrix4x4::Translation(t, mat);
+			mat *= aiMatrix4x4( r.GetMatrix() );
+			mat *= aiMatrix4x4::Scaling(s, temp);
+
+			mat.Decompose(s, r, t);
+		}
+	}
+
+
+	// ------------------------------------------------------------------------------------------------
 	// euler xyz -> quat
 	aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order) 
 	{

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXTokenizer.h
===================================================================

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list