aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp710
1 files changed, 355 insertions, 355 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp
index 5612f8a..4ba0f64 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp
@@ -1,355 +1,355 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "CSceneNodeAnimatorCameraFPS.h" 5#include "CSceneNodeAnimatorCameraFPS.h"
6#include "IVideoDriver.h" 6#include "IVideoDriver.h"
7#include "ISceneManager.h" 7#include "ISceneManager.h"
8#include "Keycodes.h" 8#include "Keycodes.h"
9#include "ICursorControl.h" 9#include "ICursorControl.h"
10#include "ICameraSceneNode.h" 10#include "ICameraSceneNode.h"
11#include "ISceneNodeAnimatorCollisionResponse.h" 11#include "ISceneNodeAnimatorCollisionResponse.h"
12 12
13namespace irr 13namespace irr
14{ 14{
15namespace scene 15namespace scene
16{ 16{
17 17
18//! constructor 18//! constructor
19CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl, 19CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl,
20 f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed, 20 f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed,
21 SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY) 21 SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY)
22: CursorControl(cursorControl), MaxVerticalAngle(88.0f), 22: CursorControl(cursorControl), MaxVerticalAngle(88.0f),
23 MoveSpeed(moveSpeed), RotateSpeed(rotateSpeed), JumpSpeed(jumpSpeed), 23 MoveSpeed(moveSpeed), RotateSpeed(rotateSpeed), JumpSpeed(jumpSpeed),
24 MouseYDirection(invertY ? -1.0f : 1.0f), 24 MouseYDirection(invertY ? -1.0f : 1.0f),
25 LastAnimationTime(0), firstUpdate(true), firstInput(true), NoVerticalMovement(noVerticalMovement) 25 LastAnimationTime(0), firstUpdate(true), firstInput(true), NoVerticalMovement(noVerticalMovement)
26{ 26{
27 #ifdef _DEBUG 27 #ifdef _DEBUG
28 setDebugName("CCameraSceneNodeAnimatorFPS"); 28 setDebugName("CCameraSceneNodeAnimatorFPS");
29 #endif 29 #endif
30 30
31 if (CursorControl) 31 if (CursorControl)
32 CursorControl->grab(); 32 CursorControl->grab();
33 33
34 allKeysUp(); 34 allKeysUp();
35 35
36 // create key map 36 // create key map
37 if (!keyMapArray || !keyMapSize) 37 if (!keyMapArray || !keyMapSize)
38 { 38 {
39 // create default key map 39 // create default key map
40 KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP)); 40 KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP));
41 KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN)); 41 KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN));
42 KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT)); 42 KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT));
43 KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT)); 43 KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT));
44 KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J)); 44 KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J));
45 } 45 }
46 else 46 else
47 { 47 {
48 // create custom key map 48 // create custom key map
49 setKeyMap(keyMapArray, keyMapSize); 49 setKeyMap(keyMapArray, keyMapSize);
50 } 50 }
51} 51}
52 52
53 53
54//! destructor 54//! destructor
55CSceneNodeAnimatorCameraFPS::~CSceneNodeAnimatorCameraFPS() 55CSceneNodeAnimatorCameraFPS::~CSceneNodeAnimatorCameraFPS()
56{ 56{
57 if (CursorControl) 57 if (CursorControl)
58 CursorControl->drop(); 58 CursorControl->drop();
59} 59}
60 60
61 61
62//! It is possible to send mouse and key events to the camera. Most cameras 62//! It is possible to send mouse and key events to the camera. Most cameras
63//! may ignore this input, but camera scene nodes which are created for 63//! may ignore this input, but camera scene nodes which are created for
64//! example with scene::ISceneManager::addMayaCameraSceneNode or 64//! example with scene::ISceneManager::addMayaCameraSceneNode or
65//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input 65//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input
66//! for changing their position, look at target or whatever. 66//! for changing their position, look at target or whatever.
67bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt) 67bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt)
68{ 68{
69 switch(evt.EventType) 69 switch(evt.EventType)
70 { 70 {
71 case EET_KEY_INPUT_EVENT: 71 case EET_KEY_INPUT_EVENT:
72 for (u32 i=0; i<KeyMap.size(); ++i) 72 for (u32 i=0; i<KeyMap.size(); ++i)
73 { 73 {
74 if (KeyMap[i].KeyCode == evt.KeyInput.Key) 74 if (KeyMap[i].KeyCode == evt.KeyInput.Key)
75 { 75 {
76 CursorKeys[KeyMap[i].Action] = evt.KeyInput.PressedDown; 76 CursorKeys[KeyMap[i].Action] = evt.KeyInput.PressedDown;
77 return true; 77 return true;
78 } 78 }
79 } 79 }
80 break; 80 break;
81 81
82 case EET_MOUSE_INPUT_EVENT: 82 case EET_MOUSE_INPUT_EVENT:
83 if (evt.MouseInput.Event == EMIE_MOUSE_MOVED) 83 if (evt.MouseInput.Event == EMIE_MOUSE_MOVED)
84 { 84 {
85 CursorPos = CursorControl->getRelativePosition(); 85 CursorPos = CursorControl->getRelativePosition();
86 return true; 86 return true;
87 } 87 }
88 break; 88 break;
89 89
90 default: 90 default:
91 break; 91 break;
92 } 92 }
93 93
94 return false; 94 return false;
95} 95}
96 96
97 97
98void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) 98void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
99{ 99{
100 if (!node || node->getType() != ESNT_CAMERA) 100 if (!node || node->getType() != ESNT_CAMERA)
101 return; 101 return;
102 102
103 ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node); 103 ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);
104 104
105 if (firstUpdate) 105 if (firstUpdate)
106 { 106 {
107 camera->updateAbsolutePosition(); 107 camera->updateAbsolutePosition();
108 if (CursorControl ) 108 if (CursorControl )
109 { 109 {
110 CursorControl->setPosition(0.5f, 0.5f); 110 CursorControl->setPosition(0.5f, 0.5f);
111 CursorPos = CenterCursor = CursorControl->getRelativePosition(); 111 CursorPos = CenterCursor = CursorControl->getRelativePosition();
112 } 112 }
113 113
114 LastAnimationTime = timeMs; 114 LastAnimationTime = timeMs;
115 115
116 firstUpdate = false; 116 firstUpdate = false;
117 } 117 }
118 118
119 // If the camera isn't the active camera, and receiving input, then don't process it. 119 // If the camera isn't the active camera, and receiving input, then don't process it.
120 if(!camera->isInputReceiverEnabled()) 120 if(!camera->isInputReceiverEnabled())
121 { 121 {
122 firstInput = true; 122 firstInput = true;
123 return; 123 return;
124 } 124 }
125 125
126 if ( firstInput ) 126 if ( firstInput )
127 { 127 {
128 allKeysUp(); 128 allKeysUp();
129 firstInput = false; 129 firstInput = false;
130 } 130 }
131 131
132 scene::ISceneManager * smgr = camera->getSceneManager(); 132 scene::ISceneManager * smgr = camera->getSceneManager();
133 if(smgr && smgr->getActiveCamera() != camera) 133 if(smgr && smgr->getActiveCamera() != camera)
134 return; 134 return;
135 135
136 // get time 136 // get time
137 f32 timeDiff = (f32) ( timeMs - LastAnimationTime ); 137 f32 timeDiff = (f32) ( timeMs - LastAnimationTime );
138 LastAnimationTime = timeMs; 138 LastAnimationTime = timeMs;
139 139
140 // update position 140 // update position
141 core::vector3df pos = camera->getPosition(); 141 core::vector3df pos = camera->getPosition();
142 142
143 // Update rotation 143 // Update rotation
144 core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); 144 core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition());
145 core::vector3df relativeRotation = target.getHorizontalAngle(); 145 core::vector3df relativeRotation = target.getHorizontalAngle();
146 146
147 if (CursorControl) 147 if (CursorControl)
148 { 148 {
149 if (CursorPos != CenterCursor) 149 if (CursorPos != CenterCursor)
150 { 150 {
151 relativeRotation.Y -= (0.5f - CursorPos.X) * RotateSpeed; 151 relativeRotation.Y -= (0.5f - CursorPos.X) * RotateSpeed;
152 relativeRotation.X -= (0.5f - CursorPos.Y) * RotateSpeed * MouseYDirection; 152 relativeRotation.X -= (0.5f - CursorPos.Y) * RotateSpeed * MouseYDirection;
153 153
154 // X < MaxVerticalAngle or X > 360-MaxVerticalAngle 154 // X < MaxVerticalAngle or X > 360-MaxVerticalAngle
155 155
156 if (relativeRotation.X > MaxVerticalAngle*2 && 156 if (relativeRotation.X > MaxVerticalAngle*2 &&
157 relativeRotation.X < 360.0f-MaxVerticalAngle) 157 relativeRotation.X < 360.0f-MaxVerticalAngle)
158 { 158 {
159 relativeRotation.X = 360.0f-MaxVerticalAngle; 159 relativeRotation.X = 360.0f-MaxVerticalAngle;
160 } 160 }
161 else 161 else
162 if (relativeRotation.X > MaxVerticalAngle && 162 if (relativeRotation.X > MaxVerticalAngle &&
163 relativeRotation.X < 360.0f-MaxVerticalAngle) 163 relativeRotation.X < 360.0f-MaxVerticalAngle)
164 { 164 {
165 relativeRotation.X = MaxVerticalAngle; 165 relativeRotation.X = MaxVerticalAngle;
166 } 166 }
167 167
168 // Do the fix as normal, special case below 168 // Do the fix as normal, special case below
169 // reset cursor position to the centre of the window. 169 // reset cursor position to the centre of the window.
170 CursorControl->setPosition(0.5f, 0.5f); 170 CursorControl->setPosition(0.5f, 0.5f);
171 CenterCursor = CursorControl->getRelativePosition(); 171 CenterCursor = CursorControl->getRelativePosition();
172 172
173 // needed to avoid problems when the event receiver is disabled 173 // needed to avoid problems when the event receiver is disabled
174 CursorPos = CenterCursor; 174 CursorPos = CenterCursor;
175 } 175 }
176 176
177 // Special case, mouse is whipped outside of window before it can update. 177 // Special case, mouse is whipped outside of window before it can update.
178 video::IVideoDriver* driver = smgr->getVideoDriver(); 178 video::IVideoDriver* driver = smgr->getVideoDriver();
179 core::vector2d<u32> mousepos(u32(CursorControl->getPosition().X), u32(CursorControl->getPosition().Y)); 179 core::vector2d<u32> mousepos(u32(CursorControl->getPosition().X), u32(CursorControl->getPosition().Y));
180 core::rect<u32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); 180 core::rect<u32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height);
181 181
182 // Only if we are moving outside quickly. 182 // Only if we are moving outside quickly.
183 bool reset = !screenRect.isPointInside(mousepos); 183 bool reset = !screenRect.isPointInside(mousepos);
184 184
185 if(reset) 185 if(reset)
186 { 186 {
187 // Force a reset. 187 // Force a reset.
188 CursorControl->setPosition(0.5f, 0.5f); 188 CursorControl->setPosition(0.5f, 0.5f);
189 CenterCursor = CursorControl->getRelativePosition(); 189 CenterCursor = CursorControl->getRelativePosition();
190 CursorPos = CenterCursor; 190 CursorPos = CenterCursor;
191 } 191 }
192 } 192 }
193 193
194 // set target 194 // set target
195 195
196 target.set(0,0, core::max_(1.f, pos.getLength())); 196 target.set(0,0, core::max_(1.f, pos.getLength()));
197 core::vector3df movedir = target; 197 core::vector3df movedir = target;
198 198
199 core::matrix4 mat; 199 core::matrix4 mat;
200 mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0)); 200 mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0));
201 mat.transformVect(target); 201 mat.transformVect(target);
202 202
203 if (NoVerticalMovement) 203 if (NoVerticalMovement)
204 { 204 {
205 mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0)); 205 mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0));
206 mat.transformVect(movedir); 206 mat.transformVect(movedir);
207 } 207 }
208 else 208 else
209 { 209 {
210 movedir = target; 210 movedir = target;
211 } 211 }
212 212
213 movedir.normalize(); 213 movedir.normalize();
214 214
215 if (CursorKeys[EKA_MOVE_FORWARD]) 215 if (CursorKeys[EKA_MOVE_FORWARD])
216 pos += movedir * timeDiff * MoveSpeed; 216 pos += movedir * timeDiff * MoveSpeed;
217 217
218 if (CursorKeys[EKA_MOVE_BACKWARD]) 218 if (CursorKeys[EKA_MOVE_BACKWARD])
219 pos -= movedir * timeDiff * MoveSpeed; 219 pos -= movedir * timeDiff * MoveSpeed;
220 220
221 // strafing 221 // strafing
222 222
223 core::vector3df strafevect = target; 223 core::vector3df strafevect = target;
224 strafevect = strafevect.crossProduct(camera->getUpVector()); 224 strafevect = strafevect.crossProduct(camera->getUpVector());
225 225
226 if (NoVerticalMovement) 226 if (NoVerticalMovement)
227 strafevect.Y = 0.0f; 227 strafevect.Y = 0.0f;
228 228
229 strafevect.normalize(); 229 strafevect.normalize();
230 230
231 if (CursorKeys[EKA_STRAFE_LEFT]) 231 if (CursorKeys[EKA_STRAFE_LEFT])
232 pos += strafevect * timeDiff * MoveSpeed; 232 pos += strafevect * timeDiff * MoveSpeed;
233 233
234 if (CursorKeys[EKA_STRAFE_RIGHT]) 234 if (CursorKeys[EKA_STRAFE_RIGHT])
235 pos -= strafevect * timeDiff * MoveSpeed; 235 pos -= strafevect * timeDiff * MoveSpeed;
236 236
237 // For jumping, we find the collision response animator attached to our camera 237 // For jumping, we find the collision response animator attached to our camera
238 // and if it's not falling, we tell it to jump. 238 // and if it's not falling, we tell it to jump.
239 if (CursorKeys[EKA_JUMP_UP]) 239 if (CursorKeys[EKA_JUMP_UP])
240 { 240 {
241 const ISceneNodeAnimatorList& animators = camera->getAnimators(); 241 const ISceneNodeAnimatorList& animators = camera->getAnimators();
242 ISceneNodeAnimatorList::ConstIterator it = animators.begin(); 242 ISceneNodeAnimatorList::ConstIterator it = animators.begin();
243 while(it != animators.end()) 243 while(it != animators.end())
244 { 244 {
245 if(ESNAT_COLLISION_RESPONSE == (*it)->getType()) 245 if(ESNAT_COLLISION_RESPONSE == (*it)->getType())
246 { 246 {
247 ISceneNodeAnimatorCollisionResponse * collisionResponse = 247 ISceneNodeAnimatorCollisionResponse * collisionResponse =
248 static_cast<ISceneNodeAnimatorCollisionResponse *>(*it); 248 static_cast<ISceneNodeAnimatorCollisionResponse *>(*it);
249 249
250 if(!collisionResponse->isFalling()) 250 if(!collisionResponse->isFalling())
251 collisionResponse->jump(JumpSpeed); 251 collisionResponse->jump(JumpSpeed);
252 } 252 }
253 253
254 it++; 254 it++;
255 } 255 }
256 } 256 }
257 257
258 // write translation 258 // write translation
259 camera->setPosition(pos); 259 camera->setPosition(pos);
260 260
261 // write right target 261 // write right target
262 target += pos; 262 target += pos;
263 camera->setTarget(target); 263 camera->setTarget(target);
264} 264}
265 265
266 266
267void CSceneNodeAnimatorCameraFPS::allKeysUp() 267void CSceneNodeAnimatorCameraFPS::allKeysUp()
268{ 268{
269 for (u32 i=0; i<EKA_COUNT; ++i) 269 for (u32 i=0; i<EKA_COUNT; ++i)
270 CursorKeys[i] = false; 270 CursorKeys[i] = false;
271} 271}
272 272
273 273
274//! Sets the rotation speed 274//! Sets the rotation speed
275void CSceneNodeAnimatorCameraFPS::setRotateSpeed(f32 speed) 275void CSceneNodeAnimatorCameraFPS::setRotateSpeed(f32 speed)
276{ 276{
277 RotateSpeed = speed; 277 RotateSpeed = speed;
278} 278}
279 279
280 280
281//! Sets the movement speed 281//! Sets the movement speed
282void CSceneNodeAnimatorCameraFPS::setMoveSpeed(f32 speed) 282void CSceneNodeAnimatorCameraFPS::setMoveSpeed(f32 speed)
283{ 283{
284 MoveSpeed = speed; 284 MoveSpeed = speed;
285} 285}
286 286
287 287
288//! Gets the rotation speed 288//! Gets the rotation speed
289f32 CSceneNodeAnimatorCameraFPS::getRotateSpeed() const 289f32 CSceneNodeAnimatorCameraFPS::getRotateSpeed() const
290{ 290{
291 return RotateSpeed; 291 return RotateSpeed;
292} 292}
293 293
294 294
295// Gets the movement speed 295// Gets the movement speed
296f32 CSceneNodeAnimatorCameraFPS::getMoveSpeed() const 296f32 CSceneNodeAnimatorCameraFPS::getMoveSpeed() const
297{ 297{
298 return MoveSpeed; 298 return MoveSpeed;
299} 299}
300 300
301 301
302//! Sets the keyboard mapping for this animator 302//! Sets the keyboard mapping for this animator
303void CSceneNodeAnimatorCameraFPS::setKeyMap(SKeyMap *map, u32 count) 303void CSceneNodeAnimatorCameraFPS::setKeyMap(SKeyMap *map, u32 count)
304{ 304{
305 // clear the keymap 305 // clear the keymap
306 KeyMap.clear(); 306 KeyMap.clear();
307 307
308 // add actions 308 // add actions
309 for (u32 i=0; i<count; ++i) 309 for (u32 i=0; i<count; ++i)
310 { 310 {
311 KeyMap.push_back(map[i]); 311 KeyMap.push_back(map[i]);
312 } 312 }
313} 313}
314 314
315void CSceneNodeAnimatorCameraFPS::setKeyMap(const core::array<SKeyMap>& keymap) 315void CSceneNodeAnimatorCameraFPS::setKeyMap(const core::array<SKeyMap>& keymap)
316{ 316{
317 KeyMap=keymap; 317 KeyMap=keymap;
318} 318}
319 319
320const core::array<SKeyMap>& CSceneNodeAnimatorCameraFPS::getKeyMap() const 320const core::array<SKeyMap>& CSceneNodeAnimatorCameraFPS::getKeyMap() const
321{ 321{
322 return KeyMap; 322 return KeyMap;
323} 323}
324 324
325 325
326//! Sets whether vertical movement should be allowed. 326//! Sets whether vertical movement should be allowed.
327void CSceneNodeAnimatorCameraFPS::setVerticalMovement(bool allow) 327void CSceneNodeAnimatorCameraFPS::setVerticalMovement(bool allow)
328{ 328{
329 NoVerticalMovement = !allow; 329 NoVerticalMovement = !allow;
330} 330}
331 331
332 332
333//! Sets whether the Y axis of the mouse should be inverted. 333//! Sets whether the Y axis of the mouse should be inverted.
334void CSceneNodeAnimatorCameraFPS::setInvertMouse(bool invert) 334void CSceneNodeAnimatorCameraFPS::setInvertMouse(bool invert)
335{ 335{
336 if (invert) 336 if (invert)
337 MouseYDirection = -1.0f; 337 MouseYDirection = -1.0f;
338 else 338 else
339 MouseYDirection = 1.0f; 339 MouseYDirection = 1.0f;
340} 340}
341 341
342 342
343ISceneNodeAnimator* CSceneNodeAnimatorCameraFPS::createClone(ISceneNode* node, ISceneManager* newManager) 343ISceneNodeAnimator* CSceneNodeAnimatorCameraFPS::createClone(ISceneNode* node, ISceneManager* newManager)
344{ 344{
345 CSceneNodeAnimatorCameraFPS * newAnimator = 345 CSceneNodeAnimatorCameraFPS * newAnimator =
346 new CSceneNodeAnimatorCameraFPS(CursorControl, RotateSpeed, MoveSpeed, JumpSpeed, 346 new CSceneNodeAnimatorCameraFPS(CursorControl, RotateSpeed, MoveSpeed, JumpSpeed,
347 0, 0, NoVerticalMovement); 347 0, 0, NoVerticalMovement);
348 newAnimator->setKeyMap(KeyMap); 348 newAnimator->setKeyMap(KeyMap);
349 return newAnimator; 349 return newAnimator;
350} 350}
351 351
352 352
353} // namespace scene 353} // namespace scene
354} // namespace irr 354} // namespace irr
355 355