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 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 // allow nice conversions when necessary 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]) { // spec may allow this? 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(); // matches case 'dim' above 00233 00234 // Do case '2 * dim' above 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 } // namespace WFMath 00246 00247 #endif // WFMATH_ATLAS_CONV_H

Generated on Tue Jul 27 21:41:56 2004 for WFMath by doxygen 1.3.7