Collada: commented out code was previously left over with an unresolved conflict...
[blender.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 #include "collada_utils.h"
31
32 #include "BLI_linklist.h"
33
34 UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP)
35 {
36         axis_angle_to_mat4_single(x_up_mat4, 'Y', -0.5 * M_PI);
37         axis_angle_to_mat4_single(y_up_mat4, 'X', 0.5 * M_PI);
38
39         unit_m4(z_up_mat4);
40         unit_m4(scale_mat4);
41 }
42
43 void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset)
44 {
45         unit = asset->getUnit();
46         up_axis = asset->getUpAxisType();
47 }
48
49 UnitConverter::UnitSystem UnitConverter::isMetricSystem()
50 {
51         switch (unit.getLinearUnitUnit()) {
52                 case COLLADAFW::FileInfo::Unit::MILLIMETER:
53                 case COLLADAFW::FileInfo::Unit::CENTIMETER:
54                 case COLLADAFW::FileInfo::Unit::DECIMETER:
55                 case COLLADAFW::FileInfo::Unit::METER:
56                 case COLLADAFW::FileInfo::Unit::KILOMETER:
57                         return UnitConverter::Metric;
58                 case COLLADAFW::FileInfo::Unit::INCH:
59                 case COLLADAFW::FileInfo::Unit::FOOT:
60                 case COLLADAFW::FileInfo::Unit::YARD:
61                         return UnitConverter::Imperial;
62                 default:
63                         return UnitConverter::None;
64         }
65 }
66
67 float UnitConverter::getLinearMeter()
68 {
69         return (float)unit.getLinearUnitMeter();
70 }
71
72 void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
73 {
74         v[0] = vec.x;
75         v[1] = vec.y;
76         v[2] = vec.z;
77 }
78
79 // TODO need also for angle conversion, time conversion...
80
81 void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in)
82 {
83         // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
84         // so here, to make a blender matrix, we swap columns and rows
85         for (int i = 0; i < 4; i++) {
86                 for (int j = 0; j < 4; j++) {
87                         out[i][j] = in[j][i];
88                 }
89         }
90 }
91
92 void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
93 {
94         transpose_m4_m4(out, in);
95 }
96
97 void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
98 {
99         float mat[4][4];
100
101         mat4_to_dae(mat, in);
102
103         for (int i = 0; i < 4; i++)
104                 for (int j = 0; j < 4; j++)
105                         out[i][j] = mat[i][j];
106 }
107
108 float(&UnitConverter::get_rotation())[4][4]
109 {
110         switch (up_axis) {
111                 case COLLADAFW::FileInfo::X_UP:
112                         return x_up_mat4;
113                         break;
114                 case COLLADAFW::FileInfo::Y_UP:
115                         return y_up_mat4;
116                         break;
117                 default:
118                         return z_up_mat4;
119                         break;
120         }
121 }
122
123
124 float(&UnitConverter::get_scale())[4][4]
125 {
126         return scale_mat4;
127 }
128
129 void UnitConverter::calculate_scale(Scene &sce)
130 {
131         PointerRNA scene_ptr, unit_settings;
132         PropertyRNA *system_ptr, *scale_ptr;
133         RNA_id_pointer_create(&sce.id, &scene_ptr);
134
135         unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
136         system_ptr    = RNA_struct_find_property(&unit_settings, "system");
137         scale_ptr     = RNA_struct_find_property(&unit_settings, "scale_length");
138
139         int   type    = RNA_property_enum_get(&unit_settings, system_ptr);
140
141         float bl_scale;
142
143         switch (type) {
144                 case USER_UNIT_NONE:
145                         bl_scale = 1.0; // map 1 Blender unit to 1 Meter
146                         break;
147
148                 case USER_UNIT_METRIC:
149                         bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
150                         break;
151
152                 default :
153                         bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
154                         // it looks like the conversion to Imperial is done implicitly.
155                         // So nothing to do here.
156                         break;
157         }
158
159         float rescale[3];
160         rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale;
161
162         size_to_mat4(scale_mat4, rescale);
163 }
164
165 /**
166  * Translation map.
167  * Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be
168  * included. Look at the IDREF XSD declaration for more.
169  * Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars,
170  * like special chars (e.g. micro sign), umlauts and so on.
171  * The COLLADA spec also allows additional chars for member access ('.'), these
172  * must obviously be removed too, otherwise they would be heavily misinterpreted.
173  */
174 const unsigned char translate_start_name_map[256] = {
175
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, 95, 95,
180         95, 95, 95, 95, 95, 95, 95, 95,
181         95, 95, 95, 95, 95, 95, 95, 95,
182         95, 95, 95, 95, 95, 95, 95, 95,
183         95, 95, 95, 95, 95, 95, 95, 95,
184         95, 65, 66, 67, 68, 69, 70, 71,
185         72, 73, 74, 75, 76, 77, 78, 79,
186         80, 81, 82, 83, 84, 85, 86, 87,
187         88, 89, 90, 95, 95, 95, 95, 95,
188         95, 97, 98, 99, 100, 101, 102, 103,
189         104, 105, 106, 107, 108, 109, 110, 111,
190         112, 113, 114, 115, 116, 117, 118, 119,
191         120, 121, 122, 95, 95, 95, 95, 95,
192
193         128, 129, 130, 131, 132, 133, 134, 135,
194         136, 137, 138, 139, 140, 141, 142, 143,
195         144, 145, 146, 147, 148, 149, 150, 151,
196         152, 153, 154, 155, 156, 157, 158, 159,
197         160, 161, 162, 163, 164, 165, 166, 167,
198         168, 169, 170, 171, 172, 173, 174, 175,
199         176, 177, 178, 179, 180, 181, 182, 183,
200         184, 185, 186, 187, 188, 189, 190, 191,
201         192, 193, 194, 195, 196, 197, 198, 199,
202         200, 201, 202, 203, 204, 205, 206, 207,
203         208, 209, 210, 211, 212, 213, 214, 215,
204         216, 217, 218, 219, 220, 221, 222, 223,
205         224, 225, 226, 227, 228, 229, 230, 231,
206         232, 233, 234, 235, 236, 237, 238, 239,
207         240, 241, 242, 243, 244, 245, 246, 247,
208         248, 249, 250, 251, 252, 253, 254, 255
209 };
210
211 const unsigned char translate_name_map[256] = {
212
213         95, 95, 95, 95, 95, 95, 95, 95,
214         95, 95, 95, 95, 95, 95, 95, 95,
215         95, 95, 95, 95, 95, 95, 95, 95,
216         95, 95, 95, 95, 95, 95, 95, 95,
217         95, 95, 95, 95, 95, 95, 95, 95,
218         95, 95, 95, 95, 95, 45, 95, 95,
219         48, 49, 50, 51, 52, 53, 54, 55,
220         56, 57, 95, 95, 95, 95, 95, 95,
221         95, 65, 66, 67, 68, 69, 70, 71,
222         72, 73, 74, 75, 76, 77, 78, 79,
223         80, 81, 82, 83, 84, 85, 86, 87,
224         88, 89, 90, 95, 95, 95, 95, 95,
225         95, 97, 98, 99, 100, 101, 102, 103,
226         104, 105, 106, 107, 108, 109, 110, 111,
227         112, 113, 114, 115, 116, 117, 118, 119,
228         120, 121, 122, 95, 95, 95, 95, 95,
229
230         128, 129, 130, 131, 132, 133, 134, 135,
231         136, 137, 138, 139, 140, 141, 142, 143,
232         144, 145, 146, 147, 148, 149, 150, 151,
233         152, 153, 154, 155, 156, 157, 158, 159,
234         160, 161, 162, 163, 164, 165, 166, 167,
235         168, 169, 170, 171, 172, 173, 174, 175,
236         176, 177, 178, 179, 180, 181, 182, 183,
237         184, 185, 186, 187, 188, 189, 190, 191,
238         192, 193, 194, 195, 196, 197, 198, 199,
239         200, 201, 202, 203, 204, 205, 206, 207,
240         208, 209, 210, 211, 212, 213, 214, 215,
241         216, 217, 218, 219, 220, 221, 222, 223,
242         224, 225, 226, 227, 228, 229, 230, 231,
243         232, 233, 234, 235, 236, 237, 238, 239,
244         240, 241, 242, 243, 244, 245, 246, 247,
245         248, 249, 250, 251, 252, 253, 254, 255
246 };
247
248 typedef std::map< std::string, std::vector<std::string> > map_string_list;
249 map_string_list global_id_map;
250
251 void clear_global_id_map()
252 {
253         global_id_map.clear();
254 }
255
256 /** Look at documentation of translate_map */
257 std::string translate_id(const char *idString)
258 {
259         std::string id = std::string(idString);
260         return translate_id(id);
261 }
262
263 std::string translate_id(const std::string &id)
264 {
265         if (id.size() == 0) {
266                 return id;
267         }
268
269         std::string id_translated = id;
270         id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
271         for (unsigned int i = 1; i < id_translated.size(); i++) {
272                 id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
273         }
274         // It's so much workload now, the if () should speed up things.
275         if (id_translated != id) {
276                 // Search duplicates
277                 map_string_list::iterator iter = global_id_map.find(id_translated);
278                 if (iter != global_id_map.end()) {
279                         unsigned int i = 0;
280                         bool found = false;
281                         for (i = 0; i < iter->second.size(); i++) {
282                                 if (id == iter->second[i]) {
283                                         found = true;
284                                         break;
285                                 }
286                         }
287                         bool convert = false;
288                         if (found) {
289                                 if (i > 0) {
290                                         convert = true;
291                                 }
292                         }
293                         else {
294                                 convert = true;
295                                 global_id_map[id_translated].push_back(id);
296                         }
297                         if (convert) {
298                                 std::stringstream out;
299                                 out << ++i;
300                                 id_translated += out.str();
301                         }
302                 }
303                 else { global_id_map[id_translated].push_back(id); }
304         }
305         return id_translated;
306 }
307
308 std::string id_name(void *id)
309 {
310         return ((ID *)id)->name + 2;
311 }
312
313 std::string get_geometry_id(Object *ob)
314 {
315         return translate_id(id_name(ob->data)) + "-mesh";
316 }
317
318 std::string get_geometry_id(Object *ob, bool use_instantiation)
319 {
320         std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);
321
322         return translate_id(geom_name) + "-mesh";
323 }
324
325 std::string get_light_id(Object *ob)
326 {
327         return translate_id(id_name(ob)) + "-light";
328 }
329
330 std::string get_joint_id(Bone *bone, Object *ob_arm)
331 {
332         return translate_id(id_name(ob_arm) + "_" + bone->name);
333 }
334
335 std::string get_joint_sid(Bone *bone, Object *ob_arm)
336 {
337         return translate_id(bone->name);
338 }
339
340 std::string get_camera_id(Object *ob)
341 {
342         return translate_id(id_name(ob)) + "-camera";
343 }
344
345 std::string get_material_id(Material *mat)
346 {
347         return translate_id(id_name(mat)) + "-material";
348 }
349
350 std::string get_morph_id(Object *ob)
351 {
352         return translate_id(id_name(ob)) + "-morph";
353 }
354