Main Page | Namespace List | Class List | File List | Namespace Members | Class 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 <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 // allow nice conversions when necessary 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]) { // spec may allow this? 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(); // matches case 'dim' above 00228 00229 // Do case '2 * dim' above 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 } // namespace WFMath 00241 00242 #endif // WFMATH_ATLAS_CONV_H

Generated on Thu Jul 29 07:09:56 2004 for WFMath by doxygen 1.3.7