| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, | 
					
						
							|  |  |  |  *                 Nathan Letwory | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:30:35 +00:00
										 |  |  | /** \file blender/collada/GeometryExporter.cpp
 | 
					
						
							|  |  |  |  *  \ingroup collada | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 22:51:02 +00:00
										 |  |  | #include <sstream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | #include "COLLADASWPrimitves.h"
 | 
					
						
							|  |  |  | #include "COLLADASWSource.h"
 | 
					
						
							|  |  |  | #include "COLLADASWVertices.h"
 | 
					
						
							|  |  |  | #include "COLLADABUUtils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "GeometryExporter.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  |     #include "BKE_DerivedMesh.h"
 | 
					
						
							|  |  |  | 	#include "BKE_main.h"
 | 
					
						
							|  |  |  | 	#include "BKE_global.h"
 | 
					
						
							|  |  |  | 	#include "BKE_library.h"
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | #include "BKE_customdata.h"
 | 
					
						
							|  |  |  | #include "BKE_material.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-24 21:15:58 +00:00
										 |  |  | #include "BKE_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | #include "collada_internal.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TODO: optimize UV sets by making indexed list with duplicates removed
 | 
					
						
							| 
									
										
										
										
											2011-09-07 18:23:30 +00:00
										 |  |  | GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {} | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-07 18:23:30 +00:00
										 |  |  | void GeometryExporter::exportGeom(Scene *sce) | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	openLibrary(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mScene = sce; | 
					
						
							|  |  |  | 	GeometryFunctor gf; | 
					
						
							| 
									
										
										
										
											2011-09-07 18:23:30 +00:00
										 |  |  | 	gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, this->export_settings->selected); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	closeLibrary(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | Mesh * GeometryExporter::get_mesh(Object *ob, int apply_modifiers) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Mesh *tmpmesh; | 
					
						
							|  |  |  | 	if (!apply_modifiers) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		tmpmesh = (Mesh*)ob->data; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		CustomDataMask mask = CD_MASK_MESH; | 
					
						
							|  |  |  | 		DerivedMesh *dm     = mesh_create_derived_view(mScene, ob, mask); | 
					
						
							|  |  |  | 		tmpmesh             = BKE_mesh_add("ColladaMesh"); // name is not important here
 | 
					
						
							|  |  |  | 		DM_to_mesh(dm, tmpmesh, ob); | 
					
						
							|  |  |  | 		dm->release(dm); | 
					
						
							|  |  |  | 		BKE_mesh_tessface_ensure(tmpmesh); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return tmpmesh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | void GeometryExporter::operator()(Object *ob) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// XXX don't use DerivedMesh, Mesh instead?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0		
 | 
					
						
							|  |  |  | 	DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Mesh *me = get_mesh(ob, this->export_settings->apply_modifiers); | 
					
						
							| 
									
										
										
										
											2012-02-24 21:15:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	std::string geom_id = get_geometry_id(ob); | 
					
						
							| 
									
										
										
										
											2012-02-02 10:34:44 +00:00
										 |  |  | 	std::string geom_name = id_name(ob->data); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	std::vector<Normal> nor; | 
					
						
							|  |  |  | 	std::vector<Face> norind; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-16 22:27:31 +00:00
										 |  |  | 	// Skip if linked geometry was already exported from another reference
 | 
					
						
							|  |  |  | 	if (exportedGeometry.find(geom_id) != exportedGeometry.end()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	exportedGeometry.insert(geom_id); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	create_normals(nor, norind, me); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// openMesh(geoId, geoName, meshId)
 | 
					
						
							| 
									
										
										
										
											2012-02-02 10:34:44 +00:00
										 |  |  | 	openMesh(geom_id, geom_name); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// writes <source> for vertex coords
 | 
					
						
							|  |  |  | 	createVertsSource(geom_id, me); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// writes <source> for normal coords
 | 
					
						
							|  |  |  | 	createNormalsSource(geom_id, me, nor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// writes <source> for uv coords if mesh has uv coords
 | 
					
						
							|  |  |  | 	if (has_uvs) | 
					
						
							|  |  |  | 		createTexcoordsSource(geom_id, me); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (has_color) | 
					
						
							|  |  |  | 		createVertexColorSource(geom_id, me); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// <vertices>
 | 
					
						
							|  |  |  | 	COLLADASW::Vertices verts(mSW); | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX)); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	COLLADASW::InputList &input_list = verts.getInputList(); | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	input_list.push_back(input); | 
					
						
							|  |  |  | 	verts.add(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX slow		
 | 
					
						
							|  |  |  | 	if (ob->totcol) { | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (int a = 0; a < ob->totcol; a++)	{ | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | 			createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | 		createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	closeMesh(); | 
					
						
							| 
									
										
										
										
											2011-03-23 00:19:38 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (me->flag & ME_TWOSIDED) { | 
					
						
							|  |  |  | 		mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	closeGeometry(); | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (this->export_settings->apply_modifiers) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		BKE_libblock_free_us(&(G.main->mesh), me); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 	dm->release(dm); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // powerful because it handles both cases when there is material and when there's not
 | 
					
						
							| 
									
										
										
										
											2011-09-20 06:25:15 +00:00
										 |  |  | void GeometryExporter::createPolylist(short material_index, | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 					bool has_uvs, | 
					
						
							|  |  |  | 					bool has_color, | 
					
						
							|  |  |  | 					Object *ob, | 
					
						
							| 
									
										
										
										
											2012-05-07 18:09:59 +00:00
										 |  |  | 					Mesh *me, | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 					std::string& geom_id, | 
					
						
							|  |  |  | 					std::vector<Face>& norind) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MFace *mfaces = me->mface; | 
					
						
							|  |  |  | 	int totfaces = me->totface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// <vcount>
 | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	int faces_in_polylist = 0; | 
					
						
							|  |  |  | 	std::vector<unsigned long> vcount_list; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// count faces with this material
 | 
					
						
							|  |  |  | 	for (i = 0; i < totfaces; i++) { | 
					
						
							|  |  |  | 		MFace *f = &mfaces[i]; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (f->mat_nr == material_index) { | 
					
						
							|  |  |  | 			faces_in_polylist++; | 
					
						
							|  |  |  | 			if (f->v4 == 0) { | 
					
						
							|  |  |  | 				vcount_list.push_back(3); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				vcount_list.push_back(4); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// no faces using this material
 | 
					
						
							|  |  |  | 	if (faces_in_polylist == 0) { | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: no faces use material %d\n", id_name(ob).c_str(), material_index); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; | 
					
						
							|  |  |  | 	COLLADASW::Polylist polylist(mSW); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// sets count attribute in <polylist>
 | 
					
						
							|  |  |  | 	polylist.setCount(faces_in_polylist); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// sets material name
 | 
					
						
							|  |  |  | 	if (ma) { | 
					
						
							| 
									
										
										
										
											2011-03-22 22:51:02 +00:00
										 |  |  | 		std::ostringstream ostr; | 
					
						
							|  |  |  | 		ostr << translate_id(id_name(ma)) << material_index+1; | 
					
						
							|  |  |  | 		polylist.setMaterial(ostr.str()); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	COLLADASW::InputList &til = polylist.getInputList(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// creates <input> in <polylist> for vertices 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	// creates <input> in <polylist> for normals
 | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	til.push_back(input1); | 
					
						
							|  |  |  | 	til.push_back(input2); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// if mesh has uv coords writes <input> for TEXCOORD
 | 
					
						
							|  |  |  | 	int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < num_layers; i++) { | 
					
						
							|  |  |  | 		// char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
 | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 		COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 								makeUrl(makeTexcoordSourceId(geom_id, i)), | 
					
						
							|  |  |  | 								2, // offset always 2, this is only until we have optimized UV sets
 | 
					
						
							| 
									
										
										
										
											2011-11-23 17:25:25 +00:00
										 |  |  | 								i  // set number equals UV map index
 | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 								); | 
					
						
							|  |  |  | 		til.push_back(input3); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (has_color) { | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 		COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::COLOR), has_uvs ? 3 : 2); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 		til.push_back(input4); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// sets <vcount>
 | 
					
						
							|  |  |  | 	polylist.setVCountList(vcount_list); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// performs the actual writing
 | 
					
						
							|  |  |  | 	polylist.prepareToAppendValues(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// <p>
 | 
					
						
							|  |  |  | 	int texindex = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < totfaces; i++) { | 
					
						
							|  |  |  | 		MFace *f = &mfaces[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (f->mat_nr == material_index) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			unsigned int *v = &f->v1; | 
					
						
							|  |  |  | 			unsigned int *n = &norind[i].v1; | 
					
						
							|  |  |  | 			for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { | 
					
						
							|  |  |  | 				polylist.appendValues(v[j]); | 
					
						
							|  |  |  | 				polylist.appendValues(n[j]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (has_uvs) | 
					
						
							|  |  |  | 					polylist.appendValues(texindex + j); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (has_color) | 
					
						
							|  |  |  | 					polylist.appendValues(texindex + j); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		texindex += 3; | 
					
						
							|  |  |  | 		if (f->v4 != 0) | 
					
						
							|  |  |  | 			texindex++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	polylist.finish(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // creates <source> for positions
 | 
					
						
							|  |  |  | void GeometryExporter::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); | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); | 
					
						
							|  |  |  | 	source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) + | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 					  ARRAY_ID_SUFFIX); | 
					
						
							|  |  |  | 	source.setAccessorCount(totverts); | 
					
						
							|  |  |  | 	source.setAccessorStride(3); | 
					
						
							|  |  |  | 	COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); | 
					
						
							|  |  |  | 	param.push_back("X"); | 
					
						
							|  |  |  | 	param.push_back("Y"); | 
					
						
							|  |  |  | 	param.push_back("Z"); | 
					
						
							|  |  |  | 	/*main function, it creates <source id = "">, <float_array id = ""
 | 
					
						
							|  |  |  | 	  count = ""> */ | 
					
						
							|  |  |  | 	source.prepareToAppendValues(); | 
					
						
							|  |  |  | 	//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.finish(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!CustomData_has_layer(&me->fdata, CD_MCOL)) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MFace *f; | 
					
						
							|  |  |  | 	int totcolor = 0, i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0, f = me->mface; i < me->totface; i++, f++) | 
					
						
							|  |  |  | 		totcolor += f->v4 ? 4 : 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	COLLADASW::FloatSourceF source(mSW); | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR)); | 
					
						
							|  |  |  | 	source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	source.setAccessorCount(totcolor); | 
					
						
							|  |  |  | 	source.setAccessorStride(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); | 
					
						
							|  |  |  | 	param.push_back("R"); | 
					
						
							|  |  |  | 	param.push_back("G"); | 
					
						
							|  |  |  | 	param.push_back("B"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	source.prepareToAppendValues(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MCol *mcol = (MCol*)me->fdata.layers[index].data; | 
					
						
							|  |  |  | 	MCol *c = mcol; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++) | 
					
						
							|  |  |  | 		for (j = 0; j < (f->v4 ? 4 : 3); j++) | 
					
						
							|  |  |  | 			source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	source.finish(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int layer_index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char suffix[20]; | 
					
						
							|  |  |  | 	sprintf(suffix, "-%d", layer_index); | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	return getIdBySemantics(geom_id, COLLADASW::InputSemantic::TEXCOORD) + suffix; | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //creates <source> for texcoords
 | 
					
						
							|  |  |  | void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-11-30 18:03:56 +00:00
										 |  |  | 	int totfaces = dm->getNumTessFaces(dm); | 
					
						
							|  |  |  | 	MFace *mfaces = dm->getTessFaceArray(dm); | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	int totfaces = me->totface; | 
					
						
							|  |  |  | 	MFace *mfaces = me->mface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int totuv = 0; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// count totuv
 | 
					
						
							|  |  |  | 	for (i = 0; i < totfaces; i++) { | 
					
						
							|  |  |  | 		MFace *f = &mfaces[i]; | 
					
						
							|  |  |  | 		if (f->v4 == 0) { | 
					
						
							|  |  |  | 			totuv+=3; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			totuv+=4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// write <source> for each layer
 | 
					
						
							|  |  |  | 	// each <source> will get id like meshName + "map-channel-1"
 | 
					
						
							|  |  |  | 	for (int a = 0; a < num_layers; a++) { | 
					
						
							|  |  |  | 		MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); | 
					
						
							|  |  |  | 		// char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a);
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		COLLADASW::FloatSourceF source(mSW); | 
					
						
							|  |  |  | 		std::string layer_id = makeTexcoordSourceId(geom_id, a); | 
					
						
							|  |  |  | 		source.setId(layer_id); | 
					
						
							|  |  |  | 		source.setArrayId(layer_id + ARRAY_ID_SUFFIX); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		source.setAccessorCount(totuv); | 
					
						
							|  |  |  | 		source.setAccessorStride(2); | 
					
						
							|  |  |  | 		COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); | 
					
						
							|  |  |  | 		param.push_back("S"); | 
					
						
							|  |  |  | 		param.push_back("T"); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		source.prepareToAppendValues(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		for (i = 0; i < totfaces; i++) { | 
					
						
							|  |  |  | 			MFace *f = &mfaces[i]; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { | 
					
						
							|  |  |  | 				source.appendValues(tface[i].uv[j][0], | 
					
						
							|  |  |  | 									tface[i].uv[j][1]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		source.finish(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //creates <source> for normals
 | 
					
						
							|  |  |  | void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::vector<Normal>& nor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	int totverts = dm->getNumVerts(dm); | 
					
						
							|  |  |  | 	MVert *verts = dm->getVertArray(dm); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	COLLADASW::FloatSourceF source(mSW); | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL)); | 
					
						
							|  |  |  | 	source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 					  ARRAY_ID_SUFFIX); | 
					
						
							|  |  |  | 	source.setAccessorCount((unsigned long)nor.size()); | 
					
						
							|  |  |  | 	source.setAccessorStride(3); | 
					
						
							|  |  |  | 	COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); | 
					
						
							|  |  |  | 	param.push_back("X"); | 
					
						
							|  |  |  | 	param.push_back("Y"); | 
					
						
							|  |  |  | 	param.push_back("Z"); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	source.prepareToAppendValues(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	std::vector<Normal>::iterator it; | 
					
						
							|  |  |  | 	for (it = nor.begin(); it != nor.end(); it++) { | 
					
						
							|  |  |  | 		Normal& n = *it; | 
					
						
							|  |  |  | 		source.appendValues(n.x, n.y, n.z); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	source.finish(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GeometryExporter::create_normals(std::vector<Normal> &nor, std::vector<Face> &ind, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, j, v; | 
					
						
							|  |  |  | 	MVert *vert = me->mvert; | 
					
						
							|  |  |  | 	std::map<unsigned int, unsigned int> nshar; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < me->totface; i++) { | 
					
						
							|  |  |  | 		MFace *fa = &me->mface[i]; | 
					
						
							|  |  |  | 		Face f; | 
					
						
							|  |  |  | 		unsigned int *nn = &f.v1; | 
					
						
							|  |  |  | 		unsigned int *vv = &fa->v1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memset(&f, 0, sizeof(f)); | 
					
						
							|  |  |  | 		v = fa->v4 == 0 ? 3 : 4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!(fa->flag & ME_SMOOTH)) { | 
					
						
							|  |  |  | 			Normal n; | 
					
						
							|  |  |  | 			if (v == 4) | 
					
						
							|  |  |  | 				normal_quad_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co, vert[fa->v4].co); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				normal_tri_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co); | 
					
						
							|  |  |  | 			nor.push_back(n); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (j = 0; j < v; j++) { | 
					
						
							|  |  |  | 			if (fa->flag & ME_SMOOTH) { | 
					
						
							|  |  |  | 				if (nshar.find(*vv) != nshar.end()) | 
					
						
							|  |  |  | 					*nn = nshar[*vv]; | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					Normal n = { | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 						(float)vert[*vv].no[0] / 32767.0f, | 
					
						
							|  |  |  | 						(float)vert[*vv].no[1] / 32767.0f, | 
					
						
							|  |  |  | 						(float)vert[*vv].no[2] / 32767.0f | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 					}; | 
					
						
							|  |  |  | 					nor.push_back(n); | 
					
						
							|  |  |  | 					*nn = (unsigned int)nor.size() - 1; | 
					
						
							|  |  |  | 					nshar[*vv] = *nn; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				vv++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				*nn = (unsigned int)nor.size() - 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			nn++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ind.push_back(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-25 16:49:59 +00:00
										 |  |  | std::string GeometryExporter::getIdBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	return geom_id + getSuffixBySemantic(type) + other_suffix; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-25 16:49:59 +00:00
										 |  |  | COLLADASW::URI GeometryExporter::getUrlBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-06 09:53:06 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	std::string id(getIdBySemantics(geom_id, type, other_suffix)); | 
					
						
							|  |  |  | 	return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COLLADASW::URI GeometryExporter::makeUrl(std::string id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* int GeometryExporter::getTriCount(MFace *faces, int totface) {
 | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	int tris = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < totface; i++) { | 
					
						
							|  |  |  | 		// if quad
 | 
					
						
							|  |  |  | 		if (faces[i].v4 != 0) | 
					
						
							|  |  |  | 			tris += 2; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			tris++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tris; | 
					
						
							|  |  |  | 	}*/ |