Mercator

Segment.h

00001 // This file may be redistributed and modified only under the terms of
00002 // the GNU General Public License (See COPYING for details).
00003 // Copyright (C) 2003 Alistair Riddoch, Damien McGinnes
00004 
00005 #ifndef MERCATOR_SEGMENT_H
00006 #define MERCATOR_SEGMENT_H
00007 
00008 #include <Mercator/Mercator.h>
00009 #include <Mercator/Matrix.h>
00010 #include <Mercator/BasePoint.h>
00011 
00012 #include <wfmath/vector.h>
00013 #include <wfmath/axisbox.h>
00014 
00015 #include <set>
00016 #include <map>
00017 
00018 namespace Mercator {
00019 
00020 class Terrain;
00021 class Surface;
00022 class TerrainMod;
00023 typedef std::set<TerrainMod *> ModList;
00024 class Area;
00025 
00026 // This class will need to be reference counted if we want the code to
00027 // be able to hold onto it, as currently they get deleted internally
00028 // whenever height points are asserted.
00029 
00032 class Segment {
00033   public:
00035     typedef std::map<int, Surface *> Surfacestore;
00036     
00038     typedef std::multimap<int, Area *> Areastore;
00039   private:
00041     const int m_res;
00043     const int m_size;
00045     const int m_xRef;
00047     const int m_yRef;
00049     Matrix<2, 2, BasePoint> m_controlPoints;
00051     float * m_points;
00053     float * m_normals;
00055     float m_max;
00057     float m_min;
00058 
00060     Surfacestore m_surfaces;
00061     
00063     Areastore m_areas;
00064   public:
00065     explicit Segment(int x, int y, unsigned int resolution);
00066     ~Segment();
00067 
00069     const int getResolution() const {
00070         return m_res;
00071     }
00072 
00074     const int getSize() const {
00075         return m_size;
00076     }
00077 
00079     const int getXRef() const {
00080         return m_xRef;
00081     }
00082 
00084     const int getYRef() const {
00085         return m_yRef;
00086     }
00087 
00091     const bool isValid() const {
00092         return (m_points != 0);
00093     }
00094 
00099     void setMinMax(float min, float max) {
00100         m_min = min;
00101         m_max = max;
00102     }
00103 
00104     void invalidate(bool points = true);
00105 
00112     void setCornerPoint(unsigned int x, unsigned int y, const BasePoint & bp) {
00113         m_controlPoints(x, y) = bp;
00114         invalidate();
00115     }
00116     
00118     const Matrix<2, 2, BasePoint> & getControlPoints() const {
00119         return m_controlPoints;
00120     }
00121 
00123     Matrix<2, 2, BasePoint> & getControlPoints() {
00124         return m_controlPoints;
00125     }
00126 
00128     const Surfacestore & getSurfaces() const {
00129         return m_surfaces;
00130     }
00131 
00133     Surfacestore & getSurfaces() {
00134         return m_surfaces;
00135     }
00136 
00138     const float * getPoints() const {
00139         return m_points;
00140     }
00141 
00143     float * getPoints() {
00144         return m_points;
00145     }
00146 
00148     const float * getNormals() const {
00149         return m_normals;
00150     }
00151 
00153     float * getNormals() {
00154         return m_normals;
00155     }
00156 
00158     float get(int x, int y) const {
00159         return m_points[y * (m_res + 1) + x];
00160     }
00161 
00162     void getHeightAndNormal(float x, float y, float &h, 
00163                     WFMath::Vector<3> &normal) const;
00164     bool clipToSegment(const WFMath::AxisBox<2> &bbox, int &lx, int &hx, int &ly, int &hy) const;
00165 
00166 
00167     void populate();
00168     void populateNormals();
00169     void populateSurfaces();
00170 
00172     float getMax() const { return m_max; }
00174     float getMin() const { return m_min; }
00175 
00177     WFMath::AxisBox<2> getRect() const;
00178 
00180     WFMath::AxisBox<3> getBox() const;
00181 
00182     void addMod(TerrainMod *t);
00183     void removeMod(TerrainMod *t);
00184     void clearMods();
00185     
00187     const Areastore& getAreas() const
00188     { return m_areas; }
00189     
00190     void addArea(Area* a);
00191     void removeArea(Area* a);
00192   private:
00197     void checkMaxMin(float h) { 
00198         if (h<m_min) {
00199             m_min=h;
00200         }
00201         if (h>m_max) {
00202             m_max=h;
00203         }
00204     } 
00205 
00206     void fill1d(const BasePoint& l, const BasePoint &h, float *array) const;
00207 
00208     void fill2d(const BasePoint& p1, const BasePoint& p2, 
00209                 const BasePoint& p3, const BasePoint& p4);
00210 
00211     float qRMD(float nn, float fn, float ff, float nf, 
00212                float roughness, float falloff, int depth) const;
00213 
00214     void applyMod(TerrainMod *t);
00215 
00216     void invalidateSurfaces();
00217 
00219     ModList m_modList;
00220 
00221 };
00222 
00223 } // namespace Mercator
00224 
00225 #endif // MERCATOR_SEGMENT_H