[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22182] branches/soc-2009-chingachgook/ source/blender/collada: * added armature/skinned mesh export
Chingiz Dyussenov
chingiz.ds at gmail.com
Mon Aug 3 16:40:23 CEST 2009
Revision: 22182
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22182
Author: chingachgook
Date: 2009-08-03 16:40:23 +0200 (Mon, 03 Aug 2009)
Log Message:
-----------
* added armature/skinned mesh export
* meshes are now exported without modifiers applied (for skinning to work), this should become a configurable option later
* had to edit OpenCollada code to make armature/skinning import work correctly
* code layout improvements
Modified Paths:
--------------
branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp
branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp
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-08-03 14:40:10 UTC (rev 22181)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp 2009-08-03 14:40:23 UTC (rev 22182)
@@ -27,6 +27,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_action.h" // pose functions
+#include "BKE_armature.h"
#include "BLI_arithb.h"
#include "BLI_string.h"
@@ -64,6 +65,7 @@
#include "COLLADASWCameraOptic.h"
#include "COLLADASWConstants.h"
#include "COLLADASWLibraryControllers.h"
+#include "COLLADASWInstanceController.h"
#include "COLLADASWBaseInputElement.h"
#include "collada_internal.h"
@@ -114,11 +116,27 @@
return data->layers[layer_index].name;
}
-std::string id_name(void *id)
+static std::string id_name(void *id)
{
return ((ID*)id)->name + 2;
}
+static std::string get_geometry_id(Object *ob)
+{
+ return id_name(ob) + "-mesh";
+}
+
+static void replace_chars(char *str, char chars[], char with)
+{
+ char *ch, *p;
+
+ for (ch = chars; *ch; ch++) {
+ while ((p = strchr(str, *ch))) {
+ *p = with;
+ }
+ }
+}
+
/*
Utilities to avoid code duplication.
Definition can take some time to understand, but they should be useful.
@@ -251,32 +269,33 @@
void operator()(Object *ob)
{
// XXX don't use DerivedMesh, Mesh instead?
-
+
+#if 0
DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH);
+#endif
Mesh *me = (Mesh*)ob->data;
- std::string geom_name(id_name(ob));
+ std::string geom_id = get_geometry_id(ob);
// openMesh(geoId, geoName, meshId)
- openMesh(geom_name, "", "");
+ openMesh(geom_id, "", "");
// writes <source> for vertex coords
- createVertsSource(geom_name, dm);
+ createVertsSource(geom_id, me);
// writes <source> for normal coords
- createNormalsSource(geom_name, dm);
+ createNormalsSource(geom_id, me);
int has_uvs = CustomData_has_layer(&me->fdata, CD_MTFACE);
// writes <source> for uv coords if mesh has uv coords
if (has_uvs) {
- createTexcoordsSource(geom_name, dm, (Mesh*)ob->data);
+ createTexcoordsSource(geom_id, (Mesh*)ob->data);
}
// <vertices>
COLLADASW::Vertices verts(mSW);
- verts.setId(getIdBySemantics(geom_name, COLLADASW::VERTEX));
+ verts.setId(getIdBySemantics(geom_id, COLLADASW::VERTEX));
COLLADASW::InputList &input_list = verts.getInputList();
- COLLADASW::Input input(COLLADASW::POSITION,
- getUrlBySemantics(geom_name, COLLADASW::POSITION));
+ COLLADASW::Input input(COLLADASW::POSITION, getUrlBySemantics(geom_id, COLLADASW::POSITION));
input_list.push_back(input);
verts.add();
@@ -285,18 +304,19 @@
for(int a = 0; a < ob->totcol; a++) {
// account for NULL materials, this should not normally happen?
Material *ma = give_current_material(ob, a + 1);
- createPolylist(ma != NULL, a, has_uvs, ob, dm, geom_name);
+ createPolylist(ma != NULL, a, has_uvs, ob, geom_id);
}
}
else {
- createPolylist(false, 0, has_uvs, ob, dm, geom_name);
+ createPolylist(false, 0, has_uvs, ob, geom_id);
}
closeMesh();
closeGeometry();
+#if 0
dm->release(dm);
-
+#endif
}
// powerful because it handles both cases when there is material and when there's not
@@ -304,12 +324,15 @@
int material_index,
bool has_uvs,
Object *ob,
- DerivedMesh *dm,
- std::string& geom_name)
+ std::string& geom_id)
{
+#if 0
MFace *mfaces = dm->getFaceArray(dm);
int totfaces = dm->getNumFaces(dm);
+#endif
Mesh *me = (Mesh*)ob->data;
+ MFace *mfaces = me->mface;
+ int totfaces = me->totface;
// <vcount>
int i;
@@ -350,11 +373,11 @@
// creates <input> in <polylist> for vertices
COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics
- (geom_name, COLLADASW::VERTEX), 0);
+ (geom_id, COLLADASW::VERTEX), 0);
// creates <input> in <polylist> for normals
COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics
- (geom_name, COLLADASW::NORMAL), 0);
+ (geom_id, COLLADASW::NORMAL), 0);
til.push_back(input1);
til.push_back(input2);
@@ -365,7 +388,7 @@
for (i = 0; i < num_layers; i++) {
char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
COLLADASW::Input input3(COLLADASW::TEXCOORD,
- makeUrl(makeTexcoordSourceId(geom_name, i)),
+ makeUrl(makeTexcoordSourceId(geom_id, i)),
1, // offset always 1, this is only until we have optimized UV sets
i // set number equals UV layer index
);
@@ -403,15 +426,18 @@
}
// creates <source> for positions
- void createVertsSource(std::string geom_name, DerivedMesh *dm)
+ void createVertsSource(std::string geom_id, Mesh *me)
{
+#if 0
int totverts = dm->getNumVerts(dm);
MVert *verts = dm->getVertArray(dm);
+#endif
+ int totverts = me->totvert;
+ MVert *verts = me->mvert;
-
COLLADASW::FloatSourceF source(mSW);
- source.setId(getIdBySemantics(geom_name, COLLADASW::POSITION));
- source.setArrayId(getIdBySemantics(geom_name, COLLADASW::POSITION) +
+ source.setId(getIdBySemantics(geom_id, COLLADASW::POSITION));
+ source.setArrayId(getIdBySemantics(geom_id, COLLADASW::POSITION) +
ARRAY_ID_SUFFIX);
source.setAccessorCount(totverts);
source.setAccessorStride(3);
@@ -425,27 +451,30 @@
//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]);
-
+ source.appendValues(verts[i].co[0], verts[i].co[1], verts[i].co[2]);
}
source.finish();
}
- std::string makeTexcoordSourceId(std::string& geom_name, int layer_index)
+ std::string makeTexcoordSourceId(std::string& geom_id, int layer_index)
{
char suffix[20];
sprintf(suffix, "-%d", layer_index);
- return getIdBySemantics(geom_name, COLLADASW::TEXCOORD) + suffix;
+ return getIdBySemantics(geom_id, COLLADASW::TEXCOORD) + suffix;
}
//creates <source> for texcoords
- void createTexcoordsSource(std::string geom_name, DerivedMesh *dm, Mesh *me)
+ void createTexcoordsSource(std::string geom_id, Mesh *me)
{
-
+#if 0
int totfaces = dm->getNumFaces(dm);
MFace *mfaces = dm->getFaceArray(dm);
+#endif
+ int totfaces = me->totface;
+ MFace *mfaces = me->mface;
+
int totuv = 0;
int i;
@@ -469,7 +498,7 @@
char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a);
COLLADASW::FloatSourceF source(mSW);
- std::string layer_id = makeTexcoordSourceId(geom_name, a);
+ std::string layer_id = makeTexcoordSourceId(geom_id, a);
source.setId(layer_id);
source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
@@ -496,14 +525,19 @@
//creates <source> for normals
- void createNormalsSource(std::string geom_name, DerivedMesh *dm)
+ void createNormalsSource(std::string geom_id, Mesh *me)
{
+#if 0
int totverts = dm->getNumVerts(dm);
MVert *verts = dm->getVertArray(dm);
-
+#endif
+
+ int totverts = me->totvert;
+ MVert *verts = me->mvert;
+
COLLADASW::FloatSourceF source(mSW);
- source.setId(getIdBySemantics(geom_name, COLLADASW::NORMAL));
- source.setArrayId(getIdBySemantics(geom_name, COLLADASW::NORMAL) +
+ source.setId(getIdBySemantics(geom_id, COLLADASW::NORMAL));
+ source.setArrayId(getIdBySemantics(geom_id, COLLADASW::NORMAL) +
ARRAY_ID_SUFFIX);
source.setAccessorCount(totverts);
source.setAccessorStride(3);
@@ -526,14 +560,14 @@
source.finish();
}
- std::string getIdBySemantics(std::string geom_name, COLLADASW::Semantics type, std::string other_suffix = "") {
- return geom_name + getSuffixBySemantic(type) + other_suffix;
+ std::string getIdBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix = "") {
+ return geom_id + getSuffixBySemantic(type) + other_suffix;
}
- COLLADASW::URI getUrlBySemantics(std::string geom_name, COLLADASW::Semantics type, std::string other_suffix = "") {
+ COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix = "") {
- std::string id(getIdBySemantics(geom_name, type, other_suffix));
+ std::string id(getIdBySemantics(geom_id, type, other_suffix));
return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id);
}
@@ -559,14 +593,120 @@
}*/
};
-// XXX exporter assumes armatures are not shared between meshes.
-class ArmatureExporter: COLLADASW::LibraryControllers
+class TransformWriter : protected TransformBase
{
+protected:
+ void add_node_transform(COLLADASW::Node& node, float mat[][4])
+ {
+ float loc[3], rot[3], size[3];
+
+ TransformBase::decompose(mat, loc, rot, size);
+
+ /*
+ // this code used to create a single <rotate> representing object rotation
+ float quat[4];
+ float axis[3];
+ float angle;
+ double angle_deg;
+ EulToQuat(rot, quat);
+ NormalQuat(quat);
+ QuatToAxisAngle(quat, axis, &angle);
+ angle_deg = angle * 180.0f / M_PI;
+ node.addRotate(axis[0], axis[1], axis[2], angle_deg);
+ */
+ node.addTranslate("location", loc[0], loc[1], loc[2]);
+
+ node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2]));
+ node.addRotateY("rotationY", COLLADABU::Math::Utils::radToDegF(rot[1]));
+ node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0]));
+
+ node.addScale("scale", size[0], size[1], size[2]);
+ }
+};
+
+class InstanceWriter
+{
+protected:
+ void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob)
+ {
+ for(int a = 0; a < ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a+1);
+
+ COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList();
+
+ if (ma) {
+ std::string matid(id_name(ma));
+ COLLADASW::InstanceMaterial im(matid, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
+
+ // create <bind_vertex_input> for each uv layer
+ Mesh *me = (Mesh*)ob->data;
+ int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+
+ for (int b = 0; b < totlayer; b++) {
+ char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, b);
+ im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", b));
+ }
+
+ iml.push_back(im);
+ }
+ }
+ }
+};
+
+// 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?
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list