2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/collada/SceneExporter.cpp
28 #include "BLI_utildefines.h"
29 #include "BKE_object.h"
32 #include "SceneExporter.h"
33 #include "collada_utils.h"
35 SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings)
36 : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings)
40 void SceneExporter::exportScene(Scene *sce)
42 // <library_visual_scenes> <visual_scene>
43 std::string id_naming = id_name(sce);
44 openVisualScene(translate_id(id_naming), id_naming);
50 void SceneExporter::exportHierarchy(Scene *sce)
53 std::vector<Object *> base_objects;
55 // Ensure all objects in the export_set are marked
56 for (node = this->export_settings->export_set; node; node = node->next) {
57 Object *ob = (Object *) node->link;
58 ob->id.flag |= LIB_DOIT;
61 // Now find all exportable base ojects (highest in export hierarchy)
62 for (node = this->export_settings->export_set; node; node = node->next) {
63 Object *ob = (Object *) node->link;
64 if (bc_is_base_node(this->export_settings->export_set, ob)) {
71 base_objects.push_back(ob);
77 // And now export the base objects:
78 for (int index = 0; index < base_objects.size(); index++) {
79 Object *ob = base_objects[index];
80 if (bc_is_marked(ob)) {
87 void SceneExporter::writeNodes(Object *ob, Scene *sce)
89 // Add associated armature first if available
90 bool armature_exported = false;
91 Object *ob_arm = bc_get_assigned_armature(ob);
93 armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
94 if (armature_exported && bc_is_marked(ob_arm)) {
95 bc_remove_mark(ob_arm);
96 writeNodes(ob_arm, sce);
97 armature_exported = true;
101 COLLADASW::Node colladaNode(mSW);
102 colladaNode.setNodeId(translate_id(id_name(ob)));
103 colladaNode.setNodeName(translate_id(id_name(ob)));
104 colladaNode.setType(COLLADASW::Node::NODE);
108 std::list<Object *> child_objects;
110 // list child objects
112 for (node=this->export_settings->export_set; node; node=node->next) {
113 // cob - child object
114 Object *cob = (Object *)node->link;
116 if (cob->parent == ob) {
123 if (bc_is_marked(cob))
124 child_objects.push_back(cob);
130 if (ob->type == OB_MESH && armature_exported)
131 // for skinned mesh we write obmat in <bind_shape_matrix>
132 TransformWriter::add_node_transform_identity(colladaNode);
134 TransformWriter::add_node_transform_ob(colladaNode, ob);
136 // <instance_geometry>
137 if (ob->type == OB_MESH) {
138 bool instance_controller_created = false;
139 if (armature_exported) {
140 instance_controller_created = arm_exporter->add_instance_controller(ob);
142 if (!instance_controller_created) {
143 COLLADASW::InstanceGeometry instGeom(mSW);
144 instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation)));
146 InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only);
152 // <instance_controller>
153 else if (ob->type == OB_ARMATURE) {
154 arm_exporter->add_armature_bones(ob, sce, this, child_objects);
158 else if (ob->type == OB_CAMERA) {
159 COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob)));
164 else if (ob->type == OB_LAMP) {
165 COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob)));
170 else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
171 if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) {
172 GroupObject *go = NULL;
173 Group *gr = ob->dup_group;
174 /* printf("group detected '%s'\n", gr->id.name+2); */
175 for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) {
176 printf("\t%s\n", go->ob->id.name);
181 if (ob->type == OB_ARMATURE) {
185 if (ob->constraints.first != NULL ){
186 bConstraint *con = (bConstraint*) ob->constraints.first;
188 std::string con_name(id_name(con));
189 std::string con_tag = con_name + "_constraint";
190 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"type",con->type);
191 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"enforce",con->enforce);
192 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"flag",con->flag);
193 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"headtail",con->headtail);
194 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
195 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"own_space",con->ownspace);
196 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"rot_error",con->rot_error);
197 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"tar_space",con->tarspace);
198 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
200 //not ideal: add the target object name as another parameter.
201 //No real mapping in the .dae
202 //Need support for multiple target objects also.
203 bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
204 ListBase targets = {NULL, NULL};
205 if (cti && cti->get_constraint_targets) {
207 bConstraintTarget *ct;
210 cti->get_constraint_targets(con, &targets);
212 for (ct = (bConstraintTarget*)targets.first; ct; ct = ct->next){
214 std::string tar_id(id_name(obtar));
215 colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"target_id",tar_id);
224 for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
225 if (bc_is_marked(*i)) {
231 if (ob->type != OB_ARMATURE)