9#include "COLLADASWBaseInputElement.h"
10#include "COLLADASWInstanceController.h"
11#include "COLLADASWPrimitves.h"
12#include "COLLADASWSource.h"
43void ControllerExporter::write_bone_URLs(COLLADASW::InstanceController &ins,
47 if (
bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) {
49 ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, node_id));
53 write_bone_URLs(ins, ob_arm, child);
63 const std::string &controller_id = get_controller_id(ob_arm, ob);
65 COLLADASW::InstanceController ins(mSW);
66 ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id));
69 if (mesh->deform_verts().is_empty()) {
75 write_bone_URLs(ins, ob_arm, bone);
79 ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only());
87 Scene *sce = blender_context.get_scene();
92 sce, *
this, this->export_settings.get_export_set());
103 export_skin_controller(ob, ob_arm);
105 if (key && this->export_settings.get_include_shapekeys()) {
106 export_morph_controller(ob, key);
111bool ArmatureExporter::already_written(
Object *ob_arm)
113 return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) !=
114 written_armatures.end();
117void ArmatureExporter::wrote(
Object *ob_arm)
119 written_armatures.push_back(ob_arm);
122void ArmatureExporter::find_objects_using_armature(
Object *ob_arm,
123 std::vector<Object *> &objects,
128 Base *base = (
Base *)sce->base.first;
130 Object *ob = base->object;
132 if (ob->
type ==
OB_MESH && get_assigned_armature(ob) == ob_arm) {
133 objects.push_back(ob);
141std::string ControllerExporter::get_controller_id(
Object *ob_arm,
Object *ob)
144 SKIN_CONTROLLER_ID_SUFFIX;
147std::string ControllerExporter::get_controller_id(
Key *key,
Object *ob)
152void ControllerExporter::export_skin_controller(
Object *ob,
Object *ob_arm)
162 bool use_instantiation = this->export_settings.get_use_object_instantiation();
165 if (((
Mesh *)ob->
data)->deform_verts().is_empty()) {
171 this->export_settings.get_export_mesh_type(),
172 this->export_settings.get_apply_modifiers(),
173 this->export_settings.get_triangulate());
175 std::string controller_name =
id_name(ob_arm);
176 std::string controller_id = get_controller_id(ob_arm, ob);
178 openSkin(controller_id,
180 COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING,
get_geometry_id(ob, use_instantiation)));
182 add_bind_shape_mat(ob);
185 std::string joints_source_id = add_joints_source(ob_arm, defbase, controller_id);
186 std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, defbase, controller_id);
188 std::list<int> vcounts;
189 std::list<int> joints;
190 std::list<float> weights;
196 std::vector<int> joint_index_by_def_index;
200 if (is_bone_defgroup(ob_arm, def)) {
201 joint_index_by_def_index.push_back(j++);
204 joint_index_by_def_index.push_back(-1);
208 const MDeformVert *dvert = mesh->deform_verts().data();
210 for (i = 0; i < mesh->verts_num; i++) {
212 std::map<int, float> jw;
219 if (idx >= joint_index_by_def_index.size()) {
225 int joint_index = joint_index_by_def_index[idx];
226 if (joint_index != -1 && vert->
dw[j].
weight > 0.0f) {
227 jw[joint_index] += vert->
dw[j].
weight;
234 float invsumw = 1.0f / sumw;
235 vcounts.push_back(jw.size());
236 for (
auto &index_and_weight : jw) {
237 joints.push_back(index_and_weight.first);
238 weights.push_back(invsumw * index_and_weight.second);
242 vcounts.push_back(0);
244 vcounts.push_back(1);
245 joints.push_back(-1);
246 weights.push_back(1.0f);
251 if (oob_counter > 0) {
253 "Ignored %d Vertex weights which use index to non existing VGroup %zu.\n",
255 joint_index_by_def_index.size());
259 std::string weights_source_id = add_weights_source(mesh, controller_id, weights);
260 add_joints_element(defbase, joints_source_id, inv_bind_mat_source_id);
261 add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
269void ControllerExporter::export_morph_controller(
Object *ob,
Key *key)
271 bool use_instantiation = this->export_settings.get_use_object_instantiation();
276 this->export_settings.get_export_mesh_type(),
277 this->export_settings.get_apply_modifiers(),
278 this->export_settings.get_triangulate());
280 std::string controller_name =
id_name(ob) +
"-morph";
281 std::string controller_id = get_controller_id(key, ob);
286 COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING,
get_geometry_id(ob, use_instantiation)));
288 std::string targets_id = add_morph_targets(key, ob);
289 std::string morph_weights_id = add_morph_weights(key, ob);
291 COLLADASW::TargetsElement targets(mSW);
293 COLLADASW::InputList &input = targets.getInputList();
295 input.push_back(COLLADASW::Input(
296 COLLADASW::InputSemantic::MORPH_TARGET,
297 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, targets_id)));
299 COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT,
300 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id)));
307 add_weight_extras(key);
312std::string ControllerExporter::add_morph_targets(
Key *key,
Object *ob)
316 COLLADASW::IdRefSource source(mSW);
317 source.setId(source_id);
318 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
319 source.setAccessorCount(key->
totkey - 1);
320 source.setAccessorStride(1);
322 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
323 param.push_back(
"IDREF");
325 source.prepareToAppendValues();
330 for (; kb; kb = kb->next) {
332 source.appendValues(geom_id);
340std::string ControllerExporter::add_morph_weights(
Key *key,
Object *ob)
344 COLLADASW::FloatSourceF source(mSW);
345 source.setId(source_id);
346 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
347 source.setAccessorCount(key->
totkey - 1);
348 source.setAccessorStride(1);
350 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
351 param.push_back(
"MORPH_WEIGHT");
353 source.prepareToAppendValues();
358 for (; kb; kb = kb->next) {
359 float weight = kb->curval;
360 source.appendValues(weight);
367void ControllerExporter::add_weight_extras(
Key *key)
370 COLLADASW::BaseExtraTechnique extra;
375 for (; kb; kb = kb->next) {
378 extra.addExtraTechniqueParameter(
"KHR",
"morph_weights", 0.000,
"MORPH_WEIGHT_TO_TARGET");
382void ControllerExporter::add_joints_element(
const ListBase *defbase,
383 const std::string &joints_source_id,
384 const std::string &inv_bind_mat_source_id)
386 COLLADASW::JointsElement joints(mSW);
387 COLLADASW::InputList &input = joints.getInputList();
389 input.push_back(COLLADASW::Input(
390 COLLADASW::InputSemantic::JOINT,
391 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
393 COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX,
394 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
398void ControllerExporter::add_bind_shape_mat(
Object *ob)
400 double bind_mat[4][4];
404 if (export_settings.get_apply_global_orientation()) {
413 if (this->export_settings.get_limit_precision()) {
417 addBindShapeTransform(bind_mat);
420std::string ControllerExporter::add_joints_source(
Object *ob_arm,
422 const std::string &controller_id)
424 std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
428 if (is_bone_defgroup(ob_arm, def)) {
433 COLLADASW::NameSource source(mSW);
434 source.setId(source_id);
435 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
436 source.setAccessorCount(totjoint);
437 source.setAccessorStride(1);
439 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
440 param.push_back(
"JOINT");
442 source.prepareToAppendValues();
445 Bone *bone = get_bone_from_defgroup(ob_arm, def);
456std::string ControllerExporter::add_inv_bind_mats_source(
Object *ob_arm,
458 const std::string &controller_id)
460 std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
464 if (is_bone_defgroup(ob_arm, def)) {
469 COLLADASW::FloatSourceF source(mSW);
470 source.setId(source_id);
471 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
472 source.setAccessorCount(totjoint);
473 source.setAccessorStride(16);
475 source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
476 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
477 param.push_back(
"TRANSFORM");
479 source.prepareToAppendValues();
484 int flag = arm->flag;
488 Depsgraph *
depsgraph = blender_context.get_depsgraph();
489 Scene *scene = blender_context.get_scene();
496 if (is_bone_defgroup(ob_arm, def)) {
501 float inv_bind_mat[4][4];
503 float bind_mat[4][4];
512 this->export_settings, pchan->
bone, bind_mat, pchan->
bone->
arm_mat,
true);
515 if (export_settings.get_open_sim()) {
517 float rot[3] = {0, 0, 0};
527 mul_m4_m4m4(world, ob_arm->object_to_world().ptr(), bind_mat);
530 if (export_settings.get_apply_global_orientation()) {
537 if (this->export_settings.get_limit_precision()) {
540 source.appendValues(inv_bind_mat);
546 Depsgraph *
depsgraph = blender_context.get_depsgraph();
547 Scene *scene = blender_context.get_scene();
560 return pchan ? pchan->
bone :
nullptr;
565 return get_bone_from_defgroup(ob_arm, def) !=
nullptr;
568std::string ControllerExporter::add_weights_source(
Mesh *mesh,
569 const std::string &controller_id,
570 const std::list<float> &weights)
572 std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
574 COLLADASW::FloatSourceF source(mSW);
575 source.setId(source_id);
576 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
577 source.setAccessorCount(weights.size());
578 source.setAccessorStride(1);
580 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
581 param.push_back(
"WEIGHT");
583 source.prepareToAppendValues();
585 for (
float weight : weights) {
586 source.appendValues(weight);
594void ControllerExporter::add_vertex_weights_element(
const std::string &weights_source_id,
595 const std::string &joints_source_id,
596 const std::list<int> &vcounts,
597 const std::list<int> &joints)
599 COLLADASW::VertexWeightsElement weightselem(mSW);
600 COLLADASW::InputList &input = weightselem.getInputList();
603 input.push_back(COLLADASW::Input(
604 COLLADASW::InputSemantic::JOINT,
605 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id),
608 COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
609 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id),
612 weightselem.setCount(vcounts.size());
615 COLLADASW::PrimitivesBase::VCountList vcountlist;
617 vcountlist.resize(vcounts.size());
618 std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin());
620 weightselem.prepareToAppendVCountValues();
621 weightselem.appendVertexCount(vcountlist);
623 weightselem.CloseVCountAndOpenVElement();
626 int weight_index = 0;
627 for (
int joint_index : joints) {
628 weightselem.appendValues(joint_index, weight_index++);
631 weightselem.finish();
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_pose_where_is(Depsgraph *depsgraph, Scene *scene, Object *ob)
Key * BKE_key_from_object(Object *ob)
void BKE_id_free(Main *bmain, void *idv)
void BKE_object_matrix_local_get(Object *ob, float r_mat[4][4])
#define LISTBASE_FOREACH(type, var, list)
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], short order)
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
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)
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)
Object * bc_get_assigned_armature(Object *ob)
void bc_create_restpose_mat(BCExportSettings &export_settings, Bone *bone, float to_mat[4][4], float from_mat[4][4], bool use_local_space)
Mesh * bc_get_mesh_copy(BlenderContext &blender_context, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4])
void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
constexpr int LIMITTED_PRECISION
const Depsgraph * depsgraph
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)