00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef WFMATH_ATLAS_CONV_H
00032 #define WFMATH_ATLAS_CONV_H
00033
00034 #include <stdexcept>
00035 #include <Atlas/Message/Object.h>
00036 #include <wfmath/const.h>
00037 #include <wfmath/point.h>
00038 #include <wfmath/vector.h>
00039 #include <wfmath/quaternion.h>
00040 #include <wfmath/axisbox.h>
00041
00042 namespace WFMath {
00043
00044
00045 struct _AtlasBadParse : public Atlas::Message::WrongTypeException,
00046 virtual public std::exception
00047 {
00048 virtual ~_AtlasBadParse() throw() {}
00049 };
00050
00051 inline Atlas::Message::Object _ArrayToAtlas(const CoordType* array, int len)
00052 {
00053 Atlas::Message::Object::ListType a;
00054
00055 for(const CoordType* i = array; i < array + len; ++i)
00056 a.push_back(*i);
00057
00058 return a;
00059 }
00060
00061 inline void _ArrayFromAtlas(CoordType* array, int len, const Atlas::Message::Object& a)
00062 {
00063 if(!a.IsList())
00064 throw _AtlasBadParse();
00065
00066 Atlas::Message::Object::ListType list(a.AsList());
00067
00068 if(list.size() != (unsigned int) len)
00069 throw _AtlasBadParse();
00070
00071 for(int i = 0; i < len; ++i)
00072 array[i] = list[i].AsFloat();
00073 }
00074
00075 template<const int dim>
00076 void Vector<dim>::fromAtlas(const Atlas::Message::Object& a)
00077 {
00078 _ArrayFromAtlas(m_elem, dim, a);
00079 m_valid = true;
00080 }
00081
00082 template<const int dim>
00083 Atlas::Message::Object Vector<dim>::toAtlas() const
00084 {
00085 return _ArrayToAtlas(m_elem, dim);
00086 }
00087
00088 inline void Quaternion::fromAtlas(const Atlas::Message::Object& a)
00089 {
00090 if(!a.IsList())
00091 throw _AtlasBadParse();
00092
00093
00094 Atlas::Message::Object::ListType list(a.AsList());
00095
00096 if(list.size() != 4)
00097 throw _AtlasBadParse();
00098
00099
00100 for(int i = 0; i < 3; ++i)
00101 m_vec[i] = list[i].AsFloat();
00102
00103 m_w = list[3].AsFloat();
00104
00105 CoordType norm = sqrt(m_w * m_w + m_vec.sqrMag());
00106
00107 m_vec /= norm;
00108 m_w /= norm;
00109
00110 m_valid = true;
00111 }
00112
00113 inline Atlas::Message::Object Quaternion::toAtlas() const
00114 {
00115 Atlas::Message::Object::ListType a;
00116
00117 for(int i = 0; i < 3; ++i)
00118 a.push_back(m_vec[i]);
00119 a.push_back(m_w);
00120
00121 return a;
00122 }
00123
00124 template<const int dim>
00125 void Point<dim>::fromAtlas(const Atlas::Message::Object& a)
00126 {
00127 _ArrayFromAtlas(m_elem, dim, a);
00128 m_valid = true;
00129 }
00130
00131 template<const int dim>
00132 Atlas::Message::Object Point<dim>::toAtlas() const
00133 {
00134 return _ArrayToAtlas(m_elem, dim);
00135 }
00136
00137 template<const int dim>
00138 void AxisBox<dim>::fromAtlas(const Atlas::Message::Object& a)
00139 {
00140 if(!a.IsList())
00141 throw _AtlasBadParse();
00142
00143 Atlas::Message::Object::ListType list(a.AsList());
00144
00145 switch(list.size()) {
00146 case 1:
00147 m_low.setToOrigin();
00148 m_high.fromAtlas(list[0]);
00149 break;
00150 case 2:
00151 m_low.fromAtlas(list[0]);
00152 m_high.fromAtlas(list[1]);
00153 break;
00154 case dim:
00155 m_low.setToOrigin();
00156 m_high.fromAtlas(a);
00157 break;
00158 case (2 * dim):
00159 for(int i = 0; i < dim; ++i) {
00160 m_low[i] = list[i].AsFloat();
00161 m_high[i] = list[i+dim].AsFloat();
00162 }
00163 m_low.setValid();
00164 m_high.setValid();
00165 break;
00166 default:
00167 throw _AtlasBadParse();
00168 }
00169
00170 for(int i = 0; i < dim; ++i) {
00171 if(m_low[i] > m_high[i]) {
00172 CoordType tmp = m_low[i];
00173 m_low[i] = m_high[i];
00174 m_high[i] = tmp;
00175 }
00176 }
00177 }
00178
00179 template<>
00180 inline void AxisBox<2>::fromAtlas(const Atlas::Message::Object& a)
00181 {
00182 if(!a.IsList())
00183 throw _AtlasBadParse();
00184
00185 Atlas::Message::Object::ListType list(a.AsList());
00186
00187 switch(list.size()) {
00188 case 1:
00189 m_low.setToOrigin();
00190 m_high.fromAtlas(list[0]);
00191 break;
00192 case 2:
00193 if(list[0].IsFloat()) {
00194 m_low.setToOrigin();
00195 m_high.fromAtlas(a);
00196 }
00197 else {
00198 m_low.fromAtlas(list[0]);
00199 m_high.fromAtlas(list[1]);
00200 }
00201 break;
00202 case 4:
00203 for(int i = 0; i < 2; ++i) {
00204 m_low[i] = list[i].AsFloat();
00205 m_high[i] = list[i+2].AsFloat();
00206 }
00207 m_low.setValid();
00208 m_high.setValid();
00209 break;
00210 default:
00211 throw _AtlasBadParse();
00212 }
00213
00214 for(int i = 0; i < 2; ++i) {
00215 if(m_low[i] > m_high[i]) {
00216 CoordType tmp = m_low[i];
00217 m_low[i] = m_high[i];
00218 m_high[i] = tmp;
00219 }
00220 }
00221 }
00222
00223 template<>
00224 inline void AxisBox<1>::fromAtlas(const Atlas::Message::Object& a)
00225 {
00226 if(!a.IsList())
00227 throw _AtlasBadParse();
00228
00229 Atlas::Message::Object::ListType list(a.AsList());
00230
00231 bool got_float = list[0].IsFloat();
00232
00233 switch(list.size()) {
00234 case 1:
00235 m_low.setToOrigin();
00236 m_high.fromAtlas(got_float ? a : list[0]);
00237 break;
00238 case 2:
00239 if(got_float) {
00240 m_low[0] = list[0].AsFloat();
00241 m_high[0] = list[1].AsFloat();
00242 m_low.setValid();
00243 m_high.setValid();
00244 }
00245 else {
00246 m_low.fromAtlas(list[0]);
00247 m_high.fromAtlas(list[1]);
00248 }
00249 break;
00250 default:
00251 throw _AtlasBadParse();
00252 }
00253
00254 if(m_low[0] > m_high[0]) {
00255 CoordType tmp = m_low[0];
00256 m_low[0] = m_high[0];
00257 m_high[0] = tmp;
00258 }
00259 }
00260
00261 template<const int dim>
00262 Atlas::Message::Object AxisBox<dim>::toAtlas() const
00263 {
00264 int i;
00265
00266 for(i = 0; i < dim; ++i)
00267 if(m_low[i] != 0)
00268 break;
00269
00270 if(i == dim)
00271 return m_high.toAtlas();
00272
00273
00274
00275 Atlas::Message::Object::ListType a;
00276 for(i = 0; i < dim; ++i)
00277 a.push_back(m_low[i]);
00278 for(i = 0; i < dim; ++i)
00279 a.push_back(m_high[i]);
00280
00281 return a;
00282 }
00283
00284 }
00285
00286 #endif // WFMATH_ATLAS_CONV_H