style cleanup
[blender.git] / source / blender / collada / SceneExporter.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/collada/SceneExporter.cpp
24  *  \ingroup collada
25  */
26
27 #include "SceneExporter.h"
28 #include "collada_utils.h"
29 #include "BKE_object.h"
30
31 SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings)
32         : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings)
33 {
34 }
35         
36 void SceneExporter::exportScene(Scene *sce)
37 {
38         // <library_visual_scenes> <visual_scene>
39         std::string id_naming = id_name(sce);
40         openVisualScene(translate_id(id_naming), id_naming);
41         exportHierarchy(sce);
42         closeVisualScene();
43         closeLibrary();
44 }
45
46 void SceneExporter::exportHierarchy(Scene *sce)
47 {       
48         LinkNode *node;
49         std::vector<Object *> base_objects;
50
51         // Ensure all objects in the export_set are marked
52         for (node = this->export_settings->export_set; node; node = node->next) {
53                 Object *ob = (Object *) node->link;
54                 ob->id.flag |= LIB_DOIT;
55         }
56         
57         // Now find all exportable base ojects (highest in export hierarchy)
58         for (node = this->export_settings->export_set; node; node = node->next) {
59                 Object *ob = (Object *) node->link;
60                 if (bc_is_base_node(this->export_settings->export_set, ob)) {
61                         switch (ob->type) {
62                                 case OB_MESH:
63                                 case OB_CAMERA:
64                                 case OB_LAMP:
65                                 case OB_EMPTY:
66                                 case OB_ARMATURE:
67                                         base_objects.push_back(ob);
68                                         break;
69                         }
70                 }
71         }
72
73         // And now export the base objects:
74         for (int index = 0; index < base_objects.size(); index++) {
75                 Object *ob = base_objects[index];
76                 if (bc_is_marked(ob)) {
77                         bc_remove_mark(ob);
78                         writeNodes(ob, sce);
79                 }
80         }
81 }
82
83 void SceneExporter::writeNodes(Object *ob, Scene *sce)
84 {
85         // Add associated armature first if available
86         bool armature_exported = false;
87         Object *ob_arm = bc_get_assigned_armature(ob);
88         if (ob_arm != NULL) {
89                 armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
90                 if (armature_exported && bc_is_marked(ob_arm)) {
91                         bc_remove_mark(ob_arm);
92                         writeNodes(ob_arm, sce);
93                         armature_exported = true;
94                 }
95         }
96
97         COLLADASW::Node colladaNode(mSW);
98         colladaNode.setNodeId(translate_id(id_name(ob)));
99         colladaNode.setNodeName(translate_id(id_name(ob)));
100         colladaNode.setType(COLLADASW::Node::NODE);
101
102         colladaNode.start();
103
104         std::list<Object *> child_objects;
105
106         // list child objects
107         LinkNode *node;
108         for (node=this->export_settings->export_set; node; node=node->next) {
109                 // cob - child object
110                 Object *cob = (Object *)node->link;
111
112                 if (cob->parent == ob) {
113                         switch (cob->type) {
114                                 case OB_MESH:
115                                 case OB_CAMERA:
116                                 case OB_LAMP:
117                                 case OB_EMPTY:
118                                 case OB_ARMATURE:
119                                         if (bc_is_marked(cob))
120                                                 child_objects.push_back(cob);
121                                         break;
122                         }
123                 }
124         }
125
126         if (ob->type == OB_MESH && armature_exported)
127                 // for skinned mesh we write obmat in <bind_shape_matrix>
128                 TransformWriter::add_node_transform_identity(colladaNode);
129         else
130                 TransformWriter::add_node_transform_ob(colladaNode, ob);
131
132         // <instance_geometry>
133         if (ob->type == OB_MESH) {
134                 bool instance_controller_created = false;
135                 if (armature_exported) {
136                         instance_controller_created = arm_exporter->add_instance_controller(ob);
137                 }
138                 if (!instance_controller_created) {
139                         COLLADASW::InstanceGeometry instGeom(mSW);
140                         instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation)));
141
142                         InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only);
143
144                         instGeom.add();
145                 }
146         }
147
148         // <instance_controller>
149         else if (ob->type == OB_ARMATURE) {
150                 arm_exporter->add_armature_bones(ob, sce, this, child_objects);
151         }
152
153         // <instance_camera>
154         else if (ob->type == OB_CAMERA) {
155                 COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob)));
156                 instCam.add();
157         }
158
159         // <instance_light>
160         else if (ob->type == OB_LAMP) {
161                 COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob)));
162                 instLa.add();
163         }
164
165         // empty object
166         else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
167                 if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) {
168                         GroupObject *go = NULL;
169                         Group *gr = ob->dup_group;
170                         /* printf("group detected '%s'\n", gr->id.name+2); */
171                         for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) {
172                                 printf("\t%s\n", go->ob->id.name);
173                         }
174                 }
175         }
176
177         if (ob->type == OB_ARMATURE) {
178                 colladaNode.end();
179         }
180
181         for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
182                 if (bc_is_marked(*i)) {
183                         bc_remove_mark(*i);
184                         writeNodes(*i, sce);
185                 }
186         }
187
188         if (ob->type != OB_ARMATURE) {
189                 colladaNode.end();
190         }
191 }
192