diff options
Diffstat (limited to 'source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp')
-rw-r--r-- | source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp | 425 |
1 files changed, 0 insertions, 425 deletions
diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp deleted file mode 100644 index a5f71b4..0000000 --- a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#include "CSceneNodeAnimatorCameraFPS.h"
-#include "IVideoDriver.h"
-#include "ISceneManager.h"
-#include "Keycodes.h"
-#include "ICursorControl.h"
-#include "ICameraSceneNode.h"
-#include "ISceneNodeAnimatorCollisionResponse.h"
-
-namespace irr
-{
-namespace scene
-{
-
-//! constructor
-CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl,
- f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed,
- SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY, float rotateSpeedKeyboard)
-: CursorControl(cursorControl),
-// On X11 we get events even when mouse is not inside the Irrlicht window, on Windows we don't.
-// It might be possible to add grabbing on Windows as well in which case this has to be somewhat changed.
-// TODO: I don't know about OSX, but in theory it should be like old Irrlicht 1.8 behavior whatever that was there.
-#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
- GrabMouse(false),
-#else
- GrabMouse(true),
-#endif
- MaxVerticalAngle(88.0f), NoVerticalMovement(noVerticalMovement),
- MoveSpeed(moveSpeed),
- RotateSpeedKeyboard(rotateSpeedKeyboard), RotateSpeed(rotateSpeed),
- JumpSpeed(jumpSpeed),
- MouseYDirection(invertY ? -1.0f : 1.0f),
- LastAnimationTime(0), HadMouseEvent(false), firstUpdate(true), firstInput(true)
-{
- #ifdef _DEBUG
- setDebugName("CCameraSceneNodeAnimatorFPS");
- #endif
-
- if (CursorControl)
- CursorControl->grab();
-
- allKeysUp();
-
- // create key map
- if (!keyMapArray || !keyMapSize)
- {
- // create default key map
- KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP));
- KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN));
- KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT));
- KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT));
- KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J));
- }
- else
- {
- // create custom key map
- setKeyMap(keyMapArray, keyMapSize);
- }
-}
-
-
-//! destructor
-CSceneNodeAnimatorCameraFPS::~CSceneNodeAnimatorCameraFPS()
-{
- if (CursorControl)
- CursorControl->drop();
-}
-
-
-//! It is possible to send mouse and key events to the camera. Most cameras
-//! may ignore this input, but camera scene nodes which are created for
-//! example with scene::ISceneManager::addMayaCameraSceneNode or
-//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input
-//! for changing their position, look at target or whatever.
-bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt)
-{
- switch(evt.EventType)
- {
- case EET_KEY_INPUT_EVENT:
- for (u32 i=0; i<KeyMap.size(); ++i)
- {
- if (KeyMap[i].KeyCode == evt.KeyInput.Key)
- {
- CursorKeys[KeyMap[i].Action] = evt.KeyInput.PressedDown;
- return true;
- }
- }
- break;
-
- case EET_MOUSE_INPUT_EVENT:
- HadMouseEvent = true;
- if ( evt.MouseInput.Event == EMIE_MOUSE_ENTER_CANVAS && CursorControl)
- {
- CursorControl->setPosition(0.5f, 0.5f);
- CenterCursor = CursorControl->getRelativePosition(false);
- CursorPos = CenterCursor;
- }
- break;
-
- default:
- break;
- }
-
- return false;
-}
-
-
-void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
-{
- if (!node || node->getType() != ESNT_CAMERA)
- return;
-
- ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);
-
- if (firstUpdate)
- {
- camera->updateAbsolutePosition();
- if (CursorControl )
- {
- CursorControl->setPosition(0.5f, 0.5f);
- CursorPos = CenterCursor = CursorControl->getRelativePosition(false);
- }
-
- LastAnimationTime = timeMs;
-
- firstUpdate = false;
- }
-
- // If the camera isn't the active camera, and receiving input, then don't process it.
- if(!camera->isInputReceiverEnabled())
- {
- firstInput = true;
- return;
- }
-
- if ( firstInput )
- {
- allKeysUp();
- firstInput = false;
- }
-
- scene::ISceneManager * smgr = camera->getSceneManager();
- if(smgr && smgr->getActiveCamera() != camera)
- return;
-
- // get time
- f32 timeDiff = (f32) ( timeMs - LastAnimationTime );
- LastAnimationTime = timeMs;
-
- // Update rotation
- core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition());
- core::vector3df relativeRotation = target.getHorizontalAngle();
-
- if (CursorControl)
- {
- bool reset = false;
-
- if ( HadMouseEvent || GrabMouse)
- CursorPos = CursorControl->getRelativePosition();
-
- if (CursorPos != CenterCursor)
- {
- relativeRotation.Y -= (CenterCursor.X - CursorPos.X) * RotateSpeed;
- relativeRotation.X -= (CenterCursor.Y - CursorPos.Y) * RotateSpeed * MouseYDirection;
-
- reset = true;
- }
-
- if ( GrabMouse && !reset)
- {
- // Special case, mouse is whipped outside of window before it can update.
- video::IVideoDriver* driver = smgr->getVideoDriver();
- core::vector2d<u32> mousepos(u32(CursorPos.X), u32(CursorPos.Y));
- core::rect<u32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height);
-
- // Only if we are moving outside quickly.
- reset = !screenRect.isPointInside(mousepos);
- }
-
- if(reset)
- {
- CursorControl->setPosition(0.5f, 0.5f);
- CenterCursor = CursorControl->getRelativePosition(false); // often no longer 0.5 due to int/float conversions
- CursorPos = CenterCursor;
- }
- }
- HadMouseEvent = false;
-
- // keyboard rotation
- if (CursorKeys[EKA_ROTATE_LEFT])
- relativeRotation.Y -= timeDiff * RotateSpeedKeyboard;
-
- if (CursorKeys[EKA_ROTATE_RIGHT])
- relativeRotation.Y += timeDiff * RotateSpeedKeyboard;
-
- // X < MaxVerticalAngle or X > 360-MaxVerticalAngle
-
- if (relativeRotation.X > MaxVerticalAngle*2 &&
- relativeRotation.X < 360.0f-MaxVerticalAngle)
- {
- relativeRotation.X = 360.0f-MaxVerticalAngle;
- }
- else
- if (relativeRotation.X > MaxVerticalAngle &&
- relativeRotation.X < 360.0f-MaxVerticalAngle)
- {
- relativeRotation.X = MaxVerticalAngle;
- }
-
- // set target
- core::vector3df pos = camera->getPosition();
- target.set(0,0, core::max_(1.f, pos.getLength())); // better float precision than (0,0,1) in target-pos calculation in camera
- core::vector3df movedir(target);
-
- core::matrix4 mat;
- mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0));
- mat.transformVect(target);
-
- if (NoVerticalMovement)
- {
- mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0));
- mat.transformVect(movedir);
- }
- else
- {
- movedir = target;
- }
-
- movedir.normalize();
-
- if (CursorKeys[EKA_MOVE_FORWARD])
- pos += movedir * timeDiff * MoveSpeed;
-
- if (CursorKeys[EKA_MOVE_BACKWARD])
- pos -= movedir * timeDiff * MoveSpeed;
-
- // strafing
-
- core::vector3df strafevect(target);
- strafevect = strafevect.crossProduct(camera->getUpVector());
-
- if (NoVerticalMovement)
- strafevect.Y = 0.0f;
-
- strafevect.normalize();
-
- if (CursorKeys[EKA_STRAFE_LEFT])
- pos += strafevect * timeDiff * MoveSpeed;
-
- if (CursorKeys[EKA_STRAFE_RIGHT])
- pos -= strafevect * timeDiff * MoveSpeed;
-
- // For jumping, we find the collision response animator attached to our camera
- // and if it's not falling, we tell it to jump.
- if (CursorKeys[EKA_JUMP_UP])
- {
- const ISceneNodeAnimatorList& animators = camera->getAnimators();
- ISceneNodeAnimatorList::ConstIterator it = animators.begin();
- while(it != animators.end())
- {
- if(ESNAT_COLLISION_RESPONSE == (*it)->getType())
- {
- ISceneNodeAnimatorCollisionResponse * collisionResponse =
- static_cast<ISceneNodeAnimatorCollisionResponse *>(*it);
-
- if(!collisionResponse->isFalling())
- collisionResponse->jump(JumpSpeed);
- }
-
- it++;
- }
- }
-
- // write translation
- camera->setPosition(pos);
-
- // write right target
- target += pos;
- camera->setTarget(target);
-}
-
-void CSceneNodeAnimatorCameraFPS::allKeysUp()
-{
- for (u32 i=0; i<EKA_COUNT; ++i)
- CursorKeys[i] = false;
-}
-
-
-//! Sets the rotation speed
-void CSceneNodeAnimatorCameraFPS::setRotateSpeed(f32 speed)
-{
- RotateSpeed = speed;
-}
-
-
-//! Sets the movement speed
-void CSceneNodeAnimatorCameraFPS::setMoveSpeed(f32 speed)
-{
- MoveSpeed = speed;
-}
-
-
-//! Gets the rotation speed
-f32 CSceneNodeAnimatorCameraFPS::getRotateSpeed() const
-{
- return RotateSpeed;
-}
-
-
-// Gets the movement speed
-f32 CSceneNodeAnimatorCameraFPS::getMoveSpeed() const
-{
- return MoveSpeed;
-}
-
-//! Sets the keyboard mapping for this animator
-void CSceneNodeAnimatorCameraFPS::setKeyMap(SKeyMap *map, u32 count)
-{
- // clear the keymap
- KeyMap.clear();
-
- // add actions
- for (u32 i=0; i<count; ++i)
- {
- KeyMap.push_back(map[i]);
- }
-}
-
-void CSceneNodeAnimatorCameraFPS::setKeyMap(const core::array<SKeyMap>& keymap)
-{
- KeyMap=keymap;
-}
-
-const core::array<SKeyMap>& CSceneNodeAnimatorCameraFPS::getKeyMap() const
-{
- return KeyMap;
-}
-
-
-//! Sets whether vertical movement should be allowed.
-void CSceneNodeAnimatorCameraFPS::setVerticalMovement(bool allow)
-{
- NoVerticalMovement = !allow;
-}
-
-
-//! Sets whether the Y axis of the mouse should be inverted.
-void CSceneNodeAnimatorCameraFPS::setInvertMouse(bool invert)
-{
- if (invert)
- MouseYDirection = -1.0f;
- else
- MouseYDirection = 1.0f;
-}
-
-
-ISceneNodeAnimator* CSceneNodeAnimatorCameraFPS::createClone(ISceneNode* node, ISceneManager* newManager)
-{
- CSceneNodeAnimatorCameraFPS * newAnimator =
- new CSceneNodeAnimatorCameraFPS(CursorControl, RotateSpeed, MoveSpeed, JumpSpeed,
- 0, 0, NoVerticalMovement);
- newAnimator->cloneMembers(this);
- newAnimator->setKeyMap(KeyMap);
- return newAnimator;
-}
-
-void CSceneNodeAnimatorCameraFPS::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
-{
- ISceneNodeAnimator::serializeAttributes(out, options);
-
- out->addFloat("MaxVerticalAngle", MaxVerticalAngle);
- out->addBool("NoVerticalMovement", NoVerticalMovement);
- out->addFloat("MoveSpeed", MoveSpeed);
- out->addFloat("RotateSpeedKeyboard", RotateSpeedKeyboard);
- out->addFloat("RotateSpeed", RotateSpeed);
- out->addFloat("JumpSpeed", JumpSpeed);
- out->addFloat("MouseYDirection", MouseYDirection);
-
- out->addInt("KeyMapSize", (s32)KeyMap.size());
- for ( u32 i=0; i < KeyMap.size(); ++i )
- {
- core::stringc name("Action");
- name += core::stringc(i);
- out->addInt(name.c_str(), (int)KeyMap[i].Action);
- name = core::stringc("KeyCode") + core::stringc(i);
- out->addInt(name.c_str(), (int)KeyMap[i].KeyCode);
- }
-}
-
-void CSceneNodeAnimatorCameraFPS::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
-{
- ISceneNodeAnimator::deserializeAttributes(in, options);
-
- MaxVerticalAngle = in->getAttributeAsFloat("MaxVerticalAngle", MaxVerticalAngle);
- NoVerticalMovement = in->getAttributeAsBool("NoVerticalMovement", NoVerticalMovement);
- MoveSpeed = in->getAttributeAsFloat("MoveSpeed", MoveSpeed);
- RotateSpeedKeyboard = in->getAttributeAsFloat("RotateSpeedKeyboard", RotateSpeedKeyboard);
- RotateSpeed = in->getAttributeAsFloat("RotateSpeed", RotateSpeed);
- JumpSpeed = in->getAttributeAsFloat("JumpSpeed", JumpSpeed);
- MouseYDirection = in->getAttributeAsFloat("MouseYDirection", MouseYDirection);
-
- if ( in->findAttribute("KeyMapSize") )
- {
- KeyMap.clear();
- s32 keyMapSize = in->getAttributeAsInt("KeyMapSize");
- for ( u32 i=0; i < (u32)keyMapSize; ++i )
- {
- SKeyMap keyMapEntry;
- core::stringc name("Action");
- name += core::stringc(i);
- keyMapEntry.Action = static_cast<EKEY_ACTION>(in->getAttributeAsInt(name.c_str()));
- name = core::stringc("KeyCode") + core::stringc(i);
- keyMapEntry.KeyCode = static_cast<EKEY_CODE>(in->getAttributeAsInt(name.c_str()));
- KeyMap.push_back(keyMapEntry);
- }
- }
-}
-
-
-} // namespace scene
-} // namespace irr
-
|