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 /src/others/irrlicht-1.8.1/examples/07.Collision/tutorial.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 'src/others/irrlicht-1.8.1/examples/07.Collision/tutorial.html')
-rw-r--r-- | src/others/irrlicht-1.8.1/examples/07.Collision/tutorial.html | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/examples/07.Collision/tutorial.html b/src/others/irrlicht-1.8.1/examples/07.Collision/tutorial.html new file mode 100644 index 0000000..c04fce9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/examples/07.Collision/tutorial.html | |||
@@ -0,0 +1,308 @@ | |||
1 | <html> | ||
2 | <head> | ||
3 | <title>Irrlicht Engine Tutorial</title> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
5 | </head> | ||
6 | |||
7 | <body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> | ||
8 | <br> | ||
9 | <table width="95%" border="0" cellspacing="0" cellpadding="2" align="center"> | ||
10 | <tr> | ||
11 | <td bgcolor="#666699" width="10"><b><a href="http://irrlicht.sourceforge.net" target="_blank"><img src="../../media/irrlichtlogo.jpg" width="88" height="31" border="0"></a></b></td> | ||
12 | <td bgcolor="#666699" width="100%"> | ||
13 | <div align="center"> | ||
14 | <div align="center"></div> | ||
15 | <div align="left"><b><font color="#FFFFFF">Tutorial 7. Collision detection | ||
16 | and response</font></b></div> | ||
17 | </div> | ||
18 | </td> | ||
19 | </tr> | ||
20 | <tr bgcolor="#eeeeff"> | ||
21 | <td height="90" colspan="2"> | ||
22 | <div align="left"> | ||
23 | <p>In this tutorial, I will show how to collision detection with the Irrlicht | ||
24 | Engine. I will describe 3 methods: Automatic collision detection for | ||
25 | moving through 3d worlds with stair climbing and sliding, manual triangle | ||
26 | picking and manual scene node picking.</p> | ||
27 | <p>The program which is described here will look like this:</p> | ||
28 | <p align="center"><img src="../../media/007shot.jpg" width="259" height="204"><br> | ||
29 | </p> | ||
30 | </div> | ||
31 | </td> | ||
32 | </tr> | ||
33 | </table> | ||
34 | <br> | ||
35 | <table width="95%" border="0" cellspacing="0" cellpadding="2" align="center"> | ||
36 | <tr> | ||
37 | <td bgcolor="#666699"> <div align="center"><b><font color="#FFFFFF"></font></b></div> | ||
38 | <b><font color="#FFFFFF">Lets start!</font></b></td> | ||
39 | </tr> | ||
40 | <tr> | ||
41 | <td height="90" bgcolor="#eeeeff" valign="top"> <div align="left"> | ||
42 | <div align="left"> | ||
43 | <p>To start, we take the program from tutorial 2, which loaded and displayed | ||
44 | a quake 3 level. We will use the level to walk in it and to pick triangles | ||
45 | from it. In addition we'll place 3 animated models into it for scene | ||
46 | node picking. The following code starts up the engine and loads a | ||
47 | quake 3 level. I will not explain it, because it should already be | ||
48 | known from tutorial 2.</p> | ||
49 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
50 | <tr> | ||
51 | <td> <pre><font size="2"><font color="#008000">#include <irrlicht.h> | ||
52 | #include <iostream><br> | ||
53 | </font><b>using namespace </b>irr; | ||
54 | |||
55 | <font color="#008000">#pragma comment(lib, "Irrlicht.lib") | ||
56 | |||
57 | </font><b>int </b>main() | ||
58 | { | ||
59 | <font color="#008000"> // let user select driver type</font> | ||
60 | <br> video::E_DRIVER_TYPE driverType;<br><br> printf("Please select the driver you want for this example:\n"\<br> " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\<br> " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\<br> " (f) NullDevice\n (otherKey) exit\n\n");<br><br> char i;<br> std::cin >> i;<br><br> switch(i)<br> {<br> case 'a': driverType = video::EDT_DIRECT3D9;break;<br> case 'b': driverType = video::EDT_DIRECT3D8;break;<br> case 'c': driverType = video::EDT_OPENGL; break;<br> case 'd': driverType = video::EDT_SOFTWARE; break;<br> case 'e': driverType = video::EDT_BURNINGSVIDEO;break; <br> case 'f': driverType = video::EDT_NULL; break;<br> default: return 0;<br> } <br> | ||
61 | <font color="#008000"> // create device</font></font></pre> | ||
62 | <pre> IrrlichtDevice *device = createDevice(driverType, | ||
63 | core::dimension2d<s32>(640, 480), 16, false);<br> | ||
64 | if (device == 0)<br> return 1; // could not create selected driver.<br><br> video::IVideoDriver* driver = device->getVideoDriver();<br> scene::ISceneManager* smgr = device->getSceneManager();<br><br> <font size="2">device->getFileSystem()->addZipFileArchive<br> (<font color="#FF0000">"../../media/map-20kdm2.pk3"</font>); | ||
65 | |||
66 | |||
67 | scene::IAnimatedMesh* q3levelmesh = smgr->getMesh(<font color="#FF0000">"20kdm2.bsp"</font>); | ||
68 | scene::ISceneNode* q3node = <font color="#800080">0</font>; | ||
69 | |||
70 | <b>if </b>(q3levelmesh) | ||
71 | q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(<font color="#800080">0</font>)); | ||
72 | </font></pre> | ||
73 | </td> | ||
74 | </tr> | ||
75 | </table> | ||
76 | <p> So far so good, we've loaded the quake 3 level like in tutorial | ||
77 | 2. Now, here comes something different: We create a triangle selector. | ||
78 | A triangle selector is a class which can fetch the triangles from | ||
79 | scene nodes for doing different things with them, for example collision | ||
80 | detection. There are different triangle selectors, and all can be | ||
81 | created with the ISceneManager. In this example, we create an OctTreeTriangleSelector, | ||
82 | which optimizes the triangle output a little bit by reducing it like | ||
83 | an octree. This is very useful for huge meshes like quake 3 levels.<br> | ||
84 | Afte we created the triangle selector, we attach it to the q3node. | ||
85 | This is not necessary, but in this way, we do not need to care for | ||
86 | the selector, for example dropping it after we do not need it anymore.</p> | ||
87 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
88 | <tr> | ||
89 | <td> <pre><font size="2">scene::ITriangleSelector* selector = <font color="#800080">0</font>; | ||
90 | |||
91 | <b>if </b>(q3node) | ||
92 | { | ||
93 | q3node->setPosition(core::vector3df(-<font color="#800080">1370</font>,-<font color="#800080">130</font>,-<font color="#800080">1400</font>)); | ||
94 | |||
95 | selector = smgr->createOctTreeTriangleSelector( | ||
96 | q3levelmesh->getMesh(<font color="#800080">0</font>), q3node, <font color="#800080">128</font>); | ||
97 | q3node->setTriangleSelector(selector); | ||
98 | }</font></pre></td> | ||
99 | </tr> | ||
100 | </table> | ||
101 | <p> We add a first person shooter camera to the scene for being able | ||
102 | to move in the quake 3 level like in tutorial 2. But this, time, we | ||
103 | add a special animator to the camera: A Collision Response animator. | ||
104 | This thing modifies the scene node to which it is attached to in that | ||
105 | way, that it may no more move through walls and is affected by gravity. | ||
106 | The only thing we have to tell the animator is how the world looks | ||
107 | like, how big the scene node is, how gravity and so on. After the | ||
108 | collision response animator is attached to the camera, we do not have | ||
109 | to do anything more for collision detection, anything is done automaticly, | ||
110 | all other collision detection code below is for picking. And please | ||
111 | note another cool feature: The collsion response animator can be attached | ||
112 | also to all other scene nodes, not only to cameras. And it can be | ||
113 | mixed with other scene node animators. In this way, collision detection | ||
114 | and response in the Irrlicht<br> | ||
115 | engine is really, really easy.<br> | ||
116 | Now we'll take a closer look on the parameters of createCollisionResponseAnimator(). | ||
117 | The first parameter is the TriangleSelector, which specifies how the | ||
118 | world, against collision detection is done looks like. The second | ||
119 | parameter is the scene node, which is the object, which is affected | ||
120 | by collision detection, in our case it is the camera. The third defines | ||
121 | how big the object is, it is the radius of an ellipsoid. Try it out | ||
122 | and change the radius to smaller values, the camera will be able to | ||
123 | move closer to walls after this. The next parameter is the direction | ||
124 | and speed of gravity. You could set it to (0,0,0) to disable gravity. | ||
125 | And the last value is just a translation: Without this, the ellipsoid | ||
126 | with which collision detection is done would be around the camera, | ||
127 | and the camera would be in the middle of the ellipsoid. But as human | ||
128 | beings, we are used to have our eyes on top of the body, with which | ||
129 | we collide with our world, not in the middle of it. So we place the | ||
130 | scene node 50 units over the center of the ellipsoid with this parameter. | ||
131 | And that's it, collision detection works now. <br> | ||
132 | </p> | ||
133 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
134 | <tr> | ||
135 | <td> <pre><font size="2"> scene::ICameraSceneNode* camera = <br> camera = smgr->addCameraSceneNodeFPS(<font color="#800080">0</font>,<font color="#800080">100.0f</font>,<font color="#800080">300.0f</font>); | ||
136 | camera->setPosition(core::vector3df(-10<font color="#800080">0</font>,<font color="#800080">50</font>,-15<font color="#800080">0</font>)); | ||
137 | |||
138 | scene::ISceneNodeAnimator* anim =<br> smgr->createCollisionResponseAnimator( | ||
139 | selector, camera, core::vector3df(<font color="#800080">30</font>,<font color="#800080">50</font>,<font color="#800080">30</font>), | ||
140 | core::vector3df(<font color="#800080">0</font>,<font color="#800080">-3</font>,<font color="#800080">0</font>), | ||
141 | core::vector3df(<font color="#800080">0</font>,<font color="#800080">50</font>,<font color="#800080">0</font>));<br> | ||
142 | selector->drop();<br> | ||
143 | camera->addAnimator(anim); | ||
144 | anim->drop();</font></pre></td> | ||
145 | </tr> | ||
146 | </table> | ||
147 | <p> Because collision detection is no big deal in irrlicht, I'll describe | ||
148 | how to do two different types of picking in the next section. But | ||
149 | before this, I'll prepare the scene a little. I need three animated | ||
150 | characters which we <br> | ||
151 | could pick later, a dynamic light for lighting them, a billboard for | ||
152 | drawing where we found an intersection, and, yes, I need to get rid | ||
153 | of this mouse cursor. :)</p> | ||
154 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
155 | <tr> | ||
156 | <td> <pre><font size="2"> <font color="#0A246A"><i>// disable mouse cursor | ||
157 | |||
158 | </i></font> device->getCursorControl()->setVisible(<b>false</b>); | ||
159 | |||
160 | <font color="#0A246A"><i>// add billboard | ||
161 | |||
162 | </i></font> scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode(); | ||
163 | bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); | ||
164 | bill->setMaterialTexture(<font color="#800080">0</font>, driver->getTexture(<br> <font color="#FF0000">"../../media/particle.bmp"</font>)); | ||
165 | bill->setMaterialFlag(video::EMF_LIGHTING, <b>false</b>); | ||
166 | bill->setSize(core::dimension2d<f32>(<font color="#800080">20.0f</font>, <font color="#800080">20.0f</font>)); | ||
167 | |||
168 | <font color="#0A246A"><i>// add 3 animated faeries. | ||
169 | |||
170 | </i></font> video::SMaterial material; | ||
171 | material.Texture1 = driver->getTexture(<font color="#FF0000"><br> "../../media/faerie2.bmp"</font>); | ||
172 | material.Lighting = <b>true</b>; | ||
173 | |||
174 | scene::IAnimatedMeshSceneNode* node = <font color="#800080">0</font>; | ||
175 | scene::IAnimatedMesh* faerie = smgr->getMesh(<br> <font color="#FF0000">"../../media/faerie.md2"</font>); | ||
176 | |||
177 | <b>if </b>(faerie) | ||
178 | { | ||
179 | node = smgr->addAnimatedMeshSceneNode(faerie); | ||
180 | node->setPosition(core::vector3df(-<font color="#800080">70</font>,<font color="#800080">0</font>,-<font color="#800080">90</font>)); | ||
181 | node->setMD2Animation(scene::EMAT_RUN); | ||
182 | node->getMaterial(<font color="#800080">0</font>) = material; | ||
183 | |||
184 | node = smgr->addAnimatedMeshSceneNode(faerie); | ||
185 | node->setPosition(core::vector3df(-<font color="#800080">70</font>,<font color="#800080">0</font>,-<font color="#800080">30</font>)); | ||
186 | node->setMD2Animation(scene::EMAT_SALUTE); | ||
187 | node->getMaterial(<font color="#800080">0</font>) = material; | ||
188 | |||
189 | node = smgr->addAnimatedMeshSceneNode(faerie); | ||
190 | node->setPosition(core::vector3df(-<font color="#800080">70</font>,<font color="#800080">0</font>,-<font color="#800080">60</font>)); | ||
191 | node->setMD2Animation(scene::EMAT_JUMP); | ||
192 | node->getMaterial(<font color="#800080">0</font>) = material; | ||
193 | } | ||
194 | |||
195 | material.Texture1 = <font color="#800080">0</font>; | ||
196 | material.Lighting = <b>false</b>; | ||
197 | |||
198 | <font color="#0A246A"><i>// Add a light | ||
199 | |||
200 | </i></font> smgr->addLightSceneNode(<font color="#800080">0</font>, core::vector3df(-<font color="#800080">60</font>,<font color="#800080">100</font>,<font color="#800080">400</font>), | ||
201 | video::SColorf(<font color="#800080">1.0f</font>,<font color="#800080">1.0f</font>,<font color="#800080">1.0f</font>,<font color="#800080">1.0f</font>), | ||
202 | <font color="#800080">600.0f</font>);</font></pre></td> | ||
203 | </tr> | ||
204 | </table> | ||
205 | <p>For not making it to complicated, I'm doing picking inside the drawing | ||
206 | loop. We take two pointers for storing the current and the last selected | ||
207 | scene node and start the loop.</p> | ||
208 | </div> | ||
209 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
210 | <tr> | ||
211 | <td> <pre><font size="2"> scene::ISceneNode* selectedSceneNode = <font color="#800080">0</font>; | ||
212 | scene::ISceneNode* lastSelectedSceneNode = <font color="#800080">0</font>; | ||
213 | |||
214 | |||
215 | <b>int </b>lastFPS = -<font color="#800080">1</font>; | ||
216 | |||
217 | <b>while</b>(device->run())<br> <strong>if</strong> (device->isWindowActive()) | ||
218 | { | ||
219 | driver->beginScene(<b>true</b>, <b>true</b>, <font color="#800080">0</font>); | ||
220 | |||
221 | smgr->drawAll();</font></pre></td> | ||
222 | </tr> | ||
223 | </table> | ||
224 | <p> After we've drawn the whole scene whit smgr->drawAll(), we'll do | ||
225 | the first picking: We want to know which triangle of the world we are | ||
226 | looking at. In addition, we want the exact point of the quake 3 level | ||
227 | we are looking at. For this, we create a 3d line starting at the position | ||
228 | of the camera and going through the lookAt-target of it. Then we ask | ||
229 | the collision manager if this line collides with a triangle of the world | ||
230 | stored in the triangle selector. If yes, we draw the 3d triangle and | ||
231 | set the position of the billboard to the intersection point. </p> | ||
232 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
233 | <tr> | ||
234 | <td><pre><font size="2"> core::line3d<f32> line; | ||
235 | line.start = camera->getPosition(); | ||
236 | line.end = line.start + | ||
237 | (camera->getTarget() - line.start).normalize() * <font color="#800080">1000.0f</font>; | ||
238 | |||
239 | core::vector3df intersection; | ||
240 | core::triangle3df tri; | ||
241 | |||
242 | <b>if </b>(smgr->getSceneCollisionManager()->getCollisionPoint( | ||
243 | line, selector, intersection, tri)) | ||
244 | { | ||
245 | bill->setPosition(intersection); | ||
246 | |||
247 | driver->setTransform(video::ETS_WORLD, core::matrix4()); | ||
248 | driver->setMaterial(material); | ||
249 | driver->draw3DTriangle(tri, video::SColor(<font color="#800080">0</font>,<font color="#800080">255</font>,<font color="#800080">0</font>,<font color="#800080">0</font>)); | ||
250 | }</font></pre></td> | ||
251 | </tr> | ||
252 | </table> | ||
253 | <p> Another type of picking supported by the Irrlicht Engine is scene | ||
254 | node picking based on bouding boxes. Every scene node has got a bounding | ||
255 | box, and because of that, it's very fast for example to get the scene | ||
256 | node which the camera looks<br> | ||
257 | at. Again, we ask the collision manager for this, and if we've got a | ||
258 | scene node, we highlight it by disabling Lighting in its material, if | ||
259 | it is not the billboard or the quake 3 level. </p> | ||
260 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
261 | <tr> | ||
262 | <td><pre><font size="2"> selectedSceneNode = smgr->getSceneCollisionManager()-> | ||
263 | getSceneNodeFromCameraBB(camera); | ||
264 | |||
265 | <b>if </b>(lastSelectedSceneNode) | ||
266 | lastSelectedSceneNode->setMaterialFlag( | ||
267 | video::EMF_LIGHTING, <b>true</b>); | ||
268 | |||
269 | <b>if </b>(selectedSceneNode == q3node || | ||
270 | selectedSceneNode == bill) | ||
271 | selectedSceneNode = <font color="#800080">0</font>; | ||
272 | |||
273 | <b>if </b>(selectedSceneNode) | ||
274 | selectedSceneNode->setMaterialFlag( | ||
275 | video::EMF_LIGHTING, <b>false</b>); | ||
276 | |||
277 | lastSelectedSceneNode = selectedSceneNode;</font></pre></td> | ||
278 | </tr> | ||
279 | </table> | ||
280 | <p> That's it, we just have to finish drawing.</p> | ||
281 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
282 | <tr> | ||
283 | <td> <pre><font size="2"> driver->endScene(); | ||
284 | |||
285 | <b>int </b>fps = driver->getFPS(); | ||
286 | |||
287 | <b>if </b>(lastFPS != fps) | ||
288 | { | ||
289 | core::stringw str = L"Collision detection example - Irrlicht Engine [";<br> str += driver->getName();<br> str += "] FPS:";<br> str += fps;<br><br> device->setWindowCaption(str.c_str());<br> lastFPS = fps;<br> } | ||
290 | } | ||
291 | |||
292 | device->drop(); | ||
293 | |||
294 | <b>return </b><font color="#800080">0</font>; | ||
295 | } | ||
296 | |||
297 | </font></pre></td> | ||
298 | </tr> | ||
299 | </table> | ||
300 | <p> </p> | ||
301 | <p> </p> | ||
302 | </div> | ||
303 | </td> | ||
304 | </tr> | ||
305 | </table> | ||
306 | <p> </p> | ||
307 | </body> | ||
308 | </html> | ||