diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8.1/examples/19.MouseAndJoystick/main.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/examples/19.MouseAndJoystick/main.cpp b/libraries/irrlicht-1.8.1/examples/19.MouseAndJoystick/main.cpp new file mode 100644 index 0000000..4563278 --- /dev/null +++ b/libraries/irrlicht-1.8.1/examples/19.MouseAndJoystick/main.cpp | |||
@@ -0,0 +1,285 @@ | |||
1 | /** Example 019 Mouse and Joystick | ||
2 | |||
3 | This tutorial builds on example 04.Movement which showed how to | ||
4 | handle keyboard events in Irrlicht. Here we'll handle mouse events | ||
5 | and joystick events, if you have a joystick connected and a device | ||
6 | that supports joysticks. These are currently Windows, Linux and SDL | ||
7 | devices. | ||
8 | */ | ||
9 | |||
10 | #ifdef _MSC_VER | ||
11 | // We'll define this to stop MSVC complaining about sprintf(). | ||
12 | #define _CRT_SECURE_NO_WARNINGS | ||
13 | #pragma comment(lib, "Irrlicht.lib") | ||
14 | #endif | ||
15 | |||
16 | #include <irrlicht.h> | ||
17 | #include "driverChoice.h" | ||
18 | |||
19 | using namespace irr; | ||
20 | |||
21 | /* | ||
22 | Just as we did in example 04.Movement, we'll store the latest state of the | ||
23 | mouse and the first joystick, updating them as we receive events. | ||
24 | */ | ||
25 | class MyEventReceiver : public IEventReceiver | ||
26 | { | ||
27 | public: | ||
28 | // We'll create a struct to record info on the mouse state | ||
29 | struct SMouseState | ||
30 | { | ||
31 | core::position2di Position; | ||
32 | bool LeftButtonDown; | ||
33 | SMouseState() : LeftButtonDown(false) { } | ||
34 | } MouseState; | ||
35 | |||
36 | // This is the one method that we have to implement | ||
37 | virtual bool OnEvent(const SEvent& event) | ||
38 | { | ||
39 | // Remember the mouse state | ||
40 | if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) | ||
41 | { | ||
42 | switch(event.MouseInput.Event) | ||
43 | { | ||
44 | case EMIE_LMOUSE_PRESSED_DOWN: | ||
45 | MouseState.LeftButtonDown = true; | ||
46 | break; | ||
47 | |||
48 | case EMIE_LMOUSE_LEFT_UP: | ||
49 | MouseState.LeftButtonDown = false; | ||
50 | break; | ||
51 | |||
52 | case EMIE_MOUSE_MOVED: | ||
53 | MouseState.Position.X = event.MouseInput.X; | ||
54 | MouseState.Position.Y = event.MouseInput.Y; | ||
55 | break; | ||
56 | |||
57 | default: | ||
58 | // We won't use the wheel | ||
59 | break; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | // The state of each connected joystick is sent to us | ||
64 | // once every run() of the Irrlicht device. Store the | ||
65 | // state of the first joystick, ignoring other joysticks. | ||
66 | // This is currently only supported on Windows and Linux. | ||
67 | if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT | ||
68 | && event.JoystickEvent.Joystick == 0) | ||
69 | { | ||
70 | JoystickState = event.JoystickEvent; | ||
71 | } | ||
72 | |||
73 | return false; | ||
74 | } | ||
75 | |||
76 | const SEvent::SJoystickEvent & GetJoystickState(void) const | ||
77 | { | ||
78 | return JoystickState; | ||
79 | } | ||
80 | |||
81 | const SMouseState & GetMouseState(void) const | ||
82 | { | ||
83 | return MouseState; | ||
84 | } | ||
85 | |||
86 | |||
87 | MyEventReceiver() | ||
88 | { | ||
89 | } | ||
90 | |||
91 | private: | ||
92 | SEvent::SJoystickEvent JoystickState; | ||
93 | }; | ||
94 | |||
95 | |||
96 | /* | ||
97 | The event receiver for keeping the pressed keys is ready, the actual responses | ||
98 | will be made inside the render loop, right before drawing the scene. So lets | ||
99 | just create an irr::IrrlichtDevice and the scene node we want to move. We also | ||
100 | create some other additional scene nodes, to show that there are also some | ||
101 | different possibilities to move and animate scene nodes. | ||
102 | */ | ||
103 | int main() | ||
104 | { | ||
105 | // ask user for driver | ||
106 | video::E_DRIVER_TYPE driverType=driverChoiceConsole(); | ||
107 | if (driverType==video::EDT_COUNT) | ||
108 | return 1; | ||
109 | |||
110 | // create device | ||
111 | MyEventReceiver receiver; | ||
112 | |||
113 | IrrlichtDevice* device = createDevice(driverType, | ||
114 | core::dimension2d<u32>(640, 480), 16, false, false, false, &receiver); | ||
115 | |||
116 | if (device == 0) | ||
117 | return 1; // could not create selected driver. | ||
118 | |||
119 | |||
120 | core::array<SJoystickInfo> joystickInfo; | ||
121 | if(device->activateJoysticks(joystickInfo)) | ||
122 | { | ||
123 | std::cout << "Joystick support is enabled and " << joystickInfo.size() << " joystick(s) are present." << std::endl; | ||
124 | |||
125 | for(u32 joystick = 0; joystick < joystickInfo.size(); ++joystick) | ||
126 | { | ||
127 | std::cout << "Joystick " << joystick << ":" << std::endl; | ||
128 | std::cout << "\tName: '" << joystickInfo[joystick].Name.c_str() << "'" << std::endl; | ||
129 | std::cout << "\tAxes: " << joystickInfo[joystick].Axes << std::endl; | ||
130 | std::cout << "\tButtons: " << joystickInfo[joystick].Buttons << std::endl; | ||
131 | |||
132 | std::cout << "\tHat is: "; | ||
133 | |||
134 | switch(joystickInfo[joystick].PovHat) | ||
135 | { | ||
136 | case SJoystickInfo::POV_HAT_PRESENT: | ||
137 | std::cout << "present" << std::endl; | ||
138 | break; | ||
139 | |||
140 | case SJoystickInfo::POV_HAT_ABSENT: | ||
141 | std::cout << "absent" << std::endl; | ||
142 | break; | ||
143 | |||
144 | case SJoystickInfo::POV_HAT_UNKNOWN: | ||
145 | default: | ||
146 | std::cout << "unknown" << std::endl; | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | std::cout << "Joystick support is not enabled." << std::endl; | ||
154 | } | ||
155 | |||
156 | core::stringw tmp = L"Irrlicht Joystick Example ("; | ||
157 | tmp += joystickInfo.size(); | ||
158 | tmp += " joysticks)"; | ||
159 | device->setWindowCaption(tmp.c_str()); | ||
160 | |||
161 | video::IVideoDriver* driver = device->getVideoDriver(); | ||
162 | scene::ISceneManager* smgr = device->getSceneManager(); | ||
163 | |||
164 | /* | ||
165 | We'll create an arrow mesh and move it around either with the joystick axis/hat, | ||
166 | or make it follow the mouse pointer. */ | ||
167 | scene::ISceneNode * node = smgr->addMeshSceneNode( | ||
168 | smgr->addArrowMesh( "Arrow", | ||
169 | video::SColor(255, 255, 0, 0), | ||
170 | video::SColor(255, 0, 255, 0), | ||
171 | 16,16, | ||
172 | 2.f, 1.3f, | ||
173 | 0.1f, 0.6f | ||
174 | ) | ||
175 | ); | ||
176 | node->setMaterialFlag(video::EMF_LIGHTING, false); | ||
177 | |||
178 | scene::ICameraSceneNode * camera = smgr->addCameraSceneNode(); | ||
179 | camera->setPosition(core::vector3df(0, 0, -10)); | ||
180 | |||
181 | // As in example 04, we'll use framerate independent movement. | ||
182 | u32 then = device->getTimer()->getTime(); | ||
183 | const f32 MOVEMENT_SPEED = 5.f; | ||
184 | |||
185 | while(device->run()) | ||
186 | { | ||
187 | // Work out a frame delta time. | ||
188 | const u32 now = device->getTimer()->getTime(); | ||
189 | const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds | ||
190 | then = now; | ||
191 | |||
192 | bool movedWithJoystick = false; | ||
193 | core::vector3df nodePosition = node->getPosition(); | ||
194 | |||
195 | if(joystickInfo.size() > 0) | ||
196 | { | ||
197 | f32 moveHorizontal = 0.f; // Range is -1.f for full left to +1.f for full right | ||
198 | f32 moveVertical = 0.f; // -1.f for full down to +1.f for full up. | ||
199 | |||
200 | const SEvent::SJoystickEvent & joystickData = receiver.GetJoystickState(); | ||
201 | |||
202 | // We receive the full analog range of the axes, and so have to implement our | ||
203 | // own dead zone. This is an empirical value, since some joysticks have more | ||
204 | // jitter or creep around the center point than others. We'll use 5% of the | ||
205 | // range as the dead zone, but generally you would want to give the user the | ||
206 | // option to change this. | ||
207 | const f32 DEAD_ZONE = 0.05f; | ||
208 | |||
209 | moveHorizontal = | ||
210 | (f32)joystickData.Axis[SEvent::SJoystickEvent::AXIS_X] / 32767.f; | ||
211 | if(fabs(moveHorizontal) < DEAD_ZONE) | ||
212 | moveHorizontal = 0.f; | ||
213 | |||
214 | moveVertical = | ||
215 | (f32)joystickData.Axis[SEvent::SJoystickEvent::AXIS_Y] / -32767.f; | ||
216 | if(fabs(moveVertical) < DEAD_ZONE) | ||
217 | moveVertical = 0.f; | ||
218 | |||
219 | // POV hat info is only currently supported on Windows, but the value is | ||
220 | // guaranteed to be 65535 if it's not supported, so we can check its range. | ||
221 | const u16 povDegrees = joystickData.POV / 100; | ||
222 | if(povDegrees < 360) | ||
223 | { | ||
224 | if(povDegrees > 0 && povDegrees < 180) | ||
225 | moveHorizontal = 1.f; | ||
226 | else if(povDegrees > 180) | ||
227 | moveHorizontal = -1.f; | ||
228 | |||
229 | if(povDegrees > 90 && povDegrees < 270) | ||
230 | moveVertical = -1.f; | ||
231 | else if(povDegrees > 270 || povDegrees < 90) | ||
232 | moveVertical = +1.f; | ||
233 | } | ||
234 | |||
235 | if(!core::equals(moveHorizontal, 0.f) || !core::equals(moveVertical, 0.f)) | ||
236 | { | ||
237 | nodePosition.X += MOVEMENT_SPEED * frameDeltaTime * moveHorizontal; | ||
238 | nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime * moveVertical; | ||
239 | movedWithJoystick = true; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | // If the arrow node isn't being moved with the joystick, then have it follow the mouse cursor. | ||
244 | if(!movedWithJoystick) | ||
245 | { | ||
246 | // Create a ray through the mouse cursor. | ||
247 | core::line3df ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( | ||
248 | receiver.GetMouseState().Position, camera); | ||
249 | |||
250 | // And intersect the ray with a plane around the node facing towards the camera. | ||
251 | core::plane3df plane(nodePosition, core::vector3df(0, 0, -1)); | ||
252 | core::vector3df mousePosition; | ||
253 | if(plane.getIntersectionWithLine(ray.start, ray.getVector(), mousePosition)) | ||
254 | { | ||
255 | // We now have a mouse position in 3d space; move towards it. | ||
256 | core::vector3df toMousePosition(mousePosition - nodePosition); | ||
257 | const f32 availableMovement = MOVEMENT_SPEED * frameDeltaTime; | ||
258 | |||
259 | if(toMousePosition.getLength() <= availableMovement) | ||
260 | nodePosition = mousePosition; // Jump to the final position | ||
261 | else | ||
262 | nodePosition += toMousePosition.normalize() * availableMovement; // Move towards it | ||
263 | } | ||
264 | } | ||
265 | |||
266 | node->setPosition(nodePosition); | ||
267 | |||
268 | // Turn lighting on and off depending on whether the left mouse button is down. | ||
269 | node->setMaterialFlag(video::EMF_LIGHTING, receiver.GetMouseState().LeftButtonDown); | ||
270 | |||
271 | driver->beginScene(true, true, video::SColor(255,113,113,133)); | ||
272 | smgr->drawAll(); // draw the 3d scene | ||
273 | driver->endScene(); | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | In the end, delete the Irrlicht device. | ||
278 | */ | ||
279 | device->drop(); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | **/ | ||