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 <wfmath/const.h>
00036 #include <wfmath/point.h>
00037 #include <wfmath/vector.h>
00038 #include <wfmath/quaternion.h>
00039 #include <wfmath/axisbox.h>
00040
00041 namespace WFMath {
00042
00043 #ifdef ATLAS_MESSAGE_ELEMENT_H
00044
00045 typedef Atlas::Message::WrongTypeException _AtlasBadParse;
00046 typedef Atlas::Message::Element _AtlasMessageType;
00047 typedef Atlas::Message::FloatType _AtlasFloatType;
00048 typedef Atlas::Message::ListType _AtlasListType;
00049
00050 inline bool _isNum(const _AtlasMessageType& a) {return a.isNum();}
00051 inline _AtlasFloatType _asNum(const _AtlasMessageType& a) {return a.asNum();}
00052
00053 #elif defined(ATLAS_MESSAGE_OBJECT_H)
00054
00055 struct _AtlasBadParse : public Atlas::Message::WrongTypeException,
00056 virtual public std::exception
00057 {
00058 virtual ~_AtlasBadParse() throw() {}
00059 };
00060
00061 typedef Atlas::Message::Object _AtlasMessageType;
00062 typedef Atlas::Message::Object::FloatType _AtlasFloatType;
00063 typedef Atlas::Message::Object::ListType _AtlasListType;
00064
00065 inline bool _isNum(const _AtlasMessageType& a) {return a.IsNum();}
00066 inline _AtlasMessageType::FloatType _asNum(const _AtlasMessageType& a) {return a.AsNum();}
00067
00068 #else
00069 #error "You must include Atlas/Message/Element.h or Atlas/Message/Object.h before wfmath/atlasconv.h"
00070 #endif
00071
00072 class AtlasInType
00073 {
00074 public:
00075 AtlasInType(const _AtlasMessageType& val) : m_val(val) {}
00076
00077 template<class C> AtlasInType(C c) : m_obj(c), m_val(m_obj) {}
00078 operator const _AtlasMessageType&() const {return m_val;}
00079 #ifdef ATLAS_MESSAGE_ELEMENT_H
00080 bool IsList() const {return m_val.isList();}
00081 const _AtlasListType& AsList() const {return m_val.asList();}
00082 #else // ATLAS_MESSAGE_OBJECT_H
00083 bool IsList() const {return m_val.IsList();}
00084 const _AtlasListType& AsList() const {return m_val.AsList();}
00085 #endif
00086 private:
00087 _AtlasMessageType m_obj;
00088 const _AtlasMessageType& m_val;
00089 };
00090
00091 class AtlasOutType
00092 {
00093 public:
00094 AtlasOutType(const _AtlasListType& l) : m_val(l) {}
00095 operator _AtlasMessageType&() {return m_val;}
00096 operator const _AtlasMessageType&() const {return m_val;}
00097 private:
00098 _AtlasMessageType m_val;
00099 };
00100
00101 inline AtlasOutType _ArrayToAtlas(const CoordType* array, unsigned len)
00102 {
00103 _AtlasListType a(len);
00104
00105 for(unsigned i = 0; i < len; ++i)
00106 a[i] = array[i];
00107
00108 return a;
00109 }
00110
00111 inline void _ArrayFromAtlas(CoordType* array, unsigned len, const AtlasInType& a)
00112 {
00113 if(!a.IsList())
00114 throw _AtlasBadParse();
00115
00116 const _AtlasListType& list(a.AsList());
00117
00118 if(list.size() != (unsigned int) len)
00119 throw _AtlasBadParse();
00120
00121 for(unsigned i = 0; i < len; ++i)
00122 array[i] = _asNum(list[i]);
00123 }
00124
00125 template<const int dim>
00126 inline void Vector<dim>::fromAtlas(const AtlasInType& a)
00127 {
00128 _ArrayFromAtlas(m_elem, dim, a);
00129 m_valid = true;
00130 }
00131
00132 template<const int dim>
00133 inline AtlasOutType Vector<dim>::toAtlas() const
00134 {
00135 return _ArrayToAtlas(m_elem, dim);
00136 }
00137
00138 inline void Quaternion::fromAtlas(const AtlasInType& a)
00139 {
00140 if(!a.IsList())
00141 throw _AtlasBadParse();
00142
00143
00144 const _AtlasListType& list(a.AsList());
00145
00146 if(list.size() != 4)
00147 throw _AtlasBadParse();
00148
00149
00150 for(int i = 0; i < 3; ++i)
00151 m_vec[i] = _asNum(list[i]);
00152
00153 m_w = _asNum(list[3]);
00154
00155 CoordType norm = sqrt(m_w * m_w + m_vec.sqrMag());
00156
00157 if (norm <= WFMATH_EPSILON) {
00158 m_valid = false;
00159 m_vec.setValid(false);
00160 return;
00161 }
00162
00163 m_vec /= norm;
00164 m_w /= norm;
00165
00166 m_valid = true;
00167 m_vec.setValid();
00168 }
00169
00170 inline AtlasOutType Quaternion::toAtlas() const
00171 {
00172 _AtlasListType a(4);
00173
00174 for(int i = 0; i < 3; ++i)
00175 a[i] = m_vec[i];
00176 a[3] = m_w;
00177
00178 return a;
00179 }
00180
00181 template<const int dim>
00182 inline void Point<dim>::fromAtlas(const AtlasInType& a)
00183 {
00184 _ArrayFromAtlas(m_elem, dim, a);
00185 m_valid = true;
00186 }
00187
00188 template<const int dim>
00189 inline AtlasOutType Point<dim>::toAtlas() const
00190 {
00191 return _ArrayToAtlas(m_elem, dim);
00192 }
00193
00194 template<const int dim>
00195 void AxisBox<dim>::fromAtlas(const AtlasInType& a)
00196 {
00197 if(!a.IsList())
00198 throw _AtlasBadParse();
00199
00200 const _AtlasListType& list(a.AsList());
00201
00202 switch(list.size()) {
00203 case dim:
00204 m_low.setToOrigin();
00205 m_high.fromAtlas(a);
00206 break;
00207 case (2 * dim):
00208 for(int i = 0; i < dim; ++i) {
00209 m_low[i] = _asNum(list[i]);
00210 m_high[i] = _asNum(list[i+dim]);
00211 }
00212 m_low.setValid();
00213 m_high.setValid();
00214 break;
00215 default:
00216 throw _AtlasBadParse();
00217 }
00218
00219 for(int i = 0; i < dim; ++i) {
00220 if(m_low[i] > m_high[i]) {
00221 CoordType tmp = m_low[i];
00222 m_low[i] = m_high[i];
00223 m_high[i] = tmp;
00224 }
00225 }
00226 }
00227
00228 template<const int dim>
00229 AtlasOutType AxisBox<dim>::toAtlas() const
00230 {
00231 int i;
00232
00233 for(i = 0; i < dim; ++i)
00234 if(m_low[i] != 0)
00235 break;
00236
00237 if(i == dim)
00238 return m_high.toAtlas();
00239
00240
00241
00242 _AtlasListType a(2*dim);
00243 for(i = 0; i < dim; ++i) {
00244 a[i] = m_low[i];
00245 a[dim+i] = m_high[i];
00246 }
00247
00248 return a;
00249 }
00250
00251 }
00252
00253 #endif // WFMATH_ATLAS_CONV_H