Collada exporter update

Added new feature: Collada: global axis rotation upon export (UI)

The new feature allows to specify the target rest coordinate system upon export.
This allows for example to export a character that is in Blender orientation (Y forward)
to match the Secondlife orientation where (-X forward)

- Refactor:Added new utility methods to collada_utils
           Made BCMatrix class more powerfull
           moved Blender related structures into new BlenderContext class
           added class wrapper to encapsulate ExportSettings structure
           Added blender context getters to ExportSettings
           added access methods to BlenderContext into ExportSettings class
           Moved class BCMatrix into BlenderContext
           moved utility functions from collada_util into BlenderContext
           replace own function for parenting by a call to ED_object_parent_set()

- Cleanup: removed obsolete parameters from methods
           renamed parameters for better understanding
           cleanup whitespace and indentation
           removed obsolete comments
This commit is contained in:
Gaia Clary 2019-05-23 12:17:17 +02:00
parent e9cf9e0a39
commit 6be9d19951
36 changed files with 993 additions and 439 deletions

View File

@ -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),

View File

@ -77,9 +77,9 @@ 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;
LinkNode *export_set = this->export_settings.get_export_set();
bool has_anim_data = bc_has_animations(sce, export_set);
int animation_count = 0;
if (has_anim_data) {
@ -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,18 @@ 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);
BCMatrix global_transform = this->export_settings.get_global_transform();
DMatrix daemat;
if (this->export_settings.get_apply_global_orientation()) {
sample.apply_transform(global_transform);
}
else {
sample.add_transform(global_transform);
}
sample.get_matrix(daemat, true, precision);
source.appendValues(daemat);
}

View File

@ -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);

View File

@ -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,49 +278,47 @@ 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);
mul_m4_m4m4(mat, mat, temp);
workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f;
invert_m4(workmat);
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, mat, workmat);
if (!is_export_root(bone)) {
copy_m4_m4(workmat, parent_rest_mat);
workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f;
mul_m4_m4m4(mat, workmat, mat);
mul_m4_m4m4(mat, temp, mat);
}
}
}
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);
TransformWriter::add_node_transform(node, mat, NULL, this->export_settings);
}
std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,68 @@ 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); // TODO: Verify 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::apply_transform(const BCMatrix &mat, bool inverse)
{
apply_transform(this->matrix, mat.matrix, this->matrix, inverse);
}
void BCMatrix::add_transform(Matrix &to, const Matrix &transform, const Matrix &from, bool inverse)
{
if (inverse) {
Matrix globinv;
invert_m4_m4(globinv, transform);
add_transform(to, globinv, from, /*inverse=*/false);
}
else {
mul_m4_m4m4(to, transform, from);
}
}
void BCMatrix::apply_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 +129,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 +191,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 +209,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++) {

View File

@ -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);

View File

@ -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;

View File

@ -21,14 +21,105 @@
#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 apply_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);
void apply_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 +138,6 @@ class BlenderContext {
ViewLayer *get_view_layer();
Main *get_main();
};
#endif
#endif

View File

@ -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();
}

View File

@ -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

View File

@ -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,16 @@ 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()) {
// do nothing, rotation is going to be applied to the Data
}
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 +539,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 +553,13 @@ 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()) {
bc_apply_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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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);
};

View File

@ -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;

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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

View File

@ -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++) {

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -28,8 +28,10 @@
void TransformWriter::add_node_transform(COLLADASW::Node &node,
float mat[4][4],
float parent_mat[4][4],
bool limit_precision)
BCExportSettings &export_settings
)
{
// bool limit_precision = export_settings.limit_precision;
float loc[3], rot[3], scale[3];
float local[4][4];
@ -42,67 +44,48 @@ void TransformWriter::add_node_transform(COLLADASW::Node &node,
copy_m4_m4(local, mat);
}
if (export_settings.get_apply_global_orientation()) {
bc_apply_global_transform(local, export_settings.get_global_transform());
}
double dmat[4][4];
UnitConverter *converter = new UnitConverter();
converter->mat4_to_dae_double(dmat, local);
delete converter;
bc_decompose(local, loc, rot, NULL, scale);
if (node.getType() == COLLADASW::Node::JOINT) {
// XXX Why are joints handled differently ?
// GC: I believe this is a mistake. Here we might want to
// export according to how the transformation type
// is set, see add_node_transform_ob()
node.addMatrix("transform", dmat);
}
else {
bc_decompose(local, loc, rot, NULL, scale);
add_transform(node, loc, rot, scale);
}
}
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.get_apply_global_orientation()) {
bc_apply_global_transform(f_obmat, export_settings.get_global_transform());
}
else {
bc_add_global_transform(f_obmat, export_settings.get_global_transform());
}
switch (transformation_type) {
case BC_TRANSFORMATION_TYPE_MATRIX: {
UnitConverter converter;

View File

@ -34,12 +34,9 @@ class TransformWriter {
void add_node_transform(COLLADASW::Node &node,
float mat[4][4],
float parent_mat[4][4],
bool limit_precision = false);
BCExportSettings &export_settings);
void add_node_transform_ob(COLLADASW::Node &node,
Object *ob,
BC_export_transformation_type transformation_type,
bool limit_precision = false);
void add_node_transform_ob(COLLADASW::Node &node, Object *ob, BCExportSettings &export_settings);
void add_node_transform_identity(COLLADASW::Node &node);

View File

@ -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);
Scene *scene = CTX_data_scene(C);
int partype = PAR_OBJECT;
const bool xmirror = false;
const bool keep_transform = false;
if (!par || bc_test_parent_loop(par, ob))
return 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,61 @@ 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;
Vector from_vec;
copy_v3_v3(from_vec, to_vec);
global_transform.get_matrix(mat, false, 6, invert);
mul_v3_m4v3(to_vec, mat, from_vec);
}
void bc_apply_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert)
{
BCMatrix mat(to_mat);
mat.apply_transform(global_transform, invert);
mat.get_matrix(to_mat);
}
void bc_apply_global_transform(Vector &to_vec, const BCMatrix &global_transform, const bool invert)
{
Matrix transform;
global_transform.get_matrix(transform);
mul_v3_m4v3(to_vec, transform, 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 +1004,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 +1015,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 +1031,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 +1040,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);
}

View File

@ -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,11 +230,58 @@ 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,
Bone *bone,
float to_mat[4][4],
float world[4][4],
bool use_local_space);
extern void bc_add_global_transform(Matrix &to_mat,
const Matrix &from_mat,
const BCMatrix &global_transform,
const bool invert = false);
extern void bc_add_global_transform(Vector &to_vec,
const Vector &from_vec,
const BCMatrix &global_transform,
const bool invert = false);
extern void bc_add_global_transform(Vector &to_vec,
const BCMatrix &global_transform,
const bool invert = false);
extern void bc_add_global_transform(Matrix &to_mat,
const BCMatrix &global_transform,
const bool invert = false);
extern void bc_apply_global_transform(Matrix &to_mat,
const BCMatrix &global_transform,
const bool invert = false);
extern void bc_apply_global_transform(Vector &to_vec,
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 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 +332,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();

View File

@ -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,