Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaia Clary <gaia.clary@machinimatrix.org>2016-05-28 19:41:54 +0300
committerGaia Clary <gaia.clary@machinimatrix.org>2016-05-28 20:22:06 +0300
commit8e2611102090939f90fd5414e3717866f240020b (patch)
tree05105cc4079172df91573490739b1475d8783223 /source/blender/collada
parent001ba5bdf5975906f294cc7bde258409be7444b0 (diff)
Collada: Adding support for bone roll and bone layers
Differential Revision: https://developer.blender.org/D2034
Diffstat (limited to 'source/blender/collada')
-rw-r--r--source/blender/collada/ArmatureExporter.cpp15
-rw-r--r--source/blender/collada/ArmatureImporter.cpp145
-rw-r--r--source/blender/collada/ArmatureImporter.h31
-rw-r--r--source/blender/collada/ExtraTags.cpp23
-rw-r--r--source/blender/collada/ExtraTags.h11
-rw-r--r--source/blender/collada/collada_utils.cpp191
-rw-r--r--source/blender/collada/collada_utils.h48
7 files changed, 313 insertions, 151 deletions
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 47a0ffda3c6..c8d92f4d329 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -67,12 +67,19 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce,
std::list<Object *>& child_objects)
{
// write bone nodes
+
+ bArmature * armature = (bArmature *)ob_arm->data;
+ ED_armature_to_edit(armature);
+
bArmature *arm = (bArmature *)ob_arm->data;
for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) {
// start from root bones
if (!bone->parent)
add_bone_node(bone, ob_arm, sce, se, child_objects);
}
+
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
}
void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone)
@@ -174,7 +181,15 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce,
node.addExtraTechniqueParameter("blender", "connect", true);
}
}
+ std::string layers = BoneExtended::get_bone_layers(bone->layer);
+ node.addExtraTechniqueParameter("blender", "layer", layers);
+ bArmature *armature = (bArmature *)ob_arm->data;
+ EditBone *ebone = bc_get_edit_bone(armature, bone->name);
+ if (ebone && ebone->roll > 0)
+ {
+ 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]);
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 4c318cd97cc..496ca4efd06 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -50,19 +50,6 @@ static const char *bc_get_joint_name(T *node)
return id.size() ? id.c_str() : node->getOriginalId().c_str();
}
-static EditBone *get_edit_bone(bArmature * armature, char *name) {
- EditBone *eBone;
-
- for (eBone = (EditBone *)armature->edbo->first; eBone; eBone = eBone->next) {
- if (STREQ(name, eBone->name))
- return eBone;
- }
-
- return NULL;
-
-}
-
-
ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings) :
import_settings(import_settings),
@@ -157,9 +144,11 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
if (parent) bone->parent = parent;
float loc[3], size[3], rot[3][3];
- float angle;
BoneExtended &be = add_bone_extended(bone, node);
+ int layer = be.get_bone_layers();
+ if (layer) bone->layer = layer;
+ arm->layer |= layer; // ensure that all populated bone layers are visible after import
float *tail = be.get_tail();
int use_connect = be.get_use_connect();
@@ -171,10 +160,16 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
case -1: break; // not defined
}
- mat4_to_loc_rot_size(loc, rot, size, mat);
- mat3_to_vec_roll(rot, NULL, &angle);
+ if (be.has_roll()) {
+ bone->roll = be.get_roll();
+ }
+ else {
+ float angle;
+ mat4_to_loc_rot_size(loc, rot, size, mat);
+ mat3_to_vec_roll(rot, NULL, &angle);
+ }
+
- bone->roll = angle;
copy_v3_v3(bone->head, mat[3]);
add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero
@@ -224,12 +219,12 @@ void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone)
if (bc_is_leaf_bone(bone)) {
BoneExtended *be = extended_bones[bone->name];
- if (be == NULL || !be->has_custom_tail()) {
+ if (be == NULL || !be->has_tail()) {
/* Collada only knows Joints, Here we guess a reasonable leaf bone length */
float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length;
- EditBone *ebone = get_edit_bone(armature, bone->name);
+ EditBone *ebone = bc_get_edit_bone(armature, bone->name);
float vec[3];
if (ebone->parent != NULL) {
@@ -303,8 +298,8 @@ void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone
BoneExtended *pbe = extended_bones[parentbone->name];
if (dominant_child != NULL) {
/* Found a valid chain. Now connect current bone with that chain.*/
- EditBone *pebone = get_edit_bone(armature, parentbone->name);
- EditBone *cebone = get_edit_bone(armature, dominant_child->get_name());
+ EditBone *pebone = bc_get_edit_bone(armature, parentbone->name);
+ EditBone *cebone = bc_get_edit_bone(armature, dominant_child->get_name());
if (pebone && !(cebone->flag & BONE_CONNECTED)) {
float vec[3];
@@ -467,6 +462,7 @@ void ArmatureImporter::create_armature_bones( )
clear_extended_boneset();
ED_armature_to_edit(armature);
+ armature->layer = 0; // layer is set according to imported bone set in create_bone()
create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature);
@@ -925,84 +921,6 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
return found;
}
-
-/**
- * BoneExtended is a helper class needed for the Bone chain finder
- * See ArmatureImporter::fix_leaf_bones()
- * and ArmatureImporter::connect_bone_chains()
- **/
-
-BoneExtended::BoneExtended(EditBone *aBone)
-{
- this->set_name(aBone->name);
- this->chain_length = 0;
- this->is_leaf = false;
- this->tail[0] = 0.0f;
- this->tail[1] = 0.5f;
- this->tail[2] = 0.0f;
- this->use_connect = -1;
- this->has_tail = false;
-}
-
-char *BoneExtended::get_name()
-{
- return name;
-}
-
-void BoneExtended::set_name(char *aName)
-{
- BLI_strncpy(name, aName, MAXBONENAME);
-}
-
-int BoneExtended::get_chain_length()
-{
- return chain_length;
-}
-
-void BoneExtended::set_chain_length(const int aLength)
-{
- chain_length = aLength;
-}
-
-void BoneExtended::set_leaf_bone(bool state)
-{
- is_leaf = state;
-}
-
-bool BoneExtended::is_leaf_bone()
-{
- return is_leaf;
-}
-
-void BoneExtended::set_tail(float vec[])
-{
- this->tail[0] = vec[0];
- this->tail[1] = vec[1];
- this->tail[2] = vec[2];
- this->has_tail = true;
-}
-
-bool BoneExtended::has_custom_tail()
-{
- return this->has_tail;
-}
-
-float *BoneExtended::get_tail()
-{
- return this->tail;
-}
-
-void BoneExtended::set_use_connect(int use_connect)
-{
- this->use_connect = use_connect;
-}
-
-int BoneExtended::get_use_connect()
-{
- return this->use_connect;
-}
-
-
BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node)
{
BoneExtended *be = new BoneExtended(bone);
@@ -1014,23 +932,30 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod
if (etit != uid_tags_map.end()) {
float tail[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
- int use_connect = -1;
+ float roll = 0;
+ int use_connect = -1;
+ std::string layers;
et = etit->second;
- et->setData("tip_x", &tail[0]);
- et->setData("tip_y", &tail[1]);
- et->setData("tip_z", &tail[2]);
- et->setData("connect", &use_connect);
- if (!(tail[0] == FLT_MAX || tail[1] == FLT_MAX || tail[2] == FLT_MAX))
+ bool has_tail = false;
+ has_tail |= et->setData("tip_x", &tail[0]);
+ has_tail |= et->setData("tip_y", &tail[1]);
+ has_tail |= et->setData("tip_z", &tail[2]);
+
+ bool has_connect = et->setData("connect", &use_connect);
+ bool has_roll = et->setData("roll", &roll);
+
+ layers = et->setData("layer", layers);
+
+ if (has_tail && !has_connect)
{
- if (use_connect == -1)
- {
- use_connect = 0; // got a bone tail definition but no connect info -> bone is not connected
- }
+ use_connect = 0; // got a bone tail definition but no connect info -> bone is not connected
}
- be->set_tail(tail);
+ be->set_bone_layers(layers);
+ if (has_tail) be->set_tail(tail);
+ if (has_roll) be->set_roll(roll);
be->set_use_connect(use_connect);
}
be->set_leaf_bone(true);
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index 4cef3d4fb38..fba8c5bd5d6 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -59,37 +59,6 @@ extern "C" {
#define UNLIMITED_CHAIN_MAX INT_MAX
#define MINIMUM_BONE_LENGTH 0.000001f
-class BoneExtended {
-
-private:
- char name[MAXBONENAME];
- int chain_length;
- bool is_leaf;
- float tail[3];
- bool use_connect;
- bool has_tail;
-
-public:
-
- BoneExtended(EditBone *aBone);
-
- void set_name(char *aName);
- char *get_name();
-
- void set_chain_length(const int aLength);
- int get_chain_length();
-
- void set_leaf_bone(bool state);
- bool is_leaf_bone();
-
- void set_tail(float *vec);
- float *get_tail();
- bool has_custom_tail();
-
- void set_use_connect(int use_connect);
- int get_use_connect();
-};
-
class ArmatureImporter : private TransformReader
{
private:
diff --git a/source/blender/collada/ExtraTags.cpp b/source/blender/collada/ExtraTags.cpp
index 6af61432fda..ea225d8a4ae 100644
--- a/source/blender/collada/ExtraTags.cpp
+++ b/source/blender/collada/ExtraTags.cpp
@@ -85,32 +85,45 @@ std::string ExtraTags::asString(std::string tag, bool *ok)
}
-void ExtraTags::setData(std::string tag, short *data)
+bool ExtraTags::setData(std::string tag, short *data)
{
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok)
*data = (short)tmp;
+ return ok;
}
-void ExtraTags::setData(std::string tag, int *data)
+
+bool ExtraTags::setData(std::string tag, int *data)
{
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok)
*data = tmp;
+ return ok;
}
-void ExtraTags::setData(std::string tag, float *data)
+
+bool ExtraTags::setData(std::string tag, float *data)
{
bool ok = false;
float tmp = asFloat(tag, &ok);
if (ok)
*data = tmp;
+ return ok;
}
-void ExtraTags::setData(std::string tag, char *data)
+
+bool ExtraTags::setData(std::string tag, char *data)
{
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok)
*data = (char)tmp;
+ return ok;
+}
+
+std::string ExtraTags::setData(std::string tag, std::string &data)
+{
+ bool ok = false;
+ std::string tmp = asString(tag, &ok);
+ return (ok) ? tmp : data;
}
-
diff --git a/source/blender/collada/ExtraTags.h b/source/blender/collada/ExtraTags.h
index 03a311a7e86..ad272dcba65 100644
--- a/source/blender/collada/ExtraTags.h
+++ b/source/blender/collada/ExtraTags.h
@@ -43,17 +43,18 @@ public:
bool addTag(std::string tag, std::string data);
/** Set given short pointer to value of tag, if it exists. */
- void setData(std::string tag, short *data);
+ bool setData(std::string tag, short *data);
/** Set given int pointer to value of tag, if it exists. */
- void setData(std::string tag, int *data);
+ bool setData(std::string tag, int *data);
/** Set given float pointer to value of tag, if it exists. */
- void setData(std::string tag, float *data);
+ bool setData(std::string tag, float *data);
/** Set given char pointer to value of tag, if it exists. */
- void setData(std::string tag, char *data);
-
+ bool setData(std::string tag, char *data);
+ std::string setData(std::string tag, std::string &data);
+
/** Return true if the extra tags is for specified profile. */
bool isProfile(std::string profile);
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 30cf404cc3d..c510eb6e0e8 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -54,6 +54,8 @@ extern "C" {
#include "BKE_scene.h"
#include "BKE_DerivedMesh.h"
+#include "ED_armature.h"
+
#include "WM_api.h" // XXX hrm, see if we can do without this
#include "WM_types.h"
@@ -378,3 +380,192 @@ bool bc_is_leaf_bone(Bone *bone)
}
return true;
}
+
+EditBone *bc_get_edit_bone(bArmature * armature, char *name) {
+ EditBone *eBone;
+
+ for (eBone = (EditBone *)armature->edbo->first; eBone; eBone = eBone->next) {
+ if (STREQ(name, eBone->name))
+ return eBone;
+ }
+
+ return NULL;
+
+}
+int bc_set_layer(int bitfield, int layer)
+{
+ return bc_set_layer(bitfield, layer, true); /* enable */
+}
+
+int bc_set_layer(int bitfield, int layer, bool enable)
+{
+ int bit = 1u << layer;
+
+ if (enable)
+ bitfield |= bit;
+ else
+ bitfield &= ~bit;
+
+ return bitfield;
+}
+
+/**
+* BoneExtended is a helper class needed for the Bone chain finder
+* See ArmatureImporter::fix_leaf_bones()
+* and ArmatureImporter::connect_bone_chains()
+**/
+
+BoneExtended::BoneExtended(EditBone *aBone)
+{
+ this->set_name(aBone->name);
+ this->chain_length = 0;
+ this->is_leaf = false;
+ this->tail[0] = 0.0f;
+ this->tail[1] = 0.5f;
+ this->tail[2] = 0.0f;
+ this->use_connect = -1;
+ this->roll = 0;
+ this->bone_layers = 0;
+
+ this->has_custom_tail = false;
+ this->has_custom_roll = false;
+}
+
+char *BoneExtended::get_name()
+{
+ return name;
+}
+
+void BoneExtended::set_name(char *aName)
+{
+ BLI_strncpy(name, aName, MAXBONENAME);
+}
+
+int BoneExtended::get_chain_length()
+{
+ return chain_length;
+}
+
+void BoneExtended::set_chain_length(const int aLength)
+{
+ chain_length = aLength;
+}
+
+void BoneExtended::set_leaf_bone(bool state)
+{
+ is_leaf = state;
+}
+
+bool BoneExtended::is_leaf_bone()
+{
+ return is_leaf;
+}
+
+void BoneExtended::set_roll(float roll)
+{
+ this->roll = roll;
+ this->has_custom_roll = true;
+}
+
+bool BoneExtended::has_roll()
+{
+ return this->has_custom_roll;
+}
+
+float BoneExtended::get_roll()
+{
+ return this->roll;
+}
+
+void BoneExtended::set_tail(float vec[])
+{
+ this->tail[0] = vec[0];
+ this->tail[1] = vec[1];
+ this->tail[2] = vec[2];
+ this->has_custom_tail = true;
+}
+
+bool BoneExtended::has_tail()
+{
+ return this->has_custom_tail;
+}
+
+float *BoneExtended::get_tail()
+{
+ return this->tail;
+}
+
+inline bool isInteger(const std::string & s)
+{
+ if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;
+
+ char * p;
+ strtol(s.c_str(), &p, 10);
+
+ return (*p == 0);
+}
+
+void BoneExtended::set_bone_layers(std::string layerString)
+{
+ std::stringstream ss(layerString);
+ std::istream_iterator<std::string> begin(ss);
+ std::istream_iterator<std::string> end;
+ std::vector<std::string> layers(begin, end);
+
+ for (std::vector<std::string>::iterator it = layers.begin(); it != layers.end(); ++it) {
+ std::string layer = *it;
+ int index = -1;
+
+ if (isInteger(layer))
+ {
+ index = std::stoi(layer);
+ if (index < 0 || index > 31)
+ index - 1;
+ }
+
+ if (index == -1)
+ {
+ //TODO
+ int x = index;
+ }
+
+ if (index != -1)
+ {
+ this->bone_layers = bc_set_layer(this->bone_layers, index);
+ }
+ }
+}
+
+std::string BoneExtended::get_bone_layers(int bitfield)
+{
+ std::string result = "";
+ std::string sep = "";
+ int bit = 1u;
+
+ for (int i = 0; i < 32; i++)
+ {
+ if (bit & bitfield)
+ {
+ result += sep + std::to_string(i);
+ sep = " ";
+ }
+ bit = bit << 1;
+ }
+ return result;
+}
+
+int BoneExtended::get_bone_layers()
+{
+ return (bone_layers == 0) ? 1 : bone_layers; // ensure that the bone is in at least one bone layer!
+}
+
+
+void BoneExtended::set_use_connect(int use_connect)
+{
+ this->use_connect = use_connect;
+}
+
+int BoneExtended::get_use_connect()
+{
+ return this->use_connect;
+}
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index 7f8e93736b5..e9f84afef61 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -46,6 +46,7 @@ extern "C" {
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_object.h"
@@ -88,6 +89,9 @@ extern void bc_match_scale(std::vector<Object *> *objects_done, UnitConverter &u
extern void bc_triangulate_mesh(Mesh *me);
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);
class BCPolygonNormalsIndices
{
@@ -105,4 +109,48 @@ class BCPolygonNormalsIndices
};
+class BoneExtended {
+
+private:
+ char name[MAXBONENAME];
+ int chain_length;
+ bool is_leaf;
+ float tail[3];
+ float roll;
+
+ int bone_layers;
+ bool use_connect;
+ bool has_custom_tail;
+ bool has_custom_roll;
+
+public:
+
+ BoneExtended(EditBone *aBone);
+
+ void set_name(char *aName);
+ char *get_name();
+
+ void set_chain_length(const int aLength);
+ int get_chain_length();
+
+ void set_leaf_bone(bool state);
+ bool is_leaf_bone();
+
+ void set_bone_layers(std::string layers);
+ int get_bone_layers();
+ static std::string get_bone_layers(int bitfield);
+
+ void set_roll(float roll);
+ bool has_roll();
+ float get_roll();
+
+ void set_tail(float *vec);
+ float *get_tail();
+ bool has_tail();
+
+ void set_use_connect(int use_connect);
+ int get_use_connect();
+};
+
+
#endif