aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/examples/07.Collision/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/examples/07.Collision/main.cpp660
1 files changed, 330 insertions, 330 deletions
diff --git a/libraries/irrlicht-1.8/examples/07.Collision/main.cpp b/libraries/irrlicht-1.8/examples/07.Collision/main.cpp
index 8387c49..1846b12 100644
--- a/libraries/irrlicht-1.8/examples/07.Collision/main.cpp
+++ b/libraries/irrlicht-1.8/examples/07.Collision/main.cpp
@@ -1,330 +1,330 @@
1/** Example 007 Collision 1/** Example 007 Collision
2 2
3We will describe 2 methods: Automatic collision detection for moving through 3We will describe 2 methods: Automatic collision detection for moving through
43d worlds with stair climbing and sliding, and manual scene node and triangle 43d worlds with stair climbing and sliding, and manual scene node and triangle
5picking using a ray. In this case, we will use a ray coming out from the 5picking using a ray. In this case, we will use a ray coming out from the
6camera, but you can use any ray. 6camera, but you can use any ray.
7 7
8To start, we take the program from tutorial 2, which loads and displays a 8To start, we take the program from tutorial 2, which loads and displays a
9quake 3 level. We will use the level to walk in it and to pick triangles from. 9quake 3 level. We will use the level to walk in it and to pick triangles from.
10In addition we'll place 3 animated models into it for triangle picking. The 10In addition we'll place 3 animated models into it for triangle picking. The
11following code starts up the engine and loads the level, as per tutorial 2. 11following code starts up the engine and loads the level, as per tutorial 2.
12*/ 12*/
13#include <irrlicht.h> 13#include <irrlicht.h>
14#include "driverChoice.h" 14#include "driverChoice.h"
15 15
16using namespace irr; 16using namespace irr;
17 17
18#ifdef _MSC_VER 18#ifdef _MSC_VER
19#pragma comment(lib, "Irrlicht.lib") 19#pragma comment(lib, "Irrlicht.lib")
20#endif 20#endif
21 21
22enum 22enum
23{ 23{
24 // I use this ISceneNode ID to indicate a scene node that is 24 // I use this ISceneNode ID to indicate a scene node that is
25 // not pickable by getSceneNodeAndCollisionPointFromRay() 25 // not pickable by getSceneNodeAndCollisionPointFromRay()
26 ID_IsNotPickable = 0, 26 ID_IsNotPickable = 0,
27 27
28 // I use this flag in ISceneNode IDs to indicate that the 28 // I use this flag in ISceneNode IDs to indicate that the
29 // scene node can be picked by ray selection. 29 // scene node can be picked by ray selection.
30 IDFlag_IsPickable = 1 << 0, 30 IDFlag_IsPickable = 1 << 0,
31 31
32 // I use this flag in ISceneNode IDs to indicate that the 32 // I use this flag in ISceneNode IDs to indicate that the
33 // scene node can be highlighted. In this example, the 33 // scene node can be highlighted. In this example, the
34 // homonids can be highlighted, but the level mesh can't. 34 // homonids can be highlighted, but the level mesh can't.
35 IDFlag_IsHighlightable = 1 << 1 35 IDFlag_IsHighlightable = 1 << 1
36}; 36};
37 37
38int main() 38int main()
39{ 39{
40 // ask user for driver 40 // ask user for driver
41 video::E_DRIVER_TYPE driverType=driverChoiceConsole(); 41 video::E_DRIVER_TYPE driverType=driverChoiceConsole();
42 if (driverType==video::EDT_COUNT) 42 if (driverType==video::EDT_COUNT)
43 return 1; 43 return 1;
44 44
45 // create device 45 // create device
46 46
47 IrrlichtDevice *device = 47 IrrlichtDevice *device =
48 createDevice(driverType, core::dimension2d<u32>(640, 480), 16, false); 48 createDevice(driverType, core::dimension2d<u32>(640, 480), 16, false);
49 49
50 if (device == 0) 50 if (device == 0)
51 return 1; // could not create selected driver. 51 return 1; // could not create selected driver.
52 52
53 video::IVideoDriver* driver = device->getVideoDriver(); 53 video::IVideoDriver* driver = device->getVideoDriver();
54 scene::ISceneManager* smgr = device->getSceneManager(); 54 scene::ISceneManager* smgr = device->getSceneManager();
55 55
56 device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3"); 56 device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
57 57
58 scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp"); 58 scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
59 scene::IMeshSceneNode* q3node = 0; 59 scene::IMeshSceneNode* q3node = 0;
60 60
61 // The Quake mesh is pickable, but doesn't get highlighted. 61 // The Quake mesh is pickable, but doesn't get highlighted.
62 if (q3levelmesh) 62 if (q3levelmesh)
63 q3node = smgr->addOctreeSceneNode(q3levelmesh->getMesh(0), 0, IDFlag_IsPickable); 63 q3node = smgr->addOctreeSceneNode(q3levelmesh->getMesh(0), 0, IDFlag_IsPickable);
64 64
65 /* 65 /*
66 So far so good, we've loaded the quake 3 level like in tutorial 2. Now, 66 So far so good, we've loaded the quake 3 level like in tutorial 2. Now,
67 here comes something different: We create a triangle selector. A 67 here comes something different: We create a triangle selector. A
68 triangle selector is a class which can fetch the triangles from scene 68 triangle selector is a class which can fetch the triangles from scene
69 nodes for doing different things with them, for example collision 69 nodes for doing different things with them, for example collision
70 detection. There are different triangle selectors, and all can be 70 detection. There are different triangle selectors, and all can be
71 created with the ISceneManager. In this example, we create an 71 created with the ISceneManager. In this example, we create an
72 OctreeTriangleSelector, which optimizes the triangle output a little 72 OctreeTriangleSelector, which optimizes the triangle output a little
73 bit by reducing it like an octree. This is very useful for huge meshes 73 bit by reducing it like an octree. This is very useful for huge meshes
74 like quake 3 levels. After we created the triangle selector, we attach 74 like quake 3 levels. After we created the triangle selector, we attach
75 it to the q3node. This is not necessary, but in this way, we do not 75 it to the q3node. This is not necessary, but in this way, we do not
76 need to care for the selector, for example dropping it after we do not 76 need to care for the selector, for example dropping it after we do not
77 need it anymore. 77 need it anymore.
78 */ 78 */
79 79
80 scene::ITriangleSelector* selector = 0; 80 scene::ITriangleSelector* selector = 0;
81 81
82 if (q3node) 82 if (q3node)
83 { 83 {
84 q3node->setPosition(core::vector3df(-1350,-130,-1400)); 84 q3node->setPosition(core::vector3df(-1350,-130,-1400));
85 85
86 selector = smgr->createOctreeTriangleSelector( 86 selector = smgr->createOctreeTriangleSelector(
87 q3node->getMesh(), q3node, 128); 87 q3node->getMesh(), q3node, 128);
88 q3node->setTriangleSelector(selector); 88 q3node->setTriangleSelector(selector);
89 // We're not done with this selector yet, so don't drop it. 89 // We're not done with this selector yet, so don't drop it.
90 } 90 }
91 91
92 92
93 /* 93 /*
94 We add a first person shooter camera to the scene so that we can see and 94 We add a first person shooter camera to the scene so that we can see and
95 move in the quake 3 level like in tutorial 2. But this, time, we add a 95 move in the quake 3 level like in tutorial 2. But this, time, we add a
96 special animator to the camera: A Collision Response animator. This 96 special animator to the camera: A Collision Response animator. This
97 animator modifies the scene node to which it is attached to in order to 97 animator modifies the scene node to which it is attached to in order to
98 prevent it moving through walls, and to add gravity to it. The 98 prevent it moving through walls, and to add gravity to it. The
99 only thing we have to tell the animator is how the world looks like, 99 only thing we have to tell the animator is how the world looks like,
100 how big the scene node is, how much gravity to apply and so on. After the 100 how big the scene node is, how much gravity to apply and so on. After the
101 collision response animator is attached to the camera, we do not have to do 101 collision response animator is attached to the camera, we do not have to do
102 anything more for collision detection, anything is done automatically. 102 anything more for collision detection, anything is done automatically.
103 The rest of the collision detection code below is for picking. And please 103 The rest of the collision detection code below is for picking. And please
104 note another cool feature: The collision response animator can be 104 note another cool feature: The collision response animator can be
105 attached also to all other scene nodes, not only to cameras. And it can 105 attached also to all other scene nodes, not only to cameras. And it can
106 be mixed with other scene node animators. In this way, collision 106 be mixed with other scene node animators. In this way, collision
107 detection and response in the Irrlicht engine is really easy. 107 detection and response in the Irrlicht engine is really easy.
108 108
109 Now we'll take a closer look on the parameters of 109 Now we'll take a closer look on the parameters of
110 createCollisionResponseAnimator(). The first parameter is the 110 createCollisionResponseAnimator(). The first parameter is the
111 TriangleSelector, which specifies how the world, against collision 111 TriangleSelector, which specifies how the world, against collision
112 detection is done looks like. The second parameter is the scene node, 112 detection is done looks like. The second parameter is the scene node,
113 which is the object, which is affected by collision detection, in our 113 which is the object, which is affected by collision detection, in our
114 case it is the camera. The third defines how big the object is, it is 114 case it is the camera. The third defines how big the object is, it is
115 the radius of an ellipsoid. Try it out and change the radius to smaller 115 the radius of an ellipsoid. Try it out and change the radius to smaller
116 values, the camera will be able to move closer to walls after this. The 116 values, the camera will be able to move closer to walls after this. The
117 next parameter is the direction and speed of gravity. We'll set it to 117 next parameter is the direction and speed of gravity. We'll set it to
118 (0, -10, 0), which approximates to realistic gravity, assuming that our 118 (0, -10, 0), which approximates to realistic gravity, assuming that our
119 units are metres. You could set it to (0,0,0) to disable gravity. And the 119 units are metres. You could set it to (0,0,0) to disable gravity. And the
120 last value is just a translation: Without this, the ellipsoid with which 120 last value is just a translation: Without this, the ellipsoid with which
121 collision detection is done would be around the camera, and the camera would 121 collision detection is done would be around the camera, and the camera would
122 be in the middle of the ellipsoid. But as human beings, we are used to have our 122 be in the middle of the ellipsoid. But as human beings, we are used to have our
123 eyes on top of the body, with which we collide with our world, not in 123 eyes on top of the body, with which we collide with our world, not in
124 the middle of it. So we place the scene node 50 units over the center 124 the middle of it. So we place the scene node 50 units over the center
125 of the ellipsoid with this parameter. And that's it, collision 125 of the ellipsoid with this parameter. And that's it, collision
126 detection works now. 126 detection works now.
127 */ 127 */
128 128
129 // Set a jump speed of 3 units per second, which gives a fairly realistic jump 129 // Set a jump speed of 3 units per second, which gives a fairly realistic jump
130 // when used with the gravity of (0, -10, 0) in the collision response animator. 130 // when used with the gravity of (0, -10, 0) in the collision response animator.
131 scene::ICameraSceneNode* camera = 131 scene::ICameraSceneNode* camera =
132 smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f); 132 smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f);
133 camera->setPosition(core::vector3df(50,50,-60)); 133 camera->setPosition(core::vector3df(50,50,-60));
134 camera->setTarget(core::vector3df(-70,30,-60)); 134 camera->setTarget(core::vector3df(-70,30,-60));
135 135
136 if (selector) 136 if (selector)
137 { 137 {
138 scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( 138 scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
139 selector, camera, core::vector3df(30,50,30), 139 selector, camera, core::vector3df(30,50,30),
140 core::vector3df(0,-10,0), core::vector3df(0,30,0)); 140 core::vector3df(0,-10,0), core::vector3df(0,30,0));
141 selector->drop(); // As soon as we're done with the selector, drop it. 141 selector->drop(); // As soon as we're done with the selector, drop it.
142 camera->addAnimator(anim); 142 camera->addAnimator(anim);
143 anim->drop(); // And likewise, drop the animator when we're done referring to it. 143 anim->drop(); // And likewise, drop the animator when we're done referring to it.
144 } 144 }
145 145
146 // Now I create three animated characters which we can pick, a dynamic light for 146 // Now I create three animated characters which we can pick, a dynamic light for
147 // lighting them, and a billboard for drawing where we found an intersection. 147 // lighting them, and a billboard for drawing where we found an intersection.
148 148
149 // First, let's get rid of the mouse cursor. We'll use a billboard to show 149 // First, let's get rid of the mouse cursor. We'll use a billboard to show
150 // what we're looking at. 150 // what we're looking at.
151 device->getCursorControl()->setVisible(false); 151 device->getCursorControl()->setVisible(false);
152 152
153 // Add the billboard. 153 // Add the billboard.
154 scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode(); 154 scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
155 bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); 155 bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
156 bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp")); 156 bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
157 bill->setMaterialFlag(video::EMF_LIGHTING, false); 157 bill->setMaterialFlag(video::EMF_LIGHTING, false);
158 bill->setMaterialFlag(video::EMF_ZBUFFER, false); 158 bill->setMaterialFlag(video::EMF_ZBUFFER, false);
159 bill->setSize(core::dimension2d<f32>(20.0f, 20.0f)); 159 bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));
160 bill->setID(ID_IsNotPickable); // This ensures that we don't accidentally ray-pick it 160 bill->setID(ID_IsNotPickable); // This ensures that we don't accidentally ray-pick it
161 161
162 /* Add 3 animated hominids, which we can pick using a ray-triangle intersection. 162 /* Add 3 animated hominids, which we can pick using a ray-triangle intersection.
163 They all animate quite slowly, to make it easier to see that accurate triangle 163 They all animate quite slowly, to make it easier to see that accurate triangle
164 selection is being performed. */ 164 selection is being performed. */
165 scene::IAnimatedMeshSceneNode* node = 0; 165 scene::IAnimatedMeshSceneNode* node = 0;
166 166
167 video::SMaterial material; 167 video::SMaterial material;
168 168
169 // Add an MD2 node, which uses vertex-based animation. 169 // Add an MD2 node, which uses vertex-based animation.
170 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/faerie.md2"), 170 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/faerie.md2"),
171 0, IDFlag_IsPickable | IDFlag_IsHighlightable); 171 0, IDFlag_IsPickable | IDFlag_IsHighlightable);
172 node->setPosition(core::vector3df(-90,-15,-140)); // Put its feet on the floor. 172 node->setPosition(core::vector3df(-90,-15,-140)); // Put its feet on the floor.
173 node->setScale(core::vector3df(1.6f)); // Make it appear realistically scaled 173 node->setScale(core::vector3df(1.6f)); // Make it appear realistically scaled
174 node->setMD2Animation(scene::EMAT_POINT); 174 node->setMD2Animation(scene::EMAT_POINT);
175 node->setAnimationSpeed(20.f); 175 node->setAnimationSpeed(20.f);
176 material.setTexture(0, driver->getTexture("../../media/faerie2.bmp")); 176 material.setTexture(0, driver->getTexture("../../media/faerie2.bmp"));
177 material.Lighting = true; 177 material.Lighting = true;
178 material.NormalizeNormals = true; 178 material.NormalizeNormals = true;
179 node->getMaterial(0) = material; 179 node->getMaterial(0) = material;
180 180
181 // Now create a triangle selector for it. The selector will know that it 181 // Now create a triangle selector for it. The selector will know that it
182 // is associated with an animated node, and will update itself as necessary. 182 // is associated with an animated node, and will update itself as necessary.
183 selector = smgr->createTriangleSelector(node); 183 selector = smgr->createTriangleSelector(node);
184 node->setTriangleSelector(selector); 184 node->setTriangleSelector(selector);
185 selector->drop(); // We're done with this selector, so drop it now. 185 selector->drop(); // We're done with this selector, so drop it now.
186 186
187 // And this B3D file uses skinned skeletal animation. 187 // And this B3D file uses skinned skeletal animation.
188 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"), 188 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"),
189 0, IDFlag_IsPickable | IDFlag_IsHighlightable); 189 0, IDFlag_IsPickable | IDFlag_IsHighlightable);
190 node->setScale(core::vector3df(10)); 190 node->setScale(core::vector3df(10));
191 node->setPosition(core::vector3df(-75,-66,-80)); 191 node->setPosition(core::vector3df(-75,-66,-80));
192 node->setRotation(core::vector3df(0,90,0)); 192 node->setRotation(core::vector3df(0,90,0));
193 node->setAnimationSpeed(8.f); 193 node->setAnimationSpeed(8.f);
194 node->getMaterial(0).NormalizeNormals = true; 194 node->getMaterial(0).NormalizeNormals = true;
195 node->getMaterial(0).Lighting = true; 195 node->getMaterial(0).Lighting = true;
196 // Just do the same as we did above. 196 // Just do the same as we did above.
197 selector = smgr->createTriangleSelector(node); 197 selector = smgr->createTriangleSelector(node);
198 node->setTriangleSelector(selector); 198 node->setTriangleSelector(selector);
199 selector->drop(); 199 selector->drop();
200 200
201 // This X files uses skeletal animation, but without skinning. 201 // This X files uses skeletal animation, but without skinning.
202 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/dwarf.x"), 202 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/dwarf.x"),
203 0, IDFlag_IsPickable | IDFlag_IsHighlightable); 203 0, IDFlag_IsPickable | IDFlag_IsHighlightable);
204 node->setPosition(core::vector3df(-70,-66,-30)); // Put its feet on the floor. 204 node->setPosition(core::vector3df(-70,-66,-30)); // Put its feet on the floor.
205 node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera. 205 node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
206 node->setAnimationSpeed(20.f); 206 node->setAnimationSpeed(20.f);
207 node->getMaterial(0).Lighting = true; 207 node->getMaterial(0).Lighting = true;
208 selector = smgr->createTriangleSelector(node); 208 selector = smgr->createTriangleSelector(node);
209 node->setTriangleSelector(selector); 209 node->setTriangleSelector(selector);
210 selector->drop(); 210 selector->drop();
211 211
212 212
213 // And this mdl file uses skinned skeletal animation. 213 // And this mdl file uses skinned skeletal animation.
214 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/yodan.mdl"), 214 node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/yodan.mdl"),
215 0, IDFlag_IsPickable | IDFlag_IsHighlightable); 215 0, IDFlag_IsPickable | IDFlag_IsHighlightable);
216 node->setPosition(core::vector3df(-90,-25,20)); 216 node->setPosition(core::vector3df(-90,-25,20));
217 node->setScale(core::vector3df(0.8f)); 217 node->setScale(core::vector3df(0.8f));
218 node->getMaterial(0).Lighting = true; 218 node->getMaterial(0).Lighting = true;
219 node->setAnimationSpeed(20.f); 219 node->setAnimationSpeed(20.f);
220 220
221 // Just do the same as we did above. 221 // Just do the same as we did above.
222 selector = smgr->createTriangleSelector(node); 222 selector = smgr->createTriangleSelector(node);
223 node->setTriangleSelector(selector); 223 node->setTriangleSelector(selector);
224 selector->drop(); 224 selector->drop();
225 225
226 material.setTexture(0, 0); 226 material.setTexture(0, 0);
227 material.Lighting = false; 227 material.Lighting = false;
228 228
229 // Add a light, so that the unselected nodes aren't completely dark. 229 // Add a light, so that the unselected nodes aren't completely dark.
230 scene::ILightSceneNode * light = smgr->addLightSceneNode(0, core::vector3df(-60,100,400), 230 scene::ILightSceneNode * light = smgr->addLightSceneNode(0, core::vector3df(-60,100,400),
231 video::SColorf(1.0f,1.0f,1.0f,1.0f), 600.0f); 231 video::SColorf(1.0f,1.0f,1.0f,1.0f), 600.0f);
232 light->setID(ID_IsNotPickable); // Make it an invalid target for selection. 232 light->setID(ID_IsNotPickable); // Make it an invalid target for selection.
233 233
234 // Remember which scene node is highlighted 234 // Remember which scene node is highlighted
235 scene::ISceneNode* highlightedSceneNode = 0; 235 scene::ISceneNode* highlightedSceneNode = 0;
236 scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager(); 236 scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
237 int lastFPS = -1; 237 int lastFPS = -1;
238 238
239 // draw the selection triangle only as wireframe 239 // draw the selection triangle only as wireframe
240 material.Wireframe=true; 240 material.Wireframe=true;
241 241
242 while(device->run()) 242 while(device->run())
243 if (device->isWindowActive()) 243 if (device->isWindowActive())
244 { 244 {
245 driver->beginScene(true, true, 0); 245 driver->beginScene(true, true, 0);
246 smgr->drawAll(); 246 smgr->drawAll();
247 247
248 // Unlight any currently highlighted scene node 248 // Unlight any currently highlighted scene node
249 if (highlightedSceneNode) 249 if (highlightedSceneNode)
250 { 250 {
251 highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, true); 251 highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, true);
252 highlightedSceneNode = 0; 252 highlightedSceneNode = 0;
253 } 253 }
254 254
255 // All intersections in this example are done with a ray cast out from the camera to 255 // All intersections in this example are done with a ray cast out from the camera to
256 // a distance of 1000. You can easily modify this to check (e.g.) a bullet 256 // a distance of 1000. You can easily modify this to check (e.g.) a bullet
257 // trajectory or a sword's position, or create a ray from a mouse click position using 257 // trajectory or a sword's position, or create a ray from a mouse click position using
258 // ISceneCollisionManager::getRayFromScreenCoordinates() 258 // ISceneCollisionManager::getRayFromScreenCoordinates()
259 core::line3d<f32> ray; 259 core::line3d<f32> ray;
260 ray.start = camera->getPosition(); 260 ray.start = camera->getPosition();
261 ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f; 261 ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f;
262 262
263 // Tracks the current intersection point with the level or a mesh 263 // Tracks the current intersection point with the level or a mesh
264 core::vector3df intersection; 264 core::vector3df intersection;
265 // Used to show with triangle has been hit 265 // Used to show with triangle has been hit
266 core::triangle3df hitTriangle; 266 core::triangle3df hitTriangle;
267 267
268 // This call is all you need to perform ray/triangle collision on every scene node 268 // This call is all you need to perform ray/triangle collision on every scene node
269 // that has a triangle selector, including the Quake level mesh. It finds the nearest 269 // that has a triangle selector, including the Quake level mesh. It finds the nearest
270 // collision point/triangle, and returns the scene node containing that point. 270 // collision point/triangle, and returns the scene node containing that point.
271 // Irrlicht provides other types of selection, including ray/triangle selector, 271 // Irrlicht provides other types of selection, including ray/triangle selector,
272 // ray/box and ellipse/triangle selector, plus associated helpers. 272 // ray/box and ellipse/triangle selector, plus associated helpers.
273 // See the methods of ISceneCollisionManager 273 // See the methods of ISceneCollisionManager
274 scene::ISceneNode * selectedSceneNode = 274 scene::ISceneNode * selectedSceneNode =
275 collMan->getSceneNodeAndCollisionPointFromRay( 275 collMan->getSceneNodeAndCollisionPointFromRay(
276 ray, 276 ray,
277 intersection, // This will be the position of the collision 277 intersection, // This will be the position of the collision
278 hitTriangle, // This will be the triangle hit in the collision 278 hitTriangle, // This will be the triangle hit in the collision
279 IDFlag_IsPickable, // This ensures that only nodes that we have 279 IDFlag_IsPickable, // This ensures that only nodes that we have
280 // set up to be pickable are considered 280 // set up to be pickable are considered
281 0); // Check the entire scene (this is actually the implicit default) 281 0); // Check the entire scene (this is actually the implicit default)
282 282
283 // If the ray hit anything, move the billboard to the collision position 283 // If the ray hit anything, move the billboard to the collision position
284 // and draw the triangle that was hit. 284 // and draw the triangle that was hit.
285 if(selectedSceneNode) 285 if(selectedSceneNode)
286 { 286 {
287 bill->setPosition(intersection); 287 bill->setPosition(intersection);
288 288
289 // We need to reset the transform before doing our own rendering. 289 // We need to reset the transform before doing our own rendering.
290 driver->setTransform(video::ETS_WORLD, core::matrix4()); 290 driver->setTransform(video::ETS_WORLD, core::matrix4());
291 driver->setMaterial(material); 291 driver->setMaterial(material);
292 driver->draw3DTriangle(hitTriangle, video::SColor(0,255,0,0)); 292 driver->draw3DTriangle(hitTriangle, video::SColor(0,255,0,0));
293 293
294 // We can check the flags for the scene node that was hit to see if it should be 294 // We can check the flags for the scene node that was hit to see if it should be
295 // highlighted. The animated nodes can be highlighted, but not the Quake level mesh 295 // highlighted. The animated nodes can be highlighted, but not the Quake level mesh
296 if((selectedSceneNode->getID() & IDFlag_IsHighlightable) == IDFlag_IsHighlightable) 296 if((selectedSceneNode->getID() & IDFlag_IsHighlightable) == IDFlag_IsHighlightable)
297 { 297 {
298 highlightedSceneNode = selectedSceneNode; 298 highlightedSceneNode = selectedSceneNode;
299 299
300 // Highlighting in this case means turning lighting OFF for this node, 300 // Highlighting in this case means turning lighting OFF for this node,
301 // which means that it will be drawn with full brightness. 301 // which means that it will be drawn with full brightness.
302 highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false); 302 highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false);
303 } 303 }
304 } 304 }
305 305
306 // We're all done drawing, so end the scene. 306 // We're all done drawing, so end the scene.
307 driver->endScene(); 307 driver->endScene();
308 308
309 int fps = driver->getFPS(); 309 int fps = driver->getFPS();
310 310
311 if (lastFPS != fps) 311 if (lastFPS != fps)
312 { 312 {
313 core::stringw str = L"Collision detection example - Irrlicht Engine ["; 313 core::stringw str = L"Collision detection example - Irrlicht Engine [";
314 str += driver->getName(); 314 str += driver->getName();
315 str += "] FPS:"; 315 str += "] FPS:";
316 str += fps; 316 str += fps;
317 317
318 device->setWindowCaption(str.c_str()); 318 device->setWindowCaption(str.c_str());
319 lastFPS = fps; 319 lastFPS = fps;
320 } 320 }
321 } 321 }
322 322
323 device->drop(); 323 device->drop();
324 324
325 return 0; 325 return 0;
326} 326}
327 327
328/* 328/*
329**/ 329**/
330 330