I am trying to rotate camera like arcball wich commanly used in directx sdk sample for rotation. I treid to do similar class with matrix but it's not working like arcball rotation please any one can tell me what i am doing wrong ?
This is my code posted . I'm begginner .
Code: Select all
#include "CUserCameraController.h"
#include <memory.h>
#include "ISceneManager.h"
#include "dimension2d.h"
#include "IVideoDriver.h"
#define Epsilon 1.0e-5
namespace irr
{
namespace scene
{
//! constructor
CUserCameraController::CUserCameraController(ISceneNode* parent,ISceneManager* mgr, s32 id)
:CCameraSceneNode(parent,mgr,id),isDrag(false)
{
allKeyUp();
//! store height and width data
video::IVideoDriver* driver = mgr->getVideoDriver();
core::dimension2d<s32> dia = driver->getScreenSize();
AdjustDia.Height = 1.0f / ((dia.Height - 1.0f) * 0.5f);
AdjustDia.Width = 1.0f / ((dia.Width - 1.0f) * 0.5f);
Target.set(0,0,1);
}
//! destructor
CUserCameraController::~CUserCameraController()
{
}
void CUserCameraController::allKeyUp()
{
memset(&MouseKeys[0],false,sizeof(bool)*3);
}
//
core::vector3df CUserCameraController::mapToSphere(const core::vector2df &point)
{
core::vector2df tmppoint = point;
//! now scale down ranges to -1 to 1
tmppoint.X = (tmppoint.X * AdjustDia.Width) - 1.0f;
tmppoint.Y = 1.0f - (tmppoint.Y * AdjustDia.Height);
//! compute square length of vector to the point from center
f32 length = tmppoint.X * tmppoint.X + tmppoint.Y * tmppoint.Y;
if (length > 1.0f)
{
f32 norm = 1.0f / sqrt(length);
return core::vector3df(tmppoint.X * norm, tmppoint.Y * norm , 0);
}
else
{
f32 z = (f32)sqrt(1.0f - length);
return core::vector3df(tmppoint.X,tmppoint.Y,z);
}
}
core::vector3df CUserCameraController::drag(const core::vector2df &point)
{
end = mapToSphere(point);
core::vector3df perp = start.crossProduct(end);
if (perp.getLength() > Epsilon)
{
return perp;
}
else
{
return core::vector3df(0,0,0);
}
}
void CUserCameraController::animate()
{
core::vector3df pos = getPosition();
if (!isDrag)
{
if (isMouseKeyDown(0))
{
isDrag = true;
start = mapToSphere(mousePos);
}
}
else
{
if (isMouseKeyDown(0))
{
core::vector3df rotation = drag(mousePos);
core::matrix4 mat;
mat.setRotationDegrees(rotation);
mat.transformVect(pos);
}
else
isDrag = false;
}
setPosition(pos);
}
bool CUserCameraController::isMouseKeyDown(s32 key)
{
return MouseKeys[key];
}
bool CUserCameraController::OnEvent(SEvent event)
{
if (event.EventType != EET_MOUSE_INPUT_EVENT)
return false;
switch(event.MouseInput.Event)
{
//! Left mouse button was pressed down.
case EMIE_LMOUSE_PRESSED_DOWN :
MouseKeys[0] = true;
break;
//! Right mouse button was pressed down.
case EMIE_RMOUSE_PRESSED_DOWN:
MouseKeys[2] = true;
break;
//! Middle mouse button was pressed down.
case EMIE_MMOUSE_PRESSED_DOWN:
MouseKeys[1] = true;
break;
//! Left mouse button was left up.
case EMIE_LMOUSE_LEFT_UP:
MouseKeys[0] = false;
break;
//! Right mouse button was left up.
case EMIE_RMOUSE_LEFT_UP:
MouseKeys[2] = false;
break;
//! Middle mouse button was left up.
case EMIE_MMOUSE_LEFT_UP:
MouseKeys[1] = false;
break;
//! The mouse cursor changed its position.
case EMIE_MOUSE_MOVED:
{
mousePos.X = (f32) event.MouseInput.X;
mousePos.Y = (f32) event.MouseInput.Y;
}
break;
//! The mouse wheel was moved. Use Wheel value in event data to find out
//! in what direction and how fast.
case EMIE_MOUSE_WHEEL:
break;
}
return true;
}
void CUserCameraController::OnPostRender(u32 timeMs)
{
animate();
ISceneNode::OnPostRender(timeMs);
}
}
}