CSceneNodeAnimatorCameraMaya2

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
wing64
Competition winner
Posts: 242
Joined: Wed Jul 23, 2008 2:35 am
Location: Thailand
Contact:

CSceneNodeAnimatorCameraMaya2

Post by wing64 »

Hi.
This is a simple class for handle camera maya style. Name's CSceneNodeAnimatorCameraMaya2.

How to use.
Alt+LeftMouseDown = Rotation
Alt+RightMouseDown = Zoom
Alt+MiddleMouseDown = Moving

How to create object.

Code: Select all

#include "CSceneNodeAnimatorCameraMaya2.h" // header

camera = g_engine.smgr->addCameraSceneNode();	
ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraMaya2();
camera->bindTargetAndRotation( true );
camera->addAnimator(anm);
anm->drop();
CSceneNodeAnimatorCameraMaya2.h

Code: Select all

// Copyright (C) 2002-2009 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#ifndef __C_SCENE_NODE_ANIMATOR_CAMERA_MAYA2_H_INCLUDED__
#define __C_SCENE_NODE_ANIMATOR_CAMERA_MAYA2_H_INCLUDED__

#include "ISceneNodeAnimatorCameraMaya.h"
#include "ICameraSceneNode.h"
#include "vector2d.h"

namespace irr
{

namespace gui
{
	class ICursorControl;
}

namespace scene
{

	//! Special scene node animator for FPS cameras
	/** This scene node animator can be attached to a camera to make it act
	like a 3d modelling tool camera
	*/
	class CSceneNodeAnimatorCameraMaya2 : public ISceneNodeAnimatorCameraMaya 
	{
	public:
		//! Constructor
		CSceneNodeAnimatorCameraMaya2(f32 rotateSpeed = 0.00025f, 
			f32 zoomSpeed = 0.0025f, f32 translationSpeed = 0.0025f);

		//! Destructor
		virtual ~CSceneNodeAnimatorCameraMaya2();

		//! Animates the scene node, currently only works on cameras
		virtual void animateNode(ISceneNode* node, u32 timeMs);

		//! Event receiver
		virtual bool OnEvent(const SEvent& event);

		//! Returns the speed of movement in units per millisecond
		virtual f32 getMoveSpeed() const;

		//! Sets the speed of movement in units per millisecond
		virtual void setMoveSpeed(f32 moveSpeed);

		//! Returns the rotation speed
		virtual f32 getRotateSpeed() const;

		//! Set the rotation speed
		virtual void setRotateSpeed(f32 rotateSpeed);

		//! Returns the zoom speed
		virtual f32 getZoomSpeed() const;

		//! Set the zoom speed
		virtual void setZoomSpeed(f32 zoomSpeed);

		//! This animator will receive events when attached to the active camera
		virtual bool isEventReceiverEnabled() const
		{
			return true;
		}

		//! Returns type of the scene node
		virtual ESCENE_NODE_ANIMATOR_TYPE getType() const 
		{
			return ESNAT_CAMERA_MAYA;
		}

		//! Creates a clone of this animator.
		/** Please note that you will have to drop
		(IReferenceCounted::drop()) the returned pointer after calling
		this. */
		virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0);

		void setAnimationSpeed(f32 framesPerSecond = 30.0f);
		f32 getAnimationSpeed() const;

		void setMouseKeyDown(s32 key, bool down) { MouseKeys[key] = down; };
		void setAltDown( bool down ) { AltKey = down; }

	private:

		void allKeysUp();
		void animate();
		bool isMouseKeyDown(s32 key);
		bool isAltDown() { return AltKey; }

		bool MouseKeys[3];
		bool AltKey;
		bool firstUpdate;

		// maya2
		core::vector3df center;
		core::vector3df position;
		core::position2df mouse_rot_rad;
		f32 ang;
		f32 FramesPerSecond;

		//core::vector3df Pos;
		bool Zooming;
		bool Rotating;
		bool Moving;
		bool Translating;
		f32 ZoomSpeed;
		f32 RotateSpeed;
		f32 TranslateSpeed;
		core::position2df RotateStart;
		core::position2df ZoomStart;
		core::position2df TranslateStart;
		scene::ICameraSceneNode* OldCamera;

		core::position2df MousePos;
	};

} // end namespace scene
} // end namespace irr

#endif

CSceneNodeAnimatorCameraMaya2.cpp

Code: Select all

// Copyright (C) 2002-2009 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#include "CSceneNodeAnimatorCameraMaya2.h"
#include "ICursorControl.h"
#include "ICameraSceneNode.h"
#include "SViewFrustum.h"
#include "ISceneManager.h"

namespace irr
{
namespace scene
{

static core::vector3df getIrrIn( ISceneNode* node )
{
   if (node)
   {
      core::matrix4 mat = node->getRelativeTransformation();
      core::vector3df in(mat[8],mat[9],mat[10]);
      in.normalize();
      return in;
   } else return core::vector3df(0,0,0);
}

static core::vector3df getIrrUp( ISceneNode* node )
{
   if (node)
   {
      core::matrix4 mat = node->getRelativeTransformation();
      core::vector3df up(mat[4],mat[5],mat[6]);
      up.normalize();
      return up;
   }
   else return core::vector3df(0,0,0);
} 

static core::vector3df getIrrLeft( ISceneNode* node )
{
   if (node)
   {
      core::matrix4 mat = node->getRelativeTransformation();
      core::vector3df left(mat[0],mat[1],mat[2]);
      left.normalize();
      return left;
   }
   else return core::vector3df(0,0,0);
} 

//! constructor
CSceneNodeAnimatorCameraMaya2::CSceneNodeAnimatorCameraMaya2(f32 rotate, f32 zoom, f32 translate)
	: Zooming(false), Rotating(false), Moving(false),
	Translating(false), ZoomSpeed(zoom), RotateSpeed(rotate), TranslateSpeed(translate),
	// maya2
	center(5,5,5),
	position(0),
	mouse_rot_rad(0),
	ang(0),
	AltKey(false),
	firstUpdate(true)
{
	#ifdef _DEBUG
	setDebugName("CSceneNodeAnimatorCameraMaya2");
	#endif

	allKeysUp();
	setAnimationSpeed( );
}


//! destructor
CSceneNodeAnimatorCameraMaya2::~CSceneNodeAnimatorCameraMaya2()
{
}


//! 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 CSceneNodeAnimatorCameraMaya2::OnEvent(const SEvent& event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT)
	{
		if( event.KeyInput.PressedDown && 
			(event.KeyInput.Key == KEY_LMENU ||
			event.KeyInput.Key == KEY_RMENU) )
			AltKey = true;
		else
			AltKey = false;
	}

	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.X = (f32)event.MouseInput.X;
		MousePos.Y = (f32)event.MouseInput.Y;
		//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.
//! nodes may calculate or store animations here, and may do other useful things,
//! dependent on what they are.
void CSceneNodeAnimatorCameraMaya2::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)
		OldCamera = camera;

	if( firstUpdate )
	{
		core::vector3df deg(core::radToDeg(mouse_rot_rad.Y), core::radToDeg(mouse_rot_rad.X), 0);

		core::vector3df r(0, 0, -20);
		core::matrix4 mat;
		mat.makeIdentity( );
		mat.setTranslation( center );
		mat.setRotationDegrees( deg );
		mat.transformVect( r );

		position = r;
		camera->setPosition( position );
		camera->setTarget( center );
		firstUpdate = false;
	}

	// rotate
	if( isAltDown() && isMouseKeyDown(0) )
	{
		if (!Rotating)
		{
			RotateStart = MousePos;
			Rotating = true;
		}
		else
		{
			core::position2df mouse_pos( MousePos );
			core::position2df df = RotateStart - mouse_pos;
			RotateStart = mouse_pos;

			mouse_rot_rad -= df * (RotateSpeed * ((f32)timeMs * FramesPerSecond));
			if( mouse_rot_rad.Y < -1.54f ) mouse_rot_rad.Y = -1.54f;
			if( mouse_rot_rad.Y > 1.54f ) mouse_rot_rad.Y = 1.54f;
			
			core::vector3df deg(core::radToDeg(mouse_rot_rad.Y), core::radToDeg(mouse_rot_rad.X), 0);

			core::vector3df r(0, 0, -20);
			core::matrix4 mat;
			mat.makeIdentity( );
			mat.setTranslation( center );
			mat.setRotationDegrees( deg );
			mat.transformVect( r );

			position = r;
			camera->setPosition( position );
			camera->setTarget( center );
		}
	} // rotate
	else
		Rotating = false;

	// moving
	if( isAltDown() && isMouseKeyDown(1) )
	{
		if (!Translating)
		{
			TranslateStart = MousePos;
			Translating = true;
		}
		else
		{
			core::position2df mouse_pos( MousePos );
			core::position2df df = TranslateStart - mouse_pos;
			TranslateStart = mouse_pos;

			core::vector3df vec;
			vec = getIrrUp(camera)*-df.Y*(TranslateSpeed* ((f32)timeMs * FramesPerSecond));
			vec += getIrrLeft(camera)*df.X*(TranslateSpeed* ((f32)timeMs * FramesPerSecond));			
			position += vec;
			center += vec;

			camera->setPosition( position );
			camera->setTarget( center );
		}
	} // moving
	else
		Translating = false;

	// zooming
	if( isAltDown() && isMouseKeyDown(2) )
	{
		if (!Zooming)
		{
			ZoomStart = MousePos;
			Zooming = true;
		}
		else
		{
			core::position2df mouse_pos( MousePos );
			core::position2df df = ZoomStart - mouse_pos;
			ZoomStart = mouse_pos;

			core::vector3df vec;
			vec = getIrrIn(camera)*-df.X*(ZoomSpeed* ((f32)timeMs * FramesPerSecond));
			position += vec;
			center += vec;

			camera->setPosition( position );
			camera->setTarget( center );
		}
	} // zooming
	else
		Zooming = false;
}


bool CSceneNodeAnimatorCameraMaya2::isMouseKeyDown(s32 key)
{
	return MouseKeys[key];
}


void CSceneNodeAnimatorCameraMaya2::allKeysUp()
{
	for (s32 i=0; i<3; ++i)
		MouseKeys[i] = false;

	AltKey = false;
}


//! Sets the rotation speed
void CSceneNodeAnimatorCameraMaya2::setRotateSpeed(f32 speed)
{
	RotateSpeed = speed;
}


//! Sets the movement speed
void CSceneNodeAnimatorCameraMaya2::setMoveSpeed(f32 speed)
{
	TranslateSpeed = speed;
}


//! Sets the zoom speed
void CSceneNodeAnimatorCameraMaya2::setZoomSpeed(f32 speed)
{
	ZoomSpeed = speed;
}


//! Gets the rotation speed
f32 CSceneNodeAnimatorCameraMaya2::getRotateSpeed() const
{
	return RotateSpeed;
}


// Gets the movement speed
f32 CSceneNodeAnimatorCameraMaya2::getMoveSpeed() const
{
	return TranslateSpeed;
}


//! Gets the zoom speed
f32 CSceneNodeAnimatorCameraMaya2::getZoomSpeed() const
{
	return ZoomSpeed;
}

ISceneNodeAnimator* CSceneNodeAnimatorCameraMaya2::createClone(ISceneNode* node, ISceneManager* newManager)
{
	CSceneNodeAnimatorCameraMaya2 * newAnimator =
		new CSceneNodeAnimatorCameraMaya2(RotateSpeed, ZoomSpeed, TranslateSpeed);
	return newAnimator;
}

//! sets the speed with witch the animation is played
void CSceneNodeAnimatorCameraMaya2::setAnimationSpeed(f32 framesPerSecond)
{
	FramesPerSecond = framesPerSecond * 0.001f;
}

f32 CSceneNodeAnimatorCameraMaya2::getAnimationSpeed() const
{
	return FramesPerSecond * 1000.f;
}

} // end namespace
} // end namespace

Post Reply