Blender  V2.59
collada_internal.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: collada_internal.cpp 38079 2011-07-04 08:59:28Z jesterking $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov.
00021  *
00022  * ***** END GPL LICENSE BLOCK *****
00023  */
00024 
00030 /* COLLADABU_ASSERT, may be able to remove later */
00031 #include "COLLADABUPlatform.h"
00032 
00033 #include "collada_internal.h"
00034 
00035 UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {}
00036 
00037 void UnitConverter::read_asset(const COLLADAFW::FileInfo* asset)
00038 {
00039         unit = asset->getUnit();
00040         up_axis = asset->getUpAxisType();
00041 }
00042 
00043 UnitConverter::UnitSystem UnitConverter::isMetricSystem()
00044 {
00045         switch(unit.getLinearUnitUnit()) {
00046                 case COLLADAFW::FileInfo::Unit::MILLIMETER:
00047                 case COLLADAFW::FileInfo::Unit::CENTIMETER:
00048                 case COLLADAFW::FileInfo::Unit::DECIMETER:
00049                 case COLLADAFW::FileInfo::Unit::METER:
00050                 case COLLADAFW::FileInfo::Unit::KILOMETER:
00051                         return UnitConverter::Metric;
00052                 case COLLADAFW::FileInfo::Unit::INCH:
00053                 case COLLADAFW::FileInfo::Unit::FOOT:
00054                 case COLLADAFW::FileInfo::Unit::YARD:
00055                         return UnitConverter::Imperial;
00056                 default:
00057                         return UnitConverter::None;
00058         }
00059 }
00060 
00061 float UnitConverter::getLinearMeter()
00062 {
00063         return (float)unit.getLinearUnitMeter();
00064 }
00065 
00066 void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
00067 {
00068         v[0] = vec.x;
00069         v[1] = vec.y;
00070         v[2] = vec.z;
00071 }
00072 
00073 // TODO need also for angle conversion, time conversion...
00074 
00075 void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in)
00076 {
00077         // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
00078         // so here, to make a blender matrix, we swap columns and rows
00079         for (int i = 0; i < 4; i++) {
00080                 for (int j = 0; j < 4; j++) {
00081                         out[i][j] = in[j][i];
00082                 }
00083         }
00084 }
00085 
00086 void UnitConverter::mat4_to_dae(float out[][4], float in[][4])
00087 {
00088         copy_m4_m4(out, in);
00089         transpose_m4(out);
00090 }
00091 
00092 void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4])
00093 {
00094         float mat[4][4];
00095 
00096         mat4_to_dae(mat, in);
00097 
00098         for (int i = 0; i < 4; i++)
00099                 for (int j = 0; j < 4; j++)
00100                         out[i][j] = mat[i][j];
00101 }
00102 
00103 void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size)
00104 {
00105         mat4_to_size(size, mat);
00106         if (eul) {
00107                 mat4_to_eul(eul, mat);
00108         }
00109         if (quat) {
00110                 mat4_to_quat(quat, mat);
00111         }
00112         copy_v3_v3(loc, mat[3]);
00113 }
00114 
00124 const unsigned char translate_start_name_map[256] = {
00125 95,  95,  95,  95,  95,  95,  95,  95,  95,
00126 95,  95,  95,  95,  95,  95,  95,  95,
00127 95,  95,  95,  95,  95,  95,  95,  95,
00128 95,  95,  95,  95,  95,  95,  95,  95,
00129 95,  95,  95,  95,  95,  95,  95,  95,
00130 95,  95,  95,  95,  95,  95,  95,  95,
00131 95,  95,  95,  95,  95,  95,  95,  95,
00132 95,  95,  95,  95,  95,  95,  95,  95,
00133 65,  66,  67,  68,  69,  70,  71,  72,
00134 73,  74,  75,  76,  77,  78,  79,  80,
00135 81,  82,  83,  84,  85,  86,  87,  88,
00136 89,  90,  95,  95,  95,  95,  95,  95,
00137 97,  98,  99,  100,  101,  102,  103,  104,
00138 105,  106,  107,  108,  109,  110,  111,  112,
00139 113,  114,  115,  116,  117,  118,  119,  120,
00140 121,  122,  95,  95,  95,  95,  95,  95,
00141 95,  95,  95,  95,  95,  95,  95,  95,
00142 95,  95,  95,  95,  95,  95,  95,  95,
00143 95,  95,  95,  95,  95,  95,  95,  95,
00144 95,  95,  95,  95,  95,  95,  95,  95,
00145 95,  95,  95,  95,  95,  95,  95,  95,
00146 95,  95,  95,  95,  95,  95,  95,  95,
00147 95,  95,  95,  95,  95,  95,  95,  95,
00148 95,  95,  95,  95,  95,  95,  95,  192,
00149 193,  194,  195,  196,  197,  198,  199,  200,
00150 201,  202,  203,  204,  205,  206,  207,  208,
00151 209,  210,  211,  212,  213,  214,  95,  216,
00152 217,  218,  219,  220,  221,  222,  223,  224,
00153 225,  226,  227,  228,  229,  230,  231,  232,
00154 233,  234,  235,  236,  237,  238,  239,  240,
00155 241,  242,  243,  244,  245,  246,  95,  248,
00156 249,  250,  251,  252,  253,  254,  255};
00157 
00158 const unsigned char translate_name_map[256] = {
00159 95,  95,  95,  95,  95,  95,  95,  95,  95,
00160 95,  95,  95,  95,  95,  95,  95,  95,
00161 95,  95,  95,  95,  95,  95,  95,  95,
00162 95,  95,  95,  95,  95,  95,  95,  95,
00163 95,  95,  95,  95,  95,  95,  95,  95,
00164 95,  95,  95,  95,  45,  95,  95,  48,
00165 49,  50,  51,  52,  53,  54,  55,  56,
00166 57,  95,  95,  95,  95,  95,  95,  95,
00167 65,  66,  67,  68,  69,  70,  71,  72,
00168 73,  74,  75,  76,  77,  78,  79,  80,
00169 81,  82,  83,  84,  85,  86,  87,  88,
00170 89,  90,  95,  95,  95,  95,  95,  95,
00171 97,  98,  99,  100,  101,  102,  103,  104,
00172 105,  106,  107,  108,  109,  110,  111,  112,
00173 113,  114,  115,  116,  117,  118,  119,  120,
00174 121,  122,  95,  95,  95,  95,  95,  95,
00175 95,  95,  95,  95,  95,  95,  95,  95,
00176 95,  95,  95,  95,  95,  95,  95,  95,
00177 95,  95,  95,  95,  95,  95,  95,  95,
00178 95,  95,  95,  95,  95,  95,  95,  95,
00179 95,  95,  95,  95,  95,  95,  95,  95,
00180 95,  95,  95,  95,  95,  95,  95,  95,
00181 95,  95,  95,  95,  95,  95,  183,  95,
00182 95,  95,  95,  95,  95,  95,  95,  192,
00183 193,  194,  195,  196,  197,  198,  199,  200,
00184 201,  202,  203,  204,  205,  206,  207,  208,
00185 209,  210,  211,  212,  213,  214,  95,  216,
00186 217,  218,  219,  220,  221,  222,  223,  224,
00187 225,  226,  227,  228,  229,  230,  231,  232,
00188 233,  234,  235,  236,  237,  238,  239,  240,
00189 241,  242,  243,  244,  245,  246,  95,  248,
00190 249,  250,  251,  252,  253,  254,  255};
00191 
00192 typedef std::map< std::string, std::vector<std::string> > map_string_list;
00193 map_string_list global_id_map;
00194 
00195 void clear_global_id_map()
00196 {
00197         global_id_map.clear();
00198 }
00199 
00201 std::string translate_id(const std::string &id)
00202 {
00203         if (id.size() == 0)
00204         { return id; }
00205         std::string id_translated = id;
00206         id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
00207         for (unsigned int i=1; i < id_translated.size(); i++)
00208         {
00209                 id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
00210         }
00211         // It's so much workload now, the if() should speed up things.
00212         if (id_translated != id)
00213         {
00214                 // Search duplicates
00215                 map_string_list::iterator iter = global_id_map.find(id_translated);
00216                 if (iter != global_id_map.end())
00217                 {
00218                         unsigned int i = 0;
00219                         bool found = false;
00220                         for (i=0; i < iter->second.size(); i++)
00221                         {
00222                                 if (id == iter->second[i])
00223                                 { 
00224                                         found = true;
00225                                         break;
00226                                 }
00227                         }
00228                         bool convert = false;
00229                         if (found)
00230                         {
00231                           if (i > 0)
00232                           { convert = true; }
00233                         }
00234                         else
00235                         { 
00236                                 convert = true;
00237                                 global_id_map[id_translated].push_back(id);
00238                         }
00239                         if (convert)
00240                         {
00241                                 std::stringstream out;
00242                                 out << ++i;
00243                                 id_translated += out.str();
00244                         }
00245                 }
00246                 else { global_id_map[id_translated].push_back(id); }
00247         }
00248         return id_translated;
00249 }
00250 
00251 std::string id_name(void *id)
00252 {
00253         return ((ID*)id)->name + 2;
00254 }
00255 
00256 std::string get_geometry_id(Object *ob)
00257 {
00258         return translate_id(id_name(ob->data)) + "-mesh";
00259 }
00260 
00261 std::string get_light_id(Object *ob)
00262 {
00263         return translate_id(id_name(ob)) + "-light";
00264 }
00265 
00266 std::string get_joint_id(Bone *bone, Object *ob_arm)
00267 {
00268         return translate_id(/*id_name(ob_arm) + "_" +*/ bone->name);
00269 }
00270 
00271 std::string get_camera_id(Object *ob)
00272 {
00273         return translate_id(id_name(ob)) + "-camera";
00274 }
00275 
00276 std::string get_material_id(Material *mat)
00277 {
00278         return translate_id(id_name(mat)) + "-material";
00279 }
00280 
00281 bool has_object_type(Scene *sce, short obtype)
00282 {
00283         Base *base= (Base*) sce->base.first;
00284         while(base) {
00285                 Object *ob = base->object;
00286                         
00287                 if (ob->type == obtype && ob->data) {
00288                         return true;
00289                 }
00290                 base= base->next;
00291         }
00292         return false;
00293 }