Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2011-08-30 13:15:55 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-08-30 13:15:55 +0400
commit9424b1ceff992f420fe6315acabfb7138cd0026e (patch)
tree2f19cac8af2ad32852cf9c46cb542e14fabe8d9b /source/blender/collada
parentd049a722fea3d150fbfad06ffdbbb5c150717134 (diff)
parent43ab8e86247b7889d16d915b4f370ceb618aaad4 (diff)
Merging pepper to trunk at revision 39791.
Important note: I used rsync to do the local merge, as "svn merge --reintegrate ^/branches/soc-2011-pepper" doesn't work with our svn server right now!
Diffstat (limited to 'source/blender/collada')
-rw-r--r--source/blender/collada/AnimationExporter.cpp1300
-rw-r--r--source/blender/collada/AnimationExporter.h163
-rw-r--r--source/blender/collada/AnimationImporter.cpp926
-rw-r--r--source/blender/collada/AnimationImporter.h80
-rw-r--r--source/blender/collada/ArmatureExporter.cpp33
-rw-r--r--source/blender/collada/ArmatureExporter.h2
-rw-r--r--source/blender/collada/ArmatureImporter.cpp249
-rw-r--r--source/blender/collada/ArmatureImporter.h22
-rw-r--r--source/blender/collada/CMakeLists.txt2
-rw-r--r--source/blender/collada/CameraExporter.cpp16
-rw-r--r--source/blender/collada/DocumentExporter.cpp633
-rw-r--r--source/blender/collada/DocumentImporter.cpp44
-rw-r--r--source/blender/collada/DocumentImporter.h7
-rw-r--r--source/blender/collada/EffectExporter.cpp30
-rw-r--r--source/blender/collada/ExtraHandler.cpp4
-rw-r--r--source/blender/collada/ExtraHandler.h5
-rw-r--r--source/blender/collada/GeometryExporter.h3
-rw-r--r--source/blender/collada/LightExporter.cpp29
-rw-r--r--source/blender/collada/SkinInfo.cpp4
-rw-r--r--source/blender/collada/TransformReader.cpp37
-rw-r--r--source/blender/collada/TransformWriter.cpp18
21 files changed, 2703 insertions, 904 deletions
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
new file mode 100644
index 00000000000..8a0a39da558
--- /dev/null
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -0,0 +1,1300 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GeometryExporter.h"
+#include "AnimationExporter.h"
+#include "MaterialExporter.h"
+
+template<class Functor>
+void forEachObjectInScene(Scene *sce, Functor &f)
+{
+ Base *base= (Base*) sce->base.first;
+
+ while(base) {
+ Object *ob = base->object;
+
+ f(ob);
+
+ base= base->next;
+ }
+}
+
+void AnimationExporter::exportAnimations(Scene *sce)
+{
+ if(hasAnimations(sce)) {
+ this->scene = sce;
+
+ openLibrary();
+
+ forEachObjectInScene(sce, *this);
+
+ closeLibrary();
+ }
+}
+
+// called for each exported object
+void AnimationExporter::operator() (Object *ob)
+{
+ FCurve *fcu;
+ char * transformName ;
+ bool isMatAnim = false;
+
+ //Export transform animations
+ if(ob->adt && ob->adt->action)
+ {
+ fcu = (FCurve*)ob->adt->action->curves.first;
+
+ //transform matrix export for bones are temporarily disabled here.
+ if ( ob->type == OB_ARMATURE )
+ {
+ bArmature *arm = (bArmature*)ob->data;
+ for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next)
+ write_bone_animation_matrix(ob, bone);
+ }
+
+ while (fcu) {
+ //for armature animations as objects
+ if ( ob->type == OB_ARMATURE )
+ transformName = fcu->rna_path;
+ else
+ transformName = extract_transform_name( fcu->rna_path );
+
+ if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
+ (!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL)||
+ (!strcmp(transformName, "rotation_quaternion")))
+ dae_animation(ob ,fcu, transformName, false);
+ fcu = fcu->next;
+ }
+
+ }
+
+ //Export Lamp parameter animations
+ if( (ob->type == OB_LAMP ) && ((Lamp*)ob ->data)->adt && ((Lamp*)ob ->data)->adt->action )
+ {
+ fcu = (FCurve*)(((Lamp*)ob ->data)->adt->action->curves.first);
+ while (fcu) {
+ transformName = extract_transform_name( fcu->rna_path );
+
+ if ((!strcmp(transformName, "color")) || (!strcmp(transformName, "spot_size"))|| (!strcmp(transformName, "spot_blend"))||
+ (!strcmp(transformName, "distance")) )
+ dae_animation(ob , fcu, transformName, true );
+ fcu = fcu->next;
+ }
+ }
+
+ //Export Camera parameter animations
+ if( (ob->type == OB_CAMERA ) && ((Camera*)ob ->data)->adt && ((Camera*)ob ->data)->adt->action )
+ {
+ fcu = (FCurve*)(((Camera*)ob ->data)->adt->action->curves.first);
+ while (fcu) {
+ transformName = extract_transform_name( fcu->rna_path );
+
+ if ((!strcmp(transformName, "lens"))||
+ (!strcmp(transformName, "ortho_scale"))||
+ (!strcmp(transformName, "clip_end"))||(!strcmp(transformName, "clip_start")))
+ dae_animation(ob , fcu, transformName, true );
+ fcu = fcu->next;
+ }
+ }
+
+ //Export Material parameter animations.
+ for(int a = 0; a < ob->totcol; a++)
+ {
+ Material *ma = give_current_material(ob, a+1);
+ if (!ma) continue;
+ if(ma->adt && ma->adt->action)
+ {
+ isMatAnim = true;
+ fcu = (FCurve*)ma->adt->action->curves.first;
+ while (fcu) {
+ transformName = extract_transform_name( fcu->rna_path );
+
+ if ((!strcmp(transformName, "specular_hardness"))||(!strcmp(transformName, "specular_color"))
+ ||(!strcmp(transformName, "diffuse_color"))||(!strcmp(transformName, "alpha"))||
+ (!strcmp(transformName, "ior")))
+ dae_animation(ob ,fcu, transformName, true, ma );
+ fcu = fcu->next;
+ }
+ }
+
+ }
+}
+
+ //euler sources from quternion sources
+ float * AnimationExporter::get_eul_source_for_quat(Object *ob )
+ {
+ FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
+ const int keys = fcu->totvert;
+ float *quat = (float*)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values");
+ float *eul = (float*)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values");
+ float temp_quat[4];
+ float temp_eul[3];
+ while(fcu)
+ {
+ char * transformName = extract_transform_name( fcu->rna_path );
+
+ if( !strcmp(transformName, "rotation_quaternion") ) {
+ for ( int i = 0 ; i < fcu->totvert ; i++){
+ *(quat + ( i * 4 ) + fcu->array_index) = fcu->bezt[i].vec[1][1];
+ }
+ }
+ fcu = fcu->next;
+ }
+
+ for ( int i = 0 ; i < keys ; i++){
+ for ( int j = 0;j<4;j++)
+ temp_quat[j] = quat[(i*4)+j];
+
+ quat_to_eul(temp_eul,temp_quat);
+
+ for (int k = 0;k<3;k++)
+ eul[i*3 + k] = temp_eul[k];
+
+ }
+ MEM_freeN(quat);
+ return eul;
+
+ }
+
+ //Get proper name for bones
+ std::string AnimationExporter::getObjectBoneName( Object* ob,const FCurve* fcu )
+ {
+ //hard-way to derive the bone name from rna_path. Must find more compact method
+ std::string rna_path = std::string(fcu->rna_path);
+
+ char* boneName = strtok((char *)rna_path.c_str(), "\"");
+ boneName = strtok(NULL,"\"");
+
+ if( boneName != NULL )
+ return /*id_name(ob) + "_" +*/ std::string(boneName);
+ else
+ return id_name(ob);
+ }
+
+ //convert f-curves to animation curves and write
+ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformName , bool is_param, Material * ma )
+ {
+ const char *axis_name = NULL;
+ char anim_id[200];
+
+ bool has_tangents = false;
+ bool quatRotation = false;
+
+ if ( !strcmp(transformName, "rotation_quaternion") )
+ {
+ fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n");
+ quatRotation = true;
+ return;
+ }
+
+ //axis names for colors
+ 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)
+ axis_name = axis_names[fcu->array_index];
+ }
+
+ //axis names for transforms
+ 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)
+ axis_name = axis_names[fcu->array_index];
+ }
+
+ //no axis name. single parameter.
+ else{
+ axis_name = "";
+ }
+
+ std::string ob_name = std::string("null");
+
+ //Create anim Id
+ if (ob->type == OB_ARMATURE)
+ {
+ ob_name = getObjectBoneName( ob , fcu);
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char*)translate_id(ob_name).c_str(),
+ transformName, axis_name);
+ }
+ else
+ {
+ if (ma)
+ ob_name = id_name(ob) + "_material";
+ else
+ ob_name = id_name(ob);
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
+ fcu->rna_path, axis_name);
+ }
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name);
+
+ // create output source
+ std::string output_id ;
+
+ //quat rotations are skipped for now, because of complications with determining axis.
+ if(quatRotation)
+ {
+ float * eul = get_eul_source_for_quat(ob);
+ float * eul_axis = (float*)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values");
+ for ( int i = 0 ; i< fcu->totvert ; i++)
+ eul_axis[i] = eul[i*3 + fcu->array_index];
+ output_id= create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis , fcu->totvert, quatRotation, anim_id, axis_name);
+ MEM_freeN(eul);
+ MEM_freeN(eul_axis);
+ }
+ 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);
+
+ // handle tangents (if required)
+ std::string intangent_id;
+ std::string outtangent_id;
+
+ if (has_tangents) {
+ // create in_tangent source
+ intangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::IN_TANGENT, fcu, anim_id, axis_name);
+
+ // create out_tangent source
+ outtangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUT_TANGENT, fcu, anim_id, axis_name);
+ }
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ if (has_tangents) {
+ sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, COLLADABU::URI(empty, intangent_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, COLLADABU::URI(empty, outtangent_id));
+ }
+
+ addSampler(sampler);
+
+ std::string target ;
+
+ if ( !is_param )
+ target = translate_id(ob_name)
+ + "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
+ else
+ {
+ if ( ob->type == OB_LAMP )
+ target = get_light_id(ob)
+ + "/" + get_light_param_sid(fcu->rna_path, -1, axis_name, true);
+
+ if ( ob->type == OB_CAMERA )
+ target = get_camera_id(ob)
+ + "/" + get_camera_param_sid(fcu->rna_path, -1, axis_name, true);
+
+ if( ma )
+ target = translate_id(id_name(ma)) + "-effect"
+ +"/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
+ }
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+ }
+
+
+
+ //write bone animations in transform matrix sources
+ void AnimationExporter::write_bone_animation_matrix(Object *ob_arm, Bone *bone)
+ {
+ if (!ob_arm->adt)
+ return;
+
+ //This will only export animations of bones in deform group.
+ /*if(!is_bone_deform_group(bone))
+ return;*/
+
+ sample_and_write_bone_animation_matrix(ob_arm, bone);
+
+ for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
+ write_bone_animation_matrix(ob_arm, child);
+ }
+
+ bool AnimationExporter::is_bone_deform_group(Bone * bone)
+ {
+ bool is_def;
+ //Check if current bone is deform
+ if((bone->flag & BONE_NO_DEFORM) == 0 ) return true;
+ //Check child bones
+ else
+ {
+ for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next){
+ //loop through all the children until deform bone is found, and then return
+ is_def = is_bone_deform_group(child);
+ if (is_def) return true;
+ }
+ }
+ //no deform bone found in children also
+ return false;
+ }
+
+ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone)
+ {
+ bArmature *arm = (bArmature*)ob_arm->data;
+ int flag = arm->flag;
+ std::vector<float> fra;
+ //char prefix[256];
+
+ FCurve* fcu = (FCurve*)ob_arm->adt->action->curves.first;
+ while(fcu)
+ {
+ std::string bone_name = getObjectBoneName(ob_arm,fcu);
+ int val = BLI_strcasecmp((char*)bone_name.c_str(),bone->name);
+ if(val==0) break;
+ fcu = fcu->next;
+ }
+
+ if(!(fcu)) return;
+ bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
+ if (!pchan)
+ return;
+
+ find_frames(ob_arm, fra);
+
+ if (flag & ARM_RESTPOS) {
+ arm->flag &= ~ARM_RESTPOS;
+ where_is_pose(scene, ob_arm);
+ }
+
+ if (fra.size()) {
+ dae_baked_animation(fra ,ob_arm, bone );
+ }
+
+ if (flag & ARM_RESTPOS)
+ arm->flag = flag;
+ where_is_pose(scene, ob_arm);
+ }
+
+ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_arm , Bone *bone)
+ {
+ std::string ob_name = id_name(ob_arm);
+ std::string bone_name = bone->name;
+ char anim_id[200];
+
+ if (!fra.size())
+ return;
+
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
+ (char*)translate_id(bone_name).c_str(), "pose_matrix");
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, "");
+
+ // create output source
+ std::string output_id;
+ output_id = create_4x4_source( fra, ob_arm , bone , anim_id);
+
+ // create interpolations source
+ std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // TODO create in/out tangents source
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ addSampler(sampler);
+
+ std::string target = translate_id(bone_name) + "/transform";
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+ }
+
+ // dae_bone_animation -> add_bone_animation
+ // (blend this into dae_bone_animation)
+ void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *values, 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];
+ 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, false);
+
+ 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());
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, is_rot, anim_id, axis_name);
+
+ // create output source
+ std::string output_id;
+ if (axis == -1)
+ output_id = create_xyz_source(values, fra.size(), anim_id);
+ else
+ output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, values, fra.size(), is_rot, anim_id, axis_name);
+
+ // create interpolations source
+ std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, axis_name);
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // TODO create in/out tangents source
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::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 AnimationExporter::convert_time(float frame)
+ {
+ return FRA2TIME(frame);
+ }
+
+ float AnimationExporter::convert_angle(float angle)
+ {
+ return COLLADABU::Math::Utils::radToDegF(angle);
+ }
+
+ std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic)
+ {
+ switch(semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ return INPUT_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::OUTPUT:
+ return OUTPUT_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::INTERPOLATION:
+ return INTERPOLATION_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ return INTANGENT_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ return OUTTANGENT_SOURCE_ID_SUFFIX;
+ default:
+ break;
+ }
+ return "";
+ }
+
+ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
+ COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform)
+ {
+ switch(semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ param.push_back("TIME");
+ break;
+ case COLLADASW::InputSemantic::OUTPUT:
+ if (is_rot) {
+ param.push_back("ANGLE");
+ }
+ else {
+ if (axis) {
+ param.push_back(axis);
+ }
+ else
+ if ( transform )
+ {
+ param.push_back("TRANSFORM");
+ }else{ //assumes if axis isn't specified all axises are added
+ param.push_back("X");
+ param.push_back("Y");
+ param.push_back("Z");
+ }
+ }
+ break;
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ param.push_back("X");
+ param.push_back("Y");
+ break;
+ default:
+ break;
+ }
+ }
+
+ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length)
+ {
+ switch (semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ *length = 1;
+ values[0] = convert_time(bezt->vec[1][0]);
+ break;
+ case COLLADASW::InputSemantic::OUTPUT:
+ *length = 1;
+ if (rotation) {
+ values[0] = (bezt->vec[1][1]) * 180.0f/M_PI;
+ }
+ else {
+ values[0] = bezt->vec[1][1];
+ }
+ break;
+
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ *length = 2;
+ values[0] = convert_time(bezt->vec[0][0]);
+ if (bezt->ipo != BEZT_IPO_BEZ) {
+ // We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain unused data
+ values[0] = 0;
+ values[1] = 0;
+ }
+ else if (rotation) {
+ values[1] = (bezt->vec[0][1]) * 180.0f/M_PI;
+ } else {
+ values[1] = bezt->vec[0][1];
+ }
+ break;
+
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ *length = 2;
+ values[0] = convert_time(bezt->vec[2][0]);
+ if (bezt->ipo != BEZT_IPO_BEZ) {
+ // We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain unused data
+ values[0] = 0;
+ values[1] = 0;
+ }
+ else if (rotation) {
+ values[1] = (bezt->vec[2][1]) * 180.0f/M_PI;
+ } else {
+ values[1] = bezt->vec[2][1];
+ }
+ break;
+ break;
+ default:
+ *length = 0;
+ break;
+ }
+ }
+
+ std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+ //bool is_rotation = !strcmp(fcu->rna_path, "rotation");
+ bool is_angle = false;
+
+ if (strstr(fcu->rna_path, "rotation")) is_angle = true;
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(fcu->totvert);
+
+ switch (semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ case COLLADASW::InputSemantic::OUTPUT:
+ source.setAccessorStride(1);
+ break;
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ source.setAccessorStride(2);
+ break;
+ }
+
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_angle, axis_name, 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, is_angle, values, &length);
+ for (int j = 0; j < length; j++)
+ source.appendValues(values[j]);
+ }
+
+ 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)
+ {
+ 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(tot);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_rot, axis_name, false);
+
+ source.prepareToAppendValues();
+
+ for (int i = 0; i < tot; i++) {
+ float val = v[i];
+ ////if (semantic == COLLADASW::InputSemantic::INPUT)
+ // val = convert_time(val);
+ //else
+ if (is_rot)
+ val *= 180.0f / M_PI;
+ source.appendValues(val);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+// only used for sources with INPUT semantic
+ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name)
+ {
+ 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(fra.size());
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_rot, axis_name, false);
+
+ source.prepareToAppendValues();
+
+ std::vector<float>::iterator it;
+ for (it = fra.begin(); it != fra.end(); it++) {
+ float val = *it;
+ //if (semantic == COLLADASW::InputSemantic::INPUT)
+ val = convert_time(val);
+ /*else if (is_rot)
+ val = convert_angle(val);*/
+ source.appendValues(val);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames , Object * ob_arm, Bone *bone , const std::string& anim_id)
+ {
+ COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+ COLLADASW::Float4x4Source source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(frames.size());
+ source.setAccessorStride(16);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, false, NULL, true);
+
+ source.prepareToAppendValues();
+
+ bPoseChannel *parchan = NULL;
+ bPoseChannel *pchan = 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;
+ int j = 0;
+ 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(scene , &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
+ where_is_pose_bone(scene, ob_arm, pchan, ctime, 1);
+
+ // 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);
+ UnitConverter converter;
+
+ float outmat[4][4];
+ converter.mat4_to_dae(outmat,mat);
+
+
+ source.appendValues(outmat);
+
+
+ j++;
+ }
+
+ enable_fcurves(ob_arm->adt->action, NULL);
+
+ source.finish();
+
+ return source_id;
+ }
+ // only used for sources with OUTPUT semantic ( locations and scale)
+ std::string AnimationExporter::create_xyz_source(float *v, int tot, const std::string& anim_id)
+ {
+ COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
+ 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(tot);
+ source.setAccessorStride(3);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, false, NULL, false);
+
+ source.prepareToAppendValues();
+
+ for (int i = 0; i < tot; i++) {
+ source.appendValues(*v, *(v + 1), *(v + 2));
+ v += 3;
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string AnimationExporter::create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
+
+ COLLADASW::NameSource 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();
+ param.push_back("INTERPOLATION");
+
+ source.prepareToAppendValues();
+
+ *has_tangents = false;
+
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ if (fcu->bezt[i].ipo==BEZT_IPO_BEZ) {
+ source.appendValues(BEZIER_NAME);
+ *has_tangents = true;
+ } else if (fcu->bezt[i].ipo==BEZT_IPO_CONST) {
+ source.appendValues(STEP_NAME);
+ } else { // BEZT_IPO_LIN
+ source.appendValues(LINEAR_NAME);
+ }
+ }
+ // unsupported? -- HERMITE, CARDINAL, BSPLINE, NURBS
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string AnimationExporter::fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
+
+ COLLADASW::NameSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(tot);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("INTERPOLATION");
+
+ source.prepareToAppendValues();
+
+ for (int i = 0; i < tot; i++) {
+ source.appendValues(LINEAR_NAME);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string AnimationExporter::get_light_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
+ {
+ std::string tm_name;
+ // when given rna_path, determine tm_type from it
+ if (rna_path) {
+ char *name = extract_transform_name(rna_path);
+
+ if (!strcmp(name, "color"))
+ tm_type = 1;
+ else if (!strcmp(name, "spot_size"))
+ tm_type = 2;
+ else if (!strcmp(name, "spot_blend"))
+ tm_type = 3;
+ else if (!strcmp(name, "distance"))
+ tm_type = 4;
+ else
+ tm_type = -1;
+ }
+
+ switch (tm_type) {
+ case 1:
+ tm_name = "color";
+ break;
+ case 2:
+ tm_name = "fall_off_angle";
+ break;
+ case 3:
+ tm_name = "fall_off_exponent";
+ break;
+ case 4:
+ tm_name = "blender/blender_dist";
+ break;
+
+ default:
+ tm_name = "";
+ break;
+ }
+
+ if (tm_name.size()) {
+ if (axis_name != "")
+ return tm_name + "." + std::string(axis_name);
+ else
+ return tm_name;
+ }
+
+ return std::string("");
+ }
+
+ std::string AnimationExporter::get_camera_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
+ {
+ std::string tm_name;
+ // when given rna_path, determine tm_type from it
+ if (rna_path) {
+ char *name = extract_transform_name(rna_path);
+
+ if (!strcmp(name, "lens"))
+ tm_type = 0;
+ else if (!strcmp(name, "ortho_scale"))
+ tm_type = 1;
+ else if (!strcmp(name, "clip_end"))
+ tm_type = 2;
+ else if (!strcmp(name, "clip_start"))
+ tm_type = 3;
+
+ else
+ tm_type = -1;
+ }
+
+ switch (tm_type) {
+ case 0:
+ tm_name = "xfov";
+ break;
+ case 1:
+ tm_name = "xmag";
+ break;
+ case 2:
+ tm_name = "zfar";
+ break;
+ case 3:
+ tm_name = "znear";
+ break;
+
+ default:
+ tm_name = "";
+ break;
+ }
+
+ if (tm_name.size()) {
+ if (axis_name != "")
+ return tm_name + "." + std::string(axis_name);
+ else
+ return tm_name;
+ }
+
+ return std::string("");
+ }
+
+ // Assign sid of the animated parameter or transform
+ // for rotation, axis name is always appended and the value of append_axis is ignored
+ std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
+ {
+ std::string tm_name;
+ bool is_rotation =false;
+ // when given rna_path, determine tm_type from it
+ if (rna_path) {
+ char *name = extract_transform_name(rna_path);
+
+ if (!strcmp(name, "rotation_euler"))
+ tm_type = 0;
+ else if (!strcmp(name, "rotation_quaternion"))
+ tm_type = 1;
+ else if (!strcmp(name, "scale"))
+ tm_type = 2;
+ else if (!strcmp(name, "location"))
+ tm_type = 3;
+ else if (!strcmp(name, "specular_hardness"))
+ tm_type = 4;
+ else if (!strcmp(name, "specular_color"))
+ tm_type = 5;
+ else if (!strcmp(name, "diffuse_color"))
+ tm_type = 6;
+ else if (!strcmp(name, "alpha"))
+ tm_type = 7;
+ else if (!strcmp(name, "ior"))
+ tm_type = 8;
+
+ else
+ tm_type = -1;
+ }
+
+ switch (tm_type) {
+ case 0:
+ case 1:
+ tm_name = "rotation";
+ is_rotation = true;
+ break;
+ case 2:
+ tm_name = "scale";
+ break;
+ case 3:
+ tm_name = "location";
+ break;
+ case 4:
+ tm_name = "shininess";
+ break;
+ case 5:
+ tm_name = "specular";
+ break;
+ case 6:
+ tm_name = "diffuse";
+ break;
+ case 7:
+ tm_name = "transparency";
+ break;
+ case 8:
+ tm_name = "index_of_refraction";
+ break;
+
+ default:
+ tm_name = "";
+ break;
+ }
+
+ if (tm_name.size()) {
+ if (is_rotation)
+ return tm_name + std::string(axis_name) + ".ANGLE";
+ else
+ if (axis_name != "")
+ return tm_name + "." + std::string(axis_name);
+ else
+ return tm_name;
+ }
+
+ return std::string("");
+ }
+
+ char* AnimationExporter::extract_transform_name(char *rna_path)
+ {
+ char *dot = strrchr(rna_path, '.');
+ return dot ? (dot + 1) : rna_path;
+ }
+
+ //find keyframes of all the objects animations
+ void AnimationExporter::find_frames(Object *ob, std::vector<float> &fra)
+ {
+ FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
+
+ for (; fcu; fcu = fcu->next) {
+
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ float f = fcu->bezt[i].vec[1][0]; //
+ if (std::find(fra.begin(), fra.end(), f) == fra.end())
+ fra.push_back(f);
+ }
+ }
+
+ // keep the keys in ascending order
+ std::sort(fra.begin(), fra.end());
+ }
+
+
+
+ // enable fcurves driving a specific bone, disable all the rest
+ // if bone_name = NULL enable all fcurves
+ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name)
+ {
+ FCurve *fcu;
+ char prefix[200];
+
+ if (bone_name)
+ BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
+
+ for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) {
+ if (bone_name) {
+ if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
+ fcu->flag &= ~FCURVE_DISABLED;
+ else
+ fcu->flag |= FCURVE_DISABLED;
+ }
+ else {
+ fcu->flag &= ~FCURVE_DISABLED;
+ }
+ }
+ }
+
+ bool AnimationExporter::hasAnimations(Scene *sce)
+ {
+ Base *base= (Base*) sce->base.first;
+
+ while(base) {
+ Object *ob = base->object;
+
+ FCurve *fcu = 0;
+ //Check for object transform animations
+ if(ob->adt && ob->adt->action)
+ fcu = (FCurve*)ob->adt->action->curves.first;
+ //Check for Lamp parameter animations
+ else if( (ob->type == OB_LAMP ) && ((Lamp*)ob ->data)->adt && ((Lamp*)ob ->data)->adt->action )
+ fcu = (FCurve*)(((Lamp*)ob ->data)->adt->action->curves.first);
+ //Check for Camera parameter animations
+ else if( (ob->type == OB_CAMERA ) && ((Camera*)ob ->data)->adt && ((Camera*)ob ->data)->adt->action )
+ fcu = (FCurve*)(((Camera*)ob ->data)->adt->action->curves.first);
+
+ //Check Material Effect parameter animations.
+ for(int a = 0; a < ob->totcol; a++)
+ {
+ Material *ma = give_current_material(ob, a+1);
+ if (!ma) continue;
+ if(ma->adt && ma->adt->action)
+ {
+ fcu = (FCurve*)ma->adt->action->curves.first;
+ }
+ }
+
+ if ( fcu)
+ return true;
+ base= base->next;
+ }
+ return false;
+ }
+
+ //------------------------------- Not used in the new system.--------------------------------------------------------
+ void AnimationExporter::find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode)
+ {
+ if (rotmode > 0)
+ find_frames(ob, fra, prefix, "rotation_euler");
+ else if (rotmode == ROT_MODE_QUAT)
+ find_frames(ob, fra, prefix, "rotation_quaternion");
+ /*else if (rotmode == ROT_MODE_AXISANGLE)
+ ;*/
+ }
+
+ void AnimationExporter::find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
+ {
+ FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
+
+ for (; fcu; fcu = fcu->next) {
+ if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
+ continue;
+
+ char *name = extract_transform_name(fcu->rna_path);
+ if (!strcmp(name, tm_name)) {
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ float f = fcu->bezt[i].vec[1][0]; //
+ if (std::find(fra.begin(), fra.end(), f) == fra.end())
+ fra.push_back(f);
+ }
+ }
+ }
+
+ // keep the keys in ascending order
+ std::sort(fra.begin(), fra.end());
+ }
+
+ void AnimationExporter::write_bone_animation(Object *ob_arm, Bone *bone)
+ {
+ if (!ob_arm->adt)
+ return;
+
+ //write bone animations for 3 transform types
+ //i=0 --> rotations
+ //i=1 --> scale
+ //i=2 --> location
+ 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 AnimationExporter::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;
+ //Fill frame array with key frame values framed at @param:transform_type
+ 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);
+ }
+ //v array will hold all values which will be exported.
+ if (fra.size()) {
+ float *values = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
+ sample_animation(values, fra, transform_type, bone, ob_arm, pchan);
+
+ if (transform_type == 0) {
+ // write x, y, z curves separately if it is rotation
+ float *axisValues = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
+
+ for (int i = 0; i < 3; i++) {
+ for (unsigned int j = 0; j < fra.size(); j++)
+ axisValues[j] = values[j * 3 + i];
+
+ dae_bone_animation(fra, axisValues, transform_type, i, id_name(ob_arm), bone->name);
+ }
+ MEM_freeN(axisValues);
+ }
+ else {
+ // write xyz at once if it is location or scale
+ dae_bone_animation(fra, values, transform_type, -1, id_name(ob_arm), bone->name);
+ }
+
+ MEM_freeN(values);
+ }
+
+ // restore restpos
+ if (flag & ARM_RESTPOS)
+ arm->flag = flag;
+ where_is_pose(scene, ob_arm);
+ }
+
+ void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pchan)
+ {
+ bPoseChannel *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(scene , &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
+ where_is_pose_bone(scene, ob_arm, pchan, ctime, 1);
+
+ // 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);
+ }
+
+
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
new file mode 100644
index 00000000000..267ad4be887
--- /dev/null
+++ b/source/blender/collada/AnimationExporter.h
@@ -0,0 +1,163 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+extern "C"
+{
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_material_types.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_fcurve.h"
+#include "BKE_animsys.h"
+#ifdef NAN_BUILDINFO
+extern char build_rev[];
+#endif
+}
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_action.h" // pose functions
+#include "BKE_armature.h"
+#include "BKE_object.h"
+
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+
+#include "RNA_access.h"
+
+#include "COLLADASWSource.h"
+#include "COLLADASWInstanceGeometry.h"
+#include "COLLADASWInputList.h"
+#include "COLLADASWPrimitves.h"
+#include "COLLADASWVertices.h"
+#include "COLLADASWLibraryAnimations.h"
+#include "COLLADASWParamTemplate.h"
+#include "COLLADASWParamBase.h"
+#include "COLLADASWSampler.h"
+#include "COLLADASWConstants.h"
+#include "COLLADASWBaseInputElement.h"
+
+#include "EffectExporter.h"
+
+#include "collada_internal.h"
+
+#include <vector>
+#include <algorithm> // std::find
+
+class AnimationExporter: COLLADASW::LibraryAnimations
+{
+private:
+ Scene *scene;
+ COLLADASW::StreamWriter *sw;
+
+public:
+
+ AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) { this->sw = sw; }
+
+
+ void exportAnimations(Scene *sce);
+
+ // called for each exported object
+ void operator() (Object *ob);
+
+protected:
+
+ void dae_animation(Object* ob, FCurve *fcu, char* transformName , bool is_param, Material *ma = NULL);
+
+ void write_bone_animation_matrix(Object *ob_arm, Bone *bone);
+
+ void write_bone_animation(Object *ob_arm, Bone *bone);
+
+ void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type);
+
+ bool is_bone_deform_group(Bone * bone);
+
+ void sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone);
+
+ void sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pChan);
+
+ void sample_animation(std::vector<float[4][4]> &mats, std::vector<float> &frames, Bone *bone, Object *ob_arm, bPoseChannel *pChan);
+
+ // 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);
+
+ void dae_baked_animation(std::vector<float> &fra, Object *ob_arm , Bone *bone);
+
+ float convert_time(float frame);
+
+ float convert_angle(float angle);
+
+ std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic);
+
+ void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
+ COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis , bool transform);
+
+ void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length);
+
+ float * get_eul_source_for_quat(Object *ob );
+
+ std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name);
+
+ 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);
+
+ std::string create_xyz_source(float *v, int tot, const std::string& anim_id);
+
+ std::string create_4x4_source(std::vector<float> &frames , Object * ob_arm, Bone *bone , const std::string& anim_id);
+
+ std::string create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents);
+
+ std::string fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name);
+ // for rotation, axis name is always appended and the value of append_axis is ignored
+ std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
+ std::string get_light_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
+ std::string get_camera_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
+ void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name);
+ void find_frames(Object *ob, std::vector<float> &fra);
+
+ void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode);
+
+ // enable fcurves driving a specific bone, disable all the rest
+ // if bone_name = NULL enable all fcurves
+ void enable_fcurves(bAction *act, char *bone_name);
+
+ bool hasAnimations(Scene *sce);
+
+ char* extract_transform_name(char *rna_path);
+
+ std::string getObjectBoneName ( Object *ob,const FCurve * fcu);
+}; \ No newline at end of file
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 336f127b11f..4a3cd5eeb06 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory, Sukhitha Jayathilake.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -50,6 +50,7 @@
#include "collada_utils.h"
#include "AnimationImporter.h"
#include "ArmatureImporter.h"
+#include "MaterialExporter.h"
#include <algorithm>
@@ -64,7 +65,6 @@ static const char *bc_get_joint_name(T *node)
FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path)
{
FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
-
fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
fcu->array_index = array_index;
@@ -89,17 +89,23 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
{
COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues();
COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues();
- // COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
- // COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
+
+ if( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER ||
+ curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP ) {
+ COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
+ COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
+ }
+
float fps = (float)FPS;
size_t dim = curve->getOutDimension();
unsigned int i;
-
+
std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
switch (dim) {
case 1: // X, Y, Z or angle
case 3: // XYZ
+ case 4:
case 16: // matrix
{
for (i = 0; i < dim; i++ ) {
@@ -108,28 +114,46 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
// fcu->rna_path = BLI_strdupn(path, strlen(path));
fcu->array_index = 0;
- //fcu->totvert = curve->getKeyCount();
+ fcu->totvert = curve->getKeyCount();
// create beztriple for each key
for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));
- // intangent
- // bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
- // bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
-
+
// input, output
bez.vec[1][0] = bc_get_float_value(input, j) * fps;
bez.vec[1][1] = bc_get_float_value(output, j * dim + i);
- // outtangent
- // bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
- // bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
- bez.ipo = U.ipo_new; /* use default interpolation mode here... */
+ if( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER ||
+ curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP)
+ {
+ COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
+ COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
+
+ // intangent
+ bez.vec[0][0] = bc_get_float_value(intan, (j * 2 * dim ) + (2 * i)) * fps;
+ bez.vec[0][1] = bc_get_float_value(intan, (j * 2 * dim )+ (2 * i) + 1);
+
+ // outtangent
+ bez.vec[2][0] = bc_get_float_value(outtan, (j * 2 * dim ) + (2 * i)) * fps;
+ bez.vec[2][1] = bc_get_float_value(outtan, (j * 2 * dim )+ (2 * i) + 1);
+ if(curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER)
+ bez.ipo = BEZT_IPO_BEZ;
+ else
+ bez.ipo = BEZT_IPO_CONST;
+ //bez.h1 = bez.h2 = HD_AUTO;
+ }
+ else
+ {
+ bez.h1 = bez.h2 = HD_AUTO;
+ bez.ipo = BEZT_IPO_LIN;
+ }
+ // bez.ipo = U.ipo_new; /* use default interpolation mode here... */
bez.f1 = bez.f2 = bez.f3 = SELECT;
- bez.h1 = bez.h2 = HD_AUTO;
+
insert_bezt_fcurve(fcu, &bez, 0);
}
@@ -147,14 +171,18 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
unused_curves.push_back(*it);
}
+
void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
{
for (unsigned int i = 0; i < cu->totvert; i++) {
// TODO convert handles too
cu->bezt[i].vec[1][1] *= M_PI / 180.0f;
+ cu->bezt[i].vec[0][1] *= M_PI / 180.0f;
+ cu->bezt[i].vec[2][1] *= M_PI / 180.0f;
}
}
+
void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated)
{
bAction *act;
@@ -253,11 +281,12 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim)
switch (interp) {
case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR:
case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
+ case COLLADAFW::AnimationCurve::INTERPOLATION_STEP:
animation_to_fcurves(curve);
break;
default:
// TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types
- fprintf(stderr, "CARDINAL, HERMITE, BSPLINE and STEP anim interpolation types not supported yet.\n");
+ fprintf(stderr, "CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n");
break;
}
}
@@ -277,10 +306,11 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim)
bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* animlist)
{
const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId();
-
+
animlist_map[animlist_id] = animlist;
-
+
#if 0
+
// should not happen
if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
return true;
@@ -288,119 +318,7 @@ bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* ani
// for bones rna_path is like: pose.bones["bone-name"].rotation
- // what does this AnimationList animate?
- Animation& animated = uid_animated_map[animlist_id];
- Object *ob = animated.ob;
-
- char rna_path[100];
- char joint_path[100];
- bool is_joint = false;
-
- // if ob is NULL, it should be a JOINT
- if (!ob) {
- ob = armature_importer->get_armature_for_joint(animated.node);
-
- if (!ob) {
- fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node));
- return true;
- }
-
- armature_importer->get_rna_path_for_joint(animated.node, joint_path, sizeof(joint_path));
-
- is_joint = true;
- }
-
- const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
-
- switch (animated.tm->getTransformationType()) {
- case COLLADAFW::Transformation::TRANSLATE:
- case COLLADAFW::Transformation::SCALE:
- {
- bool loc = animated.tm->getTransformationType() == COLLADAFW::Transformation::TRANSLATE;
- if (is_joint)
- BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
- else
- BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
-
- for (int i = 0; i < bindings.getCount(); i++) {
- const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
- COLLADAFW::UniqueId anim_uid = binding.animation;
-
- if (curve_map.find(anim_uid) == curve_map.end()) {
- fprintf(stderr, "Cannot find FCurve by animation UID.\n");
- continue;
- }
-
- std::vector<FCurve*>& fcurves = curve_map[anim_uid];
-
- switch (binding.animationClass) {
- case COLLADAFW::AnimationList::POSITION_X:
- add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
- break;
- case COLLADAFW::AnimationList::POSITION_Y:
- add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
- break;
- case COLLADAFW::AnimationList::POSITION_Z:
- add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
- break;
- case COLLADAFW::AnimationList::POSITION_XYZ:
- add_fcurves_to_object(ob, fcurves, rna_path, -1, &animated);
- break;
- default:
- fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
- binding.animationClass, loc ? "TRANSLATE" : "SCALE");
- }
- }
- }
- break;
- case COLLADAFW::Transformation::ROTATE:
- {
- if (is_joint)
- BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
- else
- BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
-
- COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm;
- COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
-
- for (int i = 0; i < bindings.getCount(); i++) {
- const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
- COLLADAFW::UniqueId anim_uid = binding.animation;
-
- if (curve_map.find(anim_uid) == curve_map.end()) {
- fprintf(stderr, "Cannot find FCurve by animation UID.\n");
- continue;
- }
- std::vector<FCurve*>& fcurves = curve_map[anim_uid];
-
- switch (binding.animationClass) {
- case COLLADAFW::AnimationList::ANGLE:
- if (COLLADABU::Math::Vector3::UNIT_X == axis) {
- add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
- }
- else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
- add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
- }
- else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
- add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
- }
- break;
- case COLLADAFW::AnimationList::AXISANGLE:
- // TODO convert axis-angle to quat? or XYZ?
- default:
- fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
- binding.animationClass);
- }
- }
- }
- break;
- case COLLADAFW::Transformation::MATRIX:
- case COLLADAFW::Transformation::SKEW:
- case COLLADAFW::Transformation::LOOKAT:
- fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n");
- break;
- }
#endif
return true;
@@ -512,66 +430,700 @@ virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act)
}
#endif
-// prerequisites:
-// animlist_map - map animlist id -> animlist
-// curve_map - map anim id -> curve(s)
-Object *AnimationImporter::translate_animation(COLLADAFW::Node *node,
- std::map<COLLADAFW::UniqueId, Object*>& object_map,
- std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
- COLLADAFW::Transformation::TransformationType tm_type,
- Object *par_job)
+
+//sets the rna_path and array index to curve
+void AnimationImporter::modify_fcurve(std::vector<FCurve*>* curves , char* rna_path , int array_index )
+{
+ std::vector<FCurve*>::iterator it;
+ int i;
+ for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) {
+ FCurve *fcu = *it;
+ fcu->rna_path = BLI_strdup(rna_path);
+
+ if (array_index == -1) fcu->array_index = i;
+ else fcu->array_index = array_index;
+
+ unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
+ }
+}
+
+void AnimationImporter::find_frames( std::vector<float>* frames , std::vector<FCurve*>* curves)
{
- bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+ std::vector<FCurve*>::iterator iter;
+ for (iter = curves->begin(); iter != curves->end(); iter++) {
+ FCurve *fcu = *iter;
+
+ for (unsigned int k = 0; k < fcu->totvert; k++) {
+ //get frame value from bezTriple
+ float fra = fcu->bezt[k].vec[1][0];
+ //if frame already not added add frame to frames
+ if (std::find(frames->begin(), frames->end(), fra) == frames->end())
+ frames->push_back(fra);
+
+ }
+ }
+}
+
+//creates the rna_paths and array indices of fcurves from animations using transformation and bound animation class of each animation.
+void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation * transform ,
+ const COLLADAFW::AnimationList::AnimationBinding * binding,
+ std::vector<FCurve*>* curves, bool is_joint, char * joint_path)
+{
+ COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
- bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+ bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+
+ //to check if the no of curves are valid
+ bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE ||tm_type == COLLADAFW::Transformation::SCALE) && binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
+
+
+ if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) {
+ fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size());
+ return;
+ }
+
+ char rna_path[100];
+
+ switch (tm_type) {
+ case COLLADAFW::Transformation::TRANSLATE:
+ case COLLADAFW::Transformation::SCALE:
+ {
+ bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE;
+ if (is_joint)
+ BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
+ else
+ BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
+
+ switch (binding->animationClass) {
+ case COLLADAFW::AnimationList::POSITION_X:
+ modify_fcurve(curves, rna_path, 0 );
+ break;
+ case COLLADAFW::AnimationList::POSITION_Y:
+ modify_fcurve(curves, rna_path, 1 );
+ break;
+ case COLLADAFW::AnimationList::POSITION_Z:
+ modify_fcurve(curves, rna_path, 2 );
+ break;
+ case COLLADAFW::AnimationList::POSITION_XYZ:
+ modify_fcurve(curves, rna_path, -1 );
+ break;
+ default:
+ fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
+ binding->animationClass, loc ? "TRANSLATE" : "SCALE");
+ }
+ break;
+ }
+
+
+ case COLLADAFW::Transformation::ROTATE:
+ {
+ if (is_joint)
+ BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
+ else
+ BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
+ std::vector<FCurve*>::iterator iter;
+ for (iter = curves->begin(); iter != curves->end(); iter++) {
+ FCurve* fcu = *iter;
+
+ //if transform is rotation the fcurves values must be turned in to radian.
+ if (is_rotation)
+ fcurve_deg_to_rad(fcu);
+ }
+ COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)transform;
+ COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
+
+ switch (binding->animationClass) {
+ case COLLADAFW::AnimationList::ANGLE:
+ if (COLLADABU::Math::Vector3::UNIT_X == axis) {
+ modify_fcurve(curves, rna_path, 0 );
+ }
+ else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
+ modify_fcurve(curves, rna_path, 1 );
+ }
+ else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
+ modify_fcurve(curves, rna_path, 2 );
+ }
+ break;
+ case COLLADAFW::AnimationList::AXISANGLE:
+ // TODO convert axis-angle to quat? or XYZ?
+ default:
+ fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
+ binding->animationClass);
+ }
+ break;
+ }
+
+ case COLLADAFW::Transformation::MATRIX:
+ /*{
+ COLLADAFW::Matrix* mat = (COLLADAFW::Matrix*)transform;
+ COLLADABU::Math::Matrix4 mat4 = mat->getMatrix();
+ switch (binding->animationClass) {
+ case COLLADAFW::AnimationList::TRANSFORM:
+
+ }
+ }*/
+ break;
+ case COLLADAFW::Transformation::SKEW:
+ case COLLADAFW::Transformation::LOOKAT:
+ fprintf(stderr, "Animation of SKEW and LOOKAT transformations is not supported yet.\n");
+ break;
+ }
+
+}
- COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
- Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
+//creates the rna_paths and array indices of fcurves from animations using color and bound animation class of each animation.
+void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves ,char * anim_type)
+{
+ char rna_path[100];
+ BLI_strncpy(rna_path,anim_type, sizeof(rna_path));
+
+ 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];
+
+ switch (bindings[j].animationClass) {
+ case COLLADAFW::AnimationList::COLOR_R:
+ modify_fcurve(&animcurves, rna_path, 0 );
+ break;
+ case COLLADAFW::AnimationList::COLOR_G:
+ modify_fcurve(&animcurves, rna_path, 1 );
+ break;
+ case COLLADAFW::AnimationList::COLOR_B:
+ modify_fcurve(&animcurves, rna_path, 2 );
+ break;
+ case COLLADAFW::AnimationList::COLOR_RGB:
+ case COLLADAFW::AnimationList::COLOR_RGBA: // to do-> set intensity
+ modify_fcurve(&animcurves, rna_path, -1 );
+ break;
+
+ default:
+ fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
+ bindings[j].animationClass, "COLOR" );
+ }
+
+ 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;
+ BLI_addtail(AnimCurves, fcu);
+ }
+ }
+
+
+}
+
+void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, char * anim_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;
+ BLI_addtail(AnimCurves, fcu);
+ }
+ }
+ }
+
+}
+
+void AnimationImporter::apply_matrix_curves( Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root ,COLLADAFW::Node* node,
+ COLLADAFW::Transformation * tm )
+{
+ bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
+ char joint_path[200];
+ if ( is_joint )
+ armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
- if (!ob) {
+ std::vector<float> frames;
+ find_frames(&frames, &animcurves);
+
+ float irest_dae[4][4];
+ float rest[4][4], irest[4][4];
+
+ if (is_joint) {
+ get_joint_rest_mat(irest_dae, root, node);
+ invert_m4(irest_dae);
+
+ Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
+ if (!bone) {
+ fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
+ return;
+ }
+
+ unit_m4(rest);
+ copy_m4_m4(rest, bone->arm_mat);
+ invert_m4_m4(irest, rest);
+ }
+ // new curves to assign matrix transform animation
+ FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale
+ unsigned int totcu = 10 ;
+ const char *tm_str = NULL;
+ char rna_path[200];
+ for (int i = 0; i < totcu; i++) {
+
+ int axis = i;
+
+ if (i < 4) {
+ tm_str = "rotation_quaternion";
+ axis = i;
+ }
+ else if (i < 7) {
+ tm_str = "location";
+ axis = i - 4;
+ }
+ else {
+ tm_str = "scale";
+ axis = i - 7;
+ }
+
+
+ if (is_joint)
+ BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
+ else
+ strcpy(rna_path, tm_str);
+ newcu[i] = create_fcurve(axis, rna_path);
+ newcu[i]->totvert = frames.size();
+ }
+
+ if (frames.size() == 0)
+ return;
+
+std::sort(frames.begin(), frames.end());
+
+ std::vector<float>::iterator it;
+
+ // sample values at each frame
+ for (it = frames.begin(); it != frames.end(); it++) {
+ float fra = *it;
+
+ float mat[4][4];
+ float matfra[4][4];
+
+ unit_m4(matfra);
+
+ // calc object-space mat
+ evaluate_transform_at_frame(matfra, node, fra);
+
+
+ // for joints, we need a special matrix
+ if (is_joint) {
+ // special matrix: iR * M * iR_dae * R
+ // where R, iR are bone rest and inverse rest mats in world space (Blender bones),
+ // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
+ float temp[4][4], par[4][4];
+
+ // calc M
+ calc_joint_parent_mat_rest(par, NULL, root, node);
+ mul_m4_m4m4(temp, matfra, par);
+
+ // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
+
+ // calc special matrix
+ mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
+ }
+ else {
+ copy_m4_m4(mat, matfra);
+ }
+
+ float rot[4], loc[3], scale[3];
+
+ mat4_to_quat(rot, mat);
+ /*for ( int i = 0 ; i < 4 ; i ++ )
+ {
+ rot[i] = rot[i] * (180 / M_PI);
+ }*/
+ copy_v3_v3(loc, mat[3]);
+ mat4_to_size(scale, mat);
+
+ // add keys
+ for (int i = 0; i < totcu; i++) {
+ if (i < 4)
+ add_bezt(newcu[i], fra, rot[i]);
+ else if (i < 7)
+ add_bezt(newcu[i], fra, loc[i - 4]);
+ else
+ add_bezt(newcu[i], fra, scale[i - 7]);
+ }
+ }
+ verify_adt_action((ID*)&ob->id, 1);
+
+ ListBase *curves = &ob->adt->action->curves;
+
+ // add curves
+ for (int i= 0; i < totcu; i++) {
+ if (is_joint)
+ add_bone_fcurve(ob, node, newcu[i]);
+ else
+ BLI_addtail(curves, newcu[i]);
+ }
+
+ if (is_joint) {
+ bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
+ chan->rotmode = ROT_MODE_QUAT;
+ }
+ else {
+ ob->rotmode = ROT_MODE_QUAT;
+ }
+
+ return;
+
+}
+
+void AnimationImporter::translate_Animations ( COLLADAFW::Node * node ,
+ std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
+ std::map<COLLADAFW::UniqueId, Object*>& object_map,
+ std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map)
+{
+ AnimationImporter::AnimMix* animType = get_animation_type(node, FW_object_map );
+
+ bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+ COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
+ Object *ob = is_joint ? armature_importer->get_armature_for_joint(root) : object_map[node->getUniqueId()];
+ if (!ob)
+ {
fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
- return NULL;
+ return;
}
- // frames at which to sample
- std::vector<float> frames;
+ bAction * act;
+ bActionGroup *grp = NULL;
+
+ if ( (animType->transform) != 0 )
+ {
+ const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
+ char joint_path[200];
+
+ if ( is_joint )
+ armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
+
+
+ if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
+ else act = ob->adt->action;
+
+ //Get the list of animation curves of the object
+ ListBase *AnimCurves = &(act->curves);
+
+ const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
+
+ //for each transformation in node
+ for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ COLLADAFW::Transformation *transform = nodeTransforms[i];
+ COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
+
+ bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+ bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
+
+ const COLLADAFW::UniqueId& listid = transform->getAnimationList();
+
+ //check if transformation has animations
+ if (animlist_map.find(listid) == animlist_map.end()) continue ;
+ else
+ {
+ //transformation 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];
+ if ( is_matrix )
+ apply_matrix_curves(ob, animcurves, root , node, transform );
+ else {
+ //calculate rnapaths and array index of fcurves according to transformation and animation class
+ Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path );
+
+ 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;
+ if ((ob->type == OB_ARMATURE))
+ add_bone_fcurve( ob, node , fcu );
+ else
+ BLI_addtail(AnimCurves, fcu);
+ }
+ }
+ }
+ }
+ if (is_rotation) {
+ if (is_joint)
+ {
+ bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
+ chan->rotmode = ROT_MODE_EUL;
+ }
+ else
+ {
+ ob->rotmode = ROT_MODE_EUL;
+ }
+ }
+ }
+ }
+ if ((animType->light) != 0)
+ {
+ Lamp * lamp = (Lamp*) ob->data;
+
+ if (!lamp->adt || !lamp->adt->action) act = verify_adt_action((ID*)&lamp->id, 1);
+ else act = lamp->adt->action;
+
+ ListBase *AnimCurves = &(act->curves);
+ const COLLADAFW::InstanceLightPointerArray& nodeLights = node->getInstanceLights();
+
+ for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
+ const COLLADAFW::Light *light = (COLLADAFW::Light *) FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
+
+ if ((animType->light & LIGHT_COLOR) != 0)
+ {
+ const COLLADAFW::Color *col = &(light->getColor());
+ const COLLADAFW::UniqueId& listid = col->getAnimationList();
+
+ Assign_color_animations(listid, AnimCurves, "color");
+ }
+ if ((animType->light & LIGHT_FOA) != 0 )
+ {
+ const COLLADAFW::AnimatableFloat *foa = &(light->getFallOffAngle());
+ const COLLADAFW::UniqueId& listid = foa->getAnimationList();
+
+ Assign_float_animations( listid ,AnimCurves, "spot_size");
+ }
+ if ( (animType->light & LIGHT_FOE) != 0 )
+ {
+ const COLLADAFW::AnimatableFloat *foe = &(light->getFallOffExponent());
+ const COLLADAFW::UniqueId& listid = foe->getAnimationList();
+
+ Assign_float_animations( listid ,AnimCurves, "spot_blend");
+
+ }
+ }
+ }
+
+ if ( (animType->camera) != 0)
+ {
+ Camera * camera = (Camera*) ob->data;
+
+ 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();
+
+ for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
+ const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
+
+ if ((animType->camera & CAMERA_XFOV) != 0 )
+ {
+ const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov());
+ const COLLADAFW::UniqueId& listid = xfov->getAnimationList();
+ Assign_float_animations( listid ,AnimCurves, "lens");
+ }
+
+ else if ((animType->camera & CAMERA_XMAG) != 0 )
+ {
+ const COLLADAFW::AnimatableFloat *xmag = &(camera->getXMag());
+ const COLLADAFW::UniqueId& listid = xmag->getAnimationList();
+ Assign_float_animations( listid ,AnimCurves, "ortho_scale");
+ }
+
+ if ((animType->camera & CAMERA_ZFAR) != 0 )
+ {
+ const COLLADAFW::AnimatableFloat *zfar = &(camera->getFarClippingPlane());
+ const COLLADAFW::UniqueId& listid = zfar->getAnimationList();
+ Assign_float_animations( listid ,AnimCurves, "clip_end");
+ }
+
+ if ((animType->camera & CAMERA_ZNEAR) != 0 )
+ {
+ const COLLADAFW::AnimatableFloat *znear = &(camera->getNearClippingPlane());
+ const COLLADAFW::UniqueId& listid = znear->getAnimationList();
+ Assign_float_animations( listid ,AnimCurves, "clip_start");
+ }
+
+ }
+ }
+ if ( animType->material != 0){
+ Material *ma = give_current_material(ob, 1);
+ if (!ma->adt || !ma->adt->action) act = verify_adt_action((ID*)&ma->id, 1);
+ else act = ma->adt->action;
+
+ ListBase *AnimCurves = &(act->curves);
+
+ const COLLADAFW::InstanceGeometryPointerArray& nodeGeoms = node->getInstanceGeometries();
+ for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
+ const COLLADAFW::MaterialBindingArray& matBinds = nodeGeoms[i]->getMaterialBindings();
+ for (unsigned int j = 0; j < matBinds.getCount(); j++) {
+ const COLLADAFW::UniqueId & matuid = matBinds[j].getReferencedMaterial();
+ const COLLADAFW::Effect *ef = (COLLADAFW::Effect *) (FW_object_map[matuid]);
+ const COLLADAFW::CommonEffectPointerArray& commonEffects = ef->getCommonEffects();
+ COLLADAFW::EffectCommon *efc = commonEffects[0];
+ if((animType->material & MATERIAL_SHININESS) != 0){
+ const COLLADAFW::FloatOrParam *shin = &(efc->getShininess());
+ const COLLADAFW::UniqueId& listid = shin->getAnimationList();
+ Assign_float_animations( listid, AnimCurves , "specular_hardness" );
+ }
+
+ if((animType->material & MATERIAL_IOR) != 0){
+ const COLLADAFW::FloatOrParam *ior = &(efc->getIndexOfRefraction());
+ const COLLADAFW::UniqueId& listid = ior->getAnimationList();
+ Assign_float_animations( listid, AnimCurves , "raytrace_transparency.ior" );
+ }
+
+ if((animType->material & MATERIAL_SPEC_COLOR) != 0){
+ const COLLADAFW::ColorOrTexture *cot = &(efc->getSpecular());
+ const COLLADAFW::UniqueId& listid = cot->getColor().getAnimationList();
+ Assign_color_animations( listid, AnimCurves , "specular_color" );
+ }
+
+ if((animType->material & MATERIAL_DIFF_COLOR) != 0){
+ const COLLADAFW::ColorOrTexture *cot = &(efc->getDiffuse());
+ const COLLADAFW::UniqueId& listid = cot->getColor().getAnimationList();
+ Assign_color_animations( listid, AnimCurves , "diffuse_color" );
+ }
+ }
+ }
+ }
+}
+
+
+//Check if object is animated by checking if animlist_map holds the animlist_id of node transforms
+AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLADAFW::Node * node ,
+ std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map)
+{
+ AnimMix *types = new AnimMix();
+
+ const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
+
+ //for each transformation in node
+ for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ COLLADAFW::Transformation *transform = nodeTransforms[i];
+ const COLLADAFW::UniqueId& listid = transform->getAnimationList();
+
+ //check if transformation has animations
+ if (animlist_map.find(listid) == animlist_map.end()) continue ;
+ else
+ {
+ types->transform = types->transform|NODE_TRANSFORM;
+ break;
+ }
+ }
+ const COLLADAFW::InstanceLightPointerArray& nodeLights = node->getInstanceLights();
+
+ for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
+ const COLLADAFW::Light *light = (COLLADAFW::Light *) FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
+ types->light = setAnimType(&(light->getColor()),(types->light), LIGHT_COLOR);
+ types->light = setAnimType(&(light->getFallOffAngle()),(types->light), LIGHT_FOA);
+ types->light = setAnimType(&(light->getFallOffExponent()),(types->light), LIGHT_FOE);
+
+ if ( types->light != 0) break;
+
+ }
+
+ const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras();
+ for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
+ const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
+
+ if ( camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE )
+ {
+ types->camera = setAnimType(&(camera->getXMag()),(types->camera), CAMERA_XFOV);
+ }
+ else
+ {
+ types->camera = setAnimType(&(camera->getXMag()),(types->camera), CAMERA_XMAG);
+ }
+ types->camera = setAnimType(&(camera->getFarClippingPlane()),(types->camera), CAMERA_ZFAR);
+ types->camera = setAnimType(&(camera->getNearClippingPlane()),(types->camera), CAMERA_ZNEAR);
+
+ if ( types->camera != 0) break;
+
+ }
+
+ const COLLADAFW::InstanceGeometryPointerArray& nodeGeoms = node->getInstanceGeometries();
+ for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
+ const COLLADAFW::MaterialBindingArray& matBinds = nodeGeoms[i]->getMaterialBindings();
+ for (unsigned int j = 0; j < matBinds.getCount(); j++) {
+ const COLLADAFW::UniqueId & matuid = matBinds[j].getReferencedMaterial();
+ const COLLADAFW::Effect *ef = (COLLADAFW::Effect *) (FW_object_map[matuid]);
+ const COLLADAFW::CommonEffectPointerArray& commonEffects = ef->getCommonEffects();
+ COLLADAFW::EffectCommon *efc = commonEffects[0];
+ types->material = setAnimType(&(efc->getShininess()),(types->material), MATERIAL_SHININESS);
+ types->material = setAnimType(&(efc->getSpecular().getColor()),(types->material), MATERIAL_SPEC_COLOR);
+ types->material = setAnimType(&(efc->getDiffuse().getColor()),(types->material), MATERIAL_DIFF_COLOR);
+ // types->material = setAnimType(&(efc->get()),(types->material), MATERIAL_TRANSPARENCY);
+ types->material = setAnimType(&(efc->getIndexOfRefraction()),(types->material), MATERIAL_IOR);
+ }
+ }
+ return types;
+}
+
+int AnimationImporter::setAnimType ( const COLLADAFW::Animatable * prop , int types, int addition)
+{
+ const COLLADAFW::UniqueId& listid = prop->getAnimationList();
+ if (animlist_map.find(listid) != animlist_map.end())
+ return types|addition;
+ else return types;
+}
+
+// Is not used anymore.
+void AnimationImporter::find_frames_old(std::vector<float> * frames, COLLADAFW::Node * node , COLLADAFW::Transformation::TransformationType tm_type)
+{
+ bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
+ bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
// for each <rotate>, <translate>, etc. there is a separate Transformation
- const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
+ const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
unsigned int i;
-
// find frames at which to sample plus convert all rotation keys to radians
- for (i = 0; i < tms.getCount(); i++) {
- COLLADAFW::Transformation *tm = tms[i];
- COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
+ for (i = 0; i < nodeTransforms.getCount(); i++) {
+ COLLADAFW::Transformation *transform = nodeTransforms[i];
+ COLLADAFW::Transformation::TransformationType nodeTmType = transform->getTransformationType();
- if (type == tm_type) {
- const COLLADAFW::UniqueId& listid = tm->getAnimationList();
+ if (nodeTmType == tm_type) {
+ //get animation bindings for the current transformation
+ const COLLADAFW::UniqueId& listid = transform->getAnimationList();
+ //if transform is animated its animlist must exist.
if (animlist_map.find(listid) != animlist_map.end()) {
+
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
-
+
if (bindings.getCount()) {
+ //for each AnimationBinding get the fcurves which animate the transform
for (unsigned int j = 0; j < bindings.getCount(); j++) {
std::vector<FCurve*>& curves = curve_map[bindings[j].animation];
- bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
+ bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE || nodeTmType == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
std::vector<FCurve*>::iterator iter;
for (iter = curves.begin(); iter != curves.end(); iter++) {
FCurve *fcu = *iter;
-
+
+ //if transform is rotation the fcurves values must be turned in to radian.
if (is_rotation)
fcurve_deg_to_rad(fcu);
for (unsigned int k = 0; k < fcu->totvert; k++) {
+ //get frame value from bezTriple
float fra = fcu->bezt[k].vec[1][0];
- if (std::find(frames.begin(), frames.end(), fra) == frames.end())
- frames.push_back(fra);
+ //if frame already not added add frame to frames
+ if (std::find(frames->begin(), frames->end(), fra) == frames->end())
+ frames->push_back(fra);
}
}
}
@@ -583,7 +1135,39 @@ Object *AnimationImporter::translate_animation(COLLADAFW::Node *node,
}
}
}
+}
+
+
+
+// prerequisites:
+// animlist_map - map animlist id -> animlist
+// curve_map - map anim id -> curve(s)
+Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
+ std::map<COLLADAFW::UniqueId, Object*>& object_map,
+ std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
+ COLLADAFW::Transformation::TransformationType tm_type,
+ Object *par_job)
+{
+
+ bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+ bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
+ bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+
+ COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
+ Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
+ const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
+ if (!ob) {
+ fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
+ return NULL;
+ }
+ // frames at which to sample
+ std::vector<float> frames;
+
+ find_frames_old(&frames, node , tm_type);
+
+ unsigned int i;
+
float irest_dae[4][4];
float rest[4][4], irest[4][4];
@@ -664,7 +1248,6 @@ Object *AnimationImporter::translate_animation(COLLADAFW::Node *node,
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
else
strcpy(rna_path, tm_str);
-
newcu[i] = create_fcurve(axis, rna_path);
#ifdef ARMATURE_TEST
@@ -812,7 +1395,7 @@ Object *AnimationImporter::translate_animation(COLLADAFW::Node *node,
}
// internal, better make it private
-// warning: evaluates only rotation
+// warning: evaluates only rotation and only assigns matrix transforms now
// prerequisites: animlist_map, curve_map
void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra)
{
@@ -826,10 +1409,12 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::
float m[4][4];
unit_m4(m);
+ if ( type != COLLADAFW::Transformation::MATRIX )
+ continue;
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
if (!evaluate_animation(tm, m, fra, nodename.c_str())) {
- switch (type) {
+ /*switch (type) {
case COLLADAFW::Transformation::ROTATE:
dae_rotate_to_mat4(tm, m);
break;
@@ -844,7 +1429,9 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::
break;
default:
fprintf(stderr, "unsupported transformation type %d\n", type);
- }
+ }*/
+ dae_matrix_to_mat4(tm, m);
+
}
float temp[4][4];
@@ -880,9 +1467,9 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float
bool is_scale = (type == COLLADAFW::Transformation::SCALE);
bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE);
- if (type == COLLADAFW::Transformation::SCALE)
+ if (is_scale)
dae_scale_to_v3(tm, vec);
- else if (type == COLLADAFW::Transformation::TRANSLATE)
+ else if (is_translate)
dae_translate_to_v3(tm, vec);
for (unsigned int j = 0; j < bindings.getCount(); j++) {
@@ -910,7 +1497,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float
if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
fprintf(stderr, "%s: UNKNOWN animation class\n", path);
- continue;
+ //continue;
}
if (type == COLLADAFW::Transformation::ROTATE) {
@@ -980,10 +1567,13 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float
i++;
j = 0;
}
+ unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), *it), unused_curves.end());
}
COLLADAFW::Matrix tm(matrix);
dae_matrix_to_mat4(&tm, mat);
+
+ std::vector<FCurve*>::iterator it;
return true;
}
@@ -1150,13 +1740,15 @@ void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurv
void AnimationImporter::add_bezt(FCurve *fcu, float fra, float value)
{
+ //float fps = (float)FPS;
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));
- bez.vec[1][0] = fra;
+ bez.vec[1][0] = fra ;
bez.vec[1][1] = value;
- bez.ipo = U.ipo_new; /* use default interpolation mode here... */
+ bez.ipo = BEZT_IPO_LIN ;/* use default interpolation mode here... */
bez.f1 = bez.f2 = bez.f3 = SELECT;
bez.h1 = bez.h2 = HD_AUTO;
insert_bezt_fcurve(fcu, &bez, 0);
calchandles_fcurve(fcu);
}
+
diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h
index 05347a1fbc1..18303eb2f0b 100644
--- a/source/blender/collada/AnimationImporter.h
+++ b/source/blender/collada/AnimationImporter.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory , Sukhitha Jayathilake.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -37,10 +37,17 @@
#include "COLLADAFWAnimationList.h"
#include "COLLADAFWNode.h"
#include "COLLADAFWUniqueId.h"
+#include "COLLADAFWLight.h"
+#include "COLLADAFWCamera.h"
+#include "COLLADAFWMaterial.h"
+#include "COLLADAFWEffect.h"
+#include "COLLADAFWInstanceGeometry.h"
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_camera_types.h"
//#include "ArmatureImporter.h"
#include "TransformReader.h"
@@ -79,6 +86,49 @@ private:
void fcurve_deg_to_rad(FCurve *cu);
void add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated);
+
+ int typeFlag;
+
+ enum lightAnim
+ {
+// INANIMATE = 0,
+ LIGHT_COLOR = 2,
+ LIGHT_FOA = 4,
+ LIGHT_FOE = 8
+ };
+
+ enum cameraAnim
+ {
+// INANIMATE = 0,
+ CAMERA_XFOV = 2,
+ CAMERA_XMAG = 4,
+ CAMERA_ZFAR = 8,
+ CAMERA_ZNEAR = 16
+ };
+
+ enum matAnim
+ {
+ MATERIAL_SHININESS = 2,
+ MATERIAL_SPEC_COLOR = 4,
+ MATERIAL_DIFF_COLOR = 1 << 3,
+ MATERIAL_TRANSPARENCY = 1 << 4,
+ MATERIAL_IOR = 1 << 5
+ };
+
+ enum AnimationType
+ {
+ INANIMATE = 0,
+ NODE_TRANSFORM = 1,
+ };
+
+ struct AnimMix
+ {
+ int transform;
+ int light;
+ int camera;
+ int material;
+ int texture;
+ };
public:
AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene);
@@ -94,16 +144,38 @@ public:
#if 0
virtual void change_eul_to_quat(Object *ob, bAction *act);
#endif
+
+ void translate_Animations( COLLADAFW::Node * Node ,
+ std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
+ std::map<COLLADAFW::UniqueId, Object*>& object_map ,
+ std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map);
+
+ AnimMix* get_animation_type( const COLLADAFW::Node * node , std::map<COLLADAFW::UniqueId,const COLLADAFW::Object*> FW_object_map ) ;
+
+ void apply_matrix_curves( Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root ,COLLADAFW::Node* node,
+ COLLADAFW::Transformation * tm );
+
+ void Assign_transform_animations(COLLADAFW::Transformation* transform ,
+ const COLLADAFW::AnimationList::AnimationBinding * binding,
+ std::vector<FCurve*>* curves, bool is_joint, char * joint_path);
+ void Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves ,char * anim_type);
+ void Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, char * anim_type);
+
+ int setAnimType ( const COLLADAFW::Animatable * prop , int type, int addition);
+
+ void modify_fcurve(std::vector<FCurve*>* curves , char* rna_path , int array_index );
// prerequisites:
// animlist_map - map animlist id -> animlist
// curve_map - map anim id -> curve(s)
- Object *translate_animation(COLLADAFW::Node *node,
+ Object * translate_animation_OLD(COLLADAFW::Node *node,
std::map<COLLADAFW::UniqueId, Object*>& object_map,
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
COLLADAFW::Transformation::TransformationType tm_type,
Object *par_job = NULL);
-
+
+ void find_frames( std::vector<float>* frames , std::vector<FCurve*>* curves );
+ void find_frames_old( std::vector<float>* frames, COLLADAFW::Node * node, COLLADAFW::Transformation::TransformationType tm_type );
// internal, better make it private
// warning: evaluates only rotation
// prerequisites: animlist_map, curve_map
@@ -131,6 +203,8 @@ public:
void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu);
void add_bezt(FCurve *fcu, float fra, float value);
+
+ void extra_data_importer(std::string elementName);
};
#endif
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index ad9098db3d8..92d06bb639f 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -39,6 +39,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "ED_armature.h"
#include "BLI_listbase.h"
@@ -177,6 +178,9 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm)
node.setNodeName(node_name);
node.setNodeSid(node_sid);
+ /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2)
+ add_blender_leaf_bone( bone, ob_arm , node );
+ else{*/
node.start();
add_bone_transform(ob_arm, bone, node);
@@ -184,10 +188,26 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm)
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
add_bone_node(child, ob_arm);
}
+ node.end();
+ //}
+}
+void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
+{
+ node.start();
+
+ add_bone_transform(ob_arm, bone, node);
+
+ node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0] );
+ node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1] );
+ 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);
+ }
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);
@@ -207,7 +227,7 @@ void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW:
mul_m4_m4m4(mat, pchan->pose_mat, ob_arm->obmat);
}
- TransformWriter::add_node_transform(node, mat, NULL);
+ TransformWriter::add_node_transform(node, mat,NULL );
}
std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob)
@@ -351,17 +371,12 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase
bPoseChannel *pchan = get_pose_channel(pose, def->name);
- float pose_mat[4][4];
float mat[4][4];
float world[4][4];
float inv_bind_mat[4][4];
- // pose_mat is the same as pchan->pose_mat, but without the rotation
- unit_m4(pose_mat);
- translate_m4(pose_mat, pchan->pose_head[0], pchan->pose_head[1], pchan->pose_head[2]);
-
- // make world-space matrix, pose_mat is armature-space
- mul_m4_m4m4(world, pose_mat, ob_arm->obmat);
+ // make world-space matrix, arm_mat is armature-space
+ mul_m4_m4m4(world, pchan->bone->arm_mat, ob_arm->obmat);
invert_m4_m4(mat, world);
converter.mat4_to_dae(inv_bind_mat, mat);
diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h
index f4488942f7b..b3441c797e8 100644
--- a/source/blender/collada/ArmatureExporter.h
+++ b/source/blender/collada/ArmatureExporter.h
@@ -92,6 +92,8 @@ private:
void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
+ void add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node);
+
std::string get_controller_id(Object *ob_arm, Object *ob);
// ob should be of type OB_MESH
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 8b8e89fd4f5..1e7879b352f 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory, Sukhitha jayathilake.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -37,6 +37,7 @@
#include "BKE_action.h"
#include "BKE_depsgraph.h"
#include "BKE_object.h"
+#include "BKE_armature.h"
#include "BLI_string.h"
#include "ED_armature.h"
@@ -78,16 +79,104 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
return &joint_index_to_joint_info_map[joint_index];
}
#endif
+void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *parent, int totchild,
+ float parent_mat[][4], Object * ob_arm)
+{
+ std::vector<COLLADAFW::Node*>::iterator it;
+ it = std::find(finished_joints.begin(),finished_joints.end(),node);
+ if ( it != finished_joints.end()) return;
+
+ float mat[4][4];
+ float obmat[4][4];
+
+ // object-space
+ get_node_mat(obmat, node, NULL, NULL);
+
+ EditBone *bone = ED_armature_edit_bone_add((bArmature*)ob_arm->data, (char*)bc_get_joint_name(node));
+ totbone++;
+
+ bPoseChannel *pchan = get_pose_channel(ob_arm->pose, (char*)bc_get_joint_name(node));
+
+ if (parent) bone->parent = parent;
+
+ float angle = 0;
+
+ // get world-space
+ if (parent){
+ mul_m4_m4m4(mat, obmat, parent_mat);
+
+ }
+ else {
+ copy_m4_m4(mat, obmat);
+
+ }
+ float loc[3], size[3], rot[3][3];
+ mat4_to_loc_rot_size( loc, rot, size, obmat);
+ mat3_to_vec_roll(rot, NULL, &angle );
+ bone->roll=angle;
+ // set head
+ copy_v3_v3(bone->head, mat[3]);
+
+
+ // set tail, don't set it to head because 0-length bones are not allowed
+ float vec[3] = {0.0f, 0.5f, 0.0f};
+ add_v3_v3v3(bone->tail, bone->head, vec);
+
+ // set parent tail
+ if (parent && totchild == 1) {
+ copy_v3_v3(parent->tail, bone->head);
+
+ // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
+ // bone->flag |= BONE_CONNECTED;
+
+ // XXX increase this to prevent "very" small bones?
+ const float epsilon = 0.000001f;
+
+ // derive leaf bone length
+ float length = len_v3v3(parent->head, parent->tail);
+ if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
+ leaf_bone_length = length;
+ }
+
+ // treat zero-sized bone like a leaf bone
+ if (length <= epsilon) {
+ add_leaf_bone(parent_mat, parent, node);
+ }
+
+ }
+
+ COLLADAFW::NodePointerArray& children = node->getChildNodes();
+ for (unsigned int i = 0; i < children.getCount(); i++) {
+ create_unskinned_bone( children[i], bone, children.getCount(), mat, ob_arm);
+ }
+
+ // in second case it's not a leaf bone, but we handle it the same way
+ if (!children.getCount() || children.getCount() > 1) {
+ add_leaf_bone(mat, bone, node);
+ }
+
+ finished_joints.push_back(node);
+
+}
void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[][4], bArmature *arm)
{
+ //Checking if bone is already made.
+ std::vector<COLLADAFW::Node*>::iterator it;
+ it = std::find(finished_joints.begin(),finished_joints.end(),node);
+ if ( it != finished_joints.end()) return;
+
float joint_inv_bind_mat[4][4];
// JointData* jd = get_joint_data(node);
float mat[4][4];
+ // TODO rename from Node "name" attrs later
+ EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node));
+ totbone++;
+
if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
// get original world-space matrix
invert_m4_m4(mat, joint_inv_bind_mat);
@@ -104,12 +193,14 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
mul_m4_m4m4(mat, obmat, parent_mat);
else
copy_m4_m4(mat, obmat);
- }
- // TODO rename from Node "name" attrs later
- EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node));
- totbone++;
+ float loc[3], size[3], rot[3][3] , angle;
+ mat4_to_loc_rot_size( loc, rot, size, obmat);
+ mat3_to_vec_roll(rot, NULL, &angle );
+ bone->roll=angle;
+ }
+
if (parent) bone->parent = parent;
// set head
@@ -137,7 +228,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
// treat zero-sized bone like a leaf bone
if (length <= epsilon) {
- add_leaf_bone(parent_mat, parent);
+ add_leaf_bone(parent_mat, parent, node);
}
/*
@@ -175,22 +266,42 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
// in second case it's not a leaf bone, but we handle it the same way
if (!children.getCount() || children.getCount() > 1) {
- add_leaf_bone(mat, bone);
+ add_leaf_bone(mat, bone , node);
}
+
+ finished_joints.push_back(node);
}
-void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone)
+void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node)
{
LeafBone leaf;
leaf.bone = bone;
copy_m4_m4(leaf.mat, mat);
BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
-
- leaf_bones.push_back(leaf);
+
+ float vec[3];
+
+ TagsMap::iterator etit;
+ ExtraTags *et = 0;
+ etit = uid_tags_map.find(node->getUniqueId().toAscii());
+ if(etit != uid_tags_map.end())
+ {
+ et = etit->second;
+ //else return;
+
+ float x,y,z;
+ et->setData("tip_x",&x);
+ et->setData("tip_y",&y);
+ et->setData("tip_z",&z);
+ float vec[3] = {x,y,z};
+ copy_v3_v3(leaf.bone->tail, leaf.bone->head);
+ add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
+ }else
+ leaf_bones.push_back(leaf);
}
-void ArmatureImporter::fix_leaf_bones()
+void ArmatureImporter::fix_leaf_bones( )
{
// just setting tail for leaf bones here
@@ -200,8 +311,8 @@ void ArmatureImporter::fix_leaf_bones()
// pointing up
float vec[3] = {0.0f, 0.0f, 1.0f};
-
- mul_v3_fl(vec, leaf_bone_length);
+
+ //mul_v3_fl(vec, leaf_bone_length);
copy_v3_v3(leaf.bone->tail, leaf.bone->head);
add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
@@ -300,6 +411,46 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm)
return armature_joints.back();
}
#endif
+void ArmatureImporter::create_armature_bones( )
+{
+ std::vector<COLLADAFW::Node*>::iterator ri;
+ //if there is an armature created for root_joint next root_joint
+ for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
+ if ( get_armature_for_joint(*ri) != NULL ) continue;
+
+ //add armature object for current joint
+ //Object *ob_arm = add_object(scene, OB_ARMATURE);
+
+ Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
+ //ob_arm->type = OB_ARMATURE;
+ ED_armature_to_edit(ob_arm);
+
+ // min_angle = 360.0f; // minimum angle between bone head-tail and a row of bone matrix
+
+ // create unskinned bones
+ /*
+ TODO:
+ check if bones have already been created for a given joint
+ */
+ leaf_bone_length = FLT_MAX;
+ create_unskinned_bone(*ri, NULL, (*ri)->getChildNodes().getCount(), NULL, ob_arm);
+
+ fix_leaf_bones();
+
+ // exit armature edit mode
+
+ unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
+
+ ED_armature_from_edit(ob_arm);
+
+ set_pose(ob_arm , *ri, NULL, NULL );
+
+ ED_armature_edit_free(ob_arm);
+ DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
+ }
+
+
+}
void ArmatureImporter::create_armature_bones(SkinInfo& skin)
{
@@ -373,7 +524,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
if (shared)
ob_arm = skin.set_armature(shared);
else
- ob_arm = skin.create_armature(scene);
+ ob_arm = skin.create_armature(scene); //once for every armature
// enter armature edit mode
ED_armature_to_edit(ob_arm);
@@ -420,14 +571,61 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// root - if this joint is the top joint in hierarchy, if a joint
// is a child of a node (not joint), root should be true since
// this is where we build armature bones from
-void ArmatureImporter::add_joint(COLLADAFW::Node *node, bool root, Object *parent)
+
+void ArmatureImporter::set_pose ( Object * ob_arm , COLLADAFW::Node * root_node , char *parentname, float parent_mat[][4])
+{
+ char * bone_name = (char *) bc_get_joint_name ( root_node);
+ float mat[4][4];
+ float obmat[4][4];
+
+ bArmature * arm = (bArmature * ) ob_arm-> data ;
+ float ax[3];
+ float angle = NULL;
+
+ // object-space
+ get_node_mat(obmat, root_node, NULL, NULL);
+
+ //if(*edbone)
+ bPoseChannel * pchan = get_pose_channel(ob_arm -> pose , bone_name);
+ //else fprintf ( "",
+
+ // get world-space
+ if (parentname){
+ mul_m4_m4m4(mat, obmat, parent_mat);
+ bPoseChannel *parchan = get_pose_channel(ob_arm->pose, parentname);
+
+ mul_m4_m4m4(pchan->pose_mat, mat , parchan->pose_mat);
+
+ }
+ else {
+ copy_m4_m4(mat, obmat);
+ float invObmat[4][4];
+ invert_m4_m4(invObmat, ob_arm->obmat);
+ mul_m4_m4m4(pchan->pose_mat, mat, invObmat);
+
+ }
+
+ mat4_to_axis_angle(ax,&angle,mat);
+ pchan->bone->roll = angle;
+
+
+ COLLADAFW::NodePointerArray& children = root_node->getChildNodes();
+ for (unsigned int i = 0; i < children.getCount(); i++) {
+ set_pose(ob_arm, children[i], bone_name, mat);
+ }
+
+}
+
+void ArmatureImporter::add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce)
{
joint_by_uid[node->getUniqueId()] = node;
if (root) {
root_joints.push_back(node);
- if (parent)
+ if (parent) {
+
joint_parent_map[node->getUniqueId()] = parent;
+ }
}
}
@@ -472,6 +670,9 @@ void ArmatureImporter::make_armatures(bContext *C)
// free memory stolen from SkinControllerData
skin.free();
}
+
+ //for bones without skins
+ create_armature_bones();
}
#if 0
@@ -549,6 +750,7 @@ bool ArmatureImporter::write_controller(const COLLADAFW::Controller* controller)
return true;
}
+
COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
{
if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end())
@@ -566,10 +768,20 @@ Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node)
if (skin.uses_joint_or_descendant(node))
return skin.get_armature();
}
-
+
+ std::map<COLLADAFW::UniqueId, Object*>::iterator arm;
+ for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) {
+ if(arm->first == node->getUniqueId() )
+ return arm->second;
+ }
return NULL;
}
+void ArmatureImporter::set_tags_map(TagsMap & tagsMap)
+{
+ this->uid_tags_map = tagsMap;
+}
+
void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count)
{
BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", bc_get_joint_name(node));
@@ -590,3 +802,6 @@ bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
return found;
}
+
+
+
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index d36bccf7e57..4f4aed210f2 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -46,6 +46,7 @@ extern "C" {
#include "MeshImporter.h"
#include "SkinInfo.h"
#include "TransformReader.h"
+#include "ExtraTags.h"
#include <map>
#include <vector>
@@ -88,7 +89,9 @@ private:
std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> geom_uid_by_controller_uid;
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> joint_by_uid; // contains all joints
std::vector<COLLADAFW::Node*> root_joints;
+ std::vector<COLLADAFW::Node*> finished_joints;
std::map<COLLADAFW::UniqueId, Object*> joint_parent_map;
+ std::map<COLLADAFW::UniqueId, Object*> unskinned_armature_map;
MeshImporterBase *mesh_importer;
AnimationImporterBase *anim_importer;
@@ -105,9 +108,15 @@ private:
void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[][4], bArmature *arm);
- void add_leaf_bone(float mat[][4], EditBone *bone);
+ void create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild,
+ float parent_mat[][4], Object * ob_arm);
+
+ void add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node);
void fix_leaf_bones();
+
+ void set_pose ( Object * ob_arm , COLLADAFW::Node * root_node ,char * parentname, float parent_mat[][4]);
+
#if 0
void set_leaf_bone_shapes(Object *ob_arm);
@@ -123,7 +132,11 @@ private:
#endif
void create_armature_bones(SkinInfo& skin);
+ void create_armature_bones( );
+ /** TagsMap typedef for uid_tags_map. */
+ typedef std::map<std::string, ExtraTags*> TagsMap;
+ TagsMap uid_tags_map;
public:
ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce);
@@ -132,7 +145,7 @@ public:
// root - if this joint is the top joint in hierarchy, if a joint
// is a child of a node (not joint), root should be true since
// this is where we build armature bones from
- void add_joint(COLLADAFW::Node *node, bool root, Object *parent);
+ void add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce);
#if 0
void add_root_joint(COLLADAFW::Node *node);
@@ -151,13 +164,16 @@ public:
bool write_controller(const COLLADAFW::Controller* controller);
COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid);
-
+
Object *get_armature_for_joint(COLLADAFW::Node *node);
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count);
// gives a world-space mat
bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint);
+
+ void set_tags_map( TagsMap& tags_map);
+
};
#endif
diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt
index 3466c3ab5c0..ffe3d5f4f85 100644
--- a/source/blender/collada/CMakeLists.txt
+++ b/source/blender/collada/CMakeLists.txt
@@ -44,6 +44,7 @@ set(INC_SYS
set(SRC
AnimationImporter.cpp
+ AnimationExporter.cpp
ArmatureExporter.cpp
ArmatureImporter.cpp
CameraExporter.cpp
@@ -66,6 +67,7 @@ set(SRC
collada_utils.cpp
AnimationImporter.h
+ AnimationExporter.h
ArmatureExporter.h
ArmatureImporter.h
CameraExporter.h
diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp
index 6ce9eb782d3..a935f45c403 100644
--- a/source/blender/collada/CameraExporter.cpp
+++ b/source/blender/collada/CameraExporter.cpp
@@ -73,19 +73,19 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
if (cam->type == CAM_PERSP) {
COLLADASW::PerspectiveOptic persp(mSW);
- persp.setXFov(lens_to_angle(cam->lens)*(180.0f/M_PI));
- persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch));
- persp.setZFar(cam->clipend);
- persp.setZNear(cam->clipsta);
+ persp.setXFov(lens_to_angle(cam->lens)*(180.0f/M_PI),"xfov");
+ persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch),false,"aspect_ratio");
+ persp.setZFar(cam->clipend, false , "zfar");
+ persp.setZNear(cam->clipsta,false , "znear");
COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name);
addCamera(ccam);
}
else {
COLLADASW::OrthographicOptic ortho(mSW);
- ortho.setXMag(cam->ortho_scale);
- ortho.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch));
- ortho.setZFar(cam->clipend);
- ortho.setZNear(cam->clipsta);
+ ortho.setXMag(cam->ortho_scale,"xmag");
+ ortho.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch),false,"aspect_ratio");
+ ortho.setZFar(cam->clipend , false , "zfar");
+ ortho.setZNear(cam->clipsta, false , "znear");
COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name);
addCamera(ccam);
}
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index b26318f6114..285ab283b37 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -114,6 +114,7 @@ extern char build_rev[];
#include "TransformWriter.h"
#include "ArmatureExporter.h"
+#include "AnimationExporter.h"
#include "CameraExporter.h"
#include "EffectExporter.h"
#include "GeometryExporter.h"
@@ -194,6 +195,7 @@ public:
Object *ob = base->object;
if (!ob->parent) {
+ if(sce->lay & ob->lay) {
switch(ob->type) {
case OB_MESH:
case OB_CAMERA:
@@ -207,6 +209,7 @@ public:
writeNodes(ob, sce);
break;
}
+ }
}
base= base->next;
@@ -301,636 +304,6 @@ public:
// TODO: it would be better to instantiate animations rather than create a new one per object
// COLLADA allows this through multiple <channel>s in <animation>.
// For this to work, we need to know objects that use a certain action.
-class AnimationExporter: COLLADASW::LibraryAnimations
-{
- Scene *scene;
- COLLADASW::StreamWriter *sw;
-
-public:
-
- AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) { this->sw = sw; }
-
-
-
- void exportAnimations(Scene *sce)
- {
- if(hasAnimations(sce)) {
- this->scene = sce;
-
- openLibrary();
-
- forEachObjectInScene(sce, *this);
-
- closeLibrary();
- }
- }
-
- // 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;
-
- 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];
-
- 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]);
-
- // check rna_path is one of: rotation, scale, location
-
- openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
-
- // create input source
- std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name);
-
- // create output source
- std::string 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->totvert, anim_id, axis_name);
-
- std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
- COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
- std::string empty;
- sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
- sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
-
- // this input is required
- sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
-
- addSampler(sampler);
-
- std::string target = translate_id(ob_name)
- + "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
- 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 (unsigned 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, 1);
-
- // 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];
- 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, false);
-
- 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());
-
- openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
-
- // create input source
- std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::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(COLLADASW::InputSemantic::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(sw, sampler_id);
- std::string empty;
- sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
- sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
-
- // TODO create in/out tangents source
-
- // this input is required
- sampler.addInput(COLLADASW::InputSemantic::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)
- {
- return FRA2TIME(frame);
- }
-
- float convert_angle(float angle)
- {
- return COLLADABU::Math::Utils::radToDegF(angle);
- }
-
- std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic)
- {
- switch(semantic) {
- case COLLADASW::InputSemantic::INPUT:
- return INPUT_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::OUTPUT:
- return OUTPUT_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::INTERPOLATION:
- return INTERPOLATION_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::IN_TANGENT:
- return INTANGENT_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::OUT_TANGENT:
- return OUTTANGENT_SOURCE_ID_SUFFIX;
- default:
- break;
- }
- return "";
- }
-
- void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
- COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis)
- {
- switch(semantic) {
- case COLLADASW::InputSemantic::INPUT:
- param.push_back("TIME");
- break;
- case COLLADASW::InputSemantic::OUTPUT:
- if (is_rot) {
- param.push_back("ANGLE");
- }
- else {
- if (axis) {
- param.push_back(axis);
- }
- else {
- param.push_back("X");
- param.push_back("Y");
- param.push_back("Z");
- }
- }
- break;
- case COLLADASW::InputSemantic::IN_TANGENT:
- case COLLADASW::InputSemantic::OUT_TANGENT:
- param.push_back("X");
- param.push_back("Y");
- break;
- default:
- break;
- }
- }
-
- void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length)
- {
- switch (semantic) {
- case COLLADASW::InputSemantic::INPUT:
- *length = 1;
- values[0] = convert_time(bezt->vec[1][0]);
- break;
- case COLLADASW::InputSemantic::OUTPUT:
- *length = 1;
- if (rotation) {
- values[0] = convert_angle(bezt->vec[1][1]);
- }
- else {
- values[0] = bezt->vec[1][1];
- }
- break;
- case COLLADASW::InputSemantic::IN_TANGENT:
- case COLLADASW::InputSemantic::OUT_TANGENT:
- // XXX
- *length = 2;
- break;
- default:
- *length = 0;
- break;
- }
- }
-
- std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name)
- {
- std::string source_id = anim_id + get_semantic_suffix(semantic);
-
- //bool is_rotation = !strcmp(fcu->rna_path, "rotation");
- bool is_rotation = false;
-
- if (strstr(fcu->rna_path, "rotation")) is_rotation = true;
-
- 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, is_rotation, axis_name);
-
- 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, is_rotation, values, &length);
- for (int j = 0; j < length; j++)
- source.appendValues(values[j]);
- }
-
- source.finish();
-
- return source_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 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(tot);
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, is_rot, axis_name);
-
- source.prepareToAppendValues();
-
- for (int i = 0; i < tot; i++) {
- float val = v[i];
- if (semantic == COLLADASW::InputSemantic::INPUT)
- val = convert_time(val);
- else if (is_rot)
- val = convert_angle(val);
- source.appendValues(val);
- }
-
- source.finish();
-
- return source_id;
- }
-
- 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)
- {
- 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(fra.size());
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, is_rot, axis_name);
-
- source.prepareToAppendValues();
-
- std::vector<float>::iterator it;
- for (it = fra.begin(); it != fra.end(); it++) {
- float val = *it;
- if (semantic == COLLADASW::InputSemantic::INPUT)
- val = convert_time(val);
- else if (is_rot)
- val = convert_angle(val);
- source.appendValues(val);
- }
-
- source.finish();
-
- return source_id;
- }
-
- // only used for sources with OUTPUT semantic
- std::string create_xyz_source(float *v, int tot, const std::string& anim_id)
- {
- COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
- 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(tot);
- source.setAccessorStride(3);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, false, NULL);
-
- source.prepareToAppendValues();
-
- for (int i = 0; i < tot; i++) {
- source.appendValues(*v, *(v + 1), *(v + 2));
- v += 3;
- }
-
- source.finish();
-
- return source_id;
- }
-
- std::string create_interpolation_source(int tot, const std::string& anim_id, const char *axis_name)
- {
- std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
-
- COLLADASW::NameSource source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(tot);
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("INTERPOLATION");
-
- source.prepareToAppendValues();
-
- for (int i = 0; i < tot; i++) {
- source.appendValues(LINEAR_NAME);
- }
-
- source.finish();
-
- return source_id;
- }
-
- // for rotation, axis name is always appended and the value of append_axis is ignored
- std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
- {
- std::string tm_name;
-
- // when given rna_path, determine tm_type from it
- if (rna_path) {
- char *name = extract_transform_name(rna_path);
-
- if (strstr(name, "rotation"))
- tm_type = 0;
- else if (!strcmp(name, "scale"))
- tm_type = 1;
- else if (!strcmp(name, "location"))
- tm_type = 2;
- else
- tm_type = -1;
- }
-
- switch (tm_type) {
- case 0:
- return std::string("rotation") + std::string(axis_name) + ".ANGLE";
- case 1:
- tm_name = "scale";
- break;
- case 2:
- tm_name = "location";
- break;
- default:
- tm_name = "";
- break;
- }
-
- if (tm_name.size()) {
- if (append_axis)
- return tm_name + std::string(".") + std::string(axis_name);
- else
- return tm_name;
- }
-
- return std::string("");
- }
-
- char *extract_transform_name(char *rna_path)
- {
- char *dot = strrchr(rna_path, '.');
- return dot ? (dot + 1) : rna_path;
- }
-
- void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
- {
- FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
-
- for (; fcu; fcu = fcu->next) {
- if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
- continue;
-
- char *name = extract_transform_name(fcu->rna_path);
- if (!strcmp(name, tm_name)) {
- for (unsigned int i = 0; i < fcu->totvert; i++) {
- float f = fcu->bezt[i].vec[1][0];
- if (std::find(fra.begin(), fra.end(), f) == fra.end())
- fra.push_back(f);
- }
- }
- }
-
- // keep the keys in ascending order
- std::sort(fra.begin(), fra.end());
- }
-
- void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode)
- {
- if (rotmode > 0)
- find_frames(ob, fra, prefix, "rotation_euler");
- else if (rotmode == ROT_MODE_QUAT)
- find_frames(ob, fra, prefix, "rotation_quaternion");
- /*else if (rotmode == ROT_MODE_AXISANGLE)
- ;*/
- }
-
- // enable fcurves driving a specific bone, disable all the rest
- // if bone_name = NULL enable all fcurves
- void enable_fcurves(bAction *act, char *bone_name)
- {
- FCurve *fcu;
- char prefix[200];
-
- if (bone_name)
- BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
-
- for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) {
- if (bone_name) {
- if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
- fcu->flag &= ~FCURVE_DISABLED;
- else
- fcu->flag |= FCURVE_DISABLED;
- }
- else {
- fcu->flag &= ~FCURVE_DISABLED;
- }
- }
- }
-
- bool hasAnimations(Scene *sce)
- {
- Base *base= (Base*) sce->base.first;
- while(base) {
- Object *ob = base->object;
-
- FCurve *fcu = 0;
- if(ob->adt && ob->adt->action)
- fcu = (FCurve*)ob->adt->action->curves.first;
-
- if ((ob->type == OB_ARMATURE && ob->data) || fcu) {
- return true;
- }
- base= base->next;
- }
- return false;
- }
-};
void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool selected)
{
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 78ee444bb4e..3a92c95e7ee 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -116,7 +116,7 @@ bool DocumentImporter::import()
/** TODO Add error handler (implement COLLADASaxFWL::IErrorHandler */
COLLADASaxFWL::Loader loader;
COLLADAFW::Root root(&loader, this);
- ExtraHandler *ehandler = new ExtraHandler(this);
+ ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
loader.registerExtraDataCallbackHandler(ehandler);
@@ -190,7 +190,7 @@ void DocumentImporter::finish()
write_node(roots[i], NULL, sce, NULL, false);
}
}
-
+ armature_importer.set_tags_map(this->uid_tags_map);
armature_importer.make_armatures(mContext);
#if 0
@@ -250,12 +250,13 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
unsigned int i;
Object *ob;
- for (i = 0; i < 4; i++)
- ob = anim_importer.translate_animation(node, object_map, root_map, types[i]);
+ //for (i = 0; i < 4; i++)
+ //ob =
+ anim_importer.translate_Animations(node, root_map, object_map, FW_object_map);
COLLADAFW::NodePointerArray &children = node->getChildNodes();
for (i = 0; i < children.getCount(); i++) {
- translate_anim_recursive(children[i], node, ob);
+ translate_anim_recursive(children[i], node, NULL);
}
}
@@ -382,7 +383,14 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
if (is_joint) {
- armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par);
+ if ( par ) {
+ Object * empty = par;
+ par = add_object(sce, OB_ARMATURE);
+ bc_set_parent(par,empty->parent, mContext);
+ //remove empty : todo
+ object_map[parent_node->getUniqueId()] = par;
+ }
+ armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce);
}
else {
COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
@@ -402,15 +410,18 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
while (geom_done < geom.getCount()) {
ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
material_texture_mapping_map);
- ++geom_done;
+ if ( ob != NULL )
+ ++geom_done;
}
while (camera_done < camera.getCount()) {
ob = create_camera_object(camera[camera_done], sce);
- ++camera_done;
+ if ( ob != NULL )
+ ++camera_done;
}
while (lamp_done < lamp.getCount()) {
ob = create_lamp_object(lamp[lamp_done], sce);
- ++lamp_done;
+ if ( ob != NULL )
+ ++lamp_done;
}
while (controller_done < controller.getCount()) {
COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done];
@@ -714,13 +725,21 @@ bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect )
return true;
const COLLADAFW::UniqueId& uid = effect->getUniqueId();
+
if (uid_effect_map.find(uid) == uid_effect_map.end()) {
fprintf(stderr, "Couldn't find a material by UID.\n");
return true;
}
Material *ma = uid_effect_map[uid];
-
+ std::map<COLLADAFW::UniqueId, Material*>::iterator iter;
+ for(iter = uid_material_map.begin(); iter != uid_material_map.end() ; iter++ )
+ {
+ if ( iter->second == ma ) {
+ this->FW_object_map[iter->first] = effect;
+ break;
+ }
+ }
COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
if (common_efs.getCount() < 1) {
fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
@@ -730,7 +749,8 @@ bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect )
// Currently only first <profile_common> is supported
COLLADAFW::EffectCommon *ef = common_efs[0];
write_profile_COMMON(ef, ma);
-
+ this->FW_object_map[effect->getUniqueId()] = effect;
+
return true;
}
@@ -846,6 +866,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
}
this->uid_camera_map[camera->getUniqueId()] = cam;
+ this->FW_object_map[camera->getUniqueId()] = camera;
// XXX import camera options
return true;
}
@@ -1043,6 +1064,7 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
}
this->uid_lamp_map[light->getUniqueId()] = lamp;
+ this->FW_object_map[light->getUniqueId()] = light;
return true;
}
diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h
index 5ccec534680..a347eed3e5a 100644
--- a/source/blender/collada/DocumentImporter.h
+++ b/source/blender/collada/DocumentImporter.h
@@ -38,6 +38,8 @@
#include "COLLADAFWController.h"
#include "COLLADAFWMorphController.h"
#include "COLLADAFWSkinController.h"
+#include "COLLADAFWEffectCommon.h"
+
#include "BKE_object.h"
@@ -45,7 +47,7 @@
#include "AnimationImporter.h"
#include "ArmatureImporter.h"
#include "MeshImporter.h"
-#include "ExtraTags.h"
+
struct Main;
@@ -155,8 +157,9 @@ private:
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> node_map;
std::vector<const COLLADAFW::VisualScene*> vscenes;
std::vector<Object*> libnode_ob;
-
+
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> root_map; // find root joint by child joint uid, for bone tree evaluation during resampling
+ std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map;
};
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index f51330165f3..355e384d000 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -94,10 +94,10 @@ void EffectsExporter::writeBlinn(COLLADASW::EffectProfile &ep, Material *ma)
COLLADASW::ColorOrTexture cot;
ep.setShaderType(COLLADASW::EffectProfile::BLINN);
// shininess
- ep.setShininess(ma->har);
+ ep.setShininess(ma->har, false , "shininess");
// specular
cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
- ep.setSpecular(cot);
+ ep.setSpecular(cot, false , "specular" );
}
void EffectsExporter::writeLambert(COLLADASW::EffectProfile &ep, Material *ma)
@@ -111,10 +111,10 @@ void EffectsExporter::writePhong(COLLADASW::EffectProfile &ep, Material *ma)
COLLADASW::ColorOrTexture cot;
ep.setShaderType(COLLADASW::EffectProfile::PHONG);
// shininess
- ep.setShininess(ma->har);
+ ep.setShininess(ma->har , false , "shininess" );
// specular
cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
- ep.setSpecular(cot);
+ ep.setSpecular(cot, false , "specular" );
}
void EffectsExporter::operator()(Material *ma, Object *ob)
@@ -150,10 +150,10 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// index of refraction
if (ma->mode & MA_RAYTRANSP) {
- ep.setIndexOfRefraction(ma->ang);
+ ep.setIndexOfRefraction(ma->ang, false , "index_of_refraction");
}
else {
- ep.setIndexOfRefraction(1.0f);
+ ep.setIndexOfRefraction(1.0f, false , "index_of_refraction");
}
COLLADASW::ColorOrTexture cot;
@@ -161,22 +161,22 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// transparency
if (ma->mode & MA_TRANSP) {
// Tod: because we are in A_ONE mode transparency is calculated like this:
- ep.setTransparency(ma->alpha);
+ ep.setTransparency(ma->alpha, false , "transparency");
// cot = getcol(1.0f, 1.0f, 1.0f, 1.0f);
// ep.setTransparent(cot);
}
// emission
cot=getcol(ma->emit, ma->emit, ma->emit, 1.0f);
- ep.setEmission(cot);
+ ep.setEmission(cot, false , "emission");
// diffuse multiplied by diffuse intensity
cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f);
- ep.setDiffuse(cot);
+ ep.setDiffuse(cot, false , "diffuse");
// ambient
cot = getcol(ma->ambr, ma->ambg, ma->ambb, 1.0f);
- ep.setAmbient(cot);
+ ep.setAmbient(cot, false , "ambient");
// reflective, reflectivity
if (ma->mode & MA_RAYMIRROR) {
@@ -193,7 +193,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// specular
if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) {
cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f);
- ep.setSpecular(cot);
+ ep.setSpecular(cot, false , "specular");
}
// XXX make this more readable if possible
@@ -274,19 +274,19 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// color
if (t->mapto & (MAP_COL | MAP_COLSPEC)) {
- ep.setDiffuse(createTexture(ima, uvname, sampler));
+ ep.setDiffuse(createTexture(ima, uvname, sampler), false , "diffuse");
}
// ambient
if (t->mapto & MAP_AMB) {
- ep.setAmbient(createTexture(ima, uvname, sampler));
+ ep.setAmbient(createTexture(ima, uvname, sampler), false , "ambient");
}
// specular
if (t->mapto & MAP_SPEC) {
- ep.setSpecular(createTexture(ima, uvname, sampler));
+ ep.setSpecular(createTexture(ima, uvname, sampler), false , "specular");
}
// emission
if (t->mapto & MAP_EMIT) {
- ep.setEmission(createTexture(ima, uvname, sampler));
+ ep.setEmission(createTexture(ima, uvname, sampler), false , "emission");
}
// reflective
if (t->mapto & MAP_REF) {
diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp
index 9999a61a470..a60ef8b2ea5 100644
--- a/source/blender/collada/ExtraHandler.cpp
+++ b/source/blender/collada/ExtraHandler.cpp
@@ -31,9 +31,10 @@
#include "ExtraHandler.h"
-ExtraHandler::ExtraHandler(DocumentImporter *dimp) : currentExtraTags(0)
+ExtraHandler::ExtraHandler(DocumentImporter *dimp, AnimationImporter *aimp) : currentExtraTags(0)
{
this->dimp = dimp;
+ this->aimp = aimp;
}
ExtraHandler::~ExtraHandler() {}
@@ -42,6 +43,7 @@ bool ExtraHandler::elementBegin( const char* elementName, const char** attribute
{
// \todo attribute handling for profile tags
currentElement = std::string(elementName);
+ //addToSidTree(attributes[0], attributes[1]);
return true;
}
diff --git a/source/blender/collada/ExtraHandler.h b/source/blender/collada/ExtraHandler.h
index de3b063290d..7296aaf1eb4 100644
--- a/source/blender/collada/ExtraHandler.h
+++ b/source/blender/collada/ExtraHandler.h
@@ -32,8 +32,10 @@
#include <algorithm> // sort()
#include "COLLADASaxFWLIExtraDataCallbackHandler.h"
+#include "COLLADASaxFWLFilePartLoader.h"
#include "DocumentImporter.h"
+#include "AnimationImporter.h"
/** \brief Handler class for <extra> data, through which different
* profiles can be handled
@@ -42,7 +44,7 @@ class ExtraHandler : public COLLADASaxFWL::IExtraDataCallbackHandler
{
public:
/** Constructor. */
- ExtraHandler(DocumentImporter *dimp);
+ ExtraHandler(DocumentImporter *dimp, AnimationImporter *aimp);
/** Destructor. */
virtual ~ExtraHandler();
@@ -69,6 +71,7 @@ private:
/** Handle to DocumentImporter for interface to extra element data saving. */
DocumentImporter* dimp;
+ AnimationImporter* aimp;
/** Holds Id of element for which <extra> XML elements are handled. */
COLLADAFW::UniqueId currentUid;
ExtraTags* currentExtraTags;
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 7f3426a1915..d9d265a66fc 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -110,7 +110,8 @@ struct GeometryFunctor {
Object *ob = base->object;
if (ob->type == OB_MESH && ob->data
- && !(export_selected && !(ob->flag && SELECT))) {
+ && !(export_selected && !(ob->flag && SELECT))
+ && ((sce->lay & ob->lay)!=0)) {
f(ob);
}
base= base->next;
diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp
index c2cc0c1e157..31ade5604a7 100644
--- a/source/blender/collada/LightExporter.cpp
+++ b/source/blender/collada/LightExporter.cpp
@@ -62,6 +62,7 @@ void LightsExporter::exportLights(Scene *sce, bool export_selected)
closeLibrary();
}
+
void LightsExporter::operator()(Object *ob)
{
Lamp *la = (Lamp*)ob->data;
@@ -86,7 +87,7 @@ void LightsExporter::operator()(Object *ob)
// sun
if (la->type == LA_SUN) {
COLLADASW::DirectionalLight cla(mSW, la_id, la_name);
- cla.setColor(col);
+ cla.setColor(col,false,"color");
cla.setConstantAttenuation(constatt);
exportBlenderProfile(cla, la);
addLight(cla);
@@ -94,7 +95,7 @@ void LightsExporter::operator()(Object *ob)
// hemi
else if (la->type == LA_HEMI) {
COLLADASW::AmbientLight cla(mSW, la_id, la_name);
- cla.setColor(col);
+ cla.setColor(col,false,"color");
cla.setConstantAttenuation(constatt);
exportBlenderProfile(cla, la);
addLight(cla);
@@ -102,9 +103,9 @@ void LightsExporter::operator()(Object *ob)
// spot
else if (la->type == LA_SPOT) {
COLLADASW::SpotLight cla(mSW, la_id, la_name);
- cla.setColor(col);
- cla.setFallOffAngle(la->spotsize);
- cla.setFallOffExponent(la->spotblend);
+ cla.setColor(col,false,"color");
+ cla.setFallOffAngle(la->spotsize,false,"fall_off_angle");
+ cla.setFallOffExponent(la->spotblend,false,"fall_off_exponent");
cla.setConstantAttenuation(constatt);
cla.setLinearAttenuation(linatt);
cla.setQuadraticAttenuation(quadatt);
@@ -114,7 +115,7 @@ void LightsExporter::operator()(Object *ob)
// lamp
else if (la->type == LA_LOCAL) {
COLLADASW::PointLight cla(mSW, la_id, la_name);
- cla.setColor(col);
+ cla.setColor(col,false,"color");
cla.setConstantAttenuation(constatt);
cla.setLinearAttenuation(linatt);
cla.setQuadraticAttenuation(quadatt);
@@ -125,7 +126,7 @@ void LightsExporter::operator()(Object *ob)
// it will be exported as a local lamp
else {
COLLADASW::PointLight cla(mSW, la_id, la_name);
- cla.setColor(col);
+ cla.setColor(col,false,"color");
cla.setConstantAttenuation(constatt);
cla.setLinearAttenuation(linatt);
cla.setQuadraticAttenuation(quadatt);
@@ -140,18 +141,18 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Lamp *la)
cla.addExtraTechniqueParameter("blender", "type", la->type);
cla.addExtraTechniqueParameter("blender", "flag", la->flag);
cla.addExtraTechniqueParameter("blender", "mode", la->mode);
- cla.addExtraTechniqueParameter("blender", "gamma", la->k);
+ cla.addExtraTechniqueParameter("blender", "gamma", la->k, "blender_gamma");
cla.addExtraTechniqueParameter("blender", "red", la->r);
cla.addExtraTechniqueParameter("blender", "green", la->g);
cla.addExtraTechniqueParameter("blender", "blue", la->b);
- cla.addExtraTechniqueParameter("blender", "shadow_r", la->shdwr);
- cla.addExtraTechniqueParameter("blender", "shadow_g", la->shdwg);
- cla.addExtraTechniqueParameter("blender", "shadow_b", la->shdwb);
- cla.addExtraTechniqueParameter("blender", "energy", la->energy);
- cla.addExtraTechniqueParameter("blender", "dist", la->dist);
+ cla.addExtraTechniqueParameter("blender", "shadow_r", la->shdwr, "blender_shadow_r");
+ cla.addExtraTechniqueParameter("blender", "shadow_g", la->shdwg, "blender_shadow_g");
+ cla.addExtraTechniqueParameter("blender", "shadow_b", la->shdwb, "blender_shadow_b");
+ cla.addExtraTechniqueParameter("blender", "energy", la->energy, "blender_energy");
+ cla.addExtraTechniqueParameter("blender", "dist", la->dist, "blender_dist");
cla.addExtraTechniqueParameter("blender", "spotsize", la->spotsize);
cla.addExtraTechniqueParameter("blender", "spotblend", la->spotblend);
- cla.addExtraTechniqueParameter("blender", "halo_intensity", la->haint);
+ cla.addExtraTechniqueParameter("blender", "halo_intensity", la->haint, "blnder_halo_intensity");
cla.addExtraTechniqueParameter("blender", "att1", la->att1);
cla.addExtraTechniqueParameter("blender", "att2", la->att2);
// \todo figure out how we can have falloff curve supported here
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index 83b9449c8f2..ce0d561c524 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -308,11 +308,15 @@ void SkinInfo::find_root_joints(const std::vector<COLLADAFW::Node*> &root_joints
std::vector<COLLADAFW::Node*>& result)
{
std::vector<COLLADAFW::Node*>::const_iterator it;
+ // for each root_joint
for (it = root_joints.begin(); it != root_joints.end(); it++) {
COLLADAFW::Node *root = *it;
std::vector<JointData>::iterator ji;
+ //for each joint_data in this skin
for (ji = joint_data.begin(); ji != joint_data.end(); ji++) {
+ //get joint node from joint map
COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid];
+ //find if joint node is in the tree belonging to the root_joint
if (find_node_in_tree(joint, root)) {
if (std::find(result.begin(), result.end(), root) == result.end())
result.push_back(root);
diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp
index 3d624520e53..0fd0c85aa09 100644
--- a/source/blender/collada/TransformReader.cpp
+++ b/source/blender/collada/TransformReader.cpp
@@ -37,6 +37,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m
{
float cur[4][4];
float copy[4][4];
+ float eul[3];
unit_m4(mat);
@@ -45,24 +46,24 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m
COLLADAFW::Transformation *tm = node->getTransformations()[i];
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
- switch(type) {
- case COLLADAFW::Transformation::TRANSLATE:
- dae_translate_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::ROTATE:
- dae_rotate_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::SCALE:
- dae_scale_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::MATRIX:
- dae_matrix_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::LOOKAT:
- case COLLADAFW::Transformation::SKEW:
- fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
- break;
- }
+ switch(type) {
+ case COLLADAFW::Transformation::TRANSLATE:
+ dae_translate_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::ROTATE:
+ dae_rotate_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::SCALE:
+ dae_scale_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::MATRIX:
+ dae_matrix_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::LOOKAT:
+ case COLLADAFW::Transformation::SKEW:
+ fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
+ break;
+ }
copy_m4_m4(copy, mat);
mul_m4_m4m4(mat, cur, copy);
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index 8638e16e1c2..7bad9bdeba7 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -48,9 +48,15 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4],
copy_m4_m4(local, mat);
}
+ double dmat[4][4];
+ UnitConverter* converter = new UnitConverter();
+ converter->mat4_to_dae_double(dmat,local);
+
TransformBase::decompose(local, loc, rot, NULL, scale);
-
- add_transform(node, loc, rot, scale);
+ if ( node.getType() == COLLADASW::Node::JOINT)
+ node.addMatrix("transform",dmat);
+ else
+ add_transform(node, loc, rot, scale);
}
void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
@@ -98,8 +104,12 @@ void TransformWriter::add_node_transform_identity(COLLADASW::Node& node)
void TransformWriter::add_transform(COLLADASW::Node& node, float loc[3], float rot[3], float scale[3])
{
node.addTranslate("location", loc[0], loc[1], loc[2]);
- node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2]));
+ /*node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2]));
node.addRotateY("rotationY", COLLADABU::Math::Utils::radToDegF(rot[1]));
- node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0]));
+ node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0]));*/
+ node.addRotateZ("rotationZ", rot[2] * 180.0f/M_PI);
+ node.addRotateY("rotationY", (rot[1]* 180.0f/M_PI));
+ node.addRotateX("rotationX", (rot[0]* 180.0f/M_PI));
+
node.addScale("scale", scale[0], scale[1], scale[2]);
}