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