[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21970] branches/soc-2009-chingachgook/ source/blender/collada: Added armature export in COLLADA exporter ( not complete yet).
Arystanbek Dyussenov
arystan.d at gmail.com
Tue Jul 28 14:08:54 CEST 2009
Revision: 21970
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21970
Author: kazanbas
Date: 2009-07-28 14:08:54 +0200 (Tue, 28 Jul 2009)
Log Message:
-----------
Added armature export in COLLADA exporter (not complete yet).
For each object in scene linked with armature writing the following information:
- bone names
- vertex weights
- bone inverse bind matrices (fake values for now)
Assuming objects don't share Armatures for now.
Modified Paths:
--------------
branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp
Added Paths:
-----------
branches/soc-2009-chingachgook/source/blender/collada/collada_internal.h
Modified: branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp 2009-07-28 11:04:32 UTC (rev 21969)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp 2009-07-28 12:08:54 UTC (rev 21970)
@@ -14,6 +14,8 @@
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_modifier_types.h"
extern "C"
{
@@ -24,12 +26,12 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_action.h" // pose functions
#include "BLI_arithb.h"
#include "BLI_string.h"
+#include "BLI_listbase.h"
-#include "DocumentExporter.h"
-
#include "COLLADASWAsset.h"
#include "COLLADASWLibraryVisualScenes.h"
#include "COLLADASWNode.h"
@@ -60,7 +62,13 @@
#include "COLLADASWInstanceCamera.h"
#include "COLLADASWInstanceLight.h"
#include "COLLADASWCameraOptic.h"
+#include "COLLADASWConstants.h"
+#include "COLLADASWLibraryControllers.h"
+#include "COLLADASWBaseInputElement.h"
+#include "collada_internal.h"
+#include "DocumentExporter.h"
+
#include <vector>
#include <algorithm> // std::find
@@ -551,6 +559,259 @@
}*/
};
+// XXX exporter assumes armatures are not shared between meshes.
+class ArmatureExporter: COLLADASW::LibraryControllers
+{
+public:
+ ArmatureExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryControllers(sw) {}
+
+ void export_armatures(Scene *sce)
+ {
+ openLibrary();
+
+ forEachMeshObjectInScene(sce, *this);
+
+ closeLibrary();
+ }
+
+ void operator()(Object *ob)
+ {
+ Object *ob_arm = NULL;
+ if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
+ ob_arm = ob->parent;
+ }
+ else {
+ ModifierData *mod = (ModifierData*)ob->modifiers.first;
+ while (mod) {
+ if (mod->type == eModifierType_Armature) {
+ ob_arm = ((ArmatureModifierData*)mod)->object;
+ }
+
+ mod = mod->next;
+ }
+ }
+
+ if (ob_arm)
+ export_armature(ob, ob_arm);
+ }
+
+private:
+
+ UnitConverter converter;
+
+ // ob should be of type OB_MESH
+ // both args are required
+ void export_armature(Object* ob, Object *ob_arm)
+ {
+ // joint names
+ // joint inverse bind matrices
+ // vertex weights
+
+ // input:
+ // joint names: ob -> vertex group names
+ // vertex group weights: me->dvert -> groups -> index, weight
+
+ /*
+ me->dvert:
+
+ typedef struct MDeformVert {
+ struct MDeformWeight *dw;
+ int totweight;
+ int flag; // flag only in use for weightpaint now
+ } MDeformVert;
+
+ typedef struct MDeformWeight {
+ int def_nr;
+ float weight;
+ } MDeformWeight;
+ */
+
+ Mesh *me = (Mesh*)ob->data;
+ if (!me->dvert) return;
+
+ std::string controller_name(ob_arm->id.name);
+ std::string controller_id = controller_name + SKIN_CONTROLLER_ID_SUFFIX;
+
+ openSkin(controller_id, controller_name, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, ob->id.name));
+
+ add_bind_shape_mat(ob);
+
+ std::string joints_source_id = add_joints_source(&ob->defbase, controller_id);
+ std::string inv_bind_mat_source_id =
+ add_inv_bind_mats_source((bArmature*)ob_arm->data, &ob->defbase, controller_id);
+ std::string weights_source_id = add_weights_source(me, controller_id);
+
+ add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
+ add_vertex_weights_element(weights_source_id, joints_source_id, me);
+
+ closeSkin();
+ closeController();
+ }
+
+ void add_joints_element(ListBase *defbase,
+ const std::string& joints_source_id, const std::string& inv_bind_mat_source_id)
+ {
+ COLLADASW::JointsElement joints(mSW);
+ COLLADASW::InputList &input = joints.getInputList();
+
+ int offset = 0;
+ input.push_back(COLLADASW::Input(COLLADASW::JOINT, // constant declared in COLLADASWInputList.h
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
+ input.push_back(COLLADASW::Input(COLLADASW::BINDMATRIX,
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
+ joints.add();
+ }
+
+ void add_bind_shape_mat(Object *ob)
+ {
+ float ob_bind_mat[4][4];
+ double dae_mat[4][4];
+
+ // TODO: get matrix from ob
+ Mat4One(ob_bind_mat);
+
+ converter.mat4_to_dae(dae_mat, ob_bind_mat);
+
+ addBindShapeTransform(dae_mat);
+ }
+
+ std::string add_joints_source(ListBase *defbase, const std::string& controller_id)
+ {
+ std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
+
+ COLLADASW::NameSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(BLI_countlist(defbase));
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
+ param.push_back("JOINT");
+
+ source.prepareToAppendValues();
+
+ bDeformGroup *def;
+
+ for (def = (bDeformGroup*)defbase->first; def; def = def->next) {
+ source.appendValues(def->name);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string add_inv_bind_mats_source(bArmature *arm, ListBase *defbase, const std::string& controller_id)
+ {
+ std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(BLI_countlist(defbase));
+ source.setAccessorStride(16);
+
+ source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
+ COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
+ param.push_back("TRANSFORM");
+
+ source.prepareToAppendValues();
+
+ bDeformGroup *def;
+
+ /*
+ Bone *get_named_bone (struct bArmature *arm, const char *name);
+ bPoseChannel *get_pose_channel(const struct bPose *pose, const char *name);
+ */
+
+ float inv_bind_mat[4][4];
+ Mat4One(inv_bind_mat);
+
+ float dae_mat[4][4];
+ converter.mat4_to_dae(dae_mat, inv_bind_mat);
+
+ // TODO: write inverse bind matrices for each bone (name taken from defbase)
+ for (def = (bDeformGroup*)defbase->first; def; def = def->next) {
+ source.appendValues(dae_mat);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string add_weights_source(Mesh *me, const std::string& controller_id)
+ {
+ std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(me->totvert);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
+ param.push_back("WEIGHT");
+
+ source.prepareToAppendValues();
+
+ // NOTE: COLLADA spec says weights should be normalized
+
+ for (int i = 0; i < me->totvert; i++) {
+ MDeformVert *vert = &me->dvert[i];
+ for (int j = 0; j < vert->totweight; j++) {
+ source.appendValues(vert->dw[j].weight);
+ }
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me)
+ {
+ COLLADASW::VertexWeightsElement weights(mSW);
+ COLLADASW::InputList &input = weights.getInputList();
+
+ int offset = 0;
+ input.push_back(COLLADASW::Input(COLLADASW::JOINT, // constant declared in COLLADASWInputList.h
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++));
+ input.push_back(COLLADASW::Input(COLLADASW::WEIGHT,
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++));
+
+ weights.setCount(me->totvert);
+
+ // write number of deformers per vertex
+ COLLADASW::PrimitivesBase::VCountList vcount;
+ int i;
+ for (i = 0; i < me->totvert; i++) {
+ vcount.push_back(me->dvert[i].totweight);
+ }
+
+ weights.prepareToAppendVCountValues();
+ weights.appendVertexCount(vcount);
+
+ std::vector<unsigned long> indices;
+
+ // write deformer index - weight index pairs
+ int weight_index = 0;
+ for (i = 0; i < me->totvert; i++) {
+ MDeformVert *dvert = &me->dvert[i];
+
+ for (int j = 0; j < dvert->totweight; j++) {
+ indices.push_back(dvert->dw[j].def_nr);
+ indices.push_back(weight_index++);
+ }
+ }
+
+ weights.CloseVCountAndOpenVElement();
+ weights.appendValues(indices);
+
+ weights.finish();
+ }
+};
+
class SceneExporter: COLLADASW::LibraryVisualScenes
{
public:
@@ -1301,7 +1562,10 @@
// <library_animations>
AnimationExporter ae(&sw);
ae.exportAnimations(sce);
-
+
+ // <library_controllers>
+ ArmatureExporter(&sw).export_armatures(sce);
+
// <library_visual_scenes>
SceneExporter se(&sw);
se.exportScene(sce);
Added: branches/soc-2009-chingachgook/source/blender/collada/collada_internal.h
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/collada_internal.h (rev 0)
+++ branches/soc-2009-chingachgook/source/blender/collada/collada_internal.h 2009-07-28 12:08:54 UTC (rev 21970)
@@ -0,0 +1,58 @@
+#ifndef BLENDER_COLLADA_H
+#define BLENDER_COLLADA_H
+
+#include "COLLADAFWFileInfo.h"
+#include "Math/COLLADABUMathMatrix4.h"
+
+class UnitConverter
+{
+private:
+ COLLADAFW::FileInfo::Unit unit;
+ COLLADAFW::FileInfo::UpAxisType up_axis;
+
+public:
+
+ UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {}
+
+ void read_asset(const COLLADAFW::FileInfo* asset)
+ {
+ }
+
+ // TODO
+ // convert vector vec from COLLADA format to Blender
+ void convertVec3(float *vec)
+ {
+ }
+
+ // TODO need also for angle conversion, time conversion...
+
+ void mat4_from_dae(float out[][4], const COLLADABU::Math::Matrix4& in)
+ {
+ // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
+ // so here, to make a blender matrix, we swap columns and rows
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ out[i][j] = in[j][i];
+ }
+ }
+ }
+
+ void mat4_to_dae(float out[][4], float in[][4])
+ {
+ Mat4CpyMat4(out, in);
+ Mat4Transp(out);
+ }
+
+ void mat4_to_dae(double out[][4], float in[][4])
+ {
+ float outf[4][4];
+
+ mat4_to_dae(outf, in);
+
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ out[i][j] = outf[i][j];
+ }
+};
+
+#endif
More information about the Bf-blender-cvs
mailing list