[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25747] trunk/blender/source/blender/ collada: Merge -c 25001, 25310, 25311, 25638, 25746 from COLLADA branch into trunk.

Arystanbek Dyussenov arystan.d at gmail.com
Tue Jan 5 18:42:01 CET 2010


Revision: 25747
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25747
Author:   kazanbas
Date:     2010-01-05 18:42:01 +0100 (Tue, 05 Jan 2010)

Log Message:
-----------
Merge -c 25001,25310,25311,25638,25746 from COLLADA branch into trunk.

Modified Paths:
--------------
    trunk/blender/source/blender/collada/DocumentExporter.cpp
    trunk/blender/source/blender/collada/DocumentImporter.cpp

Modified: trunk/blender/source/blender/collada/DocumentExporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/DocumentExporter.cpp	2010-01-05 16:07:10 UTC (rev 25746)
+++ trunk/blender/source/blender/collada/DocumentExporter.cpp	2010-01-05 17:42:01 UTC (rev 25747)
@@ -21,6 +21,7 @@
 {
 #include "BKE_DerivedMesh.h"
 #include "BKE_fcurve.h"
+#include "BKE_animsys.h"
 #include "BLI_path_util.h"
 #include "BLI_fileops.h"
 #include "ED_keyframing.h"
@@ -36,6 +37,7 @@
 #include "BKE_armature.h"
 #include "BKE_image.h"
 #include "BKE_utildefines.h"
+#include "BKE_object.h"
 
 #include "BLI_math.h"
 #include "BLI_string.h"
@@ -198,6 +200,12 @@
 	return translate_id(id_name(ob)) + "-camera";
 }
 
+std::string get_joint_id(Bone *bone, Object *ob_arm)
+{
+	return translate_id(id_name(ob_arm) + "_" + bone->name);
+}
+
+
 /*
   Utilities to avoid code duplication.
   Definition can take some time to understand, but they should be useful.
@@ -851,11 +859,6 @@
 		return ob_arm;
 	}
 
-	std::string get_joint_id(Bone *bone, Object *ob_arm)
-	{
-		return translate_id(id_name(ob_arm) + "_" + bone->name);
-	}
-
 	std::string get_joint_sid(Bone *bone)
 	{
 		char name[100];
@@ -1538,9 +1541,23 @@
 			if (t->mapto & MAP_REF) {
 				ep.setReflective(createTexture(ima, uvname, sampler));
 			}
+			// alpha
 			if (t->mapto & MAP_ALPHA) {
 				ep.setTransparent(createTexture(ima, uvname, sampler));
 			}
+			// extension:
+			// Normal map --> Must be stored with <extra> tag as different technique, 
+			// since COLLADA doesn't support normal maps, even in current COLLADA 1.5.
+			if (t->mapto & MAP_NORM) {
+				COLLADASW::Texture texture(key);
+				texture.setTexcoord(uvname);
+				texture.setSampler(*sampler);
+				// technique FCOLLADA, with the <bump> tag, is most likely the best understood,
+				// most widespread de-facto standard.
+				texture.setProfileName("FCOLLADA");
+				texture.setChildElementName("bump");				
+				ep.setExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture));
+			}
 		}
 		// performs the actual writing
 		ep.addProfileElements();
@@ -1720,9 +1737,9 @@
 class AnimationExporter: COLLADASW::LibraryAnimations
 {
 	Scene *scene;
-	std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map;
-	std::map<bActionGroup*, std::vector<FCurve*> > rotfcurves_actionGroup_map;
+
 public:
+
 	AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) {}
 
 	void exportAnimations(Scene *sce)
@@ -1736,17 +1753,278 @@
 		closeLibrary();
 	}
 
-	// create <animation> for each transform axis
+	// called for each exported object
+	void operator() (Object *ob) 
+	{
+		if (!ob->adt || !ob->adt->action) return;
+		
+		FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
+		
+		if (ob->type == OB_ARMATURE) {
+			if (!ob->data) return;
 
-	float convert_time(float frame) {
+			bArmature *arm = (bArmature*)ob->data;
+			for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next)
+				write_bone_animation(ob, bone);
+		}
+		else {
+			while (fcu) {
+				// TODO "rotation_quaternion" is also possible for objects (although euler is default)
+				if ((!strcmp(fcu->rna_path, "location") || !strcmp(fcu->rna_path, "scale")) ||
+					(!strcmp(fcu->rna_path, "rotation_euler") && ob->rotmode == ROT_MODE_EUL))
+					dae_animation(fcu, id_name(ob));
+
+				fcu = fcu->next;
+			}
+		}
+	}
+
+protected:
+
+	void dae_animation(FCurve *fcu, std::string ob_name)
+	{
+		const char *axis_names[] = {"X", "Y", "Z"};
+		const char *axis_name = NULL;
+		char anim_id[200];
+		char anim_name[200];
+		
+		if (fcu->array_index < 3)
+			axis_name = axis_names[fcu->array_index];
+
+		BLI_snprintf(anim_id, sizeof(anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
+					 fcu->rna_path, axis_names[fcu->array_index]);
+		BLI_snprintf(anim_name, sizeof(anim_name), "%s.%s.%s", 
+					 (char*)ob_name.c_str(), fcu->rna_path, axis_names[fcu->array_index]);
+
+		// check rna_path is one of: rotation, scale, location
+
+		openAnimation(anim_id, anim_name);
+
+		// create input source
+		std::string input_id = create_source_from_fcurve(Sampler::INPUT, fcu, anim_id, axis_name);
+
+		// create output source
+		std::string output_id = create_source_from_fcurve(Sampler::OUTPUT, fcu, anim_id, axis_name);
+
+		// create interpolations source
+		std::string interpolation_id = create_interpolation_source(fcu->totvert, anim_id, axis_name);
+
+		std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+		COLLADASW::LibraryAnimations::Sampler sampler(sampler_id);
+		std::string empty;
+		sampler.addInput(Sampler::INPUT, COLLADABU::URI(empty, input_id));
+		sampler.addInput(Sampler::OUTPUT, COLLADABU::URI(empty, output_id));
+
+		// this input is required
+		sampler.addInput(Sampler::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+		addSampler(sampler);
+
+		std::string target = translate_id(ob_name)
+			+ "/" + get_transform_sid(fcu->rna_path, -1, axis_name);
+		addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+		closeAnimation();
+	}
+
+	void write_bone_animation(Object *ob_arm, Bone *bone)
+	{
+		if (!ob_arm->adt)
+			return;
+
+		for (int i = 0; i < 3; i++)
+			sample_and_write_bone_animation(ob_arm, bone, i);
+
+		for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
+			write_bone_animation(ob_arm, child);
+	}
+
+	void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
+	{
+		bArmature *arm = (bArmature*)ob_arm->data;
+		int flag = arm->flag;
+		std::vector<float> fra;
+		char prefix[256];
+
+		BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone->name);
+
+		bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
+		if (!pchan)
+			return;
+
+		switch (transform_type) {
+		case 0:
+			find_rotation_frames(ob_arm, fra, prefix, pchan->rotmode);
+			break;
+		case 1:
+			find_frames(ob_arm, fra, prefix, "scale");
+			break;
+		case 2:
+			find_frames(ob_arm, fra, prefix, "location");
+			break;
+		default:
+			return;
+		}
+
+		// exit rest position
+		if (flag & ARM_RESTPOS) {
+			arm->flag &= ~ARM_RESTPOS;
+			where_is_pose(scene, ob_arm);
+		}
+
+		if (fra.size()) {
+			float *v = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
+			sample_animation(v, fra, transform_type, bone, ob_arm);
+
+			if (transform_type == 0) {
+				// write x, y, z curves separately if it is rotation
+				float *c = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
+				for (int i = 0; i < 3; i++) {
+					for (int j = 0; j < fra.size(); j++)
+						c[j] = v[j * 3 + i];
+
+					dae_bone_animation(fra, c, transform_type, i, id_name(ob_arm), bone->name);
+				}
+				MEM_freeN(c);
+			}
+			else {
+				// write xyz at once if it is location or scale
+				dae_bone_animation(fra, v, transform_type, -1, id_name(ob_arm), bone->name);
+			}
+
+			MEM_freeN(v);
+		}
+
+		// restore restpos
+		if (flag & ARM_RESTPOS) 
+			arm->flag = flag;
+		where_is_pose(scene, ob_arm);
+	}
+
+	void sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm)
+	{
+		bPoseChannel *pchan, *parchan = NULL;
+		bPose *pose = ob_arm->pose;
+
+		pchan = get_pose_channel(pose, bone->name);
+
+		if (!pchan)
+			return;
+
+		parchan = pchan->parent;
+
+		enable_fcurves(ob_arm->adt->action, bone->name);
+
+		std::vector<float>::iterator it;
+		for (it = frames.begin(); it != frames.end(); it++) {
+			float mat[4][4], ipar[4][4];
+
+			float ctime = bsystem_time(scene, ob_arm, *it, 0.0f);
+
+			BKE_animsys_evaluate_animdata(&ob_arm->id, ob_arm->adt, *it, ADT_RECALC_ANIM);
+			where_is_pose_bone(scene, ob_arm, pchan, ctime);
+
+			// compute bone local mat
+			if (bone->parent) {
+				invert_m4_m4(ipar, parchan->pose_mat);
+				mul_m4_m4m4(mat, pchan->pose_mat, ipar);
+			}
+			else
+				copy_m4_m4(mat, pchan->pose_mat);
+
+			switch (type) {
+			case 0:
+				mat4_to_eul(v, mat);
+				break;
+			case 1:
+				mat4_to_size(v, mat);
+				break;
+			case 2:
+				copy_v3_v3(v, mat[3]);
+				break;
+			}
+
+			v += 3;
+		}
+
+		enable_fcurves(ob_arm->adt->action, NULL);
+	}
+
+	// dae_bone_animation -> add_bone_animation
+	// (blend this into dae_bone_animation)
+	void dae_bone_animation(std::vector<float> &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name)
+	{
+		const char *axis_names[] = {"X", "Y", "Z"};
+		const char *axis_name = NULL;
+		char anim_id[200];
+		char anim_name[200];
+		bool is_rot = tm_type == 0;
+		
+		if (!fra.size())
+			return;
+
+		char rna_path[200];
+		BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
+					 tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
+
+		if (axis > -1)
+			axis_name = axis_names[axis];
+		
+		std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name);
+		
+		BLI_snprintf(anim_id, sizeof(anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
+					 (char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
+		BLI_snprintf(anim_name, sizeof(anim_name), "%s.%s.%s",
+					 (char*)ob_name.c_str(), (char*)bone_name.c_str(), (char*)transform_sid.c_str());
+
+		// TODO check rna_path is one of: rotation, scale, location
+
+		openAnimation(anim_id, anim_name);
+
+		// create input source
+		std::string input_id = create_source_from_vector(Sampler::INPUT, fra, is_rot, anim_id, axis_name);
+
+		// create output source
+		std::string output_id;
+		if (axis == -1)
+			output_id = create_xyz_source(v, fra.size(), anim_id);
+		else
+			output_id = create_source_from_array(Sampler::OUTPUT, v, fra.size(), is_rot, anim_id, axis_name);
+
+		// create interpolations source
+		std::string interpolation_id = create_interpolation_source(fra.size(), anim_id, axis_name);
+
+		std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+		COLLADASW::LibraryAnimations::Sampler sampler(sampler_id);
+		std::string empty;
+		sampler.addInput(Sampler::INPUT, COLLADABU::URI(empty, input_id));
+		sampler.addInput(Sampler::OUTPUT, COLLADABU::URI(empty, output_id));
+
+		// TODO create in/out tangents source
+
+		// this input is required
+		sampler.addInput(Sampler::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+		addSampler(sampler);
+
+		std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
+		addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+		closeAnimation();
+	}
+
+	float convert_time(float frame)
+	{

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list