[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49588] trunk/blender/source/blender/ collada: COLLADA: report #32237 fixed Camera exporter and Importer to use correct camera animation data

Gaia Clary gaia.clary at machinimatrix.org
Sun Aug 5 23:35:10 CEST 2012


Revision: 49588
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49588
Author:   gaiaclary
Date:     2012-08-05 21:35:09 +0000 (Sun, 05 Aug 2012)
Log Message:
-----------
COLLADA: report #32237  fixed Camera exporter and Importer to use correct camera animation data

Modified Paths:
--------------
    trunk/blender/source/blender/collada/AnimationExporter.cpp
    trunk/blender/source/blender/collada/AnimationExporter.h
    trunk/blender/source/blender/collada/AnimationImporter.cpp
    trunk/blender/source/blender/collada/AnimationImporter.h

Modified: trunk/blender/source/blender/collada/AnimationExporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/AnimationExporter.cpp	2012-08-05 21:17:58 UTC (rev 49587)
+++ trunk/blender/source/blender/collada/AnimationExporter.cpp	2012-08-05 21:35:09 UTC (rev 49588)
@@ -106,7 +106,8 @@
 
 			if ((!strcmp(transformName, "lens")) ||
 			    (!strcmp(transformName, "ortho_scale")) ||
-			    (!strcmp(transformName, "clip_end")) || (!strcmp(transformName, "clip_start")))
+			    (!strcmp(transformName, "clip_end")) || 
+				(!strcmp(transformName, "clip_start")))
 			{
 				dae_animation(ob, fcu, transformName, true);
 			}
@@ -203,8 +204,10 @@
 	}
 
 	//axis names for colors
-	else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") ||
-	         (!strcmp(transformName, "alpha")))
+	else if (!strcmp(transformName, "color") ||
+			 !strcmp(transformName, "specular_color") ||
+			 !strcmp(transformName, "diffuse_color") ||
+	         !strcmp(transformName, "alpha"))
 	{
 		const char *axis_names[] = {"R", "G", "B"};
 		if (fcu->array_index < 3)
@@ -212,8 +215,10 @@
 	}
 
 	//axis names for transforms
-	else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
-	         (!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion")))
+	else if (!strcmp(transformName, "location") ||
+			 !strcmp(transformName, "scale") ||
+	         !strcmp(transformName, "rotation_euler") ||
+			 !strcmp(transformName, "rotation_quaternion"))
 	{
 		const char *axis_names[] = {"X", "Y", "Z"};
 		if (fcu->array_index < 3)
@@ -260,9 +265,13 @@
 		MEM_freeN(eul);
 		MEM_freeN(eul_axis);
 	}
+	else if(!strcmp(transformName, "lens") && (ob->type == OB_CAMERA)) {
+		output_id = create_lens_source_from_fcurve((Camera *) ob->data, COLLADASW::InputSemantic::OUTPUT, fcu, anim_id);
+	}
 	else {
 		output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
 	}
+
 	// create interpolations source
 	std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents);
 
@@ -553,7 +562,7 @@
 	}
 }
 
-void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length)
+void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool is_rotation, float *values, int *length)
 {
 	switch (semantic) {
 		case COLLADASW::InputSemantic::INPUT:
@@ -562,7 +571,7 @@
 			break;
 		case COLLADASW::InputSemantic::OUTPUT:
 			*length = 1;
-			if (rotation) {
+			if (is_rotation) {
 				values[0] = RAD2DEGF(bezt->vec[1][1]);
 			}
 			else {
@@ -578,7 +587,7 @@
 				values[0] = 0;	
 				values[1] = 0; 	
 			}
-			else if (rotation) {
+			else if (is_rotation) {
 				values[1] = RAD2DEGF(bezt->vec[0][1]);
 			}
 			else {
@@ -594,7 +603,7 @@
 				values[0] = 0;	
 				values[1] = 0;	
 			}
-			else if (rotation) {
+			else if (is_rotation) {
 				values[1] = RAD2DEGF(bezt->vec[2][1]);
 			}
 			else {
@@ -654,6 +663,44 @@
 	return source_id;
 }
 
+/*
+ * Similar to create_source_from_fcurve, but adds conversion of lens
+ * animation data from focal length to FOV.
+ */
+std::string AnimationExporter::create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id)
+{
+	std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+	COLLADASW::FloatSourceF source(mSW);
+	source.setId(source_id);
+	source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+	source.setAccessorCount(fcu->totvert);
+
+	source.setAccessorStride(1);
+
+	COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+	add_source_parameters(param, semantic, false, "", false);
+
+	source.prepareToAppendValues();
+
+	for (unsigned int i = 0; i < fcu->totvert; i++) {
+		float values[3]; // be careful!
+		int length = 0;
+		get_source_values(&fcu->bezt[i], semantic, false, values, &length);
+		for (int j = 0; j < length; j++)
+		{
+			float val = RAD2DEGF(focallength_to_fov(values[j], cam->sensor_x));
+			source.appendValues(val);
+		}
+	}
+
+	source.finish();
+
+	return source_id;
+}
+
+
+
 //Currently called only to get OUTPUT source values ( if rotation and hence the axis is also specified )
 std::string AnimationExporter::create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name)
 {

Modified: trunk/blender/source/blender/collada/AnimationExporter.h
===================================================================
--- trunk/blender/source/blender/collada/AnimationExporter.h	2012-08-05 21:17:58 UTC (rev 49587)
+++ trunk/blender/source/blender/collada/AnimationExporter.h	2012-08-05 21:35:09 UTC (rev 49588)
@@ -133,6 +133,8 @@
 
 	std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name);
 
+	std::string create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id);
+
 	std::string create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name);
 
 	std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name);

Modified: trunk/blender/source/blender/collada/AnimationImporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/AnimationImporter.cpp	2012-08-05 21:17:58 UTC (rev 49587)
+++ trunk/blender/source/blender/collada/AnimationImporter.cpp	2012-08-05 21:35:09 UTC (rev 49588)
@@ -652,6 +652,51 @@
 	
 }
 
+/*
+ * Lens animations must be stored in COLLADA by using FOV,
+ * while blender internally uses focal length.
+ * The imported animation curves must be converted appropriately.
+ */
+void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const double aspect, Camera *cam, const char *anim_type, int fov_type)
+{
+	char rna_path[100];
+	if (animlist_map.find(listid) == animlist_map.end()) {
+		return;
+	}
+	else {
+		//anim_type has animations
+		const COLLADAFW::AnimationList *animlist = animlist_map[listid];
+		const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
+		//all the curves belonging to the current binding
+		std::vector<FCurve *> animcurves;
+		for (unsigned int j = 0; j < bindings.getCount(); j++) {
+			animcurves = curve_map[bindings[j].animation];
+
+			BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
+
+			modify_fcurve(&animcurves, rna_path, 0);
+			std::vector<FCurve *>::iterator iter;
+			//Add the curves of the current animation to the object
+			for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
+				FCurve *fcu = *iter;
+				
+				for (unsigned int i = 0; i < fcu->totvert; i++) {
+
+					double input_fov = fcu->bezt[i].vec[1][1];
+					double xfov = (fov_type == CAMERA_YFOV) ? aspect * input_fov : input_fov;
+
+					// fov is in degrees, cam->lens is in millimiters
+					double fov = fov_to_focallength(DEG2RADF(input_fov), cam->sensor_x);
+
+					fcu->bezt[i].vec[1][1] = fov;
+				}
+
+				BLI_addtail(AnimCurves, fcu);
+			}
+		}
+	}
+}
+
 void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node,
                                             COLLADAFW::Transformation *tm)
 {
@@ -796,6 +841,39 @@
 
 }
 
+/*
+ * This function returns the aspet ration from the Collada camera.
+ *
+ * Note:COLLADA allows to specify either XFov, or YFov alone. 
+ * In tghat case the aspect ratio can be determined from 
+ * the viewport aspect ratio (which is 1:1 ?)
+ * XXX: check this: its probably wrong!
+ * If both values are specified, then the aspect ration is simply xfov/yfov
+ * and if aspect ratio is efined, then .. well then its that one.
+ */
+static const double get_aspect_ratio(const COLLADAFW::Camera *camera)
+{
+	double aspect =  camera->getAspectRatio().getValue();
+
+	if(aspect == 0)
+	{
+		const double yfov   =  camera->getYFov().getValue();
+
+		if(yfov == 0)
+			aspect=1; // assume yfov and xfov are equal
+		else
+		{
+			const double xfov   =  camera->getXFov().getValue();
+			if (xfov==0)
+				aspect = 1;
+			else
+				aspect = xfov / yfov;
+		}
+	}
+	return aspect;
+}
+
+
 void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
                                              std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& root_map,
                                              std::multimap<COLLADAFW::UniqueId, Object *>& object_map,
@@ -924,11 +1002,12 @@
 	}
 
 	if (animType->camera != 0) {
-		Camera *camera  = (Camera *) ob->data;
+		Camera *cam  = (Camera *) ob->data;
+		if (!cam->adt || !cam->adt->action)
+			act = verify_adt_action((ID *)&cam->id, 1);
+		else
+			act = cam->adt->action;
 
-		if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID *)&camera->id, 1);
-		else act = camera->adt->action;
-
 		ListBase *AnimCurves = &(act->curves);
 		const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras();
 
@@ -938,13 +1017,15 @@
 			if ((animType->camera & CAMERA_XFOV) != 0) {
 				const COLLADAFW::AnimatableFloat *xfov =  &(camera->getXFov());
 				const COLLADAFW::UniqueId& listid = xfov->getAnimationList();
-				Assign_float_animations(listid, AnimCurves, "lens");
+				double aspect = get_aspect_ratio(camera); 
+				Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_XFOV);
 			}
 
 			else if ((animType->camera & CAMERA_YFOV) != 0) {
 				const COLLADAFW::AnimatableFloat *yfov =  &(camera->getYFov());
 				const COLLADAFW::UniqueId& listid = yfov->getAnimationList();
-				Assign_float_animations(listid, AnimCurves, "lens");
+				double aspect = get_aspect_ratio(camera); 
+				Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_YFOV);
 			}
 
 			else if ((animType->camera & CAMERA_XMAG) != 0) {

Modified: trunk/blender/source/blender/collada/AnimationImporter.h

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list