Index: include/SKeyMap.h
===================================================================
--- include/SKeyMap.h	(revision 4003)
+++ include/SKeyMap.h	(working copy)
@@ -19,13 +19,16 @@
 		EKA_STRAFE_RIGHT,
 		EKA_JUMP_UP,
 		EKA_CROUCH,
+		EKA_ROTATE,
+		EKA_TRANSLATE,
+		EKA_ZOOM,
 		EKA_COUNT,
 
 		//! This value is not used. It only forces this enumeration to compile in 32 bit.
 		EKA_FORCE_32BIT = 0x7fffffff
 	};
 
-	//! Struct storing which key belongs to which action.
+	//! Struct storing which keyboard key belongs to which action.
 	struct SKeyMap
 	{
 		SKeyMap() {}
Index: source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp
===================================================================
--- source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp	(revision 4003)
+++ source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp	(working copy)
@@ -15,7 +15,7 @@
 
 //! constructor
 CSceneNodeAnimatorCameraMaya::CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor,
-	f32 rotateSpeed, f32 zoomSpeed, f32 translateSpeed, f32 distance)
+	f32 rotateSpeed, f32 zoomSpeed, f32 translateSpeed, f32 distance, SKeyMap* keyMapArray, u32 keyMapSize)
 	: CursorControl(cursor), OldCamera(0), MousePos(0.5f, 0.5f),
 	ZoomSpeed(zoomSpeed), RotateSpeed(rotateSpeed), TranslateSpeed(translateSpeed),
 	CurrentZoom(distance), RotX(0.0f), RotY(0.0f),
@@ -32,6 +32,21 @@
 	}
 
 	allKeysUp();
+	FirstUpdate=true;
+
+	// create key map
+    if (!keyMapArray || !keyMapSize)
+    {
+		// create default key map
+		KeyMap.push_back(SKeyMap(EKA_ROTATE, irr::KEY_LBUTTON));
+		KeyMap.push_back(SKeyMap(EKA_TRANSLATE, irr::KEY_RBUTTON));
+		KeyMap.push_back(SKeyMap(EKA_ZOOM, irr::KEY_MBUTTON));
+    }
+    else
+    {
+        // create custom key map
+        setKeyMap(keyMapArray, keyMapSize);
+    }
 }
 
 
@@ -48,45 +63,52 @@
 //! 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)
+bool CSceneNodeAnimatorCameraMaya::OnEvent(const SEvent& evt)
 {
-	if (event.EventType != EET_MOUSE_INPUT_EVENT)
-		return false;
-
-	switch(event.MouseInput.Event)
+	switch(evt.EventType)
 	{
-	case EMIE_LMOUSE_PRESSED_DOWN:
-		MouseKeys[0] = true;
+		case EET_KEY_INPUT_EVENT:
+		for (u32 i=0; i<KeyMap.size(); ++i)
+		{
+			if (KeyMap[i].KeyCode == evt.KeyInput.Key)
+			{
+				ActionKeys[KeyMap[i].Action] = evt.KeyInput.PressedDown;
+				return true;
+			}
+		}
 		break;
-	case EMIE_RMOUSE_PRESSED_DOWN:
-		MouseKeys[2] = true;
+
+		case EET_MOUSE_INPUT_EVENT:
+
+		for (u32 i=0; i<KeyMap.size(); ++i)
+		{
+			if (KeyMap[i].KeyCode == irr::KEY_LBUTTON)
+			{
+				ActionKeys[KeyMap[i].Action] = evt.MouseInput.isLeftPressed();
+			}
+			if (KeyMap[i].KeyCode == irr::KEY_RBUTTON)
+			{
+				ActionKeys[KeyMap[i].Action] = evt.MouseInput.isRightPressed();
+			}
+			if (KeyMap[i].KeyCode == irr::KEY_MBUTTON)
+			{
+				ActionKeys[KeyMap[i].Action] = evt.MouseInput.isMiddlePressed();
+			}
+
+		}
+
+		if (evt.MouseInput.Event == EMIE_MOUSE_MOVED)
+		{
+			MousePos = CursorControl->getRelativePosition();
+			return true;
+		}
 		break;
-	case EMIE_MMOUSE_PRESSED_DOWN:
-		MouseKeys[1] = true;
+
+	default:
 		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;
+
+	return false;
 }
 
 
@@ -102,9 +124,14 @@
 
 	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())
+	{
+		// If the input receiver is down, then reset the camera, so it take the new position to start
+		FirstUpdate=true;
 		return;
+	}
 
 	scene::ISceneManager * smgr = camera->getSceneManager();
 	if (smgr && smgr->getActiveCamera() != camera)
@@ -120,11 +147,22 @@
 		OldTarget += camera->getTarget() - LastCameraTarget;
 	}
 
+	// Calculate the camera angle and position for the first time
+	if (FirstUpdate)
+	{
+		core::vector3df OffsetVector = camera->getTarget()-camera->getPosition();
+		core::vector3df OffsetVec2 = core::vector3df(OffsetVector.Z, OffsetVector.Y, OffsetVector.X);
+		core::vector3df InitialRotation = (-OffsetVec2).getHorizontalAngle();
+		RotX = -InitialRotation.Y;
+		RotY = -InitialRotation.X;
+		CurrentZoom = camera->getPosition().getDistanceFrom(camera->getTarget());
+	}
+
 	f32 nRotX = RotX;
 	f32 nRotY = RotY;
 	f32 nZoom = CurrentZoom;
 
-	if ( (isMouseKeyDown(0) && isMouseKeyDown(2)) || isMouseKeyDown(1) )
+	if (ActionKeys[EKA_ZOOM])
 	{
 		if (!Zooming)
 		{
@@ -167,7 +205,7 @@
 	tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos);
 	tvectY.normalize();
 
-	if (isMouseKeyDown(2) && !Zooming)
+	if (ActionKeys[EKA_TRANSLATE] && !Zooming)
 	{
 		if (!Translating)
 		{
@@ -190,7 +228,7 @@
 
 	// Rotation ------------------------------------
 
-	if (isMouseKeyDown(0) && !Zooming)
+	if (ActionKeys[EKA_ROTATE] && !Zooming)
 	{
 		if (!Rotating)
 		{
@@ -221,7 +259,7 @@
 
 	pos.rotateXYBy(nRotY, translate);
 	pos.rotateXZBy(-nRotX, translate);
-
+	
 	camera->setPosition(pos);
 	camera->setTarget(translate);
 
@@ -233,19 +271,13 @@
 	pos.rotateXZBy(-nRotX+180.f);
 	camera->setUpVector(pos);
 	LastCameraTarget = camera->getTarget();
+	FirstUpdate=false;
 }
 
-
-bool CSceneNodeAnimatorCameraMaya::isMouseKeyDown(s32 key) const
-{
-	return MouseKeys[key];
-}
-
-
 void CSceneNodeAnimatorCameraMaya::allKeysUp()
 {
-	for (s32 i=0; i<3; ++i)
-		MouseKeys[i] = false;
+	for (u32 i=0; i<EKA_COUNT; ++i)
+		ActionKeys[i] = false;
 }
 
 
@@ -297,7 +329,29 @@
 	return ZoomSpeed;
 }
 
+//! Sets the keyboard mapping for this animator
+void CSceneNodeAnimatorCameraMaya::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 CSceneNodeAnimatorCameraMaya::setKeyMap(const core::array<SKeyMap>& keymap)
+{
+	KeyMap=keymap;
+}
+
+const core::array<SKeyMap>& CSceneNodeAnimatorCameraMaya::getKeyMap() const
+{
+	return KeyMap;
+}
+
 //! Returns the current distance, i.e. orbit radius
 f32 CSceneNodeAnimatorCameraMaya::getDistance() const
 {
Index: source/Irrlicht/CSceneNodeAnimatorCameraMaya.h
===================================================================
--- source/Irrlicht/CSceneNodeAnimatorCameraMaya.h	(revision 4003)
+++ source/Irrlicht/CSceneNodeAnimatorCameraMaya.h	(working copy)
@@ -8,6 +8,7 @@
 #include "ISceneNodeAnimatorCameraMaya.h"
 #include "ICameraSceneNode.h"
 #include "vector2d.h"
+#include "SKeyMap.h"
 
 namespace irr
 {
@@ -29,7 +30,8 @@
 	public:
 		//! Constructor
 		CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, f32 rotateSpeed = -1500.f, 
-			f32 zoomSpeed = 200.f, f32 translationSpeed = 1500.f, f32 distance=70.f);
+			f32 zoomSpeed = 200.f, f32 translationSpeed = 1500.f, f32 distance=70.f, 
+			SKeyMap* keyMapArray=0, u32 keyMapSize=0);
 
 		//! Destructor
 		virtual ~CSceneNodeAnimatorCameraMaya();
@@ -38,7 +40,7 @@
 		virtual void animateNode(ISceneNode* node, u32 timeMs);
 
 		//! Event receiver
-		virtual bool OnEvent(const SEvent& event);
+		virtual bool OnEvent(const SEvent& evt);
 
 		//! Returns the speed of movement in units per millisecond
 		virtual f32 getMoveSpeed() const;
@@ -58,6 +60,18 @@
 		//! Set the zoom speed
 		virtual void setZoomSpeed(f32 zoomSpeed);
 
+		//! Sets the keyboard mapping for this animator (old style)
+		//! \param keymap: an array of keyboard mappings, see SKeyMap
+		//! \param count: the size of the keyboard map array
+		virtual void setKeyMap(SKeyMap *map, u32 count);
+
+		//! Sets the keyboard mapping for this animator
+		//!	\param keymap The new keymap array 
+		virtual void setKeyMap(const core::array<SKeyMap>& Keymap);
+
+		//! Gets the keyboard mapping for this animator
+		virtual const core::array<SKeyMap>& getKeyMap() const;
+
 		//! Returns the current distance, i.e. orbit radius
 		virtual f32 getDistance() const;
 
@@ -86,10 +100,7 @@
 
 		void allKeysUp();
 		void animate();
-		bool isMouseKeyDown(s32 key) const;
-
-		bool MouseKeys[3];
-
+		
 		gui::ICursorControl *CursorControl;
 		scene::ICameraSceneNode* OldCamera;
 		core::vector3df OldTarget;
@@ -107,6 +118,12 @@
 		bool Rotating;
 		bool Moving;
 		bool Translating;
+		bool FirstUpdate;
+
+		core::array<SKeyMap> KeyMap;
+		bool ActionKeys[EKA_COUNT];
+
+
 	};
 
 } // end namespace scene
