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:
authorCampbell Barton <ideasman42@gmail.com>2012-02-19 07:19:58 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-02-19 07:19:58 +0400
commitbd0f7a290b5b9497020fd8e98c9fec96b98a35db (patch)
treecc5df08c780291120c1aa9884bbbe56dd7a9267b /source/blender/collada
parent22d326a663b77c8c0c51beeb21858f0f7cd5c9b4 (diff)
parent445003973434da55614e90fcee2f99f1765afd8f (diff)
svn merge ^/trunk/blender -r44213:44235 --- fixes bmesh shading bug [#30125]
Diffstat (limited to 'source/blender/collada')
-rw-r--r--source/blender/collada/AnimationImporter.cpp182
-rw-r--r--source/blender/collada/AnimationImporter.h2
-rw-r--r--source/blender/collada/ArmatureExporter.cpp183
-rw-r--r--source/blender/collada/ArmatureExporter.h19
-rw-r--r--source/blender/collada/SceneExporter.cpp49
-rw-r--r--source/blender/collada/SceneExporter.h2
-rw-r--r--source/blender/collada/TransformWriter.cpp30
7 files changed, 345 insertions, 122 deletions
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index c47e024aba4..b889dd21177 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -834,34 +834,33 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node ,
std::vector<FCurve*> animcurves;
for (unsigned int j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
- if ( is_matrix )
+ 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_joint) {
+
+ add_bone_animation_sampled(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;
+
+ 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 (is_rotation && !is_joint) {
+ ob->rotmode = ROT_MODE_EUL;
}
}
}
@@ -992,6 +991,136 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node ,
}
}
+void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm)
+{
+ const char *bone_name = bc_get_joint_name(node);
+ char joint_path[200];
+ armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
+
+ std::vector<float> frames;
+ find_frames(&frames, &animcurves);
+
+ // convert degrees to radians
+ if (tm->getTransformationType() == COLLADAFW::Transformation::ROTATE) {
+
+ std::vector<FCurve*>::iterator iter;
+ for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
+ FCurve* fcu = *iter;
+
+ fcurve_deg_to_rad(fcu);
+ }
+ }
+
+
+ float irest_dae[4][4];
+ float rest[4][4], irest[4][4];
+
+ 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;
+ }
+
+
+ BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_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
+ // 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);
+ mult_m4_m4m4(temp, par, matfra);
+
+ // 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);
+
+ float rot[4], loc[3], scale[3];
+
+ mat4_to_quat(rot, mat);
+ 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);
+
+ // add curves
+ for (int i= 0; i < totcu; i++) {
+ add_bone_fcurve(ob, node, newcu[i]);
+ }
+
+ bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
+ chan->rotmode = ROT_MODE_QUAT;
+
+}
+
//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 ,
@@ -1406,12 +1535,10 @@ 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;
@@ -1426,8 +1553,8 @@ 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);
+ }
+ // dae_matrix_to_mat4(tm, m);
}
@@ -1510,6 +1637,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float
}
COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis();
+
float ax[3] = {axis[0], axis[1], axis[2]};
float angle = evaluate_fcurve(curves[0], fra);
axis_angle_to_mat4(mat, ax, angle);
diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h
index 118a50b0480..5fb96017dee 100644
--- a/source/blender/collada/AnimationImporter.h
+++ b/source/blender/collada/AnimationImporter.h
@@ -153,6 +153,8 @@ public:
void apply_matrix_curves( Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root ,COLLADAFW::Node* node,
COLLADAFW::Transformation * tm );
+ void add_bone_animation_sampled(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);
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 0e89f2db74b..9399ce6771d 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -43,6 +43,7 @@
#include "GeometryExporter.h"
#include "ArmatureExporter.h"
+#include "SceneExporter.h"
// XXX exporter writes wrong data for shared armatures. A separate
// controller should be written for each armature-mesh binding how do
@@ -50,14 +51,16 @@
ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {}
// write bone nodes
-void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce)
+void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce,
+ SceneExporter* se,
+ std::list<Object*>& child_objects)
{
// write bone nodes
bArmature *arm = (bArmature*)ob_arm->data;
for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) {
// start from root bones
if (!bone->parent)
- add_bone_node(bone, ob_arm);
+ add_bone_node(bone, ob_arm, sce, se, child_objects);
}
}
@@ -163,7 +166,9 @@ std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm)
}
// parent_mat is armature-space
-void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm)
+void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce,
+ SceneExporter* se,
+ std::list<Object*>& child_objects)
{
std::string node_id = get_joint_id(bone, ob_arm);
std::string node_name = std::string(bone->name);
@@ -183,14 +188,54 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm)
add_bone_transform(ob_arm, bone, node);
+ // Write nodes of childobjects, remove written objects from list
+ std::list<Object*>::iterator i = child_objects.begin();
+
+ while( i != child_objects.end() )
+ {
+ if((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name)))
+ {
+ float backup_parinv[4][4];
+
+ // SECOND_LIFE_COMPATIBILITY
+ // crude, temporary change to parentinv
+ // so transform gets exported correctly.
+ // TODO: when such objects are animated as
+ // single matrix the tweak must be applied
+ // to the result.
+ if(export_settings->second_life)
+ {
+ copy_m4_m4(backup_parinv, (*i)->parentinv);
+ // tweak objects parentinverse to match
+ // the second life- compatibility
+ float temp[4][4];
+
+ copy_m4_m4(temp, bone->arm_mat);
+ temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+
+ mult_m4_m4m4((*i)->parentinv, temp, backup_parinv);
+ }
+
+ se->writeNodes(*i, sce);
+
+ // restore original parentinv
+ if(export_settings->second_life)
+ {
+ copy_m4_m4((*i)->parentinv, backup_parinv);
+ }
+ child_objects.erase(i++);
+ }
+ else i++;
+ }
+
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
- add_bone_node(child, ob_arm);
+ add_bone_node(child, ob_arm, sce, se, child_objects);
}
node.end();
//}
}
-void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
+/*void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
{
node.start();
@@ -201,11 +246,11 @@ void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADA
node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2] );
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
- add_bone_node(child, ob_arm);
+ add_bone_node(child, ob_arm, sce, se, child_objects);
}
node.end();
-}
+}*/
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node)
{
bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
@@ -296,10 +341,64 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id);
std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id);
- std::string weights_source_id = add_weights_source(me, controller_id);
+ std::list<int> vcounts;
+ std::list<int> joints;
+ std::list<float> weights;
+
+ {
+ int i, j;
+
+ // def group index -> joint index
+ std::vector<int> joint_index_by_def_index;
+ bDeformGroup *def;
+
+ for (def = (bDeformGroup*)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
+ if (is_bone_defgroup(ob_arm, def))
+ joint_index_by_def_index.push_back(j++);
+ else
+ joint_index_by_def_index.push_back(-1);
+ }
+
+ for (i = 0; i < me->totvert; i++) {
+ MDeformVert *vert = &me->dvert[i];
+ std::map<int, float> jw;
+
+ // We're normalizing the weights later
+ float sumw = 0.0f;
+
+ for (j = 0; j < vert->totweight; j++) {
+ int joint_index = joint_index_by_def_index[vert->dw[j].def_nr];
+ if(joint_index != -1 && vert->dw[j].weight > 0.0f)
+ {
+ jw[joint_index] += vert->dw[j].weight;
+ sumw += vert->dw[j].weight;
+ }
+ }
+
+ if(sumw > 0.0f)
+ {
+ float invsumw = 1.0f/sumw;
+ vcounts.push_back(jw.size());
+ for(std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m)
+ {
+ joints.push_back((*m).first);
+ weights.push_back(invsumw*(*m).second);
+ }
+ }
+ else
+ {
+ vcounts.push_back(0);
+ /*vcounts.push_back(1);
+ joints.push_back(-1);
+ weights.push_back(1.0f);*/
+ }
+ }
+ }
+
+ std::string weights_source_id = add_weights_source(me, controller_id, weights);
add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
- add_vertex_weights_element(weights_source_id, joints_source_id, me, ob_arm, &ob->defbase);
+ add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
closeSkin();
closeController();
@@ -445,21 +544,14 @@ bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup* def)
return get_bone_from_defgroup(ob_arm, def) != NULL;
}
-std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& controller_id)
+std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& controller_id, const std::list<float>& weights)
{
std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
- int i;
- int totweight = 0;
-
- for (i = 0; i < me->totvert; i++) {
- totweight += me->dvert[i].totweight;
- }
-
COLLADASW::FloatSourceF source(mSW);
source.setId(source_id);
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totweight);
+ source.setAccessorCount(weights.size());
source.setAccessorStride(1);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@@ -467,13 +559,8 @@ std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& co
source.prepareToAppendValues();
- // NOTE: COLLADA spec says weights should be normalized
-
- for (i = 0; i < me->totvert; i++) {
- MDeformVert *vert = &me->dvert[i];
- for (int j = 0; j < vert->totweight; j++) {
- source.appendValues(vert->dw[j].weight);
- }
+ for(std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) {
+ source.appendValues(*i);
}
source.finish();
@@ -481,11 +568,12 @@ std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& co
return source_id;
}
-void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me,
- Object *ob_arm, ListBase *defbase)
+void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
+ const std::list<int>& vcounts,
+ const std::list<int>& joints)
{
- COLLADASW::VertexWeightsElement weights(mSW);
- COLLADASW::InputList &input = weights.getInputList();
+ COLLADASW::VertexWeightsElement weightselem(mSW);
+ COLLADASW::InputList &input = weightselem.getInputList();
int offset = 0;
input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
@@ -493,40 +581,25 @@ void ArmatureExporter::add_vertex_weights_element(const std::string& weights_sou
input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++));
- weights.setCount(me->totvert);
+ weightselem.setCount(vcounts.size());
// write number of deformers per vertex
- COLLADASW::PrimitivesBase::VCountList vcount;
- int i;
- for (i = 0; i < me->totvert; i++) {
- vcount.push_back(me->dvert[i].totweight);
- }
+ COLLADASW::PrimitivesBase::VCountList vcountlist;
- weights.prepareToAppendVCountValues();
- weights.appendVertexCount(vcount);
+ vcountlist.resize(vcounts.size());
+ std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin());
- // def group index -> joint index
- std::map<int, int> joint_index_by_def_index;
- bDeformGroup *def;
- int j;
- for (def = (bDeformGroup*)defbase->first, i = 0, j = 0; def; def = def->next, i++) {
- if (is_bone_defgroup(ob_arm, def))
- joint_index_by_def_index[i] = j++;
- else
- joint_index_by_def_index[i] = -1;
- }
+ weightselem.prepareToAppendVCountValues();
+ weightselem.appendVertexCount(vcountlist);
- weights.CloseVCountAndOpenVElement();
+ weightselem.CloseVCountAndOpenVElement();
// write deformer index - weight index pairs
int weight_index = 0;
- for (i = 0; i < me->totvert; i++) {
- MDeformVert *dvert = &me->dvert[i];
- for (int j = 0; j < dvert->totweight; j++) {
- weights.appendValues(joint_index_by_def_index[dvert->dw[j].def_nr]);
- weights.appendValues(weight_index++);
- }
+ for(std::list<int>::const_iterator i = joints.begin(); i != joints.end(); ++i)
+ {
+ weightselem.appendValues(*i, weight_index++);
}
- weights.finish();
+ weightselem.finish();
}
diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h
index 925e65c9b69..e9ee38d36cf 100644
--- a/source/blender/collada/ArmatureExporter.h
+++ b/source/blender/collada/ArmatureExporter.h
@@ -28,6 +28,7 @@
#ifndef __ARMATUREEXPORTER_H__
#define __ARMATUREEXPORTER_H__
+#include <list>
#include <string>
//#include <vector>
@@ -47,6 +48,8 @@
#include "ExportSettings.h"
+class SceneExporter;
+
// XXX exporter writes wrong data for shared armatures. A separate
// controller should be written for each armature-mesh binding how do
// we make controller ids then?
@@ -56,7 +59,8 @@ public:
ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
// write bone nodes
- void add_armature_bones(Object *ob_arm, Scene *sce);
+ void add_armature_bones(Object *ob_arm, Scene* sce, SceneExporter* se,
+ std::list<Object*>& child_objects);
bool is_skinned_mesh(Object *ob);
@@ -85,8 +89,10 @@ private:
std::string get_joint_sid(Bone *bone, Object *ob_arm);
- // parent_mat is armature-space
- void add_bone_node(Bone *bone, Object *ob_arm);
+ // Scene, SceneExporter and the list of child_objects
+ // are required for writing bone parented objects
+ void add_bone_node(Bone *bone, Object *ob_arm, Scene* sce, SceneExporter* se,
+ std::list<Object*>& child_objects);
void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
@@ -111,10 +117,11 @@ private:
bool is_bone_defgroup(Object *ob_arm, bDeformGroup* def);
- std::string add_weights_source(Mesh *me, const std::string& controller_id);
+ std::string add_weights_source(Mesh *me, const std::string& controller_id,
+ const std::list<float>& weights);
- void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me,
- Object *ob_arm, ListBase *defbase);
+ void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
+ const std::list<int>& vcount, const std::list<int>& joints);
};
#endif
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index 5dd452faa41..b6be8a57f7a 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -77,6 +77,29 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
node.start();
bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob);
+ std::list<Object*> child_objects;
+
+ // list child objects
+ Base *b = (Base*) sce->base.first;
+ while(b) {
+ // cob - child object
+ Object *cob = b->object;
+
+ if (cob->parent == ob) {
+ switch(cob->type) {
+ case OB_MESH:
+ case OB_CAMERA:
+ case OB_LAMP:
+ case OB_EMPTY:
+ case OB_ARMATURE:
+ child_objects.push_back(cob);
+ break;
+ }
+ }
+
+ b = b->next;
+ }
+
if (ob->type == OB_MESH && is_skinned_mesh)
// for skinned mesh we write obmat in <bind_shape_matrix>
@@ -101,7 +124,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
// <instance_controller>
else if (ob->type == OB_ARMATURE) {
- arm_exporter->add_armature_bones(ob, sce);
+ arm_exporter->add_armature_bones(ob, sce, this, child_objects);
// XXX this looks unstable...
node.end();
@@ -131,28 +154,12 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
}
}
- // write nodes for child objects
- Base *b = (Base*) sce->base.first;
- while(b) {
- // cob - child object
- Object *cob = b->object;
-
- if (cob->parent == ob) {
- switch(cob->type) {
- case OB_MESH:
- case OB_CAMERA:
- case OB_LAMP:
- case OB_EMPTY:
- case OB_ARMATURE:
- // write node...
- writeNodes(cob, sce);
- break;
- }
- }
-
- b = b->next;
+ for(std::list<Object*>::iterator i= child_objects.begin(); i != child_objects.end(); ++i)
+ {
+ writeNodes(*i, sce);
}
+
if (ob->type != OB_ARMATURE)
node.end();
}
diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h
index de01eb6e459..31b471a3e4c 100644
--- a/source/blender/collada/SceneExporter.h
+++ b/source/blender/collada/SceneExporter.h
@@ -97,6 +97,8 @@ public:
void exportScene(Scene *sce);
private:
+ // required for writeNodes() for bone-parented objects
+ friend class ArmatureExporter;
void exportHierarchy(Scene *sce);
void writeNodes(Object *ob, Scene *sce);
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index c806cd48587..0cf26a03107 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -95,20 +95,24 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
*/
/* Using parentinv should allow use of existing curves */
- // If parentinv is identity don't add it.
- bool add_parinv = false;
- for(int i = 0; i < 16; ++i)
+ if(ob->parent)
{
- float f = (i%4 == i/4) ? 1.0f : 0.0f ;
- if(ob->parentinv[i%4][i/4] != f) add_parinv = true;
- }
-
- if(add_parinv && ob->parent)
- {
- double dmat[4][4];
- UnitConverter converter;
- converter.mat4_to_dae_double(dmat, ob->parentinv);
- node.addMatrix("parentinverse", dmat);
+ // If parentinv is identity don't add it.
+ bool add_parinv = false;
+
+ for(int i = 0; i < 16; ++i)
+ {
+ float f = (i%4 == i/4) ? 1.0f : 0.0f ;
+ add_parinv |= (ob->parentinv[i%4][i/4] != f);
+ }
+
+ if(add_parinv)
+ {
+ double dmat[4][4];
+ UnitConverter converter;
+ converter.mat4_to_dae_double(dmat, ob->parentinv);
+ node.addMatrix("parentinverse", dmat);
+ }
}
add_transform(node, ob->loc, ob->rot, ob->size);