source: Revenant/geoworld/include/PNGDEM.h@ 7ef8ec4

port/mars-tycoon
Last change on this file since 7ef8ec4 was 80a6a52, checked in by Jonathan Neufeld <support@…>, 3 years ago

Get to a compile state for terrain procedural generation

  • Property mode set to 100644
File size: 6.2 KB
Line 
1#ifndef __GEOWORLDPNGDEM_H__
2#define __GEOWORLDPNGDEM_H__
3
4#include <vector>
5#include <fstream>
6#include <mars_util.h>
7#include <mars_ptr.h>
8
9#include "vmpdg.h"
10#include "gwtypedefs.h"
11
12namespace geoworld
13{
14 class PNGDEM
15 {
16 private:
17 template< typename T >
18 class HeightMapAdapter : public mars::ScalarFieldView< T >
19 {
20 public:
21 HeightMapAdapter (mars::ScalarFieldView< T > & src)
22 : mars::ScalarFieldView< T >(src) {}
23 HeightMapAdapter (const mars::ScalarFieldView< T > & src)
24 : mars::ScalarFieldView< T >(src) {}
25
26 void operator >> (PNGDEM & pngdem) const;
27 };
28
29 template< typename E, typename T >
30 class ElementalFieldAdapter : public ElementalFieldView< E, T >
31 {
32 public:
33 ElementalFieldAdapter (ElementalFieldView< E, T > & src)
34 : ElementalFieldView< E, T > (src) {}
35 ElementalFieldAdapter (const ElementalFieldView< E, T > & src)
36 : ElementalFieldView< E, T > (src) {}
37
38 void operator >> (PNGDEM & pngdem) const;
39 };
40
41 public:
42 typedef std::vector< unsigned char > PNGBuffer;
43
44 enum Format
45 {
46 Grayscale = 0,
47 RGBMultiples = 1
48 };
49
50 PNGDEM();
51
52 inline void setFormat (const Format fmt) { _fmt = fmt; }
53 inline void setDimensions(const unsigned short nWidth, const unsigned short nHeight)
54 {
55 _nWidth = nWidth;
56 _nHeight = nHeight;
57 _inbuff.resize(_nWidth * _nHeight * 4);
58 }
59 inline unsigned short getWidth () const { return _nWidth; }
60 inline unsigned short getHeight () const { return _nHeight; }
61 inline Format getFormat () const { return _fmt; }
62 mars::ptr< GeoHeightMap > createHeightMap (const float fScale = 1.0f) const;
63 void retrieveLine (GeoHeightMap::Precision * pnData, const unsigned short nY, const float fScale = 1.0f) const;
64
65 inline PNGBuffer & buffer () { return _inbuff; }
66 inline const PNGBuffer & buffer () const { return _inbuff; }
67
68 void addCrosshairPoint (const unsigned short x, const unsigned short y, int idx = -1, const float fAlpha = 1.0f);
69 void addCrosshairPoint (const unsigned short x, const unsigned short y, const float fRed, const float fGreen, const float fBlue, const float fAlpha = 1.0f);
70 inline unsigned int nextCrosshair() { return ++_nCrossIdx; }
71
72 template< typename T >
73 void operator << ( const mars::ScalarFieldView< T > & view )
74 {
75 setDimensions(view.width, view.height);
76 HeightMapAdapter< T > (view) >> *this;
77 }
78 template< typename E, typename T >
79 void operator << ( const ElementalFieldView< E, T > & view )
80 {
81 setDimensions(view.width, view.height);
82 ElementalFieldAdapter< E, T > (view) >> *this;
83 }
84
85 GeoHeightMap::Precision convertPixelComponentsToElevation( const unsigned char b, const unsigned char g, const unsigned char r ) const;
86 unsigned char convertElevationToPixelComponent( const GeoHeightMap::Precision val, const unsigned bit ) const;
87
88 void operator << (std::ifstream & input);
89 std::ostream & operator >> (std::ostream & output);
90
91 private:
92 class CrosshairPoint
93 {
94 public:
95 const unsigned short x, y;
96 const float red, green, blue, alpha;
97
98 inline CrosshairPoint (const unsigned short x, const unsigned short y, const float red, const float green, const float blue, const float alpha = 1.0f)
99 : x(x), y(y), red(red), green(green), blue(blue), alpha(alpha)
100 {}
101 };
102
103 typedef std::list< CrosshairPoint > Crosshairs;
104
105 Crosshairs _crosshairs;
106 PNGBuffer _inbuff;
107 Format _fmt;
108 unsigned int _nCrossIdx;
109 unsigned short
110 _nWidth, _nHeight;
111
112 mars::Range< GeoHeightMap::Precision > getRange (const GeoHeightMap::Precision * pnData, const unsigned short nWidth, const unsigned short nHeight) const;
113 void flushCrosshairs();
114 };
115
116 template< typename T >
117 void PNGDEM::HeightMapAdapter<T>::operator >> ( PNGDEM & pngdem ) const
118 {
119 mars::RangeX< T > mmpDEMRange = mars::ScalarFieldView<T>::range();
120 PNGDEM::PNGBuffer & buff = pngdem.buffer();
121 const double fRGBMultScaler = static_cast< double > (1 << 11);
122
123 const unsigned short
124 height = mars::ScalarFieldView<T>::height,
125 width = mars::ScalarFieldView<T>::width;
126
127 for (unsigned short j = 0; j < height; ++j)
128 {
129 const T * pnLine = mars::ScalarFieldView<T>::line(j);
130
131 for (unsigned short i = 0; i < width; ++i)
132 {
133 const unsigned int nIdxBase = j * width * 4 + i * 4;
134
135 switch (pngdem.getFormat())
136 {
137 case PNGDEM::Grayscale:
138 buff[nIdxBase + 0] =
139 buff[nIdxBase + 1] =
140 buff[nIdxBase + 2] =
141 static_cast <unsigned char> ((static_cast <double> (pnLine[i]) - static_cast <double> (mmpDEMRange.minimum)) / static_cast <double> (mmpDEMRange.delta) * 255.0);
142 break;
143 case PNGDEM::RGBMultiples:
144 {
145 const GeoHeightMap::Precision val =
146 static_cast< GeoHeightMap::Precision > (
147 static_cast< double > (pnLine[i] - mmpDEMRange.minimum)
148 / static_cast< double > (mmpDEMRange.delta)
149 * fRGBMultScaler
150 );
151
152 buff[nIdxBase + 0] = pngdem.convertElevationToPixelComponent(val, 0);
153 buff[nIdxBase + 1] = pngdem.convertElevationToPixelComponent(val, 1);
154 buff[nIdxBase + 2] = pngdem.convertElevationToPixelComponent(val, 2);
155 }
156 break;
157 }
158 buff[nIdxBase + 3] = 255;
159 }
160 }
161 }
162
163 template< typename E, typename T >
164 void PNGDEM::ElementalFieldAdapter<E, T>::operator >> ( PNGDEM & pngdem ) const
165 {
166 mars::Range< MPDGVecType< T > > mmpDEMRange = mars::ScalarFieldView<T>::range();
167 const double fdrng = mmpDEMRange.maximum.altitude - mmpDEMRange.minimum.altitude;
168 PNGDEM::PNGBuffer & buff = pngdem.buffer();
169 const unsigned short
170 height = mars::ScalarFieldView<T>::height,
171 width = mars::ScalarFieldView<T>::width;
172
173 for (unsigned short j = 0; j < height; ++j)
174 {
175 const MPDGVecType< T > * pnLine = mars::ScalarFieldView<T>::line(j);
176
177 for (unsigned short i = 0; i < width; ++i)
178 {
179 const unsigned int nIdxBase = j * width * 4 + i * 4;
180 const unsigned char nAlt =
181 static_cast< unsigned char > (
182 static_cast< double > (pnLine[i].altitude - mmpDEMRange.minimum.altitude)
183 / fdrng * 256.0f
184 );
185 const unsigned short nMIndexCycle = (pnLine[i].mindex % 7) + 1;
186
187 buff[nIdxBase + 0] = (nMIndexCycle & (1 << 0)) ? nAlt : 0;
188 buff[nIdxBase + 1] = (nMIndexCycle & (1 << 1)) ? nAlt : 0;
189 buff[nIdxBase + 2] = (nMIndexCycle & (1 << 2)) ? nAlt : 0;
190
191 buff[nIdxBase + 3] = 255;
192 }
193 }
194 }
195}
196
197#endif
Note: See TracBrowser for help on using the repository browser.