[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44231] trunk/blender/source/blender/ collada: Fix rest of #27022, collada export: add bone parenting of objects

Juha Mäki-Kanto kiskosika at gmail.com
Sat Feb 18 17:55:52 CET 2012


Revision: 44231
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44231
Author:   kanttori
Date:     2012-02-18 16:55:41 +0000 (Sat, 18 Feb 2012)
Log Message:
-----------
Fix rest of #27022, collada export: add bone parenting of objects

- SceneExporter collects a list of child-objects for armature-object and passes it onto ArmatureExporter
- SceneExporter's writeNodes is then called from ArmatureExporter for matching child-objects for bone.
- ArmatureExporter removes written child-objects from list, objects not exported as being bone parented are exported as direct children of the armature-node.
- Should play nice with current Second Life-compatibility.

A nicer implementation would require some design changes, will have to wait.

Modified Paths:
--------------
    trunk/blender/source/blender/collada/ArmatureExporter.cpp
    trunk/blender/source/blender/collada/ArmatureExporter.h
    trunk/blender/source/blender/collada/SceneExporter.cpp
    trunk/blender/source/blender/collada/SceneExporter.h

Modified: trunk/blender/source/blender/collada/ArmatureExporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/ArmatureExporter.cpp	2012-02-18 16:42:19 UTC (rev 44230)
+++ trunk/blender/source/blender/collada/ArmatureExporter.cpp	2012-02-18 16:55:41 UTC (rev 44231)
@@ -43,6 +43,7 @@
 
 #include "GeometryExporter.h"
 #include "ArmatureExporter.h"
+#include "SceneExporter.h"
 
 // XXX exporter writes wrong data for shared armatures.  A separate
 // controller should be written for each armature-mesh binding how do
@@ -50,14 +51,16 @@
 ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {}
 
 // write bone nodes
-void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce)
+void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce,
+										  SceneExporter* se,
+										  std::list<Object*>& child_objects)
 {
 	// write bone nodes
 	bArmature *arm = (bArmature*)ob_arm->data;
 	for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) {
 		// start from root bones
 		if (!bone->parent)
-			add_bone_node(bone, ob_arm);
+			add_bone_node(bone, ob_arm, sce, se, child_objects);
 	}
 }
 
@@ -163,7 +166,9 @@
 }
 
 // parent_mat is armature-space
-void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm)
+void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce,
+									 SceneExporter* se,
+									 std::list<Object*>& child_objects)
 {
 	std::string node_id = get_joint_id(bone, ob_arm);
 	std::string node_name = std::string(bone->name);
@@ -183,14 +188,54 @@
 
 	add_bone_transform(ob_arm, bone, node);
 
+	// Write nodes of childobjects, remove written objects from list
+	std::list<Object*>::iterator i = child_objects.begin();
+
+	while( i != child_objects.end() )
+	{
+		if((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name)))
+		{
+			float backup_parinv[4][4];
+
+			// SECOND_LIFE_COMPATIBILITY
+			// crude, temporary change to parentinv
+			// so transform gets exported correctly.
+			// TODO: when such objects are animated as
+			// single matrix the tweak must be applied
+			// to the result.
+			if(export_settings->second_life)
+			{
+				copy_m4_m4(backup_parinv, (*i)->parentinv);
+				// tweak objects parentinverse to match
+				// the second life- compatibility
+				float temp[4][4];
+
+				copy_m4_m4(temp, bone->arm_mat);
+				temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+
+				mult_m4_m4m4((*i)->parentinv, temp, backup_parinv);
+			}
+
+			se->writeNodes(*i, sce);
+
+			// restore original parentinv
+			if(export_settings->second_life)
+			{
+				copy_m4_m4((*i)->parentinv, backup_parinv);
+			}
+			child_objects.erase(i++);
+		}
+		else i++;
+	}
+
 	for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
-		add_bone_node(child, ob_arm);
+		add_bone_node(child, ob_arm, sce, se, child_objects);
 	}
 	node.end();
 	//}
 }
 
-void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
+/*void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
 {
 	node.start();
 	
@@ -201,11 +246,11 @@
 	node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2] );
 	
 	for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
-		add_bone_node(child, ob_arm);
+		add_bone_node(child, ob_arm, sce, se, child_objects);
 	}
 	node.end();
 	
-}
+}*/
 void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node)
 {
 	bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);

Modified: trunk/blender/source/blender/collada/ArmatureExporter.h
===================================================================
--- trunk/blender/source/blender/collada/ArmatureExporter.h	2012-02-18 16:42:19 UTC (rev 44230)
+++ trunk/blender/source/blender/collada/ArmatureExporter.h	2012-02-18 16:55:41 UTC (rev 44231)
@@ -28,6 +28,7 @@
 #ifndef __ARMATUREEXPORTER_H__
 #define __ARMATUREEXPORTER_H__
 
+#include <list>
 #include <string>
 //#include <vector>
 
@@ -47,6 +48,8 @@
 
 #include "ExportSettings.h"
 
+class SceneExporter;
+
 // XXX exporter writes wrong data for shared armatures.  A separate
 // controller should be written for each armature-mesh binding how do
 // we make controller ids then?
@@ -56,7 +59,8 @@
 	ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
 
 	// write bone nodes
-	void add_armature_bones(Object *ob_arm, Scene *sce);
+	void add_armature_bones(Object *ob_arm, Scene* sce, SceneExporter* se,
+							std::list<Object*>& child_objects);
 
 	bool is_skinned_mesh(Object *ob);
 
@@ -85,8 +89,10 @@
 
 	std::string get_joint_sid(Bone *bone, Object *ob_arm);
 
-	// parent_mat is armature-space
-	void add_bone_node(Bone *bone, Object *ob_arm);
+	// Scene, SceneExporter and the list of child_objects
+	// are required for writing bone parented objects
+	void add_bone_node(Bone *bone, Object *ob_arm, Scene* sce, SceneExporter* se,
+					   std::list<Object*>& child_objects);
 
 	void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
 

Modified: trunk/blender/source/blender/collada/SceneExporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/SceneExporter.cpp	2012-02-18 16:42:19 UTC (rev 44230)
+++ trunk/blender/source/blender/collada/SceneExporter.cpp	2012-02-18 16:55:41 UTC (rev 44231)
@@ -77,7 +77,30 @@
 	node.start();
 
 	bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob);
+	std::list<Object*> child_objects;
 
+	// list child objects
+	Base *b = (Base*) sce->base.first;
+	while(b) {
+		// cob - child object
+		Object *cob = b->object;
+
+		if (cob->parent == ob) {
+			switch(cob->type) {
+				case OB_MESH:
+				case OB_CAMERA:
+				case OB_LAMP:
+				case OB_EMPTY:
+				case OB_ARMATURE:
+					child_objects.push_back(cob);
+					break;
+			}
+		}
+
+		b = b->next;
+	}
+
+
 	if (ob->type == OB_MESH && is_skinned_mesh)
 		// for skinned mesh we write obmat in <bind_shape_matrix>
 		TransformWriter::add_node_transform_identity(node);
@@ -101,7 +124,7 @@
 
 	// <instance_controller>
 	else if (ob->type == OB_ARMATURE) {
-		arm_exporter->add_armature_bones(ob, sce);
+		arm_exporter->add_armature_bones(ob, sce, this, child_objects);
 
 		// XXX this looks unstable...
 		node.end();
@@ -131,28 +154,12 @@
 		}
 	}
 
-	// write nodes for child objects
-	Base *b = (Base*) sce->base.first;
-	while(b) {
-		// cob - child object
-		Object *cob = b->object;
+	for(std::list<Object*>::iterator i= child_objects.begin(); i != child_objects.end(); ++i)
+	{
+		writeNodes(*i, sce);
+	}
 
-		if (cob->parent == ob) {
-			switch(cob->type) {
-				case OB_MESH:
-				case OB_CAMERA:
-				case OB_LAMP:
-				case OB_EMPTY:
-				case OB_ARMATURE:
-					// write node...
-					writeNodes(cob, sce);
-					break;
-			}
-		}
 
-		b = b->next;
-	}
-
 	if (ob->type != OB_ARMATURE)
 		node.end();
 }

Modified: trunk/blender/source/blender/collada/SceneExporter.h
===================================================================
--- trunk/blender/source/blender/collada/SceneExporter.h	2012-02-18 16:42:19 UTC (rev 44230)
+++ trunk/blender/source/blender/collada/SceneExporter.h	2012-02-18 16:55:41 UTC (rev 44231)
@@ -97,6 +97,8 @@
 	void exportScene(Scene *sce);
 
 private:
+	// required for writeNodes() for bone-parented objects
+	friend class ArmatureExporter;
 	void exportHierarchy(Scene *sce);
 	void writeNodes(Object *ob, Scene *sce);
 	




More information about the Bf-blender-cvs mailing list