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 m_vec /= norm;
00158 m_w /= norm;
00159
00160 m_valid = true;
00161 m_vec.setValid();
00162 }
00163
00164 inline AtlasOutType Quaternion::toAtlas() const
00165 {
00166 _AtlasListType a(4);
00167
00168 for(int i = 0; i < 3; ++i)
00169 a[i] = m_vec[i];
00170 a[3] = m_w;
00171
00172 return a;
00173 }
00174
00175 template<const int dim>
00176 inline void Point<dim>::fromAtlas(const AtlasInType& a)
00177 {
00178 _ArrayFromAtlas(m_elem, dim, a);
00179 m_valid = true;
00180 }
00181
00182 template<const int dim>
00183 inline AtlasOutType Point<dim>::toAtlas() const
00184 {
00185 return _ArrayToAtlas(m_elem, dim);
00186 }
00187
00188 template<const int dim>
00189 void AxisBox<dim>::fromAtlas(const AtlasInType& a)
00190 {
00191 if(!a.IsList())
00192 throw _AtlasBadParse();
00193
00194 const _AtlasListType& list(a.AsList());
00195
00196 switch(list.size()) {
00197 case dim:
00198 m_low.setToOrigin();
00199 m_high.fromAtlas(a);
00200 break;
00201 case (2 * dim):
00202 for(int i = 0; i < dim; ++i) {
00203 m_low[i] = _asNum(list[i]);
00204 m_high[i] = _asNum(list[i+dim]);
00205 }
00206 m_low.setValid();
00207 m_high.setValid();
00208 break;
00209 default:
00210 throw _AtlasBadParse();
00211 }
00212
00213 for(int i = 0; i < dim; ++i) {
00214 if(m_low[i] > m_high[i]) {
00215 CoordType tmp = m_low[i];
00216 m_low[i] = m_high[i];
00217 m_high[i] = tmp;
00218 }
00219 }
00220 }
00221
00222 template<const int dim>
00223 AtlasOutType AxisBox<dim>::toAtlas() const
00224 {
00225 int i;
00226
00227 for(i = 0; i < dim; ++i)
00228 if(m_low[i] != 0)
00229 break;
00230
00231 if(i == dim)
00232 return m_high.toAtlas();
00233
00234
00235
00236 _AtlasListType a(2*dim);
00237 for(i = 0; i < dim; ++i) {
00238 a[i] = m_low[i];
00239 a[dim+i] = m_high[i];
00240 }
00241
00242 return a;
00243 }
00244
00245 }
00246
00247 #endif