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 WFMath {
00019 class MTRand;
00020 }
00021 
00022 namespace Mercator {
00023 
00024 class Terrain;
00025 class Surface;
00026 class TerrainMod;
00027 typedef std::set<const TerrainMod *> ModList;
00028 class Area;
00029 
00030 // This class will need to be reference counted if we want the code to
00031 // be able to hold onto it, as currently they get deleted internally
00032 // whenever height points are asserted.
00033 
00036 class Segment {
00037   public:
00039     typedef std::map<int, Surface *> Surfacestore;
00040     
00042     typedef std::multimap<int, const Area *> Areastore;
00043   private:
00045     const int m_res;
00047     const int m_size;
00049     const int m_xRef;
00051     const int m_yRef;
00053     Matrix<2, 2, BasePoint> m_controlPoints;
00055     float * m_points;
00057     float * m_normals;
00059     float m_max;
00061     float m_min;
00062 
00064     Surfacestore m_surfaces;
00065     
00067     Areastore m_areas;
00068 
00070     ModList m_modList;
00071   public:
00072     explicit Segment(int x, int y, unsigned int resolution);
00073     ~Segment();
00074 
00076     const int getResolution() const {
00077         return m_res;
00078     }
00079 
00081     const int getSize() const {
00082         return m_size;
00083     }
00084 
00086     const int getXRef() const {
00087         return m_xRef;
00088     }
00089 
00091     const int getYRef() const {
00092         return m_yRef;
00093     }
00094 
00098     const bool isValid() const {
00099         return (m_points != 0);
00100     }
00101 
00106     void setMinMax(float min, float max) {
00107         m_min = min;
00108         m_max = max;
00109     }
00110 
00111     void invalidate(bool points = true);
00112 
00119     void setCornerPoint(unsigned int x, unsigned int y, const BasePoint & bp) {
00120         m_controlPoints(x, y) = bp;
00121         invalidate();
00122     }
00123     
00125     const Matrix<2, 2, BasePoint> & getControlPoints() const {
00126         return m_controlPoints;
00127     }
00128 
00130     Matrix<2, 2, BasePoint> & getControlPoints() {
00131         return m_controlPoints;
00132     }
00133 
00135     const Surfacestore & getSurfaces() const {
00136         return m_surfaces;
00137     }
00138 
00140     Surfacestore & getSurfaces() {
00141         return m_surfaces;
00142     }
00143 
00145     const float * getPoints() const {
00146         return m_points;
00147     }
00148 
00150     float * getPoints() {
00151         return m_points;
00152     }
00153 
00155     const float * getNormals() const {
00156         return m_normals;
00157     }
00158 
00160     float * getNormals() {
00161         return m_normals;
00162     }
00163 
00165     float get(int x, int y) const {
00166         return m_points[y * (m_res + 1) + x];
00167     }
00168 
00169     void getHeightAndNormal(float x, float y, float &h, 
00170                     WFMath::Vector<3> &normal) const;
00171     bool clipToSegment(const WFMath::AxisBox<2> &bbox, int &lx, int &hx, int &ly, int &hy) const;
00172 
00173 
00174     void populate();
00175     void populateNormals();
00176     void populateSurfaces();
00177 
00179     float getMax() const { return m_max; }
00181     float getMin() const { return m_min; }
00182 
00184     WFMath::AxisBox<2> getRect() const;
00185 
00187     WFMath::AxisBox<3> getBox() const;
00188 
00189     int addMod(const TerrainMod *t);
00190     int updateMod(const TerrainMod *t);
00191     int removeMod(const TerrainMod *t);
00192     void clearMods();
00193     
00195     const Areastore& getAreas() const
00196     { return m_areas; }
00197 
00198     const ModList& getMods() const
00199     { return m_modList; }
00200     
00201     int addArea(const Area* a);
00202     int updateArea(const Area* a);
00203     int removeArea(const Area* a);
00204   private:
00205     void checkMaxMin(float h);
00206 
00207     void fill1d(const BasePoint& l, const BasePoint &h, float *array) const;
00208 
00209     void fill2d(const BasePoint& p1, const BasePoint& p2, 
00210                 const BasePoint& p3, const BasePoint& p4);
00211 
00212     float qRMD(WFMath::MTRand& rng, float nn, float fn, float ff, float nf,
00213                float roughness, float falloff, int depth) const;
00214 
00215     void applyMod(const TerrainMod *t);
00216 
00217     void invalidateSurfaces();
00218 
00219 };
00220 
00221 } // namespace Mercator
00222 
00223 #endif // MERCATOR_SEGMENT_H