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