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();
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};
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])
struct bPoseChannel bPoseChannel
struct bArmature bArmature
struct MDeformVert MDeformVert
struct bDeformGroup bDeformGroup
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between world
BPy_StructRNA * depsgraph
static void sanitize(Matrix &matrix, int precision)
ControllerExporter(BlenderContext &blender_context, COLLADASW::StreamWriter *sw, BCExportSettings &export_settings)
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
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)