Page Menu
Home
Search
Configure Global Search
Log In
Files
F18181
collada_weighstandboneparent.diff
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
kanttori (kanttori)
Nov 13 2013, 4:06 PM
Size
11 KB
Subscribers
None
collada_weighstandboneparent.diff
View Options
Index: source/blender/collada/ArmatureExporter.cpp
===================================================================
--- source/blender/collada/ArmatureExporter.cpp (revision 44128)
+++ source/blender/collada/ArmatureExporter.cpp (working copy)
@@ -43,6 +43,7 @@
#include "GeometryExporter.h"
#include "ArmatureExporter.h"
+#include "SceneExporter.h"
// XXX exporter writes wrong data for shared armatures. A separate
// controller should be written for each armature-mesh binding how do
@@ -50,14 +51,16 @@
ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {}
// write bone nodes
-void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce)
+void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce,
+ SceneExporter* se,
+ std::list<Object*>& child_objects)
{
// write bone nodes
bArmature *arm = (bArmature*)ob_arm->data;
for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) {
// start from root bones
if (!bone->parent)
- add_bone_node(bone, ob_arm);
+ add_bone_node(bone, ob_arm, sce, se, &child_objects);
}
}
@@ -163,7 +166,9 @@
}
// parent_mat is armature-space
-void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm)
+void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce,
+ SceneExporter* se,
+ std::list<Object*>* child_objects)
{
std::string node_id = get_joint_id(bone, ob_arm);
std::string node_name = std::string(bone->name);
@@ -183,6 +188,22 @@
add_bone_transform(ob_arm, bone, node);
+ // Write nodes of childobjects, remove written objects from list
+ if(sce && se && child_objects)
+ {
+ std::list<Object*>& cobjs = *child_objects;
+
+ for(std::list<Object*>::iterator i = cobjs.begin(); i != cobjs.end();)
+ {
+ if((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name)))
+ {
+ se->writeNodes(*i, sce);
+ cobjs.erase(i++);
+ }
+ else i++;
+ }
+ }
+
for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) {
add_bone_node(child, ob_arm);
}
@@ -296,10 +317,61 @@
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::map<int, 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[i] = j++;
+ else
+ joint_index_by_def_index[i] = -1;
+ }
+
+ for (i = 0; i < me->totvert; i++) {
+ MDeformVert *vert = &me->dvert[i];
+ std::map<int, float> jw;
+ 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)
+ {
+ sumw += jw[joint_index] += 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 +517,14 @@
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 ¶m = source.getParameterNameList();
@@ -467,25 +532,29 @@
source.prepareToAppendValues();
- // NOTE: COLLADA spec says weights should be normalized
+ for(std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) {
+ source.appendValues(*i);
+ }
+ /*// 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);
}
- }
+ }*/
source.finish();
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 +562,27 @@
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;
+ for(std::list<int>::const_iterator i = vcounts.begin(); i != vcounts.end(); ++i)
+ {
+ vcountlist.push_back(*i);
}
- weights.prepareToAppendVCountValues();
- weights.appendVertexCount(vcount);
+ weightselem.prepareToAppendVCountValues();
+ weightselem.appendVertexCount(vcountlist);
- // 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.CloseVCountAndOpenVElement();
- weights.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);
+ weightselem.appendValues(weight_index++);
}
- weights.finish();
+ weightselem.finish();
}
Index: source/blender/collada/SceneExporter.cpp
===================================================================
--- source/blender/collada/SceneExporter.cpp (revision 44128)
+++ source/blender/collada/SceneExporter.cpp (working copy)
@@ -77,7 +77,30 @@
node.start();
bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob);
+ std::list<Object*> child_objects;
+ // list child objects
+ Base *b = (Base*) sce->base.first;
+ while(b) {
+ // cob - child object
+ Object *cob = b->object;
+
+ if (cob->parent == ob) {
+ switch(cob->type) {
+ case OB_MESH:
+ case OB_CAMERA:
+ case OB_LAMP:
+ case OB_EMPTY:
+ case OB_ARMATURE:
+ child_objects.push_back(cob);
+ break;
+ }
+ }
+
+ b = b->next;
+ }
+
+
if (ob->type == OB_MESH && is_skinned_mesh)
// for skinned mesh we write obmat in <bind_shape_matrix>
TransformWriter::add_node_transform_identity(node);
@@ -101,7 +124,7 @@
// <instance_controller>
else if (ob->type == OB_ARMATURE) {
- arm_exporter->add_armature_bones(ob, sce);
+ arm_exporter->add_armature_bones(ob, sce, this, child_objects);
// XXX this looks unstable...
node.end();
@@ -131,28 +154,12 @@
}
}
- // write nodes for child objects
- Base *b = (Base*) sce->base.first;
- while(b) {
- // cob - child object
- Object *cob = b->object;
+ for(std::list<Object*>::iterator i= child_objects.begin(); i != child_objects.end(); ++i)
+ {
+ writeNodes(*i, sce);
+ }
- if (cob->parent == ob) {
- switch(cob->type) {
- case OB_MESH:
- case OB_CAMERA:
- case OB_LAMP:
- case OB_EMPTY:
- case OB_ARMATURE:
- // write node...
- writeNodes(cob, sce);
- break;
- }
- }
- b = b->next;
- }
-
if (ob->type != OB_ARMATURE)
node.end();
}
Index: source/blender/collada/ArmatureExporter.h
===================================================================
--- source/blender/collada/ArmatureExporter.h (revision 44128)
+++ source/blender/collada/ArmatureExporter.h (working copy)
@@ -28,6 +28,8 @@
#ifndef __ARMATUREEXPORTER_H__
#define __ARMATUREEXPORTER_H__
+#include <list>
+#include <map>
#include <string>
//#include <vector>
@@ -47,6 +49,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 +60,8 @@
ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
// write bone nodes
- void add_armature_bones(Object *ob_arm, Scene *sce);
+ void add_armature_bones(Object *ob_arm, Scene* sce, SceneExporter* se,
+ std::list<Object*>& child_objects);
bool is_skinned_mesh(Object *ob);
@@ -85,8 +90,11 @@
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 should
+ // either all be zero or all valid pointers
+ // They are required for writing bone parented objects
+ void add_bone_node(Bone *bone, Object *ob_arm, Scene* sce=0, SceneExporter* se=0,
+ std::list<Object*>* child_objects=0);
void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
@@ -111,10 +119,11 @@
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
Index: source/blender/collada/SceneExporter.h
===================================================================
--- source/blender/collada/SceneExporter.h (revision 44128)
+++ source/blender/collada/SceneExporter.h (working copy)
@@ -97,6 +97,7 @@
void exportScene(Scene *sce);
private:
+ friend class ArmatureExporter;
void exportHierarchy(Scene *sce);
void writeNodes(Object *ob, Scene *sce);
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
90/ef/37a2be1482e7b30c634fcd513228
Event Timeline
Log In to Comment