00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef EMBEROGRE_TERRAINTERRAINMOD_IMPL_H
00024 #define EMBEROGRE_TERRAINTERRAINMOD_IMPL_H
00025
00026 #include <Eris/Entity.h>
00027 #include <Eris/Log.h>
00028 #include <Mercator/TerrainMod.h>
00029 #include <Mercator/TerrainMod_impl.h>
00030 #include <wfmath/ball.h>
00031 #include <wfmath/polygon.h>
00032
00033
00034 namespace Eris
00035 {
00036
00043 class InnerTerrainMod_impl
00044 {
00045 public:
00046
00050 InnerTerrainMod_impl() {}
00051
00055 virtual ~InnerTerrainMod_impl() {}
00056
00066 template <typename Shape>
00067 static bool parseShapeAtlasData(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, Shape** shape);
00068
00073 virtual Mercator::TerrainMod* getModifier() = 0;
00074
00075 protected:
00076
00077 };
00078
00079 template<typename Shape>
00080 bool InnerTerrainMod_impl::parseShapeAtlasData(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, Shape** shape)
00081 {
00082 try {
00083 *shape = new Shape(shapeElement);
00084 } catch (...) {
00086 warning() << "Error when parsing shape from atlas.";
00087 return false;
00088 }
00089
00091 WFMath::Vector<3> xVec = WFMath::Vector<3>(1.0, 0.0, 0.0).rotate(orientation);
00092 double theta = atan2(xVec.y(), xVec.x());
00093 WFMath::RotMatrix<2> rm;
00094 (*shape)->rotatePoint(rm.rotation(theta), WFMath::Point<2>(0, 0));
00095
00096 (*shape)->shift(WFMath::Vector<2>(pos.x(), pos.y()));
00097 return true;
00098 }
00099
00104 template <typename Shape>
00105 class InnerTerrainModSlope_impl : public InnerTerrainMod_impl
00106 {
00107 public:
00111 InnerTerrainModSlope_impl() {}
00112
00116 virtual ~InnerTerrainModSlope_impl() {
00117 delete mTerrainMod;
00118 }
00119
00129 bool createInstance(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, float level, float dx, float dy);
00130
00134 inline virtual Mercator::TerrainMod* getModifier();
00135
00136 protected:
00137
00141 Mercator::SlopeTerrainMod<Shape>* mTerrainMod;
00142 };
00143
00144 template <typename Shape>
00145 Mercator::TerrainMod* InnerTerrainModSlope_impl<Shape>::getModifier()
00146 {
00147 return mTerrainMod;
00148 }
00149
00150 template <typename Shape>
00151 bool InnerTerrainModSlope_impl<Shape>::createInstance(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, float level, float dx, float dy)
00152 {
00153 Shape* shape(0);
00154 if (parseShapeAtlasData<Shape>(shapeElement, pos, orientation, &shape)) {
00155 mTerrainMod = new Mercator::SlopeTerrainMod<Shape>(level, dx, dy, *shape);
00156 delete shape;
00157 return true;
00158 }
00159 delete shape;
00160 return false;
00161 }
00162
00167 template <typename Shape>
00168 class InnerTerrainModLevel_impl : public InnerTerrainMod_impl
00169 {
00170 public:
00174 InnerTerrainModLevel_impl() {}
00175
00179 virtual ~InnerTerrainModLevel_impl() {
00180 delete mTerrainMod;
00181 }
00182
00190 bool createInstance(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, float height);
00191
00195 inline virtual Mercator::TerrainMod* getModifier();
00196
00197 protected:
00198
00202 Mercator::LevelTerrainMod<Shape>* mTerrainMod;
00203 };
00204
00205 template <typename Shape>
00206 Mercator::TerrainMod* InnerTerrainModLevel_impl<Shape>::getModifier()
00207 {
00208 return mTerrainMod;
00209 }
00210
00211 template <typename Shape>
00212 bool InnerTerrainModLevel_impl<Shape>::createInstance(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, float height)
00213 {
00214 Shape* shape(0);
00215 if (parseShapeAtlasData<Shape>(shapeElement, pos, orientation, &shape)) {
00216 mTerrainMod = new Mercator::LevelTerrainMod<Shape>(height, *shape);
00217 delete shape;
00218 return true;
00219 }
00220 delete shape;
00221 return false;
00222 }
00223
00228 template <typename Shape>
00229 class InnerTerrainModAdjust_impl : public InnerTerrainMod_impl
00230 {
00231 public:
00235 InnerTerrainModAdjust_impl() {}
00236
00240 virtual ~InnerTerrainModAdjust_impl() {
00241 delete mTerrainMod;
00242 }
00243
00251 bool createInstance(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, float height);
00252
00256 inline virtual Mercator::TerrainMod* getModifier();
00257
00258 protected:
00259
00263 Mercator::AdjustTerrainMod<Shape>* mTerrainMod;
00264 };
00265
00266 template <typename Shape>
00267 Mercator::TerrainMod* InnerTerrainModAdjust_impl<Shape>::getModifier()
00268 {
00269 return mTerrainMod;
00270 }
00271
00272 template <typename Shape>
00273 bool InnerTerrainModAdjust_impl<Shape>::createInstance(const Atlas::Message::Element& shapeElement, const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation, float height)
00274 {
00275 Shape* shape(0);
00276 if (parseShapeAtlasData<Shape>(shapeElement, pos, orientation, &shape)) {
00277 mTerrainMod = new Mercator::AdjustTerrainMod<Shape>(height, *shape);
00278 delete shape;
00279 return true;
00280 }
00281 delete shape;
00282 return false;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 }
00302
00303 #endif