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