diff options
author | David Walter Seikel | 2013-01-13 18:54:10 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 18:54:10 +1000 |
commit | 959831f4ef5a3e797f576c3de08cd65032c997ad (patch) | |
tree | e7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/examples/07.Collision/main.cpp | |
parent | Add info about changes to Irrlicht. (diff) | |
download | SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2 SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz |
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/examples/07.Collision/main.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/examples/07.Collision/main.cpp | 660 |
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 | ||
3 | We will describe 2 methods: Automatic collision detection for moving through | 3 | We will describe 2 methods: Automatic collision detection for moving through |
4 | 3d worlds with stair climbing and sliding, and manual scene node and triangle | 4 | 3d worlds with stair climbing and sliding, and manual scene node and triangle |
5 | picking using a ray. In this case, we will use a ray coming out from the | 5 | picking using a ray. In this case, we will use a ray coming out from the |
6 | camera, but you can use any ray. | 6 | camera, but you can use any ray. |
7 | 7 | ||
8 | To start, we take the program from tutorial 2, which loads and displays a | 8 | To start, we take the program from tutorial 2, which loads and displays a |
9 | quake 3 level. We will use the level to walk in it and to pick triangles from. | 9 | quake 3 level. We will use the level to walk in it and to pick triangles from. |
10 | In addition we'll place 3 animated models into it for triangle picking. The | 10 | In addition we'll place 3 animated models into it for triangle picking. The |
11 | following code starts up the engine and loads the level, as per tutorial 2. | 11 | following 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 | ||
16 | using namespace irr; | 16 | using 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 | ||
22 | enum | 22 | enum |
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 | ||
38 | int main() | 38 | int 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 | ||