Adding support for Matrix Transformation export
The exporter does export matrix data (4*4 Transformation matrix) only for Skeletal animation. For object animation only exporting to trans/rot/loc is implemented. This task implements Matrix export also for simple Object animation. Differential Revision: https://developer.blender.org/D3082
This commit is contained in:
parent
5f9657316e
commit
a024da55af
|
@ -49,7 +49,16 @@ bool AnimationExporter::exportAnimations(Scene *sce)
|
|||
return has_animations;
|
||||
}
|
||||
|
||||
|
||||
bool AnimationExporter::is_flat_line(std::vector<float> &values, int channel_count)
|
||||
{
|
||||
for (int i = 0; i < values.size(); i += channel_count) {
|
||||
for (int j = 0; j < channel_count; j++) {
|
||||
if (!bc_in_range(values[j], values[i+j], 0.000001))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* This function creates a complete LINEAR Collada <Animation> Entry with all needed
|
||||
* <source>, <sampler>, and <channel> entries.
|
||||
|
@ -83,9 +92,11 @@ void AnimationExporter::create_sampled_animation(int channel_count,
|
|||
std::string axis_name,
|
||||
bool is_rot)
|
||||
{
|
||||
|
||||
char anim_id[200];
|
||||
|
||||
if (is_flat_line(values, channel_count))
|
||||
return;
|
||||
|
||||
BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), label.c_str(), axis_name.c_str());
|
||||
|
||||
openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
|
||||
|
@ -97,8 +108,10 @@ void AnimationExporter::create_sampled_animation(int channel_count,
|
|||
std::string output_id;
|
||||
if (channel_count == 1)
|
||||
output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, &values[0], values.size(), is_rot, anim_id, axis_name.c_str());
|
||||
else if(channel_count == 3)
|
||||
else if (channel_count == 3)
|
||||
output_id = create_xyz_source(&values[0], times.size(), anim_id);
|
||||
else if (channel_count == 16)
|
||||
output_id = create_4x4_source(times, values, anim_id);
|
||||
|
||||
std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
|
||||
COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
|
||||
|
@ -135,26 +148,38 @@ void AnimationExporter::create_sampled_animation(int channel_count,
|
|||
void AnimationExporter::export_keyframed_animation_set(Object *ob)
|
||||
{
|
||||
FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
|
||||
|
||||
char *transformName;
|
||||
while (fcu) {
|
||||
//for armature animations as objects
|
||||
if (ob->type == OB_ARMATURE)
|
||||
transformName = fcu->rna_path;
|
||||
else
|
||||
transformName = extract_transform_name(fcu->rna_path);
|
||||
|
||||
if (
|
||||
STREQ(transformName, "location") ||
|
||||
STREQ(transformName, "scale") ||
|
||||
(STREQ(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) ||
|
||||
STREQ(transformName, "rotation_quaternion"))
|
||||
{
|
||||
create_keyframed_animation(ob, fcu, transformName, false);
|
||||
}
|
||||
fcu = fcu->next;
|
||||
if (!fcu) {
|
||||
return; /* object has no animation */
|
||||
}
|
||||
|
||||
if (this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
|
||||
|
||||
std::vector<float> ctimes;
|
||||
std::vector<float[4][4]> values;
|
||||
find_keyframes(ob, ctimes);
|
||||
if (ctimes.size() > 0)
|
||||
export_sampled_matrix_animation(ob, ctimes);
|
||||
}
|
||||
else {
|
||||
char *transformName;
|
||||
while (fcu) {
|
||||
//for armature animations as objects
|
||||
if (ob->type == OB_ARMATURE)
|
||||
transformName = fcu->rna_path;
|
||||
else
|
||||
transformName = extract_transform_name(fcu->rna_path);
|
||||
|
||||
if (
|
||||
STREQ(transformName, "location") ||
|
||||
STREQ(transformName, "scale") ||
|
||||
(STREQ(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) ||
|
||||
STREQ(transformName, "rotation_quaternion"))
|
||||
{
|
||||
create_keyframed_animation(ob, fcu, transformName, false);
|
||||
}
|
||||
fcu = fcu->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -170,20 +195,53 @@ void AnimationExporter::export_keyframed_animation_set(Object *ob)
|
|||
* Also keyframed animation exports tend to break when negative scales are involved.
|
||||
*/
|
||||
void AnimationExporter::export_sampled_animation_set(Object *ob)
|
||||
{
|
||||
std::vector<float>ctimes;
|
||||
find_sampleframes(ob, ctimes);
|
||||
if (ctimes.size() > 0) {
|
||||
if (this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX)
|
||||
export_sampled_matrix_animation(ob, ctimes);
|
||||
else
|
||||
export_sampled_transrotloc_animation(ob, ctimes);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationExporter::export_sampled_matrix_animation(Object *ob, std::vector<float> &ctimes)
|
||||
{
|
||||
UnitConverter converter;
|
||||
|
||||
std::vector<float> values;
|
||||
|
||||
for (std::vector<float>::iterator ctime = ctimes.begin(); ctime != ctimes.end(); ++ctime) {
|
||||
float fmat[4][4];
|
||||
float outmat[4][4];
|
||||
|
||||
bc_update_scene(scene, *ctime);
|
||||
BKE_object_matrix_local_get(ob, fmat);
|
||||
converter.mat4_to_dae(outmat, fmat);
|
||||
|
||||
if (this->export_settings->limit_precision)
|
||||
bc_sanitize_mat(outmat, 6);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
values.push_back(outmat[j][i]);
|
||||
}
|
||||
|
||||
std::string ob_name = id_name(ob);
|
||||
|
||||
create_sampled_animation(16, ctimes, values, ob_name, "transform", "", false);
|
||||
}
|
||||
|
||||
void AnimationExporter::export_sampled_transrotloc_animation(Object *ob, std::vector<float> &ctimes)
|
||||
{
|
||||
static int LOC = 0;
|
||||
static int EULX = 1;
|
||||
static int EULY = 2;
|
||||
static int EULZ = 3;
|
||||
static int SCALE = 4;
|
||||
static int TIME = 5;
|
||||
|
||||
if (this->export_settings->sampling_rate < 1)
|
||||
return; // to avoid infinite loop
|
||||
|
||||
std::vector<float> baked_curves[6];
|
||||
std::vector<float> &ctimes = baked_curves[TIME];
|
||||
find_sampleframes(ob, ctimes);
|
||||
std::vector<float> baked_curves[5];
|
||||
|
||||
for (std::vector<float>::iterator ctime = ctimes.begin(); ctime != ctimes.end(); ++ctime ) {
|
||||
float fmat[4][4];
|
||||
|
@ -192,7 +250,7 @@ void AnimationExporter::export_sampled_animation_set(Object *ob)
|
|||
float fsize[3];
|
||||
float feul[3];
|
||||
|
||||
evaluate_anim_with_constraints(ob, *ctime); // set object transforms to the frame
|
||||
bc_update_scene(scene, *ctime);
|
||||
|
||||
BKE_object_matrix_local_get(ob, fmat);
|
||||
mat4_decompose(floc, fquat, fsize, fmat);
|
||||
|
@ -214,16 +272,16 @@ void AnimationExporter::export_sampled_animation_set(Object *ob)
|
|||
|
||||
std::string ob_name = id_name(ob);
|
||||
|
||||
create_sampled_animation(3, baked_curves[TIME], baked_curves[SCALE], ob_name, "scale", "", false);
|
||||
create_sampled_animation(3, baked_curves[TIME], baked_curves[LOC], ob_name, "location", "", false);
|
||||
create_sampled_animation(3, ctimes, baked_curves[SCALE], ob_name, "scale", "", false);
|
||||
create_sampled_animation(3, ctimes, baked_curves[LOC], ob_name, "location", "", false);
|
||||
|
||||
/* Not sure how to export rotation as a 3channel animation,
|
||||
* so separate into 3 single animations for now:
|
||||
*/
|
||||
|
||||
create_sampled_animation(1, baked_curves[TIME], baked_curves[EULX], ob_name, "rotation", "X", true);
|
||||
create_sampled_animation(1, baked_curves[TIME], baked_curves[EULY], ob_name, "rotation", "Y", true);
|
||||
create_sampled_animation(1, baked_curves[TIME], baked_curves[EULZ], ob_name, "rotation", "Z", true);
|
||||
create_sampled_animation(1, ctimes, baked_curves[EULX], ob_name, "rotation", "X", true);
|
||||
create_sampled_animation(1, ctimes, baked_curves[EULY], ob_name, "rotation", "Y", true);
|
||||
create_sampled_animation(1, ctimes, baked_curves[EULZ], ob_name, "rotation", "Z", true);
|
||||
|
||||
fprintf(stdout, "Animation Export: Baked %zd frames for %s (sampling rate: %d)\n",
|
||||
baked_curves[0].size(),
|
||||
|
@ -242,19 +300,19 @@ void AnimationExporter::operator()(Object *ob)
|
|||
if (ob->adt && ob->adt->action) {
|
||||
|
||||
if (ob->type == OB_ARMATURE) {
|
||||
/* Export skeletal animation (if any)*/
|
||||
bArmature *arm = (bArmature *)ob->data;
|
||||
for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next)
|
||||
write_bone_animation_matrix(ob, bone);
|
||||
}
|
||||
else {
|
||||
if (this->export_settings->sampling_rate == -1) {
|
||||
export_keyframed_animation_set(ob);
|
||||
}
|
||||
else {
|
||||
export_sampled_animation_set(ob);
|
||||
}
|
||||
}
|
||||
|
||||
/* Armatures can have object animation and skeletal animation*/
|
||||
if (this->export_settings->sampling_rate < 1) {
|
||||
export_keyframed_animation_set(ob);
|
||||
}
|
||||
else {
|
||||
export_sampled_animation_set(ob);
|
||||
}
|
||||
}
|
||||
|
||||
export_object_constraint_animation(ob);
|
||||
|
@ -1186,9 +1244,51 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
|
|||
return source_id;
|
||||
}
|
||||
|
||||
std::string AnimationExporter::create_4x4_source(std::vector<float> &ctimes, std::vector<float> &values , const std::string &anim_id)
|
||||
{
|
||||
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
|
||||
std::string source_id = anim_id + get_semantic_suffix(semantic);
|
||||
|
||||
COLLADASW::Float4x4Source source(mSW);
|
||||
source.setId(source_id);
|
||||
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
|
||||
source.setAccessorCount(ctimes.size());
|
||||
source.setAccessorStride(16);
|
||||
|
||||
COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
|
||||
add_source_parameters(param, semantic, false, NULL, true);
|
||||
|
||||
source.prepareToAppendValues();
|
||||
|
||||
bPoseChannel *parchan = NULL;
|
||||
bPoseChannel *pchan = NULL;
|
||||
|
||||
|
||||
std::vector<float>::iterator it;
|
||||
|
||||
for (it = values.begin(); it != values.end(); it+=16) {
|
||||
float mat[4][4];
|
||||
|
||||
bc_copy_m4_farray(mat, &*it);
|
||||
|
||||
UnitConverter converter;
|
||||
double outmat[4][4];
|
||||
converter.mat4_to_dae_double(outmat, mat);
|
||||
|
||||
if (this->export_settings->limit_precision)
|
||||
bc_sanitize_mat(outmat, 6);
|
||||
|
||||
source.appendValues(outmat);
|
||||
}
|
||||
|
||||
source.finish();
|
||||
return source_id;
|
||||
}
|
||||
|
||||
std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob, Bone *bone, const std::string &anim_id)
|
||||
{
|
||||
bool is_bone_animation = ob->type == OB_ARMATURE && bone;
|
||||
|
||||
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
|
||||
std::string source_id = anim_id + get_semantic_suffix(semantic);
|
||||
|
||||
|
@ -1206,7 +1306,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
|
|||
bPoseChannel *parchan = NULL;
|
||||
bPoseChannel *pchan = NULL;
|
||||
|
||||
if (ob->type == OB_ARMATURE && bone) {
|
||||
if (is_bone_animation) {
|
||||
bPose *pose = ob->pose;
|
||||
pchan = BKE_pose_channel_find_name(pose, bone->name);
|
||||
if (!pchan)
|
||||
|
@ -1224,11 +1324,8 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
|
|||
float frame = *it;
|
||||
|
||||
float ctime = BKE_scene_frame_get_from_ctime(scene, frame);
|
||||
CFRA = BKE_scene_frame_get_from_ctime(scene, frame);
|
||||
//BKE_scene_update_for_newframe(G.main->eval_ctx, G.main,scene,scene->lay);
|
||||
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
|
||||
|
||||
if (bone) {
|
||||
bc_update_scene(scene, ctime);
|
||||
if (is_bone_animation) {
|
||||
if (pchan->flag & POSE_CHAIN) {
|
||||
enable_fcurves(ob->adt->action, NULL);
|
||||
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
|
||||
|
@ -1268,10 +1365,6 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
|
|||
|
||||
}
|
||||
else {
|
||||
BKE_scene_frame_set(scene, ctime);
|
||||
Main *bmain = bc_get_main();
|
||||
EvaluationContext *ev_context = bc_get_evaluation_context();
|
||||
BKE_scene_update_for_newframe(ev_context, bmain, scene, scene->lay);
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
}
|
||||
|
||||
|
|
|
@ -144,9 +144,12 @@ protected:
|
|||
|
||||
float* get_eul_source_for_quat(Object *ob );
|
||||
|
||||
bool is_flat_line(std::vector<float> &values, int channel_count);
|
||||
void export_keyframed_animation_set(Object *ob);
|
||||
void create_keyframed_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma = NULL);
|
||||
void export_sampled_animation_set(Object *ob);
|
||||
void export_sampled_transrotloc_animation(Object *ob, std::vector<float> &ctimes);
|
||||
void export_sampled_matrix_animation(Object *ob, std::vector<float> &ctimes);
|
||||
void create_sampled_animation(int channel_count, std::vector<float> ×, std::vector<float> &values, std::string, std::string label, std::string axis_name, bool is_rot);
|
||||
|
||||
void evaluate_anim_with_constraints(Object *ob, float ctime);
|
||||
|
@ -161,7 +164,7 @@ protected:
|
|||
std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name);
|
||||
|
||||
std::string create_xyz_source(float *v, int tot, const std::string& anim_id);
|
||||
|
||||
std::string create_4x4_source(std::vector<float> ×, std::vector<float> &values, const std::string& anim_id);
|
||||
std::string create_4x4_source(std::vector<float> &frames, Object * ob_arm, Bone *bone, const std::string& anim_id);
|
||||
|
||||
std::string create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents);
|
||||
|
|
|
@ -282,7 +282,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
|
|||
}
|
||||
|
||||
if (oob_counter > 0) {
|
||||
fprintf(stderr, "Ignored %d Vertex weights which use index to non existing VGroup %lu.\n",
|
||||
fprintf(stderr, "Ignored %d Vertex weights which use index to non existing VGroup %zu.\n",
|
||||
oob_counter, joint_index_by_def_index.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,29 +302,11 @@ int DocumentExporter::exportCurrentScene(Scene *sce)
|
|||
|
||||
SceneExporter se(writer, &arm_exporter, this->export_settings);
|
||||
|
||||
// <library_animations>
|
||||
AnimationExporter ae(writer, this->export_settings);
|
||||
|
||||
#if 0
|
||||
bool has_animations = ae.exportAnimations(sce);
|
||||
/* The following code seems to be an obsolete workaround
|
||||
Comment out until it proofs correct that we no longer need it.
|
||||
*/
|
||||
if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
|
||||
// channels adressing <matrix> objects is not (yet) supported
|
||||
// So we force usage of <location>, <translation> and <scale>
|
||||
fprintf(stdout,
|
||||
"For animated Ojects we must use decomposed <matrix> elements,\n" \
|
||||
"Forcing usage of TransLocRot transformation type.");
|
||||
se.setExportTransformationType(BC_TRANSFORMATION_TYPE_TRANSROTLOC);
|
||||
if (this->export_settings->include_animations) {
|
||||
// <library_animations>
|
||||
AnimationExporter ae(writer, this->export_settings);
|
||||
ae.exportAnimations(sce);
|
||||
}
|
||||
else {
|
||||
se.setExportTransformationType(this->export_settings->export_transformation_type);
|
||||
}
|
||||
#else
|
||||
ae.exportAnimations(sce);
|
||||
se.setExportTransformationType(this->export_settings->export_transformation_type);
|
||||
#endif
|
||||
se.exportScene(sce);
|
||||
|
||||
// <scene>
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
bool include_armatures;
|
||||
bool include_shapekeys;
|
||||
bool deform_bones_only;
|
||||
bool include_animations;
|
||||
int sampling_rate;
|
||||
|
||||
bool active_uv_only;
|
||||
|
|
|
@ -38,11 +38,6 @@ SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm,
|
|||
{
|
||||
}
|
||||
|
||||
void SceneExporter::setExportTransformationType(BC_export_transformation_type transformation_type)
|
||||
{
|
||||
this->transformation_type = transformation_type;
|
||||
}
|
||||
|
||||
void SceneExporter::exportScene(Scene *sce)
|
||||
{
|
||||
// <library_visual_scenes> <visual_scene>
|
||||
|
@ -138,7 +133,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
|
|||
// 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->transformation_type);
|
||||
TransformWriter::add_node_transform_ob(colladaNode, ob, this->export_settings->export_transformation_type);
|
||||
}
|
||||
|
||||
// <instance_geometry>
|
||||
|
|
|
@ -97,11 +97,8 @@ class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter,
|
|||
public:
|
||||
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
|
||||
void exportScene(Scene *sce);
|
||||
void setExportTransformationType(BC_export_transformation_type transformation_type);
|
||||
|
||||
private:
|
||||
BC_export_transformation_type transformation_type;
|
||||
// required for writeNodes() for bone-parented objects
|
||||
friend class ArmatureExporter;
|
||||
void exportHierarchy(Scene *sce);
|
||||
void writeNodes(Object *ob, Scene *sce);
|
||||
|
|
|
@ -78,6 +78,7 @@ int collada_export(Scene *sce,
|
|||
int include_armatures,
|
||||
int include_shapekeys,
|
||||
int deform_bones_only,
|
||||
int include_animations,
|
||||
int sampling_rate,
|
||||
|
||||
int active_uv_only,
|
||||
|
@ -104,7 +105,8 @@ int collada_export(Scene *sce,
|
|||
export_settings.include_armatures = include_armatures != 0;
|
||||
export_settings.include_shapekeys = include_shapekeys != 0;
|
||||
export_settings.deform_bones_only = deform_bones_only != 0;
|
||||
export_settings.sampling_rate = sampling_rate;
|
||||
export_settings.include_animations = include_animations;
|
||||
export_settings.sampling_rate = sampling_rate;
|
||||
|
||||
export_settings.active_uv_only = active_uv_only != 0;
|
||||
export_settings.export_texture_type = export_texture_type;
|
||||
|
|
|
@ -77,6 +77,7 @@ int collada_export(struct Scene *sce,
|
|||
int include_armatures,
|
||||
int include_shapekeys,
|
||||
int deform_bones_only,
|
||||
int include_animations,
|
||||
int sampling_rate,
|
||||
|
||||
int active_uv_only,
|
||||
|
|
|
@ -144,6 +144,14 @@ EvaluationContext *bc_get_evaluation_context()
|
|||
return bmain->eval_ctx;
|
||||
}
|
||||
|
||||
void bc_update_scene(Scene *scene, float ctime)
|
||||
{
|
||||
BKE_scene_frame_set(scene, ctime);
|
||||
Main *bmain = bc_get_main();
|
||||
EvaluationContext *ev_context = bc_get_evaluation_context();
|
||||
BKE_scene_update_for_newframe(ev_context, bmain, scene, scene->lay);
|
||||
}
|
||||
|
||||
Object *bc_add_object(Scene *scene, int type, const char *name)
|
||||
{
|
||||
Object *ob = BKE_object_add_only_object(G.main, type, name);
|
||||
|
@ -883,6 +891,21 @@ void bc_sanitize_mat(double mat[4][4], int precision)
|
|||
mat[i][j] = double_round(mat[i][j], precision);
|
||||
}
|
||||
|
||||
void bc_copy_m4_farray(float r[4][4], float *a)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
r[i][j] = *a++;
|
||||
}
|
||||
|
||||
void bc_copy_farray_m4(float *r, float a[4][4])
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
*r++ = a[i][j];
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns name of Active UV Layer or empty String if no active UV Layer defined.
|
||||
* Assuming the Object is of type MESH
|
||||
|
|
|
@ -65,6 +65,7 @@ typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureA
|
|||
|
||||
extern Main *bc_get_main();
|
||||
extern EvaluationContext *bc_get_evaluation_context();
|
||||
extern void bc_update_scene(Scene *scene, float ctime);
|
||||
|
||||
extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index);
|
||||
extern int bc_test_parent_loop(Object *par, Object *ob);
|
||||
|
@ -102,6 +103,13 @@ extern bool bc_is_leaf_bone(Bone *bone);
|
|||
extern EditBone *bc_get_edit_bone(bArmature * armature, char *name);
|
||||
extern int bc_set_layer(int bitfield, int layer, bool enable);
|
||||
extern int bc_set_layer(int bitfield, int layer);
|
||||
|
||||
inline bool bc_in_range(float a, float b, float range) {
|
||||
return abs(a - b) < range;
|
||||
}
|
||||
void bc_copy_m4_farray(float r[4][4], float *a);
|
||||
void bc_copy_farray_m4(float *r, float a[4][4]);
|
||||
|
||||
extern void bc_sanitize_mat(float mat[4][4], int precision);
|
||||
extern void bc_sanitize_mat(double mat[4][4], int precision);
|
||||
|
||||
|
|
|
@ -86,6 +86,9 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
|
|||
int include_armatures;
|
||||
int include_shapekeys;
|
||||
int deform_bones_only;
|
||||
|
||||
int include_animations;
|
||||
int sample_animations;
|
||||
int sampling_rate;
|
||||
|
||||
int export_texture_type;
|
||||
|
@ -137,7 +140,11 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
|
|||
include_children = RNA_boolean_get(op->ptr, "include_children");
|
||||
include_armatures = RNA_boolean_get(op->ptr, "include_armatures");
|
||||
include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys");
|
||||
sampling_rate = RNA_int_get(op->ptr, "sampling_rate");
|
||||
|
||||
include_animations = RNA_boolean_get(op->ptr, "include_animations");
|
||||
sample_animations = RNA_boolean_get(op->ptr, "sample_animations");
|
||||
sampling_rate = (sample_animations)? RNA_int_get(op->ptr, "sampling_rate") : 0;
|
||||
|
||||
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
|
||||
|
||||
export_texture_type = RNA_enum_get(op->ptr, "export_texture_type_selection");
|
||||
|
@ -167,6 +174,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
|
|||
include_armatures,
|
||||
include_shapekeys,
|
||||
deform_bones_only,
|
||||
include_animations,
|
||||
sampling_rate,
|
||||
|
||||
active_uv_only,
|
||||
|
@ -203,6 +211,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
|
|||
static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
|
||||
{
|
||||
uiLayout *box, *row, *col, *split;
|
||||
bool include_animations = RNA_boolean_get(imfptr, "include_animations");
|
||||
|
||||
/* Export Options: */
|
||||
box = uiLayoutBox(layout);
|
||||
|
@ -233,9 +242,15 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
|
|||
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
|
||||
|
||||
row = uiLayoutRow(box, false);
|
||||
uiItemR(row, imfptr, "sampling_rate", 0, NULL, ICON_NONE);
|
||||
uiItemR(row, imfptr, "include_animations", 0, NULL, ICON_NONE);
|
||||
row = uiLayoutRow(box, false);
|
||||
if (include_animations) {
|
||||
uiItemR(row, imfptr, "sample_animations", 0, NULL, ICON_NONE);
|
||||
row = uiLayoutColumn(box, false);
|
||||
uiItemR(row, imfptr, "sampling_rate", 0, NULL, ICON_NONE);
|
||||
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "sample_animations"));
|
||||
}
|
||||
|
||||
|
||||
/* Texture options */
|
||||
box = uiLayoutBox(layout);
|
||||
row = uiLayoutRow(box, false);
|
||||
|
@ -278,7 +293,6 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
|
|||
split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
|
||||
uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
|
||||
uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
|
||||
|
||||
row = uiLayoutRow(box, false);
|
||||
uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
|
||||
|
||||
|
@ -376,8 +390,14 @@ void WM_OT_collada_export(wmOperatorType *ot)
|
|||
RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only",
|
||||
"Only export deforming bones with armatures");
|
||||
|
||||
RNA_def_int(func, "sampling_rate", 0, -1, INT_MAX,
|
||||
"Samplintg Rate", "The maximum distance of frames between 2 keyframes. Disabled when value is -1", -1, INT_MAX);
|
||||
RNA_def_boolean(func, "include_animations", false,
|
||||
"Include Animations", "Export Animations if available.\nExporting Animations will enforce the decomposition of node transforms\ninto <translation> <rotation> and <scale> components");
|
||||
|
||||
RNA_def_boolean(func, "sample_animations", 0,
|
||||
"Sample Animations", "Auto-generate keyframes with a frame distance set by 'Sampling Rate'.\nWhen disabled, export only the keyframes defined in the animation f-curves (may be less accurate)");
|
||||
|
||||
RNA_def_int(func, "sampling_rate", 1, 1, INT_MAX,
|
||||
"Sampling Rate", "The distance between 2 keyframes. 1 means: Every frame is keyed", 1, INT_MAX);
|
||||
|
||||
RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map",
|
||||
"Export only the selected UV Map");
|
||||
|
|
Loading…
Reference in New Issue