<!-- Wanted to avoid copying .css to each folder, so copied default .css from doxyen in here, kicked out most stuff we don't need for examples and modified some a little bit.
Target was having a single html in each example folder which is created from the main.cpp files and needs no files besides some images below media folder.
<p>In this tutorial we'll learn how to create custom meshes and deal with them with Irrlicht. We'll create an interesting heightmap with some lighting effects. With keys 1,2,3 you can choose a different mesh layout, which is put into the mesh buffers as desired. All positions, normals, etc. are updated accordingly.</p>
<p>Ok, let's start with the headers (I think there's nothing to say about it) </p><divclass="fragment"><divclass="line"><spanclass="preprocessor">#include <irrlicht.h></span></div><divclass="line"><spanclass="preprocessor">#include "driverChoice.h"</span></div><divclass="line"></div><divclass="line"><spanclass="preprocessor">#ifdef _MSC_VER</span></div><divclass="line"><spanclass="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span></div><divclass="line"><spanclass="preprocessor">#endif</span></div><divclass="line"></div><divclass="line"><spanclass="comment">//Namespaces for the engine</span></div><divclass="line"><spanclass="keyword">using namespace </span>irr;</div><divclass="line"><spanclass="keyword">using namespace </span>video;</div><divclass="line"><spanclass="keyword">using namespace </span>core;</div><divclass="line"><spanclass="keyword">using namespace </span>scene;</div><divclass="line"><spanclass="keyword">using namespace </span>io;</div><divclass="line"><spanclass="keyword">using namespace </span>gui;</div></div><!-- fragment --><p> This is the type of the functions which work out the colour.</p><divclass="fragment"><divclass="line"><spanclass="keyword">typedef</span> SColor colour_func(f32 x, f32 y, f32 z);</div></div><!-- fragment --><p> Here comes a set of functions which can be used for coloring the nodes while creating the mesh.</p><divclass="fragment"><divclass="line"><spanclass="comment">// Greyscale, based on the height.</span></div><divclass="line">SColor grey(f32, f32, f32 z)</div><divclass="line">{</div><divclass="line"> u32 n = (u32)(255.f * z);</div><divclass="line"><spanclass="keywordflow">return</span> SColor(255, n, n, n);</div><divclass="line">}</div><divclass="line"></div><divclass="line"><spanclass="comment">// Interpolation between blue and white, with red added in one</span></div><divclass="line"><spanclass="comment">// direction and green in the other.</span></div><divclass="line">SColor yellow(f32 x, f32 y, f32)</div><divclass="line">{</div><divclass="line"><spanclass="keywordflow">return</span> SColor(255, 128 + (u32)(127.f * x), 128 + (u32)(127.f * y), 255);</div><divclass="line">}</div><divclass="line"></div><divclass="line"><spanclass="comment">// Pure white.</span></div><divclass="line">SColor white(f32, f32, f32) { <spanclass="keywordflow">return</span> SColor(255, 255, 255, 255); }</div></div><!-- fragment --><p> The type of the functions which generate the heightmap. x and y range between -0.5 and 0.5, and s is the scale of the heightmap.</p><divclass="fragment"><divclass="line"><spanclass="keyword">typedef</span> f32 generate_func(s16 x, s16 y, f32 s);</div><divclass="line"></div><divclass="line"><spanclass="comment">// An interesting sample function :-)</span></div><divclass="line">f32 eggbox(s16 x, s16 y, f32 s)</div><divclass="line">{</div><divclass="line"><spanclass="keyword">const</span> f32 r = 4.f*sqrtf((f32)(x*x + y*y))/s;</div><divclass="line"><spanclass="keyword">const</span> f32 z = (f32)exp(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));</div><divclass="line"><spanclass="keywordflow">return</span> 0.25f+0.25f*z;</div><divclass="line">}</div><divclass="line"></div><divclass="line"><spanclass="comment">// A rather dumb sine function :-/</span></div><divclass="line">f32 moresine(s16 x, s16 y, f32 s)</div><divclass="line">{</div><divclass="line"><spanclass="keyword">const</span> f32 xx=0.3f*(f32)x/s;</div><divclass="line"><spanclass="keyword">const</span> f32 yy=12*y/s;</div><divclass="line"><spanclass="keyword">const</span> f32 z = sinf(xx*xx+yy)*sinf(xx+yy*yy);</div><divclass="line"><spanclass="keywordflow">return</span> 0.25f + 0.25f * z;</div><divclass="line">}</div><divclass="line"></div><divclass="line"><spanclass="comment">// A simple function</span></div><divclass="line">f32 justexp(s16 x, s16 y, f32 s)</div><divclass="line">{</div><divclass="line"><spanclass="keyword">const</span> f32 xx=6*x/s;</div><
<p>s is a scaling factor, which is necessary if the height units are different from the coordinate units; for example, if your map has heights in meters and the coordinates are in units of a kilometer.</p><divclass="fragment"><divclass="line"> vector3df getnormal(u16 x, u16 y, f32 s)<spanclass="keyword"> const</span></div><divclass="line"><spanclass="keyword"></span>{</div><divclass="line"><spanclass="keyword">const</span> f32 zc = <spanclass="keyword">get</span>(x, y);</div><divclass="line"> f32 zl, zr, zu, zd;</div><divclass="line"></div><divclass="line"><spanclass="keywordflow">if</span> (x == 0)</div><divclass="line"> {</div><divclass="line"> zr = <spanclass="keyword">get</span>(x + 1, y);</div><divclass="line"> zl = zc + zc - zr;</div><divclass="line"> }</div><divclass="line"><spanclass="keywordflow">else</span><spanclass="keywordflow">if</span> (x == Width - 1)</div><divclass="line"> {</div><divclass="line"> zl = <spanclass="keyword">get</span>(x - 1, y);</div><divclass="line"> zr = zc + zc - zl;</div><divclass="line"> }</div><divclass="line"><spanclass="keywordflow">else</span></div><divclass="line"> {</div><divclass="line"> zr = <spanclass="keyword">get</span>(x + 1, y);</div><divclass="line"> zl = <spanclass="keyword">get</span>(x - 1, y);</div><divclass="line"> }</div><divclass="line"></div><divclass="line"><spanclass="keywordflow">if</span> (y == 0)</div><divclass="line"> {</div><divclass="line"> zd = <spanclass="keyword">get</span>(x, y + 1);</div><divclass="line"> zu = zc + zc - zd;</div><divclass="line"> }</div><divclass="line"><spanclass="keywordflow">else</span><spanclass="keywordflow">if</span> (y == Height - 1)</div><divclass="line"> {</div><divclass="line"> zu = <spanclass="keyword">get</span>(x, y - 1);</div><divclass="line"> zd = zc + zc - zu;</div><divclass="line"> }</div><divclass="line"><spanclass="keywordflow">else</span></div><divclass="line"> {</div><divclass="line"> zd = <spanclass="keyword">get</span>(x, y + 1);</div><divclass="line"> zu = <spanclass="keyword">get</span>(x, y - 1);</div><divclass="line"> }</div><divclass="line"></div><divclass="line"><spanclass="keywordflow">return</span> vector3df(s * 2 * (zl - zr), 4, s * 2 * (zd - zu)).normalize();</div><divclass="line"> }</div><divclass="line">};</div></div><!-- fragment --><p> A class which generates a mesh from a heightmap.</p><divclass="fragment"><divclass="line"><spanclass="keyword">class </span>TMesh</div><divclass="line">{</div><divclass="line"><spanclass="keyword">private</span>:</div><divclass="line"> u16 Width;</div><divclass="line"> u16 Height;</div><divclass="line"> f32 Scale;</div><divclass="line"><spanclass="keyword">public</span>:</div><divclass="line"> SMesh* Mesh;</div><divclass="line"></div><divclass="line"> TMesh() : Width(0), Height(0), Scale(1.f), Mesh(0)</div><divclass="line"> {</div><divclass="line"> Mesh = <spanclass="keyword">new</span> SMesh();</div><divclass="line"> }</div><divclass="line"></div><divclass="line"> ~TMesh()</div><divclass="line"> {</div><divclass="line"> Mesh->drop();</div><divclass="line"> }</div><divclass="line"></div><divclass="line"><spanclass="comment">// Unless the heightmap is small, it won't all fit into a single</span></div><divclass="line"><spanclass="comment">// SMeshBuffer. This function chops it into pieces and generates a</span></div><divclass="line"><spanclass="comment">// buffer from each one.</span></div><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> init(<spanclass="keyword">const</span> HeightMap &hm, f32 scale, colour_func cf, IVideoDriver *driver)</div><divclass="line"> {</div><divclas