diff options
Diffstat (limited to 'source/blender')
36 files changed, 943 insertions, 437 deletions
diff --git a/source/blender/collada/AnimationClipExporter.h b/source/blender/collada/AnimationClipExporter.h index 6d67ab7c406..ead894dc941 100644 --- a/source/blender/collada/AnimationClipExporter.h +++ b/source/blender/collada/AnimationClipExporter.h @@ -25,13 +25,13 @@ class AnimationClipExporter : COLLADASW::LibraryAnimationClips { Depsgraph *depsgraph; Scene *scene; COLLADASW::StreamWriter *sw; - const ExportSettings *export_settings; + BCExportSettings &export_settings; std::vector<std::vector<std::string>> anim_meta; public: AnimationClipExporter(Depsgraph *depsgraph, COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings, + BCExportSettings &export_settings, std::vector<std::vector<std::string>> anim_meta) : COLLADASW::LibraryAnimationClips(sw), depsgraph(depsgraph), diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index eaa1626f7d8..ba878a28e50 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -77,7 +77,7 @@ void AnimationExporter::close_animation_container(bool has_container) bool AnimationExporter::exportAnimations() { - Scene *sce = blender_context.get_scene(); + Scene *sce = export_settings.get_scene(); LinkNode *export_set = this->export_settings->export_set; bool has_anim_data = bc_has_animations(sce, export_set); @@ -87,14 +87,10 @@ bool AnimationExporter::exportAnimations() BCObjectSet animated_subset; BCAnimationSampler::get_animated_from_export_set(animated_subset, *export_set); animation_count = animated_subset.size(); - BCAnimationSampler animation_sampler(blender_context, animated_subset); + BCAnimationSampler animation_sampler(export_settings, animated_subset); try { - animation_sampler.sample_scene(export_settings->sampling_rate, - /*keyframe_at_end = */ true, - export_settings->open_sim, - export_settings->keep_keyframes, - export_settings->export_animation_type); + animation_sampler.sample_scene(export_settings, /*keyframe_at_end = */ true); openLibrary(); @@ -137,7 +133,7 @@ void AnimationExporter::exportAnimation(Object *ob, BCAnimationSampler &sampler) * Note: For Armatures the skeletal animation has already been exported (see above) * However Armatures also can have Object animation. */ - bool export_as_matrix = this->export_settings->export_transformation_type == + bool export_as_matrix = this->export_settings.get_export_transformation_type() == BC_TRANSFORMATION_TYPE_MATRIX; if (export_as_matrix) { @@ -178,7 +174,7 @@ void AnimationExporter::export_curve_animation_set(Object *ob, bool export_as_matrix) { BCAnimationCurveMap *curves = sampler.get_curves(ob); - bool keep_flat_curves = this->export_settings->keep_flat_curves; + bool keep_flat_curves = this->export_settings.get_keep_flat_curves(); BCAnimationCurveMap::iterator it; for (it = curves->begin(); it != curves->end(); ++it) { @@ -215,7 +211,7 @@ void AnimationExporter::export_curve_animation_set(Object *ob, void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler &sampler) { - bool keep_flat_curves = this->export_settings->keep_flat_curves; + bool keep_flat_curves = this->export_settings.get_keep_flat_curves(); std::vector<float> frames; sampler.get_object_frames(frames, ob); @@ -232,17 +228,31 @@ void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler & std::string target = translate_id(name) + '/' + channel_type; - export_collada_matrix_animation(id, name, target, frames, samples); + BC_global_rotation_type global_rotation_type = get_global_rotation_type(ob); + export_collada_matrix_animation( + id, name, target, frames, samples, global_rotation_type, ob->parentinv); } } } +BC_global_rotation_type AnimationExporter::get_global_rotation_type(Object *ob) +{ + bool is_export_root = this->export_settings.is_export_root(ob); + if (!is_export_root) { + return BC_NO_ROTATION; + } + + bool apply_global_rotation = this->export_settings.get_apply_global_orientation(); + + return (apply_global_rotation) ? BC_DATA_ROTATION : BC_OBJECT_ROTATION; +} + /* Write bone animations in transform matrix sources. */ void AnimationExporter::export_bone_animations_recursive(Object *ob, Bone *bone, BCAnimationSampler &sampler) { - bool keep_flat_curves = this->export_settings->keep_flat_curves; + bool keep_flat_curves = this->export_settings.get_keep_flat_curves(); std::vector<float> frames; sampler.get_bone_frames(frames, ob, bone); @@ -347,7 +357,9 @@ void AnimationExporter::export_curve_animation(Object *ob, BCAnimationCurve &cur collada_target += "/" + get_collada_sid(curve, axis); } - export_collada_curve_animation(id, curve_name, collada_target, axis, curve); + BC_global_rotation_type global_rotation_type = get_global_rotation_type(ob); + export_collada_curve_animation( + id, curve_name, collada_target, axis, curve, global_rotation_type); } void AnimationExporter::export_bone_animation(Object *ob, @@ -361,7 +373,9 @@ void AnimationExporter::export_bone_animation(Object *ob, std::string id = bc_get_action_id(id_name(action), name, bone_name, "pose_matrix"); std::string target = translate_id(id_name(ob) + "_" + bone_name) + "/transform"; - export_collada_matrix_animation(id, name, target, frames, samples); + BC_global_rotation_type global_rotation_type = get_global_rotation_type(ob); + export_collada_matrix_animation( + id, name, target, frames, samples, global_rotation_type, ob->parentinv); } bool AnimationExporter::is_bone_deform_group(Bone *bone) @@ -383,11 +397,13 @@ bool AnimationExporter::is_bone_deform_group(Bone *bone) return false; } -void AnimationExporter::export_collada_curve_animation(std::string id, - std::string name, - std::string collada_target, - std::string axis, - BCAnimationCurve &curve) +void AnimationExporter::export_collada_curve_animation( + std::string id, + std::string name, + std::string collada_target, + std::string axis, + BCAnimationCurve &curve, + BC_global_rotation_type global_rotation_type) { BCFrames frames; BCValues values; @@ -408,7 +424,7 @@ void AnimationExporter::export_collada_curve_animation(std::string id, bool has_tangents = false; std::string interpolation_id; - if (this->export_settings->keep_smooth_curves) + if (this->export_settings.get_keep_smooth_curves()) interpolation_id = collada_interpolation_source(curve, id, axis, &has_tangents); else interpolation_id = collada_linear_interpolation_source(frames.size(), id); @@ -444,11 +460,14 @@ void AnimationExporter::export_collada_curve_animation(std::string id, closeAnimation(); } -void AnimationExporter::export_collada_matrix_animation(std::string id, - std::string name, - std::string target, - BCFrames &frames, - BCMatrixSampleMap &samples) +void AnimationExporter::export_collada_matrix_animation( + std::string id, + std::string name, + std::string target, + BCFrames &frames, + BCMatrixSampleMap &samples, + BC_global_rotation_type global_rotation_type, + Matrix &parentinv) { fprintf( stdout, "Export animation matrix %s (%d control points)\n", id.c_str(), int(frames.size())); @@ -457,7 +476,7 @@ void AnimationExporter::export_collada_matrix_animation(std::string id, std::string input_id = collada_source_from_values( BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, ""); - std::string output_id = collada_source_from_values(samples, id); + std::string output_id = collada_source_from_values(samples, id, global_rotation_type, parentinv); std::string interpolation_id = collada_linear_interpolation_source(frames.size(), id); std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; @@ -540,7 +559,8 @@ std::string AnimationExporter::collada_tangent_from_curve( const std::string &anim_id, std::string axis_name) { - Scene *scene = blender_context.get_scene(); + Scene *scene = this->export_settings.get_scene(); + std::string channel = curve.get_channel_target(); const std::string source_id = anim_id + get_semantic_suffix(semantic); @@ -585,6 +605,7 @@ std::string AnimationExporter::collada_source_from_values( const std::string &anim_id, const std::string axis_name) { + BlenderContext &blender_context = this->export_settings.get_blender_context(); Scene *scene = blender_context.get_scene(); /* T can be float, int or double */ @@ -623,11 +644,14 @@ std::string AnimationExporter::collada_source_from_values( return source_id; } -/** - * Create a collada matrix source for a set of samples. +/* + * Create a collada matrix source for a set of samples */ -std::string AnimationExporter::collada_source_from_values(BCMatrixSampleMap &samples, - const std::string &anim_id) +std::string AnimationExporter::collada_source_from_values( + BCMatrixSampleMap &samples, + const std::string &anim_id, + BC_global_rotation_type global_rotation_type, + Matrix &parentinv) { COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT; std::string source_id = anim_id + get_semantic_suffix(semantic); @@ -645,11 +669,12 @@ std::string AnimationExporter::collada_source_from_values(BCMatrixSampleMap &sam BCMatrixSampleMap::iterator it; /* could be made configurable */ - int precision = (this->export_settings->limit_precision) ? 6 : -1; + int precision = (this->export_settings.get_limit_precision()) ? 6 : -1; for (it = samples.begin(); it != samples.end(); it++) { - const BCMatrix *sample = it->second; - double daemat[4][4]; - sample->get_matrix(daemat, true, precision); + BCMatrix sample = BCMatrix(*it->second); + DMatrix daemat; + sample.add_transform(this->export_settings.get_global_transform()); + sample.get_matrix(daemat, true, precision); source.appendValues(daemat); } diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h index 71d7d14a112..27474cc2b58 100644 --- a/source/blender/collada/AnimationExporter.h +++ b/source/blender/collada/AnimationExporter.h @@ -86,20 +86,22 @@ typedef enum BC_animation_source_type { BC_SOURCE_TYPE_TIMEFRAME, } BC_animation_source_type; +typedef enum BC_global_rotation_type { + BC_NO_ROTATION, + BC_OBJECT_ROTATION, + BC_DATA_ROTATION +} BC_global_rotation_type; + class AnimationExporter : COLLADASW::LibraryAnimations { private: - BlenderContext &blender_context; COLLADASW::StreamWriter *sw; - const ExportSettings *export_settings; + BCExportSettings &export_settings; + + BC_global_rotation_type get_global_rotation_type(Object *ob); public: - AnimationExporter(BlenderContext &blender_context, - COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings) - : COLLADASW::LibraryAnimations(sw), - blender_context(blender_context), - sw(sw), - export_settings(export_settings) + AnimationExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) + : COLLADASW::LibraryAnimations(sw), sw(sw), export_settings(export_settings) { } @@ -176,14 +178,17 @@ class AnimationExporter : COLLADASW::LibraryAnimations { std::string name, std::string target, std::string axis, - BCAnimationCurve &curve); + BCAnimationCurve &curve, + BC_global_rotation_type global_rotation_type); /* call to the low level collada exporter */ void export_collada_matrix_animation(std::string id, std::string name, std::string target, BCFrames &frames, - BCMatrixSampleMap &outmats); + BCMatrixSampleMap &outmats, + BC_global_rotation_type global_rotation_type, + Matrix &parentinv); BCAnimationCurve *get_modified_export_curve(Object *ob, BCAnimationCurve &curve, @@ -202,7 +207,10 @@ class AnimationExporter : COLLADASW::LibraryAnimations { const std::string axis_name); /* Output sources (matrix data) */ - std::string collada_source_from_values(BCMatrixSampleMap &samples, const std::string &anim_id); + std::string collada_source_from_values(BCMatrixSampleMap &samples, + const std::string &anim_id, + BC_global_rotation_type global_rotation_type, + Matrix &parentinv); /* Interpolation sources */ std::string collada_linear_interpolation_source(int tot, const std::string &anim_id); diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index be50b255f13..7d3904647de 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -43,8 +43,6 @@ extern "C" { #include "ArmatureExporter.h" #include "SceneExporter.h" -#include "collada_utils.h" - // write bone nodes void ArmatureExporter::add_armature_bones(Object *ob_arm, ViewLayer *view_layer, @@ -62,10 +60,7 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, } for (Bone *bone = (Bone *)armature->bonebase.first; bone; bone = bone->next) { - // start from root bones - if (!bone->parent) { - add_bone_node(bone, ob_arm, se, child_objects); - } + add_bone_node(bone, ob_arm, se, child_objects); } if (!is_edited) { @@ -77,7 +72,7 @@ void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone) { - if (bc_is_root_bone(bone, this->export_settings->deform_bones_only)) { + if (bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) { std::string joint_id = translate_id(id_name(ob_arm) + "_" + bone->name); ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, joint_id)); } @@ -109,7 +104,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob) } InstanceWriter::add_material_bindings( - ins.getBindMaterial(), ob, this->export_settings->active_uv_only); + ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only()); ins.add(); return true; @@ -157,7 +152,7 @@ void ArmatureExporter::add_bone_node(Bone *bone, SceneExporter *se, std::vector<Object *> &child_objects) { - if (!(this->export_settings->deform_bones_only && bone->flag & BONE_NO_DEFORM)) { + if (can_export(bone)) { std::string node_id = translate_id(id_name(ob_arm) + "_" + bone->name); std::string node_name = std::string(bone->name); std::string node_sid = get_joint_sid(bone); @@ -169,8 +164,8 @@ void ArmatureExporter::add_bone_node(Bone *bone, node.setNodeName(node_name); node.setNodeSid(node_sid); - if (this->export_settings->use_blender_profile) { - if (bone->parent) { + if (this->export_settings.get_use_blender_profile()) { + if (!is_export_root(bone)) { if (bone->flag & BONE_CONNECTED) { node.addExtraTechniqueParameter("blender", "connect", true); } @@ -184,9 +179,19 @@ void ArmatureExporter::add_bone_node(Bone *bone, node.addExtraTechniqueParameter("blender", "roll", ebone->roll); } if (bc_is_leaf_bone(bone)) { - node.addExtraTechniqueParameter("blender", "tip_x", bone->arm_tail[0] - bone->arm_head[0]); - node.addExtraTechniqueParameter("blender", "tip_y", bone->arm_tail[1] - bone->arm_head[1]); - node.addExtraTechniqueParameter("blender", "tip_z", bone->arm_tail[2] - bone->arm_head[2]); + Vector head, tail; + const BCMatrix &global_transform = this->export_settings.get_global_transform(); + if (this->export_settings.get_apply_global_orientation()) { + bc_add_global_transform(head, bone->arm_head, global_transform); + bc_add_global_transform(tail, bone->arm_tail, global_transform); + } + else { + copy_v3_v3(head, bone->arm_head); + copy_v3_v3(tail, bone->arm_tail); + } + node.addExtraTechniqueParameter("blender", "tip_x", tail[0] - head[0]); + node.addExtraTechniqueParameter("blender", "tip_y", tail[1] - head[1]); + node.addExtraTechniqueParameter("blender", "tip_z", tail[2] - head[2]); } } @@ -195,12 +200,13 @@ void ArmatureExporter::add_bone_node(Bone *bone, add_bone_transform(ob_arm, bone, node); // Write nodes of childobjects, remove written objects from list - std::vector<Object *>::iterator i = child_objects.begin(); + std::vector<Object *>::iterator iter = child_objects.begin(); - while (i != child_objects.end()) { - if ((*i)->partype == PARBONE && STREQ((*i)->parsubstr, bone->name)) { + while (iter != child_objects.end()) { + Object *ob = *iter; + if (ob->partype == PARBONE && STREQ(ob->parsubstr, bone->name)) { float backup_parinv[4][4]; - copy_m4_m4(backup_parinv, (*i)->parentinv); + copy_m4_m4(backup_parinv, ob->parentinv); // crude, temporary change to parentinv // so transform gets exported correctly. @@ -208,28 +214,28 @@ void ArmatureExporter::add_bone_node(Bone *bone, // Add bone tail- translation... don't know why // bone parenting is against the tail of a bone // and not it's head, seems arbitrary. - (*i)->parentinv[3][1] += bone->length; + ob->parentinv[3][1] += bone->length; // OPEN_SIM_COMPATIBILITY // TODO: when such objects are animated as // single matrix the tweak must be applied // to the result. - if (export_settings->open_sim) { + if (export_settings.get_open_sim()) { // tweak objects parentinverse to match compatibility float temp[4][4]; copy_m4_m4(temp, bone->arm_mat); temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - mul_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); + mul_m4_m4m4(ob->parentinv, temp, ob->parentinv); } - se->writeNodes(*i); - copy_m4_m4((*i)->parentinv, backup_parinv); - i = child_objects.erase(i); + se->writeNode(ob); + copy_m4_m4(ob->parentinv, backup_parinv); + iter = child_objects.erase(iter); } else - i++; + iter++; } for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { @@ -244,6 +250,18 @@ void ArmatureExporter::add_bone_node(Bone *bone, } } +bool ArmatureExporter::is_export_root(Bone *bone) +{ + Bone *entry = bone->parent; + while (entry) { + if (can_export(entry)) { + return false; + } + entry = entry->parent; + } + return can_export(bone); +} + void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node &node) { // bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name); @@ -260,47 +278,49 @@ void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW: bc_create_restpose_mat(this->export_settings, bone, bone_rest_mat, bone->arm_mat, true); - if (bone->parent) { - /* Get bone-space matrix from parent pose. */ -#if 0 - bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, bone->parent->name); - float invpar[4][4]; - invert_m4_m4(invpar, parchan->pose_mat); - mul_m4_m4m4(mat, invpar, pchan->pose_mat); -#endif - float invpar[4][4]; + if (is_export_root(bone)) { + copy_m4_m4(mat, bone_rest_mat); + } + else { + Matrix parent_inverse; bc_create_restpose_mat( this->export_settings, bone->parent, parent_rest_mat, bone->parent->arm_mat, true); - invert_m4_m4(invpar, parent_rest_mat); - mul_m4_m4m4(mat, invpar, bone_rest_mat); - } - else { - copy_m4_m4(mat, bone_rest_mat); + invert_m4_m4(parent_inverse, parent_rest_mat); + mul_m4_m4m4(mat, parent_inverse, bone_rest_mat); } // OPEN_SIM_COMPATIBILITY - if (export_settings->open_sim) { + if (export_settings.get_open_sim()) { // Remove rotations vs armature from transform // parent_rest_rot * mat * irest_rot - float temp[4][4]; - copy_m4_m4(temp, bone_rest_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - invert_m4(temp); + Matrix workmat; + copy_m4_m4(workmat, bone_rest_mat); + + workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f; + invert_m4(workmat); + + mul_m4_m4m4(mat, mat, workmat); - mul_m4_m4m4(mat, mat, temp); + if (!is_export_root(bone)) { + copy_m4_m4(workmat, parent_rest_mat); + workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f; - if (bone->parent) { - copy_m4_m4(temp, parent_rest_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + mul_m4_m4m4(mat, workmat, mat); - mul_m4_m4m4(mat, temp, mat); + if (this->export_settings.get_apply_global_orientation()) { + Vector v; + copy_v3_v3(v, mat[3]); + bc_add_global_transform(v, this->export_settings.get_global_transform()); + copy_v3_v3(mat[3], v); + } } } } - if (this->export_settings->limit_precision) + if (this->export_settings.get_limit_precision()) { bc_sanitize_mat(mat, LIMITTED_PRECISION); + } TransformWriter::add_node_transform(node, mat, NULL); } diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index 6ef6007960e..da6d6f79ef5 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -56,7 +56,7 @@ class ArmatureExporter : public COLLADASW::LibraryControllers, // we make controller ids then? ArmatureExporter(BlenderContext &blender_context, COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings) + BCExportSettings &export_settings) : COLLADASW::LibraryControllers(sw), blender_context(blender_context), export_settings(export_settings) @@ -72,7 +72,7 @@ class ArmatureExporter : public COLLADASW::LibraryControllers, private: BlenderContext &blender_context; - const ExportSettings *export_settings; + BCExportSettings &export_settings; #if 0 std::vector<Object *> written_armatures; @@ -91,6 +91,12 @@ class ArmatureExporter : public COLLADASW::LibraryControllers, SceneExporter *se, std::vector<Object *> &child_objects); + inline bool can_export(Bone *bone) + { + return !(export_settings.get_deform_bones_only() && bone->flag & BONE_NO_DEFORM); + } + + bool is_export_root(Bone *bone); void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node &node); std::string get_controller_id(Object *ob_arm, Object *ob); diff --git a/source/blender/collada/BCAnimationSampler.cpp b/source/blender/collada/BCAnimationSampler.cpp index ee574e2968b..7b0c6c41a01 100644 --- a/source/blender/collada/BCAnimationSampler.cpp +++ b/source/blender/collada/BCAnimationSampler.cpp @@ -44,8 +44,8 @@ extern "C" { static std::string EMPTY_STRING; static BCAnimationCurveMap BCEmptyAnimationCurves; -BCAnimationSampler::BCAnimationSampler(BlenderContext &blender_context, BCObjectSet &object_set) - : blender_context(blender_context) +BCAnimationSampler::BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &object_set) + : export_settings(export_settings) { BCObjectSet::iterator it; for (it = object_set.begin(); it != object_set.end(); ++it) { @@ -65,6 +65,7 @@ BCAnimationSampler::~BCAnimationSampler() void BCAnimationSampler::add_object(Object *ob) { + BlenderContext blender_context = export_settings.get_blender_context(); BCAnimation *animation = new BCAnimation(blender_context.get_context(), ob); objects[ob] = animation; @@ -156,6 +157,10 @@ void BCAnimationSampler::update_animation_curves(BCAnimation &animation, BCSample &BCAnimationSampler::sample_object(Object *ob, int frame_index, bool for_opensim) { BCSample &ob_sample = sample_data.add(ob, frame_index); + //if (export_settings.get_apply_global_orientation()) { + // const BCMatrix &global_transform = export_settings.get_global_transform(); + // ob_sample.get_matrix(global_transform); + //} if (ob->type == OB_ARMATURE) { bPoseChannel *pchan; @@ -163,6 +168,7 @@ BCSample &BCAnimationSampler::sample_object(Object *ob, int frame_index, bool fo Bone *bone = pchan->bone; Matrix bmat; if (bc_bone_matrix_local_get(ob, bone, bmat, for_opensim)) { + ob_sample.add_bone_matrix(bone, bmat); } } @@ -170,12 +176,14 @@ BCSample &BCAnimationSampler::sample_object(Object *ob, int frame_index, bool fo return ob_sample; } -void BCAnimationSampler::sample_scene(int sampling_rate, - int keyframe_at_end, - bool for_opensim, - bool keep_keyframes, - BC_export_animation_type export_animation_type) +void BCAnimationSampler::sample_scene(BCExportSettings &export_settings, bool keyframe_at_end) { + BlenderContext blender_context = export_settings.get_blender_context(); + int sampling_rate = export_settings.get_sampling_rate(); + bool for_opensim = export_settings.get_open_sim(); + bool keep_keyframes = export_settings.get_keep_keyframes(); + BC_export_animation_type export_animation_type = export_settings.get_export_animation_type(); + Scene *scene = blender_context.get_scene(); BCFrameSet scene_sample_frames; get_sample_frames(scene_sample_frames, sampling_rate, keyframe_at_end, scene); diff --git a/source/blender/collada/BCAnimationSampler.h b/source/blender/collada/BCAnimationSampler.h index 9544c6be916..e8d2ab56ae7 100644 --- a/source/blender/collada/BCAnimationSampler.h +++ b/source/blender/collada/BCAnimationSampler.h @@ -147,7 +147,7 @@ class BCSampleFrameContainer { class BCAnimationSampler { private: - BlenderContext &blender_context; + BCExportSettings &export_settings; BCSampleFrameContainer sample_data; BCAnimationObjectMap objects; @@ -169,16 +169,12 @@ class BCAnimationSampler { BCAnimation &animation, float *ref, float *val, std::string data_path, int length); public: - BCAnimationSampler(BlenderContext &blender_context, BCObjectSet &animated_subset); + BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &animated_subset); ~BCAnimationSampler(); void add_object(Object *ob); - void sample_scene(int sampling_rate, - int keyframe_at_end, - bool for_opensim, - bool keep_keyframes, - BC_export_animation_type export_animation_type); + void sample_scene(BCExportSettings &export_settings, bool keyframe_at_end); BCAnimationCurveMap *get_curves(Object *ob); void get_object_frames(BCFrames &frames, Object *ob); diff --git a/source/blender/collada/BCSampleData.cpp b/source/blender/collada/BCSampleData.cpp index 868526928b0..ceb0e07b9eb 100644 --- a/source/blender/collada/BCSampleData.cpp +++ b/source/blender/collada/BCSampleData.cpp @@ -20,10 +20,6 @@ #include "BCSampleData.h" #include "collada_utils.h" -BCSample::BCSample(Object *ob) : obmat(ob) -{ -} - BCSample::~BCSample() { BCBoneMatrixMap::iterator it; @@ -43,6 +39,11 @@ void BCSample::add_bone_matrix(Bone *bone, Matrix &mat) bonemats[bone] = matrix; } +BCMatrix::BCMatrix(const BCMatrix &mat) +{ + set_transform(mat.matrix); +} + BCMatrix::BCMatrix(Matrix &mat) { set_transform(mat); @@ -53,11 +54,51 @@ BCMatrix::BCMatrix(Object *ob) set_transform(ob); } -void BCMatrix::set_transform(Matrix &mat) +BCMatrix::BCMatrix() { - copy_m4_m4(matrix, mat); - mat4_decompose(this->loc, this->q, this->size, mat); - quat_to_eul(this->rot, this->q); + unit(); +} + +BCMatrix::BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis global_up_axis) +{ + float mrot[3][3]; + float mat[4][4]; + mat3_from_axis_conversion( + BC_DEFAULT_FORWARD, BC_DEFAULT_UP, global_forward_axis, global_up_axis, mrot); + + // transpose_m3(mrot); // Assume that mat3_from_axis_conversion() returns a transposed matrix + copy_m4_m3(mat, mrot); + set_transform(mat); +} + +void BCMatrix::add_transform(const Matrix &mat, bool inverse) +{ + add_transform(this->matrix, mat, this->matrix, inverse); +} + +void BCMatrix::add_transform(const BCMatrix &mat, bool inverse) +{ + add_transform(this->matrix, mat.matrix, this->matrix, inverse); +} + +void BCMatrix::add_transform(Matrix &to, const Matrix &transform, const Matrix &from, bool inverse) +{ + Matrix globinv; + invert_m4_m4(globinv, transform); + if (inverse) { + add_transform(to, globinv, from, /*inverse=*/false); + } + else { + mul_m4_m4m4(to, transform, from); + mul_m4_m4m4(to, to, globinv); + } +} + +void BCMatrix::add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from) +{ + Matrix workmat; + invert_m4_m4(workmat, transform); + mul_m4_m4m4(to, workmat, from); } void BCMatrix::set_transform(Object *ob) @@ -71,6 +112,13 @@ void BCMatrix::set_transform(Object *ob) quat_to_compatible_eul(this->rot, ob->rot, this->q); } +void BCMatrix::set_transform(Matrix &mat) +{ + copy_m4_m4(matrix, mat); + mat4_decompose(this->loc, this->q, this->size, mat); + quat_to_eul(this->rot, this->q); +} + const BCMatrix *BCSample::get_matrix(Bone *bone) const { BCBoneMatrixMap::const_iterator it = bonemats.find(bone); @@ -126,12 +174,14 @@ void BCMatrix::sanitize(Matrix &mat, int precision) void BCMatrix::unit() { - unit_m4(matrix); + unit_m4(this->matrix); + mat4_decompose(this->loc, this->q, this->size, this->matrix); + quat_to_eul(this->rot, this->q); } /* We need double here because the OpenCollada API needs it. * precision = -1 indicates to not limit the precision. */ -void BCMatrix::get_matrix(double (&mat)[4][4], const bool transposed, const int precision) const +void BCMatrix::get_matrix(DMatrix &mat, const bool transposed, const int precision) const { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { @@ -142,6 +192,24 @@ void BCMatrix::get_matrix(double (&mat)[4][4], const bool transposed, const int } } +void BCMatrix::get_matrix(Matrix &mat, + const bool transposed, + const int precision, + const bool inverted) const +{ + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) { + float val = (transposed) ? matrix[j][i] : matrix[i][j]; + if (precision >= 0) + val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision); + mat[i][j] = val; + } + + if (inverted) { + invert_m4(mat); + } +} + const bool BCMatrix::in_range(const BCMatrix &other, float distance) const { for (int i = 0; i < 4; i++) { diff --git a/source/blender/collada/BCSampleData.h b/source/blender/collada/BCSampleData.h index 9cb56c95e0f..709bd3e59ef 100644 --- a/source/blender/collada/BCSampleData.h +++ b/source/blender/collada/BCSampleData.h @@ -24,6 +24,8 @@ #include <map> #include <algorithm> +#include "ExportSettings.h" + extern "C" { #include "BKE_object.h" #include "BLI_math_rotation.h" @@ -34,40 +36,6 @@ extern "C" { #include "DNA_camera_types.h" } -typedef float(Matrix)[4][4]; - -class BCMatrix { - - private: - mutable float matrix[4][4]; - mutable float size[3]; - mutable float rot[3]; - mutable float loc[3]; - mutable float q[4]; - - void unit(); - void copy(Matrix &r, Matrix &a); - void set_transform(Object *ob); - void set_transform(Matrix &mat); - - public: - float (&location() const)[3]; - float (&rotation() const)[3]; - float (&scale() const)[3]; - float (&quat() const)[4]; - - BCMatrix(Matrix &mat); - BCMatrix(Object *ob); - - void get_matrix(double (&mat)[4][4], - const bool transposed = false, - const int precision = -1) const; - - const bool in_range(const BCMatrix &other, float distance) const; - static void sanitize(Matrix &matrix, int precision); - static void transpose(Matrix &matrix); -}; - typedef std::map<Bone *, BCMatrix *> BCBoneMatrixMap; class BCSample { @@ -76,7 +44,10 @@ class BCSample { BCBoneMatrixMap bonemats; /* For Armature animation */ public: - BCSample(Object *ob); + BCSample(Object *ob) : obmat(ob) + { + } + ~BCSample(); void add_bone_matrix(Bone *bone, Matrix &mat); diff --git a/source/blender/collada/BlenderContext.cpp b/source/blender/collada/BlenderContext.cpp index 384f235e00c..709f84c3f77 100644 --- a/source/blender/collada/BlenderContext.cpp +++ b/source/blender/collada/BlenderContext.cpp @@ -18,9 +18,92 @@ * \ingroup collada */ +#include <vector> + #include "BlenderContext.h" #include "BKE_scene.h" +bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer) +{ + Object *root = bc_get_highest_exported_ancestor_or_self(export_set, ob, view_layer); + return (root == ob); +} + +/** + * Returns the highest selected ancestor + * returns NULL if no ancestor is selected + * IMPORTANT: This function expects that all exported objects have set: + * ob->id.tag & LIB_TAG_DOIT + */ +Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set, + Object *ob, + ViewLayer *view_layer) +{ + Object *ancestor = ob; + while (ob->parent) { + if (bc_is_in_Export_set(export_set, ob->parent, view_layer)) { + ancestor = ob->parent; + } + ob = ob->parent; + } + return ancestor; +} + +void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer) +{ + Base *base; + for (base = (Base *)view_layer->object_bases.first; base; base = base->next) { + Object *cob = base->object; + if (cob->parent == ob) { + switch (ob->type) { + case OB_MESH: + case OB_CAMERA: + case OB_LAMP: + case OB_EMPTY: + case OB_ARMATURE: + child_set.push_back(cob); + default: + break; + } + } + } +} + +bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer) +{ + bool to_export = (BLI_linklist_index(export_set, ob) != -1); + + if (!to_export) { + /* Mark this object as to_export even if it is not in the + export list, but it contains children to export */ + + std::vector<Object *> children; + bc_get_children(children, ob, view_layer); + for (int i = 0; i < children.size(); i++) { + if (bc_is_in_Export_set(export_set, children[i], view_layer)) { + to_export = true; + break; + } + } + } + return to_export; +} + +int bc_is_marked(Object *ob) +{ + return ob && (ob->id.tag & LIB_TAG_DOIT); +} + +void bc_remove_mark(Object *ob) +{ + ob->id.tag &= ~LIB_TAG_DOIT; +} + +void bc_set_mark(Object *ob) +{ + ob->id.tag |= LIB_TAG_DOIT; +} + BlenderContext::BlenderContext(bContext *C) { context = C; diff --git a/source/blender/collada/BlenderContext.h b/source/blender/collada/BlenderContext.h index f79f3a52507..98c190afa94 100644 --- a/source/blender/collada/BlenderContext.h +++ b/source/blender/collada/BlenderContext.h @@ -21,14 +21,100 @@ #ifndef __BLENDERCONTEXT_H__ #define __BLENDERCONTEXT_H__ +#ifdef __cplusplus + extern "C" { +#endif + #include "DNA_object_types.h" +#include "BLI_linklist.h" #include "BKE_context.h" #include "BKE_main.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "DNA_layer_types.h" + +typedef float(Vector)[3]; +typedef float(Matrix)[4][4]; +typedef double(DMatrix)[4][4]; + +typedef enum BC_global_forward_axis { + BC_GLOBAL_FORWARD_X = 0, + BC_GLOBAL_FORWARD_Y = 1, + BC_GLOBAL_FORWARD_Z = 2, + BC_GLOBAL_FORWARD_MINUS_X = 3, + BC_GLOBAL_FORWARD_MINUS_Y = 4, + BC_GLOBAL_FORWARD_MINUS_Z = 5 +} BC_global_forward_axis; + +typedef enum BC_global_up_axis { + BC_GLOBAL_UP_X = 0, + BC_GLOBAL_UP_Y = 1, + BC_GLOBAL_UP_Z = 2, + BC_GLOBAL_UP_MINUS_X = 3, + BC_GLOBAL_UP_MINUS_Y = 4, + BC_GLOBAL_UP_MINUS_Z = 5 +} BC_global_up_axis; + +static const BC_global_forward_axis BC_DEFAULT_FORWARD = BC_GLOBAL_FORWARD_Y; +static const BC_global_up_axis BC_DEFAULT_UP = BC_GLOBAL_UP_Z; + +bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer); +bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer); +Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set, + Object *ob, + ViewLayer *view_layer); +int bc_is_marked(Object *ob); +void bc_remove_mark(Object *ob); +void bc_set_mark(Object *ob); + +#ifdef __cplusplus } +class BCMatrix { + + private: + mutable float matrix[4][4]; + mutable float size[3]; + mutable float rot[3]; + mutable float loc[3]; + mutable float q[4]; + + void unit(); + void copy(Matrix &r, Matrix &a); + + public: + float (&location() const)[3]; + float (&rotation() const)[3]; + float (&scale() const)[3]; + float (&quat() const)[4]; + + BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis global_up_axis); + BCMatrix(const BCMatrix &mat); + BCMatrix(Matrix &mat); + BCMatrix(Object *ob); + BCMatrix(); + + void get_matrix(DMatrix &matrix, const bool transposed = false, const int precision = -1) const; + void get_matrix(Matrix &matrix, + const bool transposed = false, + const int precision = -1, + const bool inverted = false) const; + void set_transform(Object *ob); + void set_transform(Matrix &mat); + void add_transform(Matrix &to, + const Matrix &transform, + const Matrix &from, + const bool inverted = false); + void add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from); + void add_transform(const Matrix &matrix, const bool inverted = false); + void add_transform(const BCMatrix &matrix, const bool inverted = false); + + const bool in_range(const BCMatrix &other, float distance) const; + static void sanitize(Matrix &matrix, int precision); + static void transpose(Matrix &matrix); +}; + class BlenderContext { private: bContext *context; @@ -47,5 +133,6 @@ class BlenderContext { ViewLayer *get_view_layer(); Main *get_main(); }; +#endif #endif diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index a46ee74be91..74862c44270 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -29,8 +29,7 @@ extern "C" { #include "collada_internal.h" -CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings) +CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) : COLLADASW::LibraryCameras(sw), export_settings(export_settings) { } @@ -52,7 +51,7 @@ void CamerasExporter::exportCameras(Scene *sce) { openLibrary(); - forEachCameraObjectInExportSet(sce, *this, this->export_settings->export_set); + forEachCameraObjectInExportSet(sce, *this, this->export_settings.get_export_set()); closeLibrary(); } diff --git a/source/blender/collada/CameraExporter.h b/source/blender/collada/CameraExporter.h index 0a90fc017e8..04bcc4a5dad 100644 --- a/source/blender/collada/CameraExporter.h +++ b/source/blender/collada/CameraExporter.h @@ -34,13 +34,13 @@ extern "C" { class CamerasExporter : COLLADASW::LibraryCameras { public: - CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + CamerasExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings); void exportCameras(Scene *sce); void operator()(Object *ob, Scene *sce); private: bool exportBlenderProfile(COLLADASW::Camera &cla, Camera *cam); - const ExportSettings *export_settings; + BCExportSettings &export_settings; }; #endif diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp index c79a4e1a1f7..4ae185ae684 100644 --- a/source/blender/collada/ControllerExporter.cpp +++ b/source/blender/collada/ControllerExporter.cpp @@ -57,7 +57,7 @@ void ControllerExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone) { - if (bc_is_root_bone(bone, this->export_settings->deform_bones_only)) { + if (bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) { std::string node_id = translate_id(id_name(ob_arm) + "_" + bone->name); ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, node_id)); } @@ -89,7 +89,7 @@ bool ControllerExporter::add_instance_controller(Object *ob) } InstanceWriter::add_material_bindings( - ins.getBindMaterial(), ob, this->export_settings->active_uv_only); + ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only()); ins.add(); return true; @@ -102,7 +102,7 @@ void ControllerExporter::export_controllers() GeometryFunctor gf; gf.forEachMeshObjectInExportSet<ControllerExporter>( - sce, *this, this->export_settings->export_set); + sce, *this, this->export_settings.get_export_set()); closeLibrary(); } @@ -115,7 +115,7 @@ void ControllerExporter::operator()(Object *ob) if (ob_arm) { export_skin_controller(ob, ob_arm); } - if (key && this->export_settings->include_shapekeys) { + if (key && this->export_settings.get_include_shapekeys()) { export_morph_controller(ob, key); } } @@ -189,7 +189,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) } MDeformWeight; #endif - bool use_instantiation = this->export_settings->use_object_instantiation; + bool use_instantiation = this->export_settings.get_use_object_instantiation(); Mesh *me; if (((Mesh *)ob->data)->dvert == NULL) { @@ -198,9 +198,9 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) me = bc_get_mesh_copy(blender_context, ob, - this->export_settings->export_mesh_type, - this->export_settings->apply_modifiers, - this->export_settings->triangulate); + this->export_settings.get_export_mesh_type(), + this->export_settings.get_apply_modifiers(), + this->export_settings.get_triangulate()); std::string controller_name = id_name(ob_arm); std::string controller_id = get_controller_id(ob_arm, ob); @@ -297,14 +297,14 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) void ControllerExporter::export_morph_controller(Object *ob, Key *key) { - bool use_instantiation = this->export_settings->use_object_instantiation; + bool use_instantiation = this->export_settings.get_use_object_instantiation(); Mesh *me; me = bc_get_mesh_copy(blender_context, ob, - this->export_settings->export_mesh_type, - this->export_settings->apply_modifiers, - this->export_settings->triangulate); + this->export_settings.get_export_mesh_type(), + this->export_settings.get_apply_modifiers(), + this->export_settings.get_triangulate()); std::string controller_name = id_name(ob) + "-morph"; std::string controller_id = get_controller_id(key, ob); @@ -431,9 +431,15 @@ void ControllerExporter::add_bind_shape_mat(Object *ob) float f_obmat[4][4]; BKE_object_matrix_local_get(ob, f_obmat); + if (export_settings.get_apply_global_orientation()) { + } + else { + bc_add_global_transform(f_obmat, export_settings.get_global_transform()); + } + // UnitConverter::mat4_to_dae_double(bind_mat, ob->obmat); UnitConverter::mat4_to_dae_double(bind_mat, f_obmat); - if (this->export_settings->limit_precision) + if (this->export_settings.get_limit_precision()) bc_sanitize_mat(bind_mat, LIMITTED_PRECISION); addBindShapeTransform(bind_mat); @@ -532,8 +538,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, this->export_settings, pchan->bone, bind_mat, pchan->bone->arm_mat, true); /* SL/OPEN_SIM COMPATIBILITY */ - if (export_settings->open_sim) { - + if (export_settings.get_open_sim()) { float loc[3]; float rot[3] = {0, 0, 0}; float scale[3]; @@ -547,9 +552,19 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, /* make world-space matrix (bind_mat is armature-space) */ mul_m4_m4m4(world, ob_arm->obmat, bind_mat); + if (export_settings.get_apply_global_orientation()) { + Vector loc; + copy_v3_v3(loc, world[3]); + bc_add_global_transform(loc, export_settings.get_global_transform()); + copy_v3_v3(world[3], loc); + } + else { + bc_add_global_transform(world, export_settings.get_global_transform()); + } + invert_m4_m4(mat, world); UnitConverter::mat4_to_dae(inv_bind_mat, mat); - if (this->export_settings->limit_precision) + if (this->export_settings.get_limit_precision()) bc_sanitize_mat(inv_bind_mat, LIMITTED_PRECISION); source.appendValues(inv_bind_mat); } diff --git a/source/blender/collada/ControllerExporter.h b/source/blender/collada/ControllerExporter.h index 38d85cb7ebc..200f8431f62 100644 --- a/source/blender/collada/ControllerExporter.h +++ b/source/blender/collada/ControllerExporter.h @@ -53,13 +53,17 @@ class SceneExporter; class ControllerExporter : public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter { + private: + BlenderContext &blender_context; + BCExportSettings export_settings; + public: // 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? ControllerExporter(BlenderContext &blender_context, COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings) + BCExportSettings &export_settings) : COLLADASW::LibraryControllers(sw), blender_context(blender_context), export_settings(export_settings) @@ -75,9 +79,6 @@ class ControllerExporter : public COLLADASW::LibraryControllers, void operator()(Object *ob); private: - BlenderContext &blender_context; - const ExportSettings *export_settings; - #if 0 std::vector<Object *> written_armatures; diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index c8202eb3cf6..f9232851fbb 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -146,9 +146,9 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) return data->layers[layer_index].name; } -DocumentExporter::DocumentExporter(BlenderContext &blender_context, - const ExportSettings *export_settings) - : blender_context(blender_context), export_settings(export_settings) +DocumentExporter::DocumentExporter(BlenderContext &blender_context, ExportSettings *exportSettings) + : blender_context(blender_context), + export_settings(BCExportSettings(exportSettings, blender_context)) { } @@ -262,7 +262,7 @@ int DocumentExporter::exportCurrentScene() asset.getContributor().mAuthoringTool = version_buf; asset.add(); - LinkNode *export_set = this->export_settings->export_set; + LinkNode *export_set = this->export_settings.get_export_set(); // <library_cameras> if (bc_has_object_type(export_set, OB_CAMERA)) { CamerasExporter ce(writer, this->export_settings); @@ -296,7 +296,8 @@ int DocumentExporter::exportCurrentScene() // <library_controllers> ArmatureExporter arm_exporter(blender_context, writer, this->export_settings); ControllerExporter controller_exporter(blender_context, writer, this->export_settings); - if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys) { + if (bc_has_object_type(export_set, OB_ARMATURE) || + this->export_settings.get_include_shapekeys()) { controller_exporter.export_controllers(); } @@ -304,9 +305,9 @@ int DocumentExporter::exportCurrentScene() SceneExporter se(blender_context, writer, &arm_exporter, this->export_settings); - if (this->export_settings->include_animations) { + if (this->export_settings.get_include_animations()) { // <library_animations> - AnimationExporter ae(blender_context, writer, this->export_settings); + AnimationExporter ae(writer, this->export_settings); ae.exportAnimations(); } @@ -322,10 +323,10 @@ int DocumentExporter::exportCurrentScene() delete writer; // Finally move the created document into place - fprintf(stdout, "Collada export to: %s\n", this->export_settings->filepath); - int status = BLI_rename(native_filename.c_str(), this->export_settings->filepath); + fprintf(stdout, "Collada export to: %s\n", this->export_settings.get_filepath()); + int status = BLI_rename(native_filename.c_str(), this->export_settings.get_filepath()); if (status != 0) { - status = BLI_copy(native_filename.c_str(), this->export_settings->filepath); + status = BLI_copy(native_filename.c_str(), this->export_settings.get_filepath()); BLI_delete(native_filename.c_str(), false, false); } return status; diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h index a5608d13a71..70722ae601e 100644 --- a/source/blender/collada/DocumentExporter.h +++ b/source/blender/collada/DocumentExporter.h @@ -31,13 +31,13 @@ extern "C" { class DocumentExporter { public: - DocumentExporter(BlenderContext &blender_context, const ExportSettings *export_settings); + DocumentExporter(BlenderContext &blender_context, ExportSettings *export_settings); int exportCurrentScene(); void exportScenes(const char *filename); private: BlenderContext &blender_context; - const ExportSettings *export_settings; + BCExportSettings export_settings; KeyImageMap key_image_map; }; diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 3aceebe0422..60813fb951c 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -1125,7 +1125,6 @@ bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim) if (mImportStage == Fetching_Controller_data) return true; - /* return true; */ return anim_importer.write_animation(anim); } diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index a6e75ba41a9..61603226dfd 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -53,7 +53,7 @@ static std::string getActiveUVLayerName(Object *ob) } EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings, + BCExportSettings &export_settings, KeyImageMap &key_image_map) : COLLADASW::LibraryEffects(sw), export_settings(export_settings), key_image_map(key_image_map) { @@ -84,7 +84,8 @@ void EffectsExporter::exportEffects(bContext *C, Scene *sce) this->scene = sce; openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set); + mf.forEachMaterialInExportSet<EffectsExporter>( + sce, *this, this->export_settings.get_export_set()); closeLibrary(); } diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h index 25df2d7eb89..75511800081 100644 --- a/source/blender/collada/EffectExporter.h +++ b/source/blender/collada/EffectExporter.h @@ -40,7 +40,7 @@ class EffectsExporter : COLLADASW::LibraryEffects { public: EffectsExporter(COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings, + BCExportSettings &export_settings, KeyImageMap &key_image_map); void exportEffects(bContext *C, Scene *sce); @@ -73,7 +73,7 @@ class EffectsExporter : COLLADASW::LibraryEffects { bool hasEffects(Scene *sce); - const ExportSettings *export_settings; + BCExportSettings &export_settings; KeyImageMap &key_image_map; Scene *scene; bContext *mContext; diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index a362b72be00..7112aeadb2a 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -22,10 +22,13 @@ #define __EXPORTSETTINGS_H__ #ifdef __cplusplus +# include <vector> + extern "C" { #endif #include "BLI_linklist.h" +#include "BlenderContext.h" typedef enum BC_export_mesh_type { BC_MESH_TYPE_VIEW, @@ -52,6 +55,10 @@ typedef enum BC_ui_export_section { typedef struct ExportSettings { bool apply_modifiers; + BC_global_forward_axis global_forward; + BC_global_up_axis global_up; + bool apply_global_orientation; + BC_export_mesh_type export_mesh_type; bool selected; @@ -86,6 +93,196 @@ typedef struct ExportSettings { #ifdef __cplusplus } + +void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer); + +class BCExportSettings { + + private: + const ExportSettings &export_settings; + BlenderContext &blender_context; + const BCMatrix global_transform; + + public: + BCExportSettings(ExportSettings *exportSettings, BlenderContext &blenderContext) + : export_settings(*exportSettings), + blender_context(blenderContext), + global_transform(BCMatrix(exportSettings->global_forward, exportSettings->global_up)) + + { + } + + const BCMatrix &get_global_transform() + { + return global_transform; + } + + bool get_apply_modifiers() + { + return export_settings.apply_modifiers; + } + + BC_global_forward_axis get_global_forward() + { + return export_settings.global_forward; + } + + BC_global_up_axis get_global_up() + { + return export_settings.global_up; + } + + bool get_apply_global_orientation() + { + return export_settings.apply_global_orientation; + } + + BC_export_mesh_type get_export_mesh_type() + { + return export_settings.export_mesh_type; + } + + bool get_selected() + { + return export_settings.selected; + } + + bool get_include_children() + { + return export_settings.include_children; + } + + bool get_include_armatures() + { + return export_settings.include_armatures; + } + + bool get_include_shapekeys() + { + return export_settings.include_shapekeys; + } + + bool get_deform_bones_only() + { + return export_settings.deform_bones_only; + } + + bool get_include_animations() + { + return export_settings.include_animations; + } + + bool get_include_all_actions() + { + return export_settings.include_all_actions; + } + + int get_sampling_rate() + { + return export_settings.sampling_rate; + } + + bool get_keep_smooth_curves() + { + return export_settings.keep_smooth_curves; + } + + bool get_keep_keyframes() + { + return export_settings.keep_keyframes; + } + + bool get_keep_flat_curves() + { + return export_settings.keep_flat_curves; + } + + bool get_active_uv_only() + { + return export_settings.active_uv_only; + } + + BC_export_animation_type get_export_animation_type() + { + return export_settings.export_animation_type; + } + + bool get_use_texture_copies() + { + return export_settings.use_texture_copies; + } + + bool get_triangulate() + { + return export_settings.triangulate; + } + + bool get_use_object_instantiation() + { + return export_settings.use_object_instantiation; + } + + bool get_use_blender_profile() + { + return export_settings.use_blender_profile; + } + + bool get_sort_by_name() + { + return export_settings.sort_by_name; + } + + BC_export_transformation_type get_export_transformation_type() + { + return export_settings.export_transformation_type; + } + + bool get_open_sim() + { + return export_settings.open_sim; + } + + bool get_limit_precision() + { + return export_settings.limit_precision; + } + + bool get_keep_bind_info() + { + return export_settings.keep_bind_info; + } + + char *get_filepath() + { + return export_settings.filepath; + } + + LinkNode *get_export_set() + { + return export_settings.export_set; + } + + BlenderContext &get_blender_context() + { + return blender_context; + } + + Scene *get_scene() + { + return blender_context.get_scene(); + } + + ViewLayer *get_view_layer() + { + return blender_context.get_view_layer(); + } + + bool is_export_root(Object *ob) + { + return bc_is_base_node(get_export_set(), ob, get_view_layer()); + } +}; + #endif #endif diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index bda6fec70a8..c0573dcc081 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -48,19 +48,20 @@ void GeometryExporter::exportGeom() openLibrary(); GeometryFunctor gf; - gf.forEachMeshObjectInExportSet<GeometryExporter>(sce, *this, this->export_settings->export_set); + gf.forEachMeshObjectInExportSet<GeometryExporter>( + sce, *this, this->export_settings.get_export_set()); closeLibrary(); } void GeometryExporter::operator()(Object *ob) { - bool use_instantiation = this->export_settings->use_object_instantiation; + bool use_instantiation = this->export_settings.get_use_object_instantiation(); Mesh *me = bc_get_mesh_copy(blender_context, ob, - this->export_settings->export_mesh_type, - this->export_settings->apply_modifiers, - this->export_settings->triangulate); + this->export_settings.get_export_mesh_type(), + this->export_settings.get_apply_modifiers(), + this->export_settings.get_triangulate()); std::string geom_id = get_geometry_id(ob, use_instantiation); std::vector<Normal> nor; @@ -128,7 +129,7 @@ void GeometryExporter::operator()(Object *ob) closeGeometry(); - if (this->export_settings->include_shapekeys) { + if (this->export_settings.get_include_shapekeys()) { Key *key = BKE_key_from_object(ob); if (key) { KeyBlock *kb = (KeyBlock *)key->block.first; @@ -380,14 +381,14 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); for (int i = 0; i < num_layers; i++) { int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i); - if (!this->export_settings->active_uv_only || layer_index == active_uv_index) { + if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) { // char *name = CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, i); COLLADASW::Input texcoord_input( COLLADASW::InputSemantic::TEXCOORD, - makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)), + makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())), 2, // this is only until we have optimized UV sets - (this->export_settings->active_uv_only) ? 0 : layer_index - 1 /* set (0,1,2,...) */ + (this->export_settings.get_active_uv_only()) ? 0 : layer_index - 1 /* set (0,1,2,...) */ ); til.push_back(texcoord_input); } @@ -466,7 +467,14 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) /* appends data to <float_array> */ int i = 0; for (i = 0; i < totverts; i++) { - source.appendValues(verts[i].co[0], verts[i].co[1], verts[i].co[2]); + Vector co; + // if (export_settings.get_apply_global_orientation()) { + bc_add_global_transform(co, verts[i].co, export_settings.get_global_transform()); + //} + // else { + // copy_v3_v3(co, verts[i].co); + //} + source.appendValues(co[0], co[1], co[2]); } source.finish(); @@ -547,12 +555,12 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); for (int a = 0; a < num_layers; a++) { int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, a); - if (!this->export_settings->active_uv_only || layer_index == active_uv_index) { + if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) { MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId( - geom_id, a, this->export_settings->active_uv_only); + geom_id, a, this->export_settings.get_active_uv_only()); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); @@ -606,7 +614,12 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v std::vector<Normal>::iterator it; for (it = nor.begin(); it != nor.end(); it++) { Normal &n = *it; - source.appendValues(n.x, n.y, n.z); + + Vector no{n.x, n.y, n.z}; + // if (export_settings.get_apply_global_orientation()) { + bc_add_global_transform(no, export_settings.get_global_transform()); + //} + source.appendValues(no[0], no[1], no[2]); } source.finish(); diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 976059b0925..7262784db82 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -41,8 +41,6 @@ struct Depsgraph; -extern Object *bc_get_highest_selected_ancestor_or_self(Object *ob); - class Normal { public: float x; @@ -66,7 +64,7 @@ class GeometryExporter : COLLADASW::LibraryGeometries { /* TODO: optimize UV sets by making indexed list with duplicates removed */ GeometryExporter(BlenderContext &blender_context, COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings) + BCExportSettings &export_settings) : COLLADASW::LibraryGeometries(sw), blender_context(blender_context), export_settings(export_settings) @@ -122,7 +120,7 @@ class GeometryExporter : COLLADASW::LibraryGeometries { private: std::set<std::string> exportedGeometry; BlenderContext &blender_context; - const ExportSettings *export_settings; + BCExportSettings &export_settings; Mesh *get_mesh(Scene *sce, Object *ob, int apply_modifiers); }; diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index b606799efde..71201c8a55c 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -43,7 +43,7 @@ extern "C" { #include "MaterialExporter.h" ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings, + BCExportSettings &export_settings, KeyImageMap &key_image_map) : COLLADASW::LibraryImages(sw), export_settings(export_settings), key_image_map(key_image_map) { @@ -76,7 +76,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies) char export_file[FILE_MAX]; /* Destination folder for exported assets */ - BLI_split_dir_part(this->export_settings->filepath, export_dir, sizeof(export_dir)); + BLI_split_dir_part(this->export_settings.get_filepath(), export_dir, sizeof(export_dir)); if (is_generated || is_dirty || use_copies || is_packed) { @@ -152,7 +152,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies) void ImagesExporter::exportImages(Scene *sce) { - bool use_texture_copies = this->export_settings->use_texture_copies; + bool use_texture_copies = this->export_settings.get_use_texture_copies(); openLibrary(); KeyImageMap::iterator iter; diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h index ac0c1d5c976..b72d2709382 100644 --- a/source/blender/collada/ImageExporter.h +++ b/source/blender/collada/ImageExporter.h @@ -38,12 +38,12 @@ class ImagesExporter : COLLADASW::LibraryImages { public: ImagesExporter(COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings, + BCExportSettings &export_settings, KeyImageMap &key_image_map); void exportImages(Scene *sce); private: - const ExportSettings *export_settings; + BCExportSettings &export_settings; KeyImageMap &key_image_map; void export_UV_Image(Image *image, bool use_texture_copies); }; diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp index 39721b2eb3c..463981ceefa 100644 --- a/source/blender/collada/LightExporter.cpp +++ b/source/blender/collada/LightExporter.cpp @@ -41,7 +41,7 @@ void forEachLightObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) } } -LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) +LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) : COLLADASW::LibraryLights(sw), export_settings(export_settings) { } @@ -50,7 +50,7 @@ void LightsExporter::exportLights(Scene *sce) { openLibrary(); - forEachLightObjectInExportSet(sce, *this, this->export_settings->export_set); + forEachLightObjectInExportSet(sce, *this, this->export_settings.get_export_set()); closeLibrary(); } diff --git a/source/blender/collada/LightExporter.h b/source/blender/collada/LightExporter.h index fc468f1f4a3..045ccfe1ce8 100644 --- a/source/blender/collada/LightExporter.h +++ b/source/blender/collada/LightExporter.h @@ -32,13 +32,13 @@ class LightsExporter : COLLADASW::LibraryLights { public: - LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + LightsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings); void exportLights(Scene *sce); void operator()(Object *ob); private: bool exportBlenderProfile(COLLADASW::Light &cla, Light *la); - const ExportSettings *export_settings; + BCExportSettings &export_settings; }; #endif diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index e071712b20d..8bf7a220c4a 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -23,7 +23,7 @@ #include "collada_internal.h" MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, - const ExportSettings *export_settings) + BCExportSettings &export_settings) : COLLADASW::LibraryMaterials(sw), export_settings(export_settings) { /* pass */ @@ -36,7 +36,7 @@ void MaterialsExporter::exportMaterials(Scene *sce) MaterialFunctor mf; mf.forEachMaterialInExportSet<MaterialsExporter>( - sce, *this, this->export_settings->export_set); + sce, *this, this->export_settings.get_export_set()); closeLibrary(); } @@ -45,7 +45,7 @@ void MaterialsExporter::exportMaterials(Scene *sce) bool MaterialsExporter::hasMaterials(Scene *sce) { LinkNode *node; - for (node = this->export_settings->export_set; node; node = node->next) { + for (node = this->export_settings.get_export_set(); node; node = node->next) { Object *ob = (Object *)node->link; int a; for (a = 0; a < ob->totcol; a++) { diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h index d47a001596d..027fba1f8ef 100644 --- a/source/blender/collada/MaterialExporter.h +++ b/source/blender/collada/MaterialExporter.h @@ -41,13 +41,13 @@ extern "C" { class MaterialsExporter : COLLADASW::LibraryMaterials { public: - MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + MaterialsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings); void exportMaterials(Scene *sce); void operator()(Material *ma, Object *ob); private: bool hasMaterials(Scene *sce); - const ExportSettings *export_settings; + BCExportSettings &export_settings; }; // used in forEachMaterialInScene diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 8017790572f..22b2eed79d3 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -23,10 +23,12 @@ extern "C" { #include "BKE_collection.h" #include "BKE_object.h" #include "BLI_listbase.h" +#include "BKE_library.h" } #include "SceneExporter.h" #include "collada_utils.h" +#include "BCSampleData.h" void SceneExporter::exportScene() { @@ -43,18 +45,18 @@ void SceneExporter::exportScene() void SceneExporter::exportHierarchy() { LinkNode *node; - std::vector<Object *> base_objects; + ColladaBaseNodes base_objects; /* Ensure all objects in the export_set are marked */ - for (node = this->export_settings->export_set; node; node = node->next) { + for (node = this->export_settings.get_export_set(); node; node = node->next) { Object *ob = (Object *)node->link; ob->id.tag |= LIB_TAG_DOIT; } /* Now find all exportable base objects (highest in export hierarchy) */ - for (node = this->export_settings->export_set; node; node = node->next) { + for (node = this->export_settings.get_export_set(); node; node = node->next) { Object *ob = (Object *)node->link; - if (bc_is_base_node(this->export_settings->export_set, ob)) { + if (this->export_settings.is_export_root(ob)) { switch (ob->type) { case OB_MESH: case OB_CAMERA: @@ -62,7 +64,7 @@ void SceneExporter::exportHierarchy() case OB_EMPTY: case OB_GPENCIL: case OB_ARMATURE: - base_objects.push_back(ob); + base_objects.add(ob); break; } } @@ -70,10 +72,10 @@ void SceneExporter::exportHierarchy() /* And now export the base objects: */ for (int index = 0; index < base_objects.size(); index++) { - Object *ob = base_objects[index]; + Object *ob = base_objects.get(index); + writeNode(ob); if (bc_is_marked(ob)) { bc_remove_mark(ob); - writeNodes(ob); } } } @@ -88,30 +90,31 @@ void SceneExporter::writeNodeList(std::vector<Object *> &child_objects, Object * * the hidden elements are exported as well. */ for (int i = 0; i < child_objects.size(); ++i) { Object *child = child_objects[i]; + writeNode(child); if (bc_is_marked(child)) { bc_remove_mark(child); - writeNodes(child); } } } -void SceneExporter::writeNodes(Object *ob) +void SceneExporter::writeNode(Object *ob) { ViewLayer *view_layer = blender_context.get_view_layer(); std::vector<Object *> child_objects; bc_get_children(child_objects, ob, view_layer); - bool can_export = bc_is_in_Export_set(this->export_settings->export_set, ob, view_layer); + bool can_export = bc_is_in_Export_set(this->export_settings.get_export_set(), ob, view_layer); /* Add associated armature first if available */ bool armature_exported = false; Object *ob_arm = bc_get_assigned_armature(ob); if (ob_arm != NULL) { - armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm, view_layer); + armature_exported = bc_is_in_Export_set( + this->export_settings.get_export_set(), ob_arm, view_layer); if (armature_exported && bc_is_marked(ob_arm)) { + writeNode(ob_arm); bc_remove_mark(ob_arm); - writeNodes(ob_arm); armature_exported = true; } } @@ -123,16 +126,12 @@ void SceneExporter::writeNodes(Object *ob) colladaNode.setType(COLLADASW::Node::NODE); colladaNode.start(); - if (ob->type == OB_MESH && armature_exported) { /* for skinned mesh we write obmat in <bind_shape_matrix> */ TransformWriter::add_node_transform_identity(colladaNode); } else { - TransformWriter::add_node_transform_ob(colladaNode, - ob, - this->export_settings->export_transformation_type, - this->export_settings->limit_precision); + TransformWriter::add_node_transform_ob(colladaNode, ob, this->export_settings); } /* <instance_geometry> */ @@ -143,12 +142,12 @@ void SceneExporter::writeNodes(Object *ob) } if (!instance_controller_created) { COLLADASW::InstanceGeometry instGeom(mSW); - instGeom.setUrl( - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, - get_geometry_id(ob, this->export_settings->use_object_instantiation))); + instGeom.setUrl(COLLADASW::URI( + COLLADABU::Utils::EMPTY_STRING, + get_geometry_id(ob, this->export_settings.get_use_object_instantiation()))); instGeom.setName(encode_xml(id_name(ob))); InstanceWriter::add_material_bindings( - instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only); + instGeom.getBindMaterial(), ob, this->export_settings.get_active_uv_only()); instGeom.add(); } } @@ -232,7 +231,11 @@ void SceneExporter::writeNodes(Object *ob) } } } + bc_remove_mark(ob); writeNodeList(child_objects, ob); colladaNode.end(); } + else { + writeNodeList(child_objects, ob); + } } diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h index dc0a0c3e2ad..a61d045ad5d 100644 --- a/source/blender/collada/SceneExporter.h +++ b/source/blender/collada/SceneExporter.h @@ -82,9 +82,10 @@ extern "C" { #include "COLLADASWBaseInputElement.h" #include "ArmatureExporter.h" - #include "ExportSettings.h" +extern void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer); + class SceneExporter : COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter { @@ -92,7 +93,7 @@ class SceneExporter : COLLADASW::LibraryVisualScenes, SceneExporter(BlenderContext &blender_context, COLLADASW::StreamWriter *sw, ArmatureExporter *arm, - const ExportSettings *export_settings) + BCExportSettings &export_settings) : COLLADASW::LibraryVisualScenes(sw), blender_context(blender_context), arm_exporter(arm), @@ -106,11 +107,11 @@ class SceneExporter : COLLADASW::LibraryVisualScenes, BlenderContext &blender_context; friend class ArmatureExporter; ArmatureExporter *arm_exporter; - const ExportSettings *export_settings; + BCExportSettings &export_settings; void exportHierarchy(); void writeNodeList(std::vector<Object *> &child_objects, Object *parent); - void writeNodes(Object *ob); + void writeNode(Object *ob); }; #endif diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index 2ab9105976e..dfe4add8e7f 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -27,9 +27,9 @@ void TransformWriter::add_node_transform(COLLADASW::Node &node, float mat[4][4], - float parent_mat[4][4], - bool limit_precision) + float parent_mat[4][4]) { + // bool limit_precision = export_settings.limit_precision; float loc[3], rot[3], scale[3]; float local[4][4]; @@ -60,49 +60,26 @@ void TransformWriter::add_node_transform(COLLADASW::Node &node, void TransformWriter::add_node_transform_ob(COLLADASW::Node &node, Object *ob, - BC_export_transformation_type transformation_type, - bool limit_precision) + BCExportSettings &export_settings) { -#if 0 - float rot[3], loc[3], scale[3]; - - if (ob->parent) { - float C[4][4], tmat[4][4], imat[4][4], mat[4][4]; - - // factor out scale from obmat - - copy_v3_v3(scale, ob->scale); - - ob->scale[0] = ob->scale[1] = ob->scale[2] = 1.0f; - BKE_object_to_mat4(ob, C); - copy_v3_v3(ob->scale, scale); - - mul_m4_series(tmat, ob->parent->obmat, ob->parentinv, C); - - // calculate local mat - - invert_m4_m4(imat, ob->parent->obmat); - mul_m4_m4m4(mat, imat, tmat); - - // done - - mat4_to_eul(rot, mat); - copy_v3_v3(loc, mat[3]); - } - else { - copy_v3_v3(loc, ob->loc); - copy_v3_v3(rot, ob->rot); - copy_v3_v3(scale, ob->scale); - } - - add_transform(node, loc, rot, scale); -#endif + BC_export_transformation_type transformation_type = + export_settings.get_export_transformation_type(); + bool limit_precision = export_settings.get_limit_precision(); /* Export the local Matrix (relative to the object parent, * be it an object, bone or vertex(-tices)). */ - float f_obmat[4][4]; + Matrix f_obmat; BKE_object_matrix_local_get(ob, f_obmat); + // if (export_settings.is_export_root(ob)) { + // if (export_settings.get_apply_global_orientation()) { + // // do nothing. The rotation happens in the object data + // } + // else { + bc_add_global_transform(f_obmat, export_settings.get_global_transform()); + // } + //} + switch (transformation_type) { case BC_TRANSFORMATION_TYPE_MATRIX: { UnitConverter converter; diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h index 22ba0716cfe..827d43e30f1 100644 --- a/source/blender/collada/TransformWriter.h +++ b/source/blender/collada/TransformWriter.h @@ -31,15 +31,9 @@ class TransformWriter { protected: - void add_node_transform(COLLADASW::Node &node, - float mat[4][4], - float parent_mat[4][4], - bool limit_precision = false); - - void add_node_transform_ob(COLLADASW::Node &node, - Object *ob, - BC_export_transformation_type transformation_type, - bool limit_precision = false); + void add_node_transform(COLLADASW::Node &node, float mat[4][4], float parent_mat[4][4]); + + void add_node_transform_ob(COLLADASW::Node &node, Object *ob, BCExportSettings &export_settings); void add_node_transform_identity(COLLADASW::Node &node); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index c0e3ab2ca47..8b8c9854781 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -60,6 +60,7 @@ extern "C" { #include "ED_armature.h" #include "ED_screen.h" #include "ED_node.h" +#include "ED_object.h" #include "MEM_guardedalloc.h" @@ -104,26 +105,6 @@ int bc_test_parent_loop(Object *par, Object *ob) return bc_test_parent_loop(par->parent, ob); } -void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer) -{ - Base *base; - for (base = (Base *)view_layer->object_bases.first; base; base = base->next) { - Object *cob = base->object; - if (cob->parent == ob) { - switch (ob->type) { - case OB_MESH: - case OB_CAMERA: - case OB_LAMP: - case OB_EMPTY: - case OB_ARMATURE: - child_set.push_back(cob); - default: - break; - } - } - } -} - bool bc_validateConstraints(bConstraint *con) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); @@ -146,43 +127,19 @@ bool bc_validateConstraints(bConstraint *con) return true; } -/* a shortened version of parent_set_exec() - * if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting */ -int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) +bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) { - Object workob; - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Scene *sce = CTX_data_scene(C); - - if (!par || bc_test_parent_loop(par, ob)) - return false; + Scene *scene = CTX_data_scene(C); + int partype = PAR_OBJECT; + const bool xmirror = false; + const bool keep_transform = false; - ob->parent = par; - ob->partype = PAROBJECT; - - ob->parsubstr[0] = 0; - - if (is_parent_space) { - float mat[4][4]; - /* calc par->obmat */ - BKE_object_where_is_calc(depsgraph, sce, par); - - /* move child obmat into world space */ - mul_m4_m4m4(mat, par->obmat, ob->obmat); - copy_m4_m4(ob->obmat, mat); + if (par && is_parent_space) { + mul_m4_m4m4(ob->obmat, par->obmat, ob->obmat); } - /* apply child obmat (i.e. decompose it into rot/loc/size) */ - BKE_object_apply_mat4(ob, ob->obmat, 0, 0); - - /* compute parentinv */ - BKE_object_workob_calc_parent(depsgraph, sce, ob, &workob); - invert_m4_m4(ob->parentinv, workob.obmat); - - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - DEG_id_tag_update(&par->id, ID_RECALC_TRANSFORM); - - return true; + bool ok = ED_object_parent_set(NULL, C, scene, ob, par, partype, xmirror, keep_transform, NULL); + return ok; } std::vector<bAction *> bc_getSceneActions(const bContext *C, Object *ob, bool all_actions) @@ -309,49 +266,6 @@ Object *bc_get_assigned_armature(Object *ob) return ob_arm; } -/** - * Returns the highest selected ancestor - * returns NULL if no ancestor is selected - * IMPORTANT: This function expects that all exported objects have set: - * ob->id.tag & LIB_TAG_DOIT - */ -Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob) - -{ - Object *ancestor = ob; - while (ob->parent && bc_is_marked(ob->parent)) { - ob = ob->parent; - ancestor = ob; - } - return ancestor; -} - -bool bc_is_base_node(LinkNode *export_set, Object *ob) -{ - Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob); - return (root == ob); -} - -bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer) -{ - bool to_export = (BLI_linklist_index(export_set, ob) != -1); - - if (!to_export) { - /* Mark this object as to_export even if it is not in the - * export list, but it contains children to export. */ - - std::vector<Object *> children; - bc_get_children(children, ob, view_layer); - for (int i = 0; i < children.size(); i++) { - if (bc_is_in_Export_set(export_set, children[i], view_layer)) { - to_export = true; - break; - } - } - } - return to_export; -} - bool bc_has_object_type(LinkNode *export_set, short obtype) { LinkNode *node; @@ -366,21 +280,6 @@ bool bc_has_object_type(LinkNode *export_set, short obtype) return false; } -int bc_is_marked(Object *ob) -{ - return ob && (ob->id.tag & LIB_TAG_DOIT); -} - -void bc_remove_mark(Object *ob) -{ - ob->id.tag &= ~LIB_TAG_DOIT; -} - -void bc_set_mark(Object *ob) -{ - ob->id.tag |= LIB_TAG_DOIT; -} - /* Use bubble sort algorithm for sorting the export set */ void bc_bubble_sort_by_Object_name(LinkNode *export_set) { @@ -1040,13 +939,45 @@ bool bc_has_animations(Scene *sce, LinkNode *export_set) return false; } +void bc_add_global_transform(Matrix &to_mat, + const Matrix &from_mat, + const BCMatrix &global_transform, + const bool invert) +{ + copy_m4_m4(to_mat, from_mat); + bc_add_global_transform(to_mat, global_transform, invert); +} + +void bc_add_global_transform(Vector &to_vec, + const Vector &from_vec, + const BCMatrix &global_transform, + const bool invert) +{ + copy_v3_v3(to_vec, from_vec); + bc_add_global_transform(to_vec, global_transform, invert); +} + +void bc_add_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert) +{ + BCMatrix mat(to_mat); + mat.add_transform(global_transform, invert); + mat.get_matrix(to_mat); +} + +void bc_add_global_transform(Vector &to_vec, const BCMatrix &global_transform, const bool invert) +{ + Matrix mat; + global_transform.get_matrix(mat, false, 6, invert); + mul_v3_m4v3(to_vec, mat, to_vec); +} + /** * Check if custom information about bind matrix exists and modify the from_mat * accordingly. * * Note: This is old style for Blender <= 2.78 only kept for compatibility */ -void bc_create_restpose_mat(const ExportSettings *export_settings, +void bc_create_restpose_mat(BCExportSettings &export_settings, Bone *bone, float to_mat[4][4], float from_mat[4][4], @@ -1057,9 +988,9 @@ void bc_create_restpose_mat(const ExportSettings *export_settings, float scale[3]; static const float V0[3] = {0, 0, 0}; - if (!has_custom_props(bone, export_settings->keep_bind_info, "restpose_loc") && - !has_custom_props(bone, export_settings->keep_bind_info, "restpose_rot") && - !has_custom_props(bone, export_settings->keep_bind_info, "restpose_scale")) { + if (!has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_loc") && + !has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_rot") && + !has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_scale")) { /* No need */ copy_m4_m4(to_mat, from_mat); return; @@ -1068,7 +999,7 @@ void bc_create_restpose_mat(const ExportSettings *export_settings, bc_decompose(from_mat, loc, rot, NULL, scale); loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6); - if (export_settings->keep_bind_info) { + if (export_settings.get_keep_bind_info()) { bc_get_property_vector(bone, "restpose_loc", loc, loc); if (use_local_space && bone->parent) { @@ -1084,7 +1015,7 @@ void bc_create_restpose_mat(const ExportSettings *export_settings, } } - if (export_settings->keep_bind_info) { + if (export_settings.get_keep_bind_info()) { if (bc_get_IDProperty(bone, "restpose_rot_x")) rot[0] = DEG2RADF(bc_get_property(bone, "restpose_rot_x", 0)); if (bc_get_IDProperty(bone, "restpose_rot_y")) @@ -1093,7 +1024,7 @@ void bc_create_restpose_mat(const ExportSettings *export_settings, rot[2] = DEG2RADF(bc_get_property(bone, "restpose_rot_z", 0)); } - if (export_settings->keep_bind_info) { + if (export_settings.get_keep_bind_info()) { bc_get_property_vector(bone, "restpose_scale", scale, scale); } diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 522aeb1ad1e..acbf6f94add 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -133,10 +133,9 @@ std::string bc_get_action_id(std::string action_name, extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned int index); extern int bc_test_parent_loop(Object *par, Object *ob); -extern void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer); extern bool bc_validateConstraints(bConstraint *con); -extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true); +bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true); extern Object *bc_add_object( Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name); extern Mesh *bc_get_mesh_copy(BlenderContext &blender_context, @@ -146,15 +145,8 @@ extern Mesh *bc_get_mesh_copy(BlenderContext &blender_context, bool triangulate); extern Object *bc_get_assigned_armature(Object *ob); -extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob); -extern bool bc_is_base_node(LinkNode *export_set, Object *ob); -extern bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer); extern bool bc_has_object_type(LinkNode *export_set, short obtype); -extern int bc_is_marked(Object *ob); -extern void bc_remove_mark(Object *ob); -extern void bc_set_mark(Object *ob); - extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); @@ -238,12 +230,55 @@ extern bool bc_is_animated(BCMatrixSampleMap &values); extern bool bc_has_animations(Scene *sce, LinkNode *node); extern bool bc_has_animations(Object *ob); -extern void bc_create_restpose_mat(const ExportSettings *export_settings, +void bc_add_global_transform(Matrix &to_mat, + const Matrix &from_mat, + const BCMatrix &global_transform, + const bool invert = false); +void bc_add_global_transform(Vector &to_vec, + const Vector &from_vec, + const BCMatrix &global_transform, + const bool invert = false); + +void bc_add_global_transform(Vector &to_vec, + const BCMatrix &global_transform, + const bool invert = false); +void bc_add_global_transform(Matrix &to_mat, + const BCMatrix &global_transform, + const bool invert = false); + +extern void bc_create_restpose_mat(BCExportSettings &export_settings, Bone *bone, float to_mat[4][4], - float world[4][4], + float from_mat[4][4], bool use_local_space); +class ColladaBaseNodes { + private: + std::vector<Object *> base_objects; + + public: + void add(Object *ob) + { + base_objects.push_back(ob); + } + + bool contains(Object *ob) + { + std::vector<Object *>::iterator it = std::find(base_objects.begin(), base_objects.end(), ob); + return (it != base_objects.end()); + } + + int size() + { + return base_objects.size(); + } + + Object *get(int index) + { + return base_objects[index]; + } +}; + class BCPolygonNormalsIndices { std::vector<unsigned int> normal_indices; @@ -293,7 +328,7 @@ class BoneExtended { bool has_roll(); float get_roll(); - void set_tail(float *vec); + void set_tail(float vec[]); float *get_tail(); bool has_tail(); diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 9796bf89cf3..aa0c2b58468 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -81,6 +81,9 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filepath[FILE_MAX]; int apply_modifiers; + int global_forward; + int global_up; + int apply_global_orientation; int export_mesh_type; int selected; int include_children; @@ -140,6 +143,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) /* Options panel */ apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); export_mesh_type = RNA_enum_get(op->ptr, "export_mesh_type_selection"); + global_forward = RNA_enum_get(op->ptr, "export_global_forward_selection"); + global_up = RNA_enum_get(op->ptr, "export_global_up_selection"); + apply_global_orientation = RNA_boolean_get(op->ptr, "apply_global_orientation"); + selected = RNA_boolean_get(op->ptr, "selected"); include_children = RNA_boolean_get(op->ptr, "include_children"); include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); @@ -181,6 +188,11 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) export_settings.filepath = filepath; export_settings.apply_modifiers = apply_modifiers != 0; + export_settings.global_forward = global_forward; + export_settings.global_up = global_up; + export_settings.apply_global_orientation = apply_global_orientation != 0; + + export_settings.export_mesh_type = export_mesh_type; export_settings.export_mesh_type = export_mesh_type; export_settings.selected = selected != 0; export_settings.include_children = include_children != 0; @@ -250,7 +262,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) { - uiLayout *box, *row, *col, *split; + uiLayout *bbox, *box, *row, *col, *split; bool include_animations = RNA_boolean_get(imfptr, "include_animations"); int ui_section = RNA_enum_get(imfptr, "prop_bc_export_ui_section"); @@ -272,6 +284,18 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) /* Export Data options */ /* =================== */ + bbox = uiLayoutBox(layout); + row = uiLayoutRow(bbox, false); + uiItemL(row, IFACE_("Global Orientation:"), ICON_ORIENTATION_GLOBAL); + row = uiLayoutRow(bbox, false); + uiItemR(row, imfptr, "export_global_forward_selection", 0, "", ICON_NONE); + + row = uiLayoutRow(bbox, false); + uiItemR(row, imfptr, "export_global_up_selection", 0, "", ICON_NONE); + + row = uiLayoutRow(bbox, false); + uiItemR(row, imfptr, "apply_global_orientation", 0, NULL, ICON_NONE); + row = uiLayoutRow(box, false); uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE); @@ -287,6 +311,8 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); + row = uiLayoutRow(box, false); + /* Texture options */ box = uiLayoutBox(layout); row = uiLayoutRow(box, false); @@ -418,6 +444,26 @@ void WM_OT_collada_export(wmOperatorType *ot) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem prop_bc_export_global_forward[] = { + {BC_GLOBAL_FORWARD_X, "X", 0, "X Forward", "Global Forward is positive X Axis"}, + {BC_GLOBAL_FORWARD_Y, "Y", 0, "Y Forward", "Global Forward is positive Y Axis"}, + {BC_GLOBAL_FORWARD_Z, "Z", 0, "Z Forward", "Global Forward is positive Z Axis"}, + {BC_GLOBAL_FORWARD_MINUS_X, "-X", 0, "-X Forward", "Global Forward is negative X Axis"}, + {BC_GLOBAL_FORWARD_MINUS_Y, "-Y", 0, "-Y Forward", "Global Forward is negative Y Axis"}, + {BC_GLOBAL_FORWARD_MINUS_Z, "-Z", 0, "-Z Forward", "Global Forward is negative Z Axis"}, + {0, NULL, 0, NULL, NULL}, + }; + + static const EnumPropertyItem prop_bc_export_global_up[] = { + {BC_GLOBAL_UP_X, "X", 0, "X Up", "Global UP is positive X Axis"}, + {BC_GLOBAL_UP_Y, "Y", 0, "Y Up", "Global UP is positive Y Axis"}, + {BC_GLOBAL_UP_Z, "Z", 0, "Z Up", "Global UP is positive Z Axis"}, + {BC_GLOBAL_UP_MINUS_X, "-X", 0, "-X Up", "Global UP is negative X Axis"}, + {BC_GLOBAL_UP_MINUS_Y, "-Y", 0, "-Y Up", "Global UP is negative Y Axis"}, + {BC_GLOBAL_UP_MINUS_Z, "-Z", 0, "-Z Up", "Global UP is negative Z Axis"}, + {0, NULL, 0, NULL, NULL}, + }; + static const EnumPropertyItem prop_bc_export_transformation_type[] = { {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", @@ -503,6 +549,29 @@ void WM_OT_collada_export(wmOperatorType *ot) "Resolution", "Modifier resolution for export"); + RNA_def_enum(func, + "export_global_forward_selection", + prop_bc_export_global_forward, + BC_DEFAULT_FORWARD, + "Global Forward Axis", + "Global Forward axis for export"); + + RNA_def_enum(func, + "export_global_up_selection", + prop_bc_export_global_up, + BC_DEFAULT_UP, + "Global Up Axis", + "Global Up axis for export"); + + RNA_def_boolean(func, "", false, "Selection Only", "Export only selected elements"); + + RNA_def_boolean(func, + "apply_global_orientation", + false, + "Apply Global Orientation", + "enabled: Rotate all root objects to match the global orientation " + "settings.\ndisabled: set global orientation in Collada assets"); + RNA_def_boolean(func, "selected", false, "Selection Only", "Export only selected elements"); RNA_def_boolean(func, |