diff options
author | David Walter Seikel | 2016-03-28 22:28:34 +1000 |
---|---|---|
committer | David Walter Seikel | 2016-03-28 22:28:34 +1000 |
commit | 7028cbe09c688437910a25623098762bf0fa592d (patch) | |
tree | 10b5af58277d9880380c2251f109325542c4e6eb /libraries/irrlicht-1.8.1/doc/html/example023.html | |
parent | Move lemon to the src/others directory. (diff) | |
download | SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.zip SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.gz SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.bz2 SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.xz |
Move Irrlicht to src/others.
Diffstat (limited to 'libraries/irrlicht-1.8.1/doc/html/example023.html')
-rw-r--r-- | libraries/irrlicht-1.8.1/doc/html/example023.html | 502 |
1 files changed, 0 insertions, 502 deletions
diff --git a/libraries/irrlicht-1.8.1/doc/html/example023.html b/libraries/irrlicht-1.8.1/doc/html/example023.html deleted file mode 100644 index 4906006..0000000 --- a/libraries/irrlicht-1.8.1/doc/html/example023.html +++ /dev/null | |||
@@ -1,502 +0,0 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
2 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
3 | <head> | ||
4 | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||
5 | <title>Irrlicht 3D Engine: Tutorial 23: SMeshBufferHandling</title> | ||
6 | |||
7 | <link href="tabs.css" rel="stylesheet" type="text/css"/> | ||
8 | <link href="doxygen.css" rel="stylesheet" type="text/css" /> | ||
9 | <link href="navtree.css" rel="stylesheet" type="text/css"/> | ||
10 | <script type="text/javascript" src="jquery.js"></script> | ||
11 | <script type="text/javascript" src="resize.js"></script> | ||
12 | <script type="text/javascript" src="navtree.js"></script> | ||
13 | <script type="text/javascript"> | ||
14 | $(document).ready(initResizable); | ||
15 | </script> | ||
16 | <link href="search/search.css" rel="stylesheet" type="text/css"/> | ||
17 | <script type="text/javascript" src="search/search.js"></script> | ||
18 | <script type="text/javascript"> | ||
19 | $(document).ready(function() { searchBox.OnSelectItem(0); }); | ||
20 | </script> | ||
21 | |||
22 | </head> | ||
23 | <body> | ||
24 | <div id="top"><!-- do not remove this div! --> | ||
25 | |||
26 | |||
27 | <div id="titlearea"> | ||
28 | <table cellspacing="0" cellpadding="0"> | ||
29 | <tbody> | ||
30 | <tr style="height: 56px;"> | ||
31 | |||
32 | <td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td> | ||
33 | |||
34 | |||
35 | <td style="padding-left: 0.5em;"> | ||
36 | <div id="projectname">Irrlicht 3D Engine | ||
37 | |||
38 | </div> | ||
39 | |||
40 | </td> | ||
41 | |||
42 | |||
43 | |||
44 | |||
45 | <td> <div id="MSearchBox" class="MSearchBoxInactive"> | ||
46 | <span class="left"> | ||
47 | <img id="MSearchSelect" src="search/mag_sel.png" | ||
48 | onmouseover="return searchBox.OnSearchSelectShow()" | ||
49 | onmouseout="return searchBox.OnSearchSelectHide()" | ||
50 | alt=""/> | ||
51 | <input type="text" id="MSearchField" value="Search" accesskey="S" | ||
52 | onfocus="searchBox.OnSearchFieldFocus(true)" | ||
53 | onblur="searchBox.OnSearchFieldFocus(false)" | ||
54 | onkeyup="searchBox.OnSearchFieldChange(event)"/> | ||
55 | </span><span class="right"> | ||
56 | <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a> | ||
57 | </span> | ||
58 | </div> | ||
59 | </td> | ||
60 | |||
61 | |||
62 | </tr> | ||
63 | </tbody> | ||
64 | </table> | ||
65 | </div> | ||
66 | |||
67 | <!-- Generated by Doxygen 1.7.5.1 --> | ||
68 | <script type="text/javascript"> | ||
69 | var searchBox = new SearchBox("searchBox", "search",false,'Search'); | ||
70 | </script> | ||
71 | <script type="text/javascript" src="dynsections.js"></script> | ||
72 | </div> | ||
73 | <div id="side-nav" class="ui-resizable side-nav-resizable"> | ||
74 | <div id="nav-tree"> | ||
75 | <div id="nav-tree-contents"> | ||
76 | </div> | ||
77 | </div> | ||
78 | <div id="splitbar" style="-moz-user-select:none;" | ||
79 | class="ui-resizable-handle"> | ||
80 | </div> | ||
81 | </div> | ||
82 | <script type="text/javascript"> | ||
83 | initNavTree('example023.html',''); | ||
84 | </script> | ||
85 | <div id="doc-content"> | ||
86 | <div class="header"> | ||
87 | <div class="headertitle"> | ||
88 | <div class="title">Tutorial 23: SMeshBufferHandling </div> </div> | ||
89 | </div> | ||
90 | <div class="contents"> | ||
91 | <div class="textblock"><div class="image"> | ||
92 | <img src="023shot.jpg" alt="023shot.jpg"/> | ||
93 | </div> | ||
94 | <p>A tutorial by geoff.</p> | ||
95 | <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> | ||
96 | <p>Ok, let's start with the headers (I think there's nothing to say about it) </p> | ||
97 | <div class="fragment"><pre class="fragment"><span class="preprocessor">#include <<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>></span> | ||
98 | <span class="preprocessor">#include "<a class="code" href="driver_choice_8h.html">driverChoice.h</a>"</span> | ||
99 | |||
100 | <span class="preprocessor">#ifdef _MSC_VER</span> | ||
101 | <span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span> | ||
102 | <span class="preprocessor"></span><span class="preprocessor">#endif</span> | ||
103 | <span class="preprocessor"></span> | ||
104 | <span class="comment">//Namespaces for the engine</span> | ||
105 | <span class="keyword">using namespace </span>irr; | ||
106 | <span class="keyword">using namespace </span>video; | ||
107 | <span class="keyword">using namespace </span>core; | ||
108 | <span class="keyword">using namespace </span>scene; | ||
109 | <span class="keyword">using namespace </span>io; | ||
110 | <span class="keyword">using namespace </span>gui; | ||
111 | </pre></div><p> This is the type of the functions which work out the colour. </p> | ||
112 | <div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> SColor colour_func(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> x, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z); | ||
113 | </pre></div><p> Here comes a set of functions which can be used for coloring the nodes while creating the mesh. </p> | ||
114 | <div class="fragment"><pre class="fragment"><span class="comment">// Greyscale, based on the height.</span> | ||
115 | SColor grey(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) | ||
116 | { | ||
117 | <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> n = (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(255.f * z); | ||
118 | <span class="keywordflow">return</span> SColor(255, n, n, n); | ||
119 | } | ||
120 | |||
121 | <span class="comment">// Interpolation between blue and white, with red added in one</span> | ||
122 | <span class="comment">// direction and green in the other.</span> | ||
123 | SColor yellow(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> x, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>) | ||
124 | { | ||
125 | <span class="keywordflow">return</span> SColor(255, 128 + (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(127.f * x), 128 + (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(127.f * y), 255); | ||
126 | } | ||
127 | |||
128 | <span class="comment">// Pure white.</span> | ||
129 | SColor white(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>) { <span class="keywordflow">return</span> SColor(255, 255, 255, 255); } | ||
130 | </pre></div><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> | ||
131 | <div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> generate_func(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s); | ||
132 | |||
133 | <span class="comment">// An interesting sample function :-)</span> | ||
134 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> eggbox(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s) | ||
135 | { | ||
136 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> r = 4.f*sqrtf((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)(x*x + y*y))/s; | ||
137 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = expf(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y)); | ||
138 | <span class="keywordflow">return</span> 0.25f+0.25f*z; | ||
139 | } | ||
140 | |||
141 | <span class="comment">// A rather dumb sine function :-/</span> | ||
142 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> moresine(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s) | ||
143 | { | ||
144 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx=0.3f*(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x/s; | ||
145 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy=12*y/s; | ||
146 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = sinf(xx*xx+yy)*sinf(xx+yy*yy); | ||
147 | <span class="keywordflow">return</span> 0.25f + 0.25f * z; | ||
148 | } | ||
149 | |||
150 | <span class="comment">// A simple function</span> | ||
151 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> justexp(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s) | ||
152 | { | ||
153 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx=6*x/s; | ||
154 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy=6*y/s; | ||
155 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = (xx*xx+yy*yy); | ||
156 | <span class="keywordflow">return</span> 0.3f*z*cosf(xx*yy); | ||
157 | } | ||
158 | </pre></div><p> A simple class for representing heightmaps. Most of this should be obvious. </p> | ||
159 | <div class="fragment"><pre class="fragment"><span class="keyword">class </span>HeightMap | ||
160 | { | ||
161 | <span class="keyword">private</span>: | ||
162 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Width; | ||
163 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Height; | ||
164 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s; | ||
165 | core::array<f32> data; | ||
166 | <span class="keyword">public</span>: | ||
167 | HeightMap(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> _w, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> _h) : Width(_w), Height(_h), s(0.f), data(0) | ||
168 | { | ||
169 | s = sqrtf((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)(Width * Width + Height * Height)); | ||
170 | data.set_used(Width * Height); | ||
171 | } | ||
172 | |||
173 | <span class="comment">// Fill the heightmap with values generated from f.</span> | ||
174 | <span class="keywordtype">void</span> generate(generate_func f) | ||
175 | { | ||
176 | <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; | ||
177 | <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = 0; y < Height; ++y) | ||
178 | <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x < Width; ++x) | ||
179 | <span class="keyword">set</span>(i++, calc(f, x, y)); | ||
180 | } | ||
181 | |||
182 | <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> height()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> Height; } | ||
183 | <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> width()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> Width; } | ||
184 | |||
185 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> calc(generate_func f, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y)<span class="keyword"> const</span> | ||
186 | <span class="keyword"> </span>{ | ||
187 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x - Width*0.5f; | ||
188 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)y - Height*0.5f; | ||
189 | <span class="keywordflow">return</span> f((<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a>)xx, (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a>)yy, s); | ||
190 | } | ||
191 | |||
192 | <span class="comment">// The height at (x, y) is at position y * Width + x.</span> | ||
193 | |||
194 | <span class="keywordtype">void</span> <span class="keyword">set</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) { data[y * Width + x] = z; } | ||
195 | <span class="keywordtype">void</span> <span class="keyword">set</span>(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) { data[i] = z; } | ||
196 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> <span class="keyword">get</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y) <span class="keyword">const</span> { <span class="keywordflow">return</span> data[y * Width + x]; } | ||
197 | </pre></div><p> The only difficult part. This considers the normal at (x, y) to be the cross product of the vectors between the adjacent points in the horizontal and vertical directions.</p> | ||
198 | <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 metres and the coordinates are in units of a kilometer. </p> | ||
199 | <div class="fragment"><pre class="fragment"> <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a> getnormal(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)<span class="keyword"> const</span> | ||
200 | <span class="keyword"> </span>{ | ||
201 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> zc = <span class="keyword">get</span>(x, y); | ||
202 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> zl, zr, zu, zd; | ||
203 | |||
204 | <span class="keywordflow">if</span> (x == 0) | ||
205 | { | ||
206 | zr = <span class="keyword">get</span>(x + 1, y); | ||
207 | zl = zc + zc - zr; | ||
208 | } | ||
209 | <span class="keywordflow">else</span> <span class="keywordflow">if</span> (x == Width - 1) | ||
210 | { | ||
211 | zl = <span class="keyword">get</span>(x - 1, y); | ||
212 | zr = zc + zc - zl; | ||
213 | } | ||
214 | <span class="keywordflow">else</span> | ||
215 | { | ||
216 | zr = <span class="keyword">get</span>(x + 1, y); | ||
217 | zl = <span class="keyword">get</span>(x - 1, y); | ||
218 | } | ||
219 | |||
220 | <span class="keywordflow">if</span> (y == 0) | ||
221 | { | ||
222 | zd = <span class="keyword">get</span>(x, y + 1); | ||
223 | zu = zc + zc - zd; | ||
224 | } | ||
225 | <span class="keywordflow">else</span> <span class="keywordflow">if</span> (y == Height - 1) | ||
226 | { | ||
227 | zu = <span class="keyword">get</span>(x, y - 1); | ||
228 | zd = zc + zc - zu; | ||
229 | } | ||
230 | <span class="keywordflow">else</span> | ||
231 | { | ||
232 | zd = <span class="keyword">get</span>(x, y + 1); | ||
233 | zu = <span class="keyword">get</span>(x, y - 1); | ||
234 | } | ||
235 | |||
236 | <span class="keywordflow">return</span> <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(s * 2 * (zl - zr), 4, s * 2 * (zd - zu)).normalize(); | ||
237 | } | ||
238 | }; | ||
239 | </pre></div><p> A class which generates a mesh from a heightmap. </p> | ||
240 | <div class="fragment"><pre class="fragment"><span class="keyword">class </span>TMesh | ||
241 | { | ||
242 | <span class="keyword">private</span>: | ||
243 | <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Width; | ||
244 | <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Height; | ||
245 | <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> Scale; | ||
246 | <span class="keyword">public</span>: | ||
247 | SMesh* Mesh; | ||
248 | |||
249 | TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f) | ||
250 | { | ||
251 | Mesh = <span class="keyword">new</span> SMesh(); | ||
252 | } | ||
253 | |||
254 | ~TMesh() | ||
255 | { | ||
256 | Mesh->drop(); | ||
257 | } | ||
258 | |||
259 | <span class="comment">// Unless the heightmap is small, it won't all fit into a single</span> | ||
260 | <span class="comment">// SMeshBuffer. This function chops it into pieces and generates a</span> | ||
261 | <span class="comment">// buffer from each one.</span> | ||
262 | |||
263 | <span class="keywordtype">void</span> init(<span class="keyword">const</span> HeightMap &hm, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> scale, colour_func cf, IVideoDriver *driver) | ||
264 | { | ||
265 | Scale = scale; | ||
266 | |||
267 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> mp = driver -> getMaximalPrimitiveCount(); | ||
268 | Width = hm.width(); | ||
269 | Height = hm.height(); | ||
270 | |||
271 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> sw = mp / (6 * Height); <span class="comment">// the width of each piece</span> | ||
272 | |||
273 | <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; | ||
274 | <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> y0 = 0; y0 < Height; y0 += sw) | ||
275 | { | ||
276 | <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y1 = y0 + sw; | ||
277 | <span class="keywordflow">if</span> (y1 >= Height) | ||
278 | y1 = Height - 1; <span class="comment">// the last one might be narrower</span> | ||
279 | addstrip(hm, cf, y0, y1, i); | ||
280 | ++i; | ||
281 | } | ||
282 | <span class="keywordflow">if</span> (i<Mesh->getMeshBufferCount()) | ||
283 | { | ||
284 | <span class="comment">// clear the rest</span> | ||
285 | <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> j=i; j<Mesh->getMeshBufferCount(); ++j) | ||
286 | { | ||
287 | Mesh->getMeshBuffer(j)->drop(); | ||
288 | } | ||
289 | Mesh->MeshBuffers.erase(i,Mesh->getMeshBufferCount()-i); | ||
290 | } | ||
291 | <span class="comment">// set dirty flag to make sure that hardware copies of this</span> | ||
292 | <span class="comment">// buffer are also updated, see IMesh::setHardwareMappingHint</span> | ||
293 | Mesh->setDirty(); | ||
294 | Mesh->recalculateBoundingBox(); | ||
295 | } | ||
296 | |||
297 | <span class="comment">// Generate a SMeshBuffer which represents all the vertices and</span> | ||
298 | <span class="comment">// indices for values of y between y0 and y1, and add it to the</span> | ||
299 | <span class="comment">// mesh.</span> | ||
300 | |||
301 | <span class="keywordtype">void</span> addstrip(<span class="keyword">const</span> HeightMap &hm, colour_func cf, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y0, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y1, <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> bufNum) | ||
302 | { | ||
303 | <a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a> *buf = 0; | ||
304 | <span class="keywordflow">if</span> (bufNum<Mesh->getMeshBufferCount()) | ||
305 | { | ||
306 | buf = (<a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a>*)Mesh->getMeshBuffer(bufNum); | ||
307 | } | ||
308 | <span class="keywordflow">else</span> | ||
309 | { | ||
310 | <span class="comment">// create new buffer</span> | ||
311 | buf = <span class="keyword">new</span> <a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a>(); | ||
312 | Mesh->addMeshBuffer(buf); | ||
313 | <span class="comment">// to simplify things we drop here but continue using buf</span> | ||
314 | buf->drop(); | ||
315 | } | ||
316 | buf->Vertices.set_used((1 + y1 - y0) * Width); | ||
317 | |||
318 | <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; | ||
319 | <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = y0; y <= y1; ++y) | ||
320 | { | ||
321 | <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x < Width; ++x) | ||
322 | { | ||
323 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = hm.get(x, y); | ||
324 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x/(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)Width; | ||
325 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)y/(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)Height; | ||
326 | |||
327 | S3DVertex& v = buf->Vertices[i++]; | ||
328 | v.Pos.set(x, Scale * z, y); | ||
329 | v.Normal.set(hm.getnormal(x, y, Scale)); | ||
330 | v.Color=cf(xx, yy, z); | ||
331 | v.TCoords.set(xx, yy); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | buf->Indices.set_used(6 * (Width - 1) * (y1 - y0)); | ||
336 | i=0; | ||
337 | <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = y0; y < y1; ++y) | ||
338 | { | ||
339 | <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x < Width - 1; ++x) | ||
340 | { | ||
341 | <span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> n = (y-y0) * Width + x; | ||
342 | buf->Indices[i]=n; | ||
343 | buf->Indices[++i]=n + Width; | ||
344 | buf->Indices[++i]=n + Width + 1; | ||
345 | buf->Indices[++i]=n + Width + 1; | ||
346 | buf->Indices[++i]=n + 1; | ||
347 | buf->Indices[++i]=n; | ||
348 | ++i; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | buf->recalculateBoundingBox(); | ||
353 | } | ||
354 | }; | ||
355 | </pre></div><p>Our event receiver implementation, taken from tutorial 4. </p> | ||
356 | <div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver | ||
357 | { | ||
358 | <span class="keyword">public</span>: | ||
359 | <span class="comment">// This is the one method that we have to implement</span> | ||
360 | <span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent& event) | ||
361 | { | ||
362 | <span class="comment">// Remember whether each key is down or up</span> | ||
363 | <span class="keywordflow">if</span> (event.EventType == <a class="code" href="namespaceirr.html#ac9eed96e06e85ce3c86fcbbbe9e48a0ca6f90390f3147a1693e5e2e3422d6ca09" title="A key input event.">irr::EET_KEY_INPUT_EVENT</a>) | ||
364 | KeyIsDown[<span class="keyword">event</span>.KeyInput.Key] = <span class="keyword">event</span>.KeyInput.PressedDown; | ||
365 | |||
366 | <span class="keywordflow">return</span> <span class="keyword">false</span>; | ||
367 | } | ||
368 | |||
369 | <span class="comment">// This is used to check whether a key is being held down</span> | ||
370 | <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3">EKEY_CODE</a> keyCode)<span class="keyword"> const</span> | ||
371 | <span class="keyword"> </span>{ | ||
372 | <span class="keywordflow">return</span> KeyIsDown[keyCode]; | ||
373 | } | ||
374 | |||
375 | MyEventReceiver() | ||
376 | { | ||
377 | <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; i<<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a205b48c0c4ed7489ab8980657343283e">KEY_KEY_CODES_COUNT</a>; ++i) | ||
378 | KeyIsDown[i] = <span class="keyword">false</span>; | ||
379 | } | ||
380 | |||
381 | <span class="keyword">private</span>: | ||
382 | <span class="comment">// We use this array to store the current state of each key</span> | ||
383 | <span class="keywordtype">bool</span> KeyIsDown[<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a205b48c0c4ed7489ab8980657343283e">KEY_KEY_CODES_COUNT</a>]; | ||
384 | }; | ||
385 | </pre></div><p>Much of this is code taken from some of the examples. We merely set up a mesh from a heightmap, light it with a moving light, and allow the user to navigate around it. </p> | ||
386 | <div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[]) | ||
387 | { | ||
388 | <span class="comment">// ask user for driver</span> | ||
389 | <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole(); | ||
390 | <span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>) | ||
391 | <span class="keywordflow">return</span> 1; | ||
392 | |||
393 | MyEventReceiver receiver; | ||
394 | IrrlichtDevice* device = <a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType, | ||
395 | <a class="code" href="namespaceirr_1_1core.html#ad2e562e3219072e2f7fc7c2bba0ef0cb" title="Typedef for an unsigned integer dimension.">core::dimension2du</a>(800, 600), 32, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span>, | ||
396 | &receiver); | ||
397 | |||
398 | <span class="keywordflow">if</span>(device == 0) | ||
399 | <span class="keywordflow">return</span> 1; | ||
400 | |||
401 | IVideoDriver *driver = device->getVideoDriver(); | ||
402 | ISceneManager *smgr = device->getSceneManager(); | ||
403 | device->setWindowCaption(L<span class="stringliteral">"Irrlicht Example for SMesh usage."</span>); | ||
404 | </pre></div><p>Create the custom mesh and initialize with a heightmap </p> | ||
405 | <div class="fragment"><pre class="fragment"> TMesh mesh; | ||
406 | HeightMap hm = HeightMap(255, 255); | ||
407 | hm.generate(eggbox); | ||
408 | mesh.init(hm, 50.f, grey, driver); | ||
409 | |||
410 | <span class="comment">// Add the mesh to the scene graph</span> | ||
411 | IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh); | ||
412 | meshnode->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3ae1d176d0ce05ccc5df9e43ce854393bb" title="Is backface culling enabled? Default: true.">video::EMF_BACK_FACE_CULLING</a>, <span class="keyword">false</span>); | ||
413 | |||
414 | <span class="comment">// light is just for nice effects</span> | ||
415 | ILightSceneNode *node = smgr->addLightSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,100,0), | ||
416 | SColorf(1.0f, 0.6f, 0.7f, 1.0f), 500.0f); | ||
417 | <span class="keywordflow">if</span> (node) | ||
418 | { | ||
419 | node->getLightData().Attenuation.set(0.f, 1.f/500.f, 0.f); | ||
420 | ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,150,0),250.0f); | ||
421 | <span class="keywordflow">if</span> (anim) | ||
422 | { | ||
423 | node->addAnimator(anim); | ||
424 | anim->drop(); | ||
425 | } | ||
426 | } | ||
427 | |||
428 | ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(); | ||
429 | <span class="keywordflow">if</span> (camera) | ||
430 | { | ||
431 | camera->setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(-20.f, 150.f, -20.f)); | ||
432 | camera->setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(200.f, -80.f, 150.f)); | ||
433 | camera->setFarValue(20000.0f); | ||
434 | } | ||
435 | </pre></div><p>Just a usual render loop with event handling. The custom mesh is a usual part of the scene graph which gets rendered by drawAll. </p> | ||
436 | <div class="fragment"><pre class="fragment"> <span class="keywordflow">while</span>(device->run()) | ||
437 | { | ||
438 | <span class="keywordflow">if</span>(!device->isWindowActive()) | ||
439 | { | ||
440 | device->sleep(100); | ||
441 | <span class="keywordflow">continue</span>; | ||
442 | } | ||
443 | |||
444 | <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3ae559e3169016a3180c45c2828f391af2">irr::KEY_KEY_W</a>)) | ||
445 | { | ||
446 | meshnode->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3abc620823efed8d6bdbd46c8a0180893a" title="Draw as wireframe or filled triangles? Default: false.">video::EMF_WIREFRAME</a>, !meshnode->getMaterial(0).Wireframe); | ||
447 | } | ||
448 | <span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a61ec605d669b598d2e7106981a326fde">irr::KEY_KEY_1</a>)) | ||
449 | { | ||
450 | hm.generate(eggbox); | ||
451 | mesh.init(hm, 50.f, grey, driver); | ||
452 | } | ||
453 | <span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3aa7574bf313b5c29547f01c36f0a4a4f8">irr::KEY_KEY_2</a>)) | ||
454 | { | ||
455 | hm.generate(moresine); | ||
456 | mesh.init(hm, 50.f, yellow, driver); | ||
457 | } | ||
458 | <span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a577dcff3b86e6dd45f70d8c691dd3c91">irr::KEY_KEY_3</a>)) | ||
459 | { | ||
460 | hm.generate(justexp); | ||
461 | mesh.init(hm, 50.f, yellow, driver); | ||
462 | } | ||
463 | |||
464 | driver->beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, SColor(0xff000000)); | ||
465 | smgr->drawAll(); | ||
466 | driver->endScene(); | ||
467 | } | ||
468 | |||
469 | device->drop(); | ||
470 | |||
471 | <span class="keywordflow">return</span> 0; | ||
472 | } | ||
473 | </pre></div><p>That's it! Just compile and play around with the program. </p> | ||
474 | </div></div> | ||
475 | </div> | ||
476 | <div id="nav-path" class="navpath"> | ||
477 | <ul> | ||
478 | <!-- window showing the filter options --> | ||
479 | <div id="MSearchSelectWindow" | ||
480 | onmouseover="return searchBox.OnSearchSelectShow()" | ||
481 | onmouseout="return searchBox.OnSearchSelectHide()" | ||
482 | onkeydown="return searchBox.OnSearchSelectKey(event)"> | ||
483 | <a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Defines</a></div> | ||
484 | |||
485 | <!-- iframe showing the search results (closed by default) --> | ||
486 | <div id="MSearchResultsWindow"> | ||
487 | <iframe src="javascript:void(0)" frameborder="0" | ||
488 | name="MSearchResults" id="MSearchResults"> | ||
489 | </iframe> | ||
490 | </div> | ||
491 | |||
492 | |||
493 | <li class="footer"> | ||
494 | <a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht | ||
495 | Engine</a> Documentation © 2003-2012 by Nikolaus Gebhardt. Generated on Sun Nov 17 2013 20:18:41 for Irrlicht 3D Engine by | ||
496 | <a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li> | ||
497 | </ul> | ||
498 | </div> | ||
499 | |||
500 | |||
501 | </body> | ||
502 | </html> | ||