[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