Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

atlasconv.h

00001 // atlasconv.h (Functions to convert WFMath library object to/from an Atlas Message)
00002 //
00003 //  The WorldForge Project
00004 //  Copyright (C) 2001  The WorldForge Project
00005 //
00006 //  This program is free software; you can redistribute it and/or modify
00007 //  it under the terms of the GNU General Public License as published by
00008 //  the Free Software Foundation; either version 2 of the License, or
00009 //  (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 //
00020 //  For information about WorldForge and its authors, please contact
00021 //  the Worldforge Web Site at http://www.worldforge.org.
00022 
00023 // Author: Ron Steinke
00024 // Created: 2001-12-11
00025 
00026 // Since we don't want WFMath and Atlas to depend on each other,
00027 // we're putting all the atlas interface functions into this header.
00028 
00029 // WARNING! WARNING! Do not include this file in any other file in wfmath.
00030 
00031 #ifndef WFMATH_ATLAS_CONV_H
00032 #define WFMATH_ATLAS_CONV_H
00033 
00034 #include <stdexcept>
00035 #include <Atlas/Message/Object.h>
00036 #include <wfmath/const.h>
00037 #include <wfmath/point.h>
00038 #include <wfmath/vector.h>
00039 #include <wfmath/quaternion.h>
00040 #include <wfmath/axisbox.h>
00041 
00042 namespace WFMath {
00043 
00044 // Change this when we go to Atlas-0.5
00045 struct _AtlasBadParse : public Atlas::Message::WrongTypeException,
00046                         virtual public std::exception
00047 {
00048   virtual ~_AtlasBadParse() throw() {}
00049 };
00050 
00051 inline Atlas::Message::Object _ArrayToAtlas(const CoordType* array, int len)
00052 {
00053   Atlas::Message::Object::ListType a;
00054 
00055   for(const CoordType* i = array; i < array + len; ++i)
00056     a.push_back(*i);
00057 
00058   return a;
00059 }
00060 
00061 inline void _ArrayFromAtlas(CoordType* array, int len, const Atlas::Message::Object& a)
00062 {
00063   if(!a.IsList())
00064     throw _AtlasBadParse();
00065 
00066   Atlas::Message::Object::ListType list(a.AsList());
00067 
00068   if(list.size() != (unsigned int) len)
00069     throw _AtlasBadParse();
00070 
00071   for(int i = 0; i < len; ++i)
00072     array[i] = list[i].AsFloat();
00073 }
00074 
00075 template<const int dim>
00076 void Vector<dim>::fromAtlas(const Atlas::Message::Object& a)
00077 {
00078   _ArrayFromAtlas(m_elem, dim, a);
00079   m_valid = true;
00080 }
00081 
00082 template<const int dim>
00083 Atlas::Message::Object Vector<dim>::toAtlas() const
00084 {
00085   return _ArrayToAtlas(m_elem, dim);
00086 }
00087 
00088 inline void Quaternion::fromAtlas(const Atlas::Message::Object& a)
00089 {
00090   if(!a.IsList())
00091     throw _AtlasBadParse();
00092 
00093 
00094   Atlas::Message::Object::ListType list(a.AsList());
00095 
00096   if(list.size() != 4)
00097     throw _AtlasBadParse();
00098 
00099 
00100   for(int i = 0; i < 3; ++i)
00101     m_vec[i] = list[i].AsFloat();
00102 
00103   m_w = list[3].AsFloat();
00104 
00105   CoordType norm = sqrt(m_w * m_w + m_vec.sqrMag());
00106 
00107   m_vec /= norm;
00108   m_w /= norm;
00109 
00110   m_valid = true;
00111 }
00112 
00113 inline Atlas::Message::Object Quaternion::toAtlas() const
00114 {
00115   Atlas::Message::Object::ListType a;
00116 
00117   for(int i = 0; i < 3; ++i)
00118     a.push_back(m_vec[i]);
00119   a.push_back(m_w);
00120 
00121   return a;
00122 }
00123 
00124 template<const int dim>
00125 void Point<dim>::fromAtlas(const Atlas::Message::Object& a)
00126 {
00127   _ArrayFromAtlas(m_elem, dim, a);
00128   m_valid = true;
00129 }
00130 
00131 template<const int dim>
00132 Atlas::Message::Object Point<dim>::toAtlas() const
00133 {
00134   return _ArrayToAtlas(m_elem, dim);
00135 }
00136 
00137 template<const int dim>
00138 void AxisBox<dim>::fromAtlas(const Atlas::Message::Object& a)
00139 {
00140   if(!a.IsList())
00141     throw _AtlasBadParse();
00142 
00143   Atlas::Message::Object::ListType list(a.AsList());
00144 
00145   switch(list.size()) {
00146     case 1:
00147       m_low.setToOrigin();
00148       m_high.fromAtlas(list[0]);
00149       break;
00150     case 2:
00151       m_low.fromAtlas(list[0]);
00152       m_high.fromAtlas(list[1]);
00153       break;
00154     case dim:
00155       m_low.setToOrigin();
00156       m_high.fromAtlas(a);
00157       break;
00158     case (2 * dim):
00159       for(int i = 0; i < dim; ++i) {
00160         m_low[i] = list[i].AsFloat();
00161         m_high[i] = list[i+dim].AsFloat();
00162       }
00163       m_low.setValid();
00164       m_high.setValid();
00165       break;
00166     default:
00167       throw _AtlasBadParse();
00168   }
00169 
00170   for(int i = 0; i < dim; ++i) {
00171     if(m_low[i] > m_high[i]) { // spec may allow this?
00172       CoordType tmp = m_low[i];
00173       m_low[i] = m_high[i];
00174       m_high[i] = tmp;
00175     }
00176   }
00177 }
00178 
00179 template<>
00180 inline void AxisBox<2>::fromAtlas(const Atlas::Message::Object& a)
00181 {
00182   if(!a.IsList())
00183     throw _AtlasBadParse();
00184 
00185   Atlas::Message::Object::ListType list(a.AsList());
00186 
00187   switch(list.size()) {
00188     case 1:
00189       m_low.setToOrigin();
00190       m_high.fromAtlas(list[0]);
00191       break;
00192     case 2: // 2 possible different cases
00193       if(list[0].IsFloat()) {
00194         m_low.setToOrigin();
00195         m_high.fromAtlas(a);
00196       }
00197       else {
00198         m_low.fromAtlas(list[0]);
00199         m_high.fromAtlas(list[1]);
00200       }
00201       break;
00202     case 4:
00203       for(int i = 0; i < 2; ++i) {
00204         m_low[i] = list[i].AsFloat();
00205         m_high[i] = list[i+2].AsFloat();
00206       }
00207       m_low.setValid();
00208       m_high.setValid();
00209       break;
00210     default:
00211       throw _AtlasBadParse();
00212   }
00213 
00214   for(int i = 0; i < 2; ++i) {
00215     if(m_low[i] > m_high[i]) { // spec may allow this?
00216       CoordType tmp = m_low[i];
00217       m_low[i] = m_high[i];
00218       m_high[i] = tmp;
00219     }
00220   }
00221 }
00222 
00223 template<>
00224 inline void AxisBox<1>::fromAtlas(const Atlas::Message::Object& a)
00225 {
00226   if(!a.IsList())
00227     throw _AtlasBadParse();
00228 
00229   Atlas::Message::Object::ListType list(a.AsList());
00230 
00231   bool got_float = list[0].IsFloat();
00232 
00233   switch(list.size()) {
00234     case 1:
00235       m_low.setToOrigin();
00236       m_high.fromAtlas(got_float ? a : list[0]);
00237       break;
00238     case 2:
00239       if(got_float) {
00240         m_low[0] = list[0].AsFloat();
00241         m_high[0] = list[1].AsFloat(); 
00242         m_low.setValid();
00243         m_high.setValid();
00244       }
00245       else {
00246         m_low.fromAtlas(list[0]);
00247         m_high.fromAtlas(list[1]);
00248       }
00249       break;
00250     default:
00251       throw _AtlasBadParse();
00252   }
00253 
00254   if(m_low[0] > m_high[0]) { // spec may allow this?
00255     CoordType tmp = m_low[0];
00256     m_low[0] = m_high[0];
00257     m_high[0] = tmp;
00258   }
00259 }
00260 
00261 template<const int dim>
00262 Atlas::Message::Object AxisBox<dim>::toAtlas() const
00263 {
00264   int i;
00265 
00266   for(i = 0; i < dim; ++i)
00267     if(m_low[i] != 0)
00268       break;
00269 
00270   if(i == dim)
00271     return m_high.toAtlas(); // matches case 'dim' above
00272 
00273   // Do case '2 * dim' above
00274 
00275   Atlas::Message::Object::ListType a;
00276   for(i = 0; i < dim; ++i)
00277     a.push_back(m_low[i]);
00278   for(i = 0; i < dim; ++i)
00279     a.push_back(m_high[i]);
00280 
00281   return a;
00282 }
00283 
00284 } // namespace WFMath
00285 
00286 #endif // WFMATH_ATLAS_CONV_H

Generated on Wed May 28 09:20:31 2003 for WFMath by doxygen1.3-rc3