123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- // 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 "CSceneNodeAnimatorCameraMaya.h"
- #include "ICursorControl.h"
- #include "ICameraSceneNode.h"
- #include "SViewFrustum.h"
- #include "ISceneManager.h"
- namespace irr
- {
- namespace scene
- {
- //! constructor
- CSceneNodeAnimatorCameraMaya::CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor,
- f32 rotateSpeed, f32 zoomSpeed, f32 translateSpeed, f32 distance)
- : CursorControl(cursor), OldCamera(0), MousePos(0.5f, 0.5f),
- ZoomSpeed(zoomSpeed), RotateSpeed(rotateSpeed), TranslateSpeed(translateSpeed),
- CurrentZoom(distance), RotX(0.0f), RotY(0.0f),
- Zooming(false), Rotating(false), Moving(false), Translating(false)
- {
- #ifdef _DEBUG
- setDebugName("CSceneNodeAnimatorCameraMaya");
- #endif
- if (CursorControl)
- {
- CursorControl->grab();
- MousePos = CursorControl->getRelativePosition();
- }
- allKeysUp();
- }
- //! destructor
- CSceneNodeAnimatorCameraMaya::~CSceneNodeAnimatorCameraMaya()
- {
- 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::addMeshViewerCameraSceneNode, may want to get this input
- //! for changing their position, look at target or whatever.
- bool CSceneNodeAnimatorCameraMaya::OnEvent(const SEvent& event)
- {
- if (event.EventType != EET_MOUSE_INPUT_EVENT)
- return false;
- switch(event.MouseInput.Event)
- {
- case EMIE_LMOUSE_PRESSED_DOWN:
- MouseKeys[0] = true;
- break;
- case EMIE_RMOUSE_PRESSED_DOWN:
- MouseKeys[2] = true;
- break;
- case EMIE_MMOUSE_PRESSED_DOWN:
- MouseKeys[1] = true;
- break;
- case EMIE_LMOUSE_LEFT_UP:
- MouseKeys[0] = false;
- break;
- case EMIE_RMOUSE_LEFT_UP:
- MouseKeys[2] = false;
- break;
- case EMIE_MMOUSE_LEFT_UP:
- MouseKeys[1] = false;
- break;
- case EMIE_MOUSE_MOVED:
- MousePos = CursorControl->getRelativePosition();
- break;
- case EMIE_MOUSE_WHEEL:
- case EMIE_LMOUSE_DOUBLE_CLICK:
- case EMIE_RMOUSE_DOUBLE_CLICK:
- case EMIE_MMOUSE_DOUBLE_CLICK:
- case EMIE_LMOUSE_TRIPLE_CLICK:
- case EMIE_RMOUSE_TRIPLE_CLICK:
- case EMIE_MMOUSE_TRIPLE_CLICK:
- case EMIE_COUNT:
- return false;
- }
- return true;
- }
- //! OnAnimate() is called just before rendering the whole scene.
- void CSceneNodeAnimatorCameraMaya::animateNode(ISceneNode *node, u32 timeMs)
- {
- //Alt + LM = Rotate around camera pivot
- //Alt + LM + MM = Dolly forth/back in view direction (speed % distance camera pivot - max distance to pivot)
- //Alt + MM = Move on camera plane (Screen center is about the mouse pointer, depending on move speed)
- if (!node || node->getType() != ESNT_CAMERA)
- return;
- ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);
- // If the camera isn't the active camera, and receiving input, then don't process it.
- if (!camera->isInputReceiverEnabled())
- return;
- scene::ISceneManager * smgr = camera->getSceneManager();
- if (smgr && smgr->getActiveCamera() != camera)
- return;
- if (OldCamera != camera)
- {
- LastCameraTarget = OldTarget = camera->getTarget();
- OldCamera = camera;
- }
- else
- {
- OldTarget += camera->getTarget() - LastCameraTarget;
- }
- f32 nRotX = RotX;
- f32 nRotY = RotY;
- f32 nZoom = CurrentZoom;
- if ( (isMouseKeyDown(0) && isMouseKeyDown(2)) || isMouseKeyDown(1) )
- {
- if (!Zooming)
- {
- ZoomStart = MousePos;
- Zooming = true;
- }
- else
- {
- const f32 targetMinDistance = 0.1f;
- nZoom += (ZoomStart.X - MousePos.X) * ZoomSpeed;
- if (nZoom < targetMinDistance) // jox: fixed bug: bounce back when zooming to close
- nZoom = targetMinDistance;
- }
- }
- else if (Zooming)
- {
- const f32 old = CurrentZoom;
- CurrentZoom = CurrentZoom + (ZoomStart.X - MousePos.X ) * ZoomSpeed;
- nZoom = CurrentZoom;
- if (nZoom < 0)
- nZoom = CurrentZoom = old;
- Zooming = false;
- }
- // Translation ---------------------------------
- core::vector3df translate(OldTarget);
- const core::vector3df upVector(camera->getUpVector());
- const core::vector3df target = camera->getTarget();
- core::vector3df pos = camera->getPosition();
- core::vector3df tvectX = pos - target;
- tvectX = tvectX.crossProduct(upVector);
- tvectX.normalize();
- const SViewFrustum* const va = camera->getViewFrustum();
- core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown());
- tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos);
- tvectY.normalize();
- if (isMouseKeyDown(2) && !Zooming)
- {
- if (!Translating)
- {
- TranslateStart = MousePos;
- Translating = true;
- }
- else
- {
- translate += tvectX * (TranslateStart.X - MousePos.X)*TranslateSpeed +
- tvectY * (TranslateStart.Y - MousePos.Y)*TranslateSpeed;
- }
- }
- else if (Translating)
- {
- translate += tvectX * (TranslateStart.X - MousePos.X)*TranslateSpeed +
- tvectY * (TranslateStart.Y - MousePos.Y)*TranslateSpeed;
- OldTarget = translate;
- Translating = false;
- }
- // Rotation ------------------------------------
- if (isMouseKeyDown(0) && !Zooming)
- {
- if (!Rotating)
- {
- RotateStart = MousePos;
- Rotating = true;
- nRotX = RotX;
- nRotY = RotY;
- }
- else
- {
- nRotX += (RotateStart.X - MousePos.X) * RotateSpeed;
- nRotY += (RotateStart.Y - MousePos.Y) * RotateSpeed;
- }
- }
- else if (Rotating)
- {
- RotX += (RotateStart.X - MousePos.X) * RotateSpeed;
- RotY += (RotateStart.Y - MousePos.Y) * RotateSpeed;
- nRotX = RotX;
- nRotY = RotY;
- Rotating = false;
- }
- // Set pos ------------------------------------
- pos = translate;
- pos.X += nZoom;
- pos.rotateXYBy(nRotY, translate);
- pos.rotateXZBy(-nRotX, translate);
- camera->setPosition(pos);
- camera->setTarget(translate);
- // Rotation Error ----------------------------
- // jox: fixed bug: jitter when rotating to the top and bottom of y
- pos.set(0,1,0);
- pos.rotateXYBy(-nRotY);
- pos.rotateXZBy(-nRotX+180.f);
- camera->setUpVector(pos);
- LastCameraTarget = camera->getTarget();
- }
- bool CSceneNodeAnimatorCameraMaya::isMouseKeyDown(s32 key) const
- {
- return MouseKeys[key];
- }
- void CSceneNodeAnimatorCameraMaya::allKeysUp()
- {
- for (s32 i=0; i<3; ++i)
- MouseKeys[i] = false;
- }
- //! Sets the rotation speed
- void CSceneNodeAnimatorCameraMaya::setRotateSpeed(f32 speed)
- {
- RotateSpeed = speed;
- }
- //! Sets the movement speed
- void CSceneNodeAnimatorCameraMaya::setMoveSpeed(f32 speed)
- {
- TranslateSpeed = speed;
- }
- //! Sets the zoom speed
- void CSceneNodeAnimatorCameraMaya::setZoomSpeed(f32 speed)
- {
- ZoomSpeed = speed;
- }
- //! Set the distance
- void CSceneNodeAnimatorCameraMaya::setDistance(f32 distance)
- {
- CurrentZoom=distance;
- }
-
- //! Gets the rotation speed
- f32 CSceneNodeAnimatorCameraMaya::getRotateSpeed() const
- {
- return RotateSpeed;
- }
- // Gets the movement speed
- f32 CSceneNodeAnimatorCameraMaya::getMoveSpeed() const
- {
- return TranslateSpeed;
- }
- //! Gets the zoom speed
- f32 CSceneNodeAnimatorCameraMaya::getZoomSpeed() const
- {
- return ZoomSpeed;
- }
- //! Returns the current distance, i.e. orbit radius
- f32 CSceneNodeAnimatorCameraMaya::getDistance() const
- {
- return CurrentZoom;
- }
- ISceneNodeAnimator* CSceneNodeAnimatorCameraMaya::createClone(ISceneNode* node, ISceneManager* newManager)
- {
- CSceneNodeAnimatorCameraMaya * newAnimator =
- new CSceneNodeAnimatorCameraMaya(CursorControl, RotateSpeed, ZoomSpeed, TranslateSpeed);
- return newAnimator;
- }
- } // end namespace
- } // end namespace
|