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 // WFMATH_ATLAS_CONV_H