style cleanup: comment blocks
[blender-staging.git] / source / blender / collada / collada_internal.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.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/collada/collada_internal.cpp
24  *  \ingroup collada
25  */
26
27
28 /* COLLADABU_ASSERT, may be able to remove later */
29 #include "COLLADABUPlatform.h"
30
31 #include "collada_internal.h"
32
33 UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {}
34
35 void UnitConverter::read_asset(const COLLADAFW::FileInfo* asset)
36 {
37         unit = asset->getUnit();
38         up_axis = asset->getUpAxisType();
39 }
40
41 UnitConverter::UnitSystem UnitConverter::isMetricSystem()
42 {
43         switch(unit.getLinearUnitUnit()) {
44                 case COLLADAFW::FileInfo::Unit::MILLIMETER:
45                 case COLLADAFW::FileInfo::Unit::CENTIMETER:
46                 case COLLADAFW::FileInfo::Unit::DECIMETER:
47                 case COLLADAFW::FileInfo::Unit::METER:
48                 case COLLADAFW::FileInfo::Unit::KILOMETER:
49                         return UnitConverter::Metric;
50                 case COLLADAFW::FileInfo::Unit::INCH:
51                 case COLLADAFW::FileInfo::Unit::FOOT:
52                 case COLLADAFW::FileInfo::Unit::YARD:
53                         return UnitConverter::Imperial;
54                 default:
55                         return UnitConverter::None;
56         }
57 }
58
59 float UnitConverter::getLinearMeter()
60 {
61         return (float)unit.getLinearUnitMeter();
62 }
63
64 void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
65 {
66         v[0] = vec.x;
67         v[1] = vec.y;
68         v[2] = vec.z;
69 }
70
71 // TODO need also for angle conversion, time conversion...
72
73 void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in)
74 {
75         // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
76         // so here, to make a blender matrix, we swap columns and rows
77         for (int i = 0; i < 4; i++) {
78                 for (int j = 0; j < 4; j++) {
79                         out[i][j] = in[j][i];
80                 }
81         }
82 }
83
84 void UnitConverter::mat4_to_dae(float out[][4], float in[][4])
85 {
86         copy_m4_m4(out, in);
87         transpose_m4(out);
88 }
89
90 void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4])
91 {
92         float mat[4][4];
93
94         mat4_to_dae(mat, in);
95
96         for (int i = 0; i < 4; i++)
97                 for (int j = 0; j < 4; j++)
98                         out[i][j] = mat[i][j];
99 }
100
101 void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size)
102 {
103         mat4_to_size(size, mat);
104         if (eul) {
105                 mat4_to_eul(eul, mat);
106         }
107         if (quat) {
108                 mat4_to_quat(quat, mat);
109         }
110         copy_v3_v3(loc, mat[3]);
111 }
112
113 /**
114  * Translation map.
115  * Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be
116  * included. Look at the IDREF XSD declaration for more.
117  * Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars,
118  * like special chars (e.g. micro sign), umlauts and so on.
119  * The COLLADA spec also allows additional chars for member access ('.'), these
120  * must obviously be removed too, otherwise they would be heavily misinterpreted.
121  */
122 const unsigned char translate_start_name_map[256] = {
123 95,  95,  95,  95,  95,  95,  95,  95,  95,
124 95,  95,  95,  95,  95,  95,  95,  95,
125 95,  95,  95,  95,  95,  95,  95,  95,
126 95,  95,  95,  95,  95,  95,  95,  95,
127 95,  95,  95,  95,  95,  95,  95,  95,
128 95,  95,  95,  95,  95,  95,  95,  95,
129 95,  95,  95,  95,  95,  95,  95,  95,
130 95,  95,  95,  95,  95,  95,  95,  95,
131 65,  66,  67,  68,  69,  70,  71,  72,
132 73,  74,  75,  76,  77,  78,  79,  80,
133 81,  82,  83,  84,  85,  86,  87,  88,
134 89,  90,  95,  95,  95,  95,  95,  95,
135 97,  98,  99,  100,  101,  102,  103,  104,
136 105,  106,  107,  108,  109,  110,  111,  112,
137 113,  114,  115,  116,  117,  118,  119,  120,
138 121,  122,  95,  95,  95,  95,  95,  95,
139 95,  95,  95,  95,  95,  95,  95,  95,
140 95,  95,  95,  95,  95,  95,  95,  95,
141 95,  95,  95,  95,  95,  95,  95,  95,
142 95,  95,  95,  95,  95,  95,  95,  95,
143 95,  95,  95,  95,  95,  95,  95,  95,
144 95,  95,  95,  95,  95,  95,  95,  95,
145 95,  95,  95,  95,  95,  95,  95,  95,
146 95,  95,  95,  95,  95,  95,  95,  192,
147 193,  194,  195,  196,  197,  198,  199,  200,
148 201,  202,  203,  204,  205,  206,  207,  208,
149 209,  210,  211,  212,  213,  214,  95,  216,
150 217,  218,  219,  220,  221,  222,  223,  224,
151 225,  226,  227,  228,  229,  230,  231,  232,
152 233,  234,  235,  236,  237,  238,  239,  240,
153 241,  242,  243,  244,  245,  246,  95,  248,
154 249,  250,  251,  252,  253,  254,  255};
155
156 const unsigned char translate_name_map[256] = {
157 95,  95,  95,  95,  95,  95,  95,  95,  95,
158 95,  95,  95,  95,  95,  95,  95,  95,
159 95,  95,  95,  95,  95,  95,  95,  95,
160 95,  95,  95,  95,  95,  95,  95,  95,
161 95,  95,  95,  95,  95,  95,  95,  95,
162 95,  95,  95,  95,  45,  95,  95,  48,
163 49,  50,  51,  52,  53,  54,  55,  56,
164 57,  95,  95,  95,  95,  95,  95,  95,
165 65,  66,  67,  68,  69,  70,  71,  72,
166 73,  74,  75,  76,  77,  78,  79,  80,
167 81,  82,  83,  84,  85,  86,  87,  88,
168 89,  90,  95,  95,  95,  95,  95,  95,
169 97,  98,  99,  100,  101,  102,  103,  104,
170 105,  106,  107,  108,  109,  110,  111,  112,
171 113,  114,  115,  116,  117,  118,  119,  120,
172 121,  122,  95,  95,  95,  95,  95,  95,
173 95,  95,  95,  95,  95,  95,  95,  95,
174 95,  95,  95,  95,  95,  95,  95,  95,
175 95,  95,  95,  95,  95,  95,  95,  95,
176 95,  95,  95,  95,  95,  95,  95,  95,
177 95,  95,  95,  95,  95,  95,  95,  95,
178 95,  95,  95,  95,  95,  95,  95,  95,
179 95,  95,  95,  95,  95,  95,  183,  95,
180 95,  95,  95,  95,  95,  95,  95,  192,
181 193,  194,  195,  196,  197,  198,  199,  200,
182 201,  202,  203,  204,  205,  206,  207,  208,
183 209,  210,  211,  212,  213,  214,  95,  216,
184 217,  218,  219,  220,  221,  222,  223,  224,
185 225,  226,  227,  228,  229,  230,  231,  232,
186 233,  234,  235,  236,  237,  238,  239,  240,
187 241,  242,  243,  244,  245,  246,  95,  248,
188 249,  250,  251,  252,  253,  254,  255};
189
190 typedef std::map< std::string, std::vector<std::string> > map_string_list;
191 map_string_list global_id_map;
192
193 void clear_global_id_map()
194 {
195         global_id_map.clear();
196 }
197
198 /** Look at documentation of translate_map */
199 std::string translate_id(const std::string &id)
200 {
201         if (id.size() == 0)
202         { return id; }
203         std::string id_translated = id;
204         id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
205         for (unsigned int i=1; i < id_translated.size(); i++)
206         {
207                 id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
208         }
209         // It's so much workload now, the if() should speed up things.
210         if (id_translated != id)
211         {
212                 // Search duplicates
213                 map_string_list::iterator iter = global_id_map.find(id_translated);
214                 if (iter != global_id_map.end())
215                 {
216                         unsigned int i = 0;
217                         bool found = false;
218                         for (i=0; i < iter->second.size(); i++)
219                         {
220                                 if (id == iter->second[i])
221                                 { 
222                                         found = true;
223                                         break;
224                                 }
225                         }
226                         bool convert = false;
227                         if (found)
228                         {
229                           if (i > 0)
230                           { convert = true; }
231                         }
232                         else
233                         { 
234                                 convert = true;
235                                 global_id_map[id_translated].push_back(id);
236                         }
237                         if (convert)
238                         {
239                                 std::stringstream out;
240                                 out << ++i;
241                                 id_translated += out.str();
242                         }
243                 }
244                 else { global_id_map[id_translated].push_back(id); }
245         }
246         return id_translated;
247 }
248
249 std::string id_name(void *id)
250 {
251         return ((ID*)id)->name + 2;
252 }
253
254 std::string get_geometry_id(Object *ob)
255 {
256         return translate_id(id_name(ob->data)) + "-mesh";
257 }
258
259 std::string get_light_id(Object *ob)
260 {
261         return translate_id(id_name(ob)) + "-light";
262 }
263
264 std::string get_joint_id(Bone *bone, Object *ob_arm)
265 {
266         return translate_id(/*id_name(ob_arm) + "_" +*/ bone->name);
267 }
268
269 std::string get_camera_id(Object *ob)
270 {
271         return translate_id(id_name(ob)) + "-camera";
272 }
273
274 std::string get_material_id(Material *mat)
275 {
276         return translate_id(id_name(mat)) + "-material";
277 }
278
279 bool has_object_type(Scene *sce, short obtype)
280 {
281         Base *base= (Base*) sce->base.first;
282         while(base) {
283                 Object *ob = base->object;
284                         
285                 if (ob->type == obtype && ob->data) {
286                         return true;
287                 }
288                 base= base->next;
289         }
290         return false;
291 }