2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 /** \file blender/collada/collada_internal.cpp
22 /* COLLADABU_ASSERT, may be able to remove later */
23 #include "COLLADABUPlatform.h"
24 #include "collada_utils.h"
26 #include "BLI_linklist.h"
27 #include "ED_armature.h"
29 UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP)
31 axis_angle_to_mat4_single(x_up_mat4, 'Y', -0.5 * M_PI);
32 axis_angle_to_mat4_single(y_up_mat4, 'X', 0.5 * M_PI);
38 void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset)
40 unit = asset->getUnit();
41 up_axis = asset->getUpAxisType();
44 UnitConverter::UnitSystem UnitConverter::isMetricSystem()
46 switch (unit.getLinearUnitUnit()) {
47 case COLLADAFW::FileInfo::Unit::MILLIMETER:
48 case COLLADAFW::FileInfo::Unit::CENTIMETER:
49 case COLLADAFW::FileInfo::Unit::DECIMETER:
50 case COLLADAFW::FileInfo::Unit::METER:
51 case COLLADAFW::FileInfo::Unit::KILOMETER:
52 return UnitConverter::Metric;
53 case COLLADAFW::FileInfo::Unit::INCH:
54 case COLLADAFW::FileInfo::Unit::FOOT:
55 case COLLADAFW::FileInfo::Unit::YARD:
56 return UnitConverter::Imperial;
58 return UnitConverter::None;
62 float UnitConverter::getLinearMeter()
64 return (float)unit.getLinearUnitMeter();
67 void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
74 // TODO need also for angle conversion, time conversion...
76 void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in)
78 // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
79 // so here, to make a blender matrix, we swap columns and rows
80 for (int i = 0; i < 4; i++) {
81 for (int j = 0; j < 4; j++) {
87 void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
89 transpose_m4_m4(out, in);
92 void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
98 for (int i = 0; i < 4; i++)
99 for (int j = 0; j < 4; j++)
100 out[i][j] = mat[i][j];
103 float(&UnitConverter::get_rotation())[4][4]
106 case COLLADAFW::FileInfo::X_UP:
109 case COLLADAFW::FileInfo::Y_UP:
119 float(&UnitConverter::get_scale())[4][4]
124 void UnitConverter::calculate_scale(Scene &sce)
126 PointerRNA scene_ptr, unit_settings;
127 PropertyRNA *system_ptr, *scale_ptr;
128 RNA_id_pointer_create(&sce.id, &scene_ptr);
130 unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
131 system_ptr = RNA_struct_find_property(&unit_settings, "system");
132 scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
134 int type = RNA_property_enum_get(&unit_settings, system_ptr);
140 bl_scale = 1.0; // map 1 Blender unit to 1 Meter
143 case USER_UNIT_METRIC:
144 bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
148 bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
149 // it looks like the conversion to Imperial is done implicitly.
150 // So nothing to do here.
155 rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale;
157 size_to_mat4(scale_mat4, rescale);
162 * Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be
163 * included. Look at the IDREF XSD declaration for more.
164 * Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars,
165 * like special chars (e.g. micro sign), umlauts and so on.
166 * The COLLADA spec also allows additional chars for member access ('.'), these
167 * must obviously be removed too, otherwise they would be heavily misinterpreted.
169 const unsigned char translate_start_name_map[256] = {
171 95, 95, 95, 95, 95, 95, 95, 95,
172 95, 95, 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, 65, 66, 67, 68, 69, 70, 71,
180 72, 73, 74, 75, 76, 77, 78, 79,
181 80, 81, 82, 83, 84, 85, 86, 87,
182 88, 89, 90, 95, 95, 95, 95, 95,
183 95, 97, 98, 99, 100, 101, 102, 103,
184 104, 105, 106, 107, 108, 109, 110, 111,
185 112, 113, 114, 115, 116, 117, 118, 119,
186 120, 121, 122, 95, 95, 95, 95, 95,
188 128, 129, 130, 131, 132, 133, 134, 135,
189 136, 137, 138, 139, 140, 141, 142, 143,
190 144, 145, 146, 147, 148, 149, 150, 151,
191 152, 153, 154, 155, 156, 157, 158, 159,
192 160, 161, 162, 163, 164, 165, 166, 167,
193 168, 169, 170, 171, 172, 173, 174, 175,
194 176, 177, 178, 179, 180, 181, 182, 183,
195 184, 185, 186, 187, 188, 189, 190, 191,
196 192, 193, 194, 195, 196, 197, 198, 199,
197 200, 201, 202, 203, 204, 205, 206, 207,
198 208, 209, 210, 211, 212, 213, 214, 215,
199 216, 217, 218, 219, 220, 221, 222, 223,
200 224, 225, 226, 227, 228, 229, 230, 231,
201 232, 233, 234, 235, 236, 237, 238, 239,
202 240, 241, 242, 243, 244, 245, 246, 247,
203 248, 249, 250, 251, 252, 253, 254, 255,
206 const unsigned char translate_name_map[256] = {
208 95, 95, 95, 95, 95, 95, 95, 95,
209 95, 95, 95, 95, 95, 95, 95, 95,
210 95, 95, 95, 95, 95, 95, 95, 95,
211 95, 95, 95, 95, 95, 95, 95, 95,
212 95, 95, 95, 95, 95, 95, 95, 95,
213 95, 95, 95, 95, 95, 45, 95, 95,
214 48, 49, 50, 51, 52, 53, 54, 55,
215 56, 57, 95, 95, 95, 95, 95, 95,
216 95, 65, 66, 67, 68, 69, 70, 71,
217 72, 73, 74, 75, 76, 77, 78, 79,
218 80, 81, 82, 83, 84, 85, 86, 87,
219 88, 89, 90, 95, 95, 95, 95, 95,
220 95, 97, 98, 99, 100, 101, 102, 103,
221 104, 105, 106, 107, 108, 109, 110, 111,
222 112, 113, 114, 115, 116, 117, 118, 119,
223 120, 121, 122, 95, 95, 95, 95, 95,
225 128, 129, 130, 131, 132, 133, 134, 135,
226 136, 137, 138, 139, 140, 141, 142, 143,
227 144, 145, 146, 147, 148, 149, 150, 151,
228 152, 153, 154, 155, 156, 157, 158, 159,
229 160, 161, 162, 163, 164, 165, 166, 167,
230 168, 169, 170, 171, 172, 173, 174, 175,
231 176, 177, 178, 179, 180, 181, 182, 183,
232 184, 185, 186, 187, 188, 189, 190, 191,
233 192, 193, 194, 195, 196, 197, 198, 199,
234 200, 201, 202, 203, 204, 205, 206, 207,
235 208, 209, 210, 211, 212, 213, 214, 215,
236 216, 217, 218, 219, 220, 221, 222, 223,
237 224, 225, 226, 227, 228, 229, 230, 231,
238 232, 233, 234, 235, 236, 237, 238, 239,
239 240, 241, 242, 243, 244, 245, 246, 247,
240 248, 249, 250, 251, 252, 253, 254, 255,
243 typedef std::map< std::string, std::vector<std::string> > map_string_list;
244 map_string_list global_id_map;
246 void clear_global_id_map()
248 global_id_map.clear();
251 /** Look at documentation of translate_map */
252 std::string translate_id(const char *idString)
254 std::string id = std::string(idString);
255 return translate_id(id);
258 std::string translate_id(const std::string &id)
260 if (id.size() == 0) {
264 std::string id_translated = id;
265 id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
266 for (unsigned int i = 1; i < id_translated.size(); i++) {
267 id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
269 // It's so much workload now, the if () should speed up things.
270 if (id_translated != id) {
272 map_string_list::iterator iter = global_id_map.find(id_translated);
273 if (iter != global_id_map.end()) {
276 for (i = 0; i < iter->second.size(); i++) {
277 if (id == iter->second[i]) {
282 bool convert = false;
290 global_id_map[id_translated].push_back(id);
293 std::stringstream out;
295 id_translated += out.str();
298 else { global_id_map[id_translated].push_back(id); }
300 return id_translated;
303 std::string id_name(void *id)
305 return ((ID *)id)->name + 2;
308 std::string encode_xml(std::string xml)
310 const std::map<char, std::string> escape {
318 std::map<char, std::string>::const_iterator it;
319 std::string encoded_xml = "";
321 for (unsigned int i = 0; i < xml.size(); i++) {
325 if (it == escape.end()) {
329 encoded_xml += it->second;
335 std::string get_geometry_id(Object *ob)
337 return translate_id(id_name(ob->data)) + "-mesh";
340 std::string get_geometry_id(Object *ob, bool use_instantiation)
342 std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);
344 return translate_id(geom_name) + "-mesh";
347 std::string get_light_id(Object *ob)
349 return translate_id(id_name(ob)) + "-light";
352 std::string get_joint_sid(Bone *bone)
354 return translate_id(bone->name);
356 std::string get_joint_sid(EditBone *bone)
358 return translate_id(bone->name);
361 std::string get_camera_id(Object *ob)
363 return translate_id(id_name(ob)) + "-camera";
366 std::string get_effect_id(Material *mat)
368 return translate_id(id_name(mat)) + "-effect";
371 std::string get_material_id(Material *mat)
373 return translate_id(id_name(mat)) + "-material";
376 std::string get_morph_id(Object *ob)
378 return translate_id(id_name(ob)) + "-morph";