| 
									
										
										
										
											2011-09-06 22:18:12 +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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/collada/SceneExporter.cpp
 | 
					
						
							|  |  |  |  *  \ingroup collada | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-01 15:34:38 +00:00
										 |  |  | extern "C" { | 
					
						
							|  |  |  | 	#include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 	#include "BKE_object.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-08 00:24:49 +01:00
										 |  |  | 	#include "BLI_listbase.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-01 15:34:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | #include "SceneExporter.h"
 | 
					
						
							| 
									
										
										
										
											2012-06-07 17:55:26 +00:00
										 |  |  | #include "collada_utils.h"
 | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-07 18:23:30 +00:00
										 |  |  | SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings) | 
					
						
							|  |  |  | 	: COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings) | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-06 23:21:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void SceneExporter::setExportTransformationType(BC_export_transformation_type transformation_type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	this->transformation_type = transformation_type; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-07 18:23:30 +00:00
										 |  |  | void SceneExporter::exportScene(Scene *sce) | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	// <library_visual_scenes> <visual_scene>
 | 
					
						
							|  |  |  | 	std::string id_naming = id_name(sce); | 
					
						
							|  |  |  | 	openVisualScene(translate_id(id_naming), id_naming); | 
					
						
							| 
									
										
										
										
											2011-09-07 18:23:30 +00:00
										 |  |  | 	exportHierarchy(sce); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 	closeVisualScene(); | 
					
						
							|  |  |  | 	closeLibrary(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | void SceneExporter::exportHierarchy(Scene *sce) | 
					
						
							|  |  |  | {	 | 
					
						
							|  |  |  | 	LinkNode *node; | 
					
						
							|  |  |  | 	std::vector<Object *> base_objects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Ensure all objects in the export_set are marked
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	for (node = this->export_settings->export_set; node; node = node->next) { | 
					
						
							|  |  |  | 		Object *ob = (Object *) node->link; | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 		ob->id.flag |= LIB_DOIT; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// Now find all exportable base ojects (highest in export hierarchy)
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	for (node = this->export_settings->export_set; node; node = node->next) { | 
					
						
							|  |  |  | 		Object *ob = (Object *) node->link; | 
					
						
							| 
									
										
										
										
											2012-06-27 18:29:47 +00:00
										 |  |  | 		if (bc_is_base_node(this->export_settings->export_set, ob)) { | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 			switch (ob->type) { | 
					
						
							|  |  |  | 				case OB_MESH: | 
					
						
							|  |  |  | 				case OB_CAMERA: | 
					
						
							|  |  |  | 				case OB_LAMP: | 
					
						
							|  |  |  | 				case OB_EMPTY: | 
					
						
							|  |  |  | 				case OB_ARMATURE: | 
					
						
							|  |  |  | 					base_objects.push_back(ob); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-06-07 17:55:26 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 	// And now export the base objects:
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	for (int index = 0; index < base_objects.size(); index++) { | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 		Object *ob = base_objects[index]; | 
					
						
							|  |  |  | 		if (bc_is_marked(ob)) { | 
					
						
							|  |  |  | 			bc_remove_mark(ob); | 
					
						
							|  |  |  | 			writeNodes(ob, sce); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-06 23:21:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | void SceneExporter::writeNodes(Object *ob, Scene *sce) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-07 17:55:26 +00:00
										 |  |  | 	// Add associated armature first if available
 | 
					
						
							| 
									
										
										
										
											2012-06-14 18:29:29 +00:00
										 |  |  | 	bool armature_exported = false; | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 	Object *ob_arm = bc_get_assigned_armature(ob); | 
					
						
							| 
									
										
										
										
											2012-06-27 18:29:47 +00:00
										 |  |  | 	if (ob_arm != NULL) { | 
					
						
							| 
									
										
										
										
											2012-06-14 18:29:29 +00:00
										 |  |  | 		armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm); | 
					
						
							|  |  |  | 		if (armature_exported && bc_is_marked(ob_arm)) { | 
					
						
							|  |  |  | 			bc_remove_mark(ob_arm); | 
					
						
							|  |  |  | 			writeNodes(ob_arm, sce); | 
					
						
							|  |  |  | 			armature_exported = true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-06-07 17:55:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 	COLLADASW::Node colladaNode(mSW); | 
					
						
							|  |  |  | 	colladaNode.setNodeId(translate_id(id_name(ob))); | 
					
						
							|  |  |  | 	colladaNode.setNodeName(translate_id(id_name(ob))); | 
					
						
							|  |  |  | 	colladaNode.setType(COLLADASW::Node::NODE); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 	colladaNode.start(); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	std::list<Object *> child_objects; | 
					
						
							| 
									
										
										
										
											2012-02-18 16:55:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 	// list child objects
 | 
					
						
							| 
									
										
										
										
											2012-06-14 18:29:29 +00:00
										 |  |  | 	LinkNode *node; | 
					
						
							|  |  |  | 	for (node=this->export_settings->export_set; node; node=node->next) { | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 		// cob - child object
 | 
					
						
							|  |  |  | 		Object *cob = (Object *)node->link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cob->parent == ob) { | 
					
						
							|  |  |  | 			switch (cob->type) { | 
					
						
							|  |  |  | 				case OB_MESH: | 
					
						
							|  |  |  | 				case OB_CAMERA: | 
					
						
							|  |  |  | 				case OB_LAMP: | 
					
						
							|  |  |  | 				case OB_EMPTY: | 
					
						
							|  |  |  | 				case OB_ARMATURE: | 
					
						
							|  |  |  | 					if (bc_is_marked(cob)) | 
					
						
							| 
									
										
										
										
											2012-05-24 14:56:09 +00:00
										 |  |  | 						child_objects.push_back(cob); | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2012-02-18 16:55:41 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-24 14:56:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-18 16:55:41 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-14 18:29:29 +00:00
										 |  |  | 	if (ob->type == OB_MESH && armature_exported) | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 		// for skinned mesh we write obmat in <bind_shape_matrix>
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 		TransformWriter::add_node_transform_identity(colladaNode); | 
					
						
							| 
									
										
										
										
											2013-03-06 23:21:52 +00:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		TransformWriter::add_node_transform_ob(colladaNode, ob, this->transformation_type); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// <instance_geometry>
 | 
					
						
							|  |  |  | 	if (ob->type == OB_MESH) { | 
					
						
							| 
									
										
										
										
											2012-06-07 17:55:26 +00:00
										 |  |  | 		bool instance_controller_created = false; | 
					
						
							| 
									
										
										
										
											2012-06-14 18:29:29 +00:00
										 |  |  | 		if (armature_exported) { | 
					
						
							| 
									
										
										
										
											2012-06-07 17:55:26 +00:00
										 |  |  | 			instance_controller_created = arm_exporter->add_instance_controller(ob); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		if (!instance_controller_created) { | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 			COLLADASW::InstanceGeometry instGeom(mSW); | 
					
						
							| 
									
										
										
										
											2012-05-26 22:46:28 +00:00
										 |  |  | 			instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation))); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-22 16:16:58 +00:00
										 |  |  | 			InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			instGeom.add(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// <instance_controller>
 | 
					
						
							|  |  |  | 	else if (ob->type == OB_ARMATURE) { | 
					
						
							| 
									
										
										
										
											2012-02-18 16:55:41 +00:00
										 |  |  | 		arm_exporter->add_armature_bones(ob, sce, this, child_objects); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// <instance_camera>
 | 
					
						
							|  |  |  | 	else if (ob->type == OB_CAMERA) { | 
					
						
							|  |  |  | 		COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob))); | 
					
						
							|  |  |  | 		instCam.add(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// <instance_light>
 | 
					
						
							|  |  |  | 	else if (ob->type == OB_LAMP) { | 
					
						
							|  |  |  | 		COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob))); | 
					
						
							|  |  |  | 		instLa.add(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// empty object
 | 
					
						
							|  |  |  | 	else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) { | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 			GroupObject *go = NULL; | 
					
						
							|  |  |  | 			Group *gr = ob->dup_group; | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 			/* printf("group detected '%s'\n", gr->id.name + 2); */ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) { | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 				printf("\t%s\n", go->ob->id.name); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 	if (ob->type == OB_ARMATURE) { | 
					
						
							|  |  |  | 		colladaNode.end(); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | 	if (BLI_listbase_is_empty(&ob->constraints) == false) { | 
					
						
							| 
									
										
										
										
											2013-03-18 11:44:56 +00:00
										 |  |  | 		bConstraint *con = (bConstraint *) ob->constraints.first; | 
					
						
							| 
									
										
										
										
											2013-02-02 04:58:03 +00:00
										 |  |  | 		while (con) { | 
					
						
							| 
									
										
										
										
											2014-04-27 18:43:50 +02:00
										 |  |  | 			std::string con_name(translate_id(con->name)); | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 			std::string con_tag = con_name + "_constraint"; | 
					
						
							| 
									
										
										
										
											2014-04-27 18:43:50 +02:00
										 |  |  | 			printf("%s\n", con_name.c_str()); | 
					
						
							|  |  |  | 			printf("%s\n\n", con_tag.c_str()); | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"type",con->type); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"enforce",con->enforce); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"flag",con->flag); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"headtail",con->headtail); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"own_space",con->ownspace); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"rot_error",con->rot_error); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"tar_space",con->tarspace); | 
					
						
							|  |  |  | 			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			//not ideal: add the target object name as another parameter. 
 | 
					
						
							|  |  |  | 			//No real mapping in the .dae
 | 
					
						
							|  |  |  | 			//Need support for multiple target objects also.
 | 
					
						
							| 
									
										
										
										
											2014-04-11 11:47:07 +10:00
										 |  |  | 			bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 			ListBase targets = {NULL, NULL}; | 
					
						
							|  |  |  | 			if (cti && cti->get_constraint_targets) { | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 				bConstraintTarget *ct; | 
					
						
							|  |  |  | 				Object *obtar; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 				cti->get_constraint_targets(con, &targets); | 
					
						
							| 
									
										
										
										
											2013-05-06 11:12:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) { | 
					
						
							|  |  |  | 					obtar = ct->tar; | 
					
						
							|  |  |  | 					std::string tar_id((obtar) ? id_name(obtar) : ""); | 
					
						
							|  |  |  | 					colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"target_id",tar_id); | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-05-06 11:12:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (cti->flush_constraint_targets) | 
					
						
							|  |  |  | 					cti->flush_constraint_targets(con, &targets, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-02-04 00:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 			con = con->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) { | 
					
						
							|  |  |  | 		if (bc_is_marked(*i)) { | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 			bc_remove_mark(*i); | 
					
						
							|  |  |  | 			writeNodes(*i, sce); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-18 16:55:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | 	if (ob->type != OB_ARMATURE) | 
					
						
							| 
									
										
										
										
											2012-06-12 21:25:29 +00:00
										 |  |  | 		colladaNode.end(); | 
					
						
							| 
									
										
										
										
											2011-09-06 22:18:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 |