21 #include "COLLADASWBaseInputElement.h"
22 #include "COLLADASWInstanceController.h"
23 #include "COLLADASWPrimitves.h"
24 #include "COLLADASWSource.h"
53 void ControllerExporter::write_bone_URLs(COLLADASW::InstanceController &ins,
57 if (
bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) {
63 write_bone_URLs(ins, ob_arm, child);
73 const std::string &controller_id = get_controller_id(ob_arm, ob);
75 COLLADASW::InstanceController ins(mSW);
86 write_bone_URLs(ins, ob_arm, bone);
90 ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only());
98 Scene *sce = blender_context.get_scene();
103 sce, *
this, this->export_settings.get_export_set());
114 export_skin_controller(ob, ob_arm);
116 if (key && this->export_settings.get_include_shapekeys()) {
117 export_morph_controller(ob, key);
122 bool ArmatureExporter::already_written(
Object *ob_arm)
124 return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) !=
125 written_armatures.end();
128 void ArmatureExporter::wrote(
Object *ob_arm)
130 written_armatures.push_back(ob_arm);
133 void ArmatureExporter::find_objects_using_armature(
Object *ob_arm,
134 std::vector<Object *> &objects,
139 Base *base = (
Base *)sce->base.first;
143 if (ob->
type ==
OB_MESH && get_assigned_armature(ob) == ob_arm) {
144 objects.push_back(ob);
152 std::string ControllerExporter::get_controller_id(
Object *ob_arm,
Object *ob)
155 SKIN_CONTROLLER_ID_SUFFIX;
158 std::string ControllerExporter::get_controller_id(
Key *key,
Object *ob)
165 void ControllerExporter::export_skin_controller(
Object *ob,
Object *ob_arm)
175 bool use_instantiation = this->export_settings.get_use_object_instantiation();
178 if (((
Mesh *)ob->
data)->dvert ==
nullptr) {
184 this->export_settings.get_export_mesh_type(),
185 this->export_settings.get_apply_modifiers(),
186 this->export_settings.get_triangulate());
188 std::string controller_name =
id_name(ob_arm);
189 std::string controller_id = get_controller_id(ob_arm, ob);
191 openSkin(controller_id,
195 add_bind_shape_mat(ob);
197 std::string joints_source_id = add_joints_source(ob_arm, &ob->
defbase, controller_id);
198 std::string inv_bind_mat_source_id = add_inv_bind_mats_source(
199 ob_arm, &ob->
defbase, controller_id);
201 std::list<int> vcounts;
202 std::list<int> joints;
203 std::list<float> weights;
209 std::vector<int> joint_index_by_def_index;
213 if (is_bone_defgroup(ob_arm, def)) {
214 joint_index_by_def_index.push_back(j++);
217 joint_index_by_def_index.push_back(-1);
222 for (i = 0; i < me->
totvert; i++) {
224 std::map<int, float> jw;
231 if (idx >= joint_index_by_def_index.size()) {
237 int joint_index = joint_index_by_def_index[idx];
238 if (joint_index != -1 && vert->
dw[j].
weight > 0.0f) {
239 jw[joint_index] += vert->
dw[j].
weight;
246 float invsumw = 1.0f / sumw;
247 vcounts.push_back(jw.size());
248 for (
auto &index_and_weight : jw) {
249 joints.push_back(index_and_weight.first);
250 weights.push_back(invsumw * index_and_weight.second);
254 vcounts.push_back(0);
256 vcounts.push_back(1);
257 joints.push_back(-1);
258 weights.push_back(1.0f);
263 if (oob_counter > 0) {
265 "Ignored %d Vertex weights which use index to non existing VGroup %zu.\n",
267 joint_index_by_def_index.size());
271 std::string weights_source_id = add_weights_source(me, controller_id, weights);
272 add_joints_element(&ob->
defbase, joints_source_id, inv_bind_mat_source_id);
273 add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
281 void ControllerExporter::export_morph_controller(
Object *ob,
Key *key)
283 bool use_instantiation = this->export_settings.get_use_object_instantiation();
288 this->export_settings.get_export_mesh_type(),
289 this->export_settings.get_apply_modifiers(),
290 this->export_settings.get_triangulate());
292 std::string controller_name =
id_name(ob) +
"-morph";
293 std::string controller_id = get_controller_id(key, ob);
300 std::string targets_id = add_morph_targets(key, ob);
301 std::string morph_weights_id = add_morph_weights(key, ob);
303 COLLADASW::TargetsElement targets(mSW);
305 COLLADASW::InputList &input = targets.getInputList();
307 input.push_back(COLLADASW::Input(
308 COLLADASW::InputSemantic::MORPH_TARGET,
311 COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT,
319 add_weight_extras(key);
324 std::string ControllerExporter::add_morph_targets(
Key *key,
Object *ob)
328 COLLADASW::IdRefSource source(mSW);
329 source.setId(source_id);
330 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
331 source.setAccessorCount(key->
totkey - 1);
332 source.setAccessorStride(1);
334 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
335 param.push_back(
"IDREF");
337 source.prepareToAppendValues();
342 for (; kb; kb = kb->
next) {
344 source.appendValues(geom_id);
352 std::string ControllerExporter::add_morph_weights(
Key *key,
Object *ob)
356 COLLADASW::FloatSourceF source(mSW);
357 source.setId(source_id);
358 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
359 source.setAccessorCount(key->
totkey - 1);
360 source.setAccessorStride(1);
362 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
363 param.push_back(
"MORPH_WEIGHT");
365 source.prepareToAppendValues();
370 for (; kb; kb = kb->
next) {
371 float weight = kb->
curval;
372 source.appendValues(weight);
380 void ControllerExporter::add_weight_extras(
Key *key)
383 COLLADASW::BaseExtraTechnique extra;
388 for (; kb; kb = kb->
next) {
391 extra.addExtraTechniqueParameter(
"KHR",
"morph_weights", 0.000,
"MORPH_WEIGHT_TO_TARGET");
395 void ControllerExporter::add_joints_element(
ListBase *defbase,
396 const std::string &joints_source_id,
397 const std::string &inv_bind_mat_source_id)
399 COLLADASW::JointsElement joints(mSW);
400 COLLADASW::InputList &input = joints.getInputList();
402 input.push_back(COLLADASW::Input(
403 COLLADASW::InputSemantic::JOINT,
406 COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX,
411 void ControllerExporter::add_bind_shape_mat(
Object *ob)
413 double bind_mat[4][4];
417 if (export_settings.get_apply_global_orientation()) {
426 if (this->export_settings.get_limit_precision()) {
430 addBindShapeTransform(bind_mat);
433 std::string ControllerExporter::add_joints_source(
Object *ob_arm,
435 const std::string &controller_id)
437 std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
442 if (is_bone_defgroup(ob_arm, def)) {
447 COLLADASW::NameSource source(mSW);
448 source.setId(source_id);
449 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
450 source.setAccessorCount(totjoint);
451 source.setAccessorStride(1);
453 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
454 param.push_back(
"JOINT");
456 source.prepareToAppendValues();
459 Bone *bone = get_bone_from_defgroup(ob_arm, def);
470 std::string ControllerExporter::add_inv_bind_mats_source(
Object *ob_arm,
472 const std::string &controller_id)
474 std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
478 if (is_bone_defgroup(ob_arm, def)) {
483 COLLADASW::FloatSourceF source(mSW);
484 source.setId(source_id);
485 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
486 source.setAccessorCount(totjoint);
487 source.setAccessorStride(16);
489 source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
490 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
491 param.push_back(
"TRANSFORM");
493 source.prepareToAppendValues();
498 int flag = arm->
flag;
510 if (is_bone_defgroup(ob_arm, def)) {
515 float inv_bind_mat[4][4];
517 float bind_mat[4][4];
526 this->export_settings, pchan->
bone, bind_mat, pchan->
bone->
arm_mat,
true);
529 if (export_settings.get_open_sim()) {
531 float rot[3] = {0, 0, 0};
544 if (export_settings.get_apply_global_orientation()) {
551 if (this->export_settings.get_limit_precision()) {
554 source.appendValues(inv_bind_mat);
574 return pchan ? pchan->
bone :
nullptr;
579 return get_bone_from_defgroup(ob_arm, def) !=
nullptr;
582 std::string ControllerExporter::add_weights_source(
Mesh *me,
583 const std::string &controller_id,
584 const std::list<float> &weights)
586 std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
588 COLLADASW::FloatSourceF source(mSW);
589 source.setId(source_id);
590 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
591 source.setAccessorCount(weights.size());
592 source.setAccessorStride(1);
594 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
595 param.push_back(
"WEIGHT");
597 source.prepareToAppendValues();
599 for (
float weight : weights) {
600 source.appendValues(weight);
608 void ControllerExporter::add_vertex_weights_element(
const std::string &weights_source_id,
609 const std::string &joints_source_id,
610 const std::list<int> &vcounts,
611 const std::list<int> &joints)
613 COLLADASW::VertexWeightsElement weightselem(mSW);
614 COLLADASW::InputList &input = weightselem.getInputList();
617 input.push_back(COLLADASW::Input(
618 COLLADASW::InputSemantic::JOINT,
622 COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
626 weightselem.setCount(vcounts.size());
629 COLLADASW::PrimitivesBase::VCountList vcountlist;
631 vcountlist.resize(vcounts.size());
632 std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin());
634 weightselem.prepareToAppendVCountValues();
635 weightselem.appendVertexCount(vcountlist);
637 weightselem.CloseVCountAndOpenVElement();
640 int weight_index = 0;
641 for (
int joint_index : joints) {
642 weightselem.appendValues(joint_index, weight_index++);
645 weightselem.finish();
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
struct Key * BKE_key_from_object(const struct Object *ob)
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void loc_eulO_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3], const short order)
bool invert_m4_m4(float R[4][4], const float A[4][4])
struct Depsgraph Depsgraph
static void sanitize(Matrix &matrix, int precision)
bool add_instance_controller(Object *ob)
void operator()(Object *ob)
bool is_skinned_mesh(Object *ob)
void export_controllers()
void add_material_bindings(COLLADASW::BindMaterial &bind_material, Object *ob, bool active_uv_only)
static void mat4_to_dae(float out[4][4], float in[4][4])
static void mat4_to_dae_double(double out[4][4], float in[4][4])
std::string get_joint_sid(Bone *bone)
std::string translate_id(const char *idString)
std::string get_geometry_id(Object *ob)
std::string id_name(void *id)
bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
Mesh * bc_get_mesh_copy(BlenderContext &blender_context, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
void bc_add_global_transform(Matrix &to_mat, const Matrix &from_mat, const BCMatrix &global_transform, const bool invert)
void bc_apply_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert)
void bc_create_restpose_mat(BCExportSettings &export_settings, Bone *bone, float to_mat[4][4], float from_mat[4][4], bool use_local_space)
bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4])
Object * bc_get_assigned_armature(Object *ob)
void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
constexpr int LIMITTED_PRECISION
const Depsgraph * depsgraph
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
struct MDeformVert * dvert