Code: Select all
/*!-----------------------------------------------------------------------------
| Turn around origin tutorial |
| author: arras |
| date: 01.12.2009 |
| |
| use arrow keys (X,Y axis) and Q W (Z axis) to rotate node around origin |
------------------------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include <irrlicht.h>
using namespace irr;
// this one will rotate node around absolute X and Y axis
// if you try to rotate around Z (Q,W keys) strange things will happen
void rotateAround1(scene::ISceneNode *node, const core::vector3df &origin,
const core::vector3df &angle)
{
// current relative position of node against origin
core::vector3df pos = node->getPosition() - origin;
// new rotation of node
core::vector3df newRot = node->getRotation() + angle;
// position were node is when unrotated
f32 distance = pos.getLength();
core::vector3df newPos(0,0,distance); // this assumes Z axis points "forward"
// now rotate position vector with new rotation
// to find out new position of node
core::matrix4 m;
m.setRotationDegrees(newRot);
m.rotateVect(newPos);
// get it absolute
newPos += origin;
// position node
node->setPosition(newPos);
// rotate node
node->setRotation(newRot);
cout << "X: " << newRot.X << ", Y: " << newRot.Y << ", Z: " << newRot.Z
<<endl;
}
// this one allows rotation around all 3 axes, but rotation will be relative
void rotateAround2(scene::ISceneNode *node, const core::vector3df &origin,
const core::vector3df &angle)
{
// current relative position of node against origin
core::vector3df pos = node->getPosition() - origin;
// current rotation of node
core::vector3df rot = node->getRotation();
// position were node is when unrotated
f32 distance = pos.getLength();
core::vector3df newPos(0,0,distance); // this assumes Z axis points "forward"
// to calculate new rotation, we need to use 2 matrices
core::matrix4 m, n;
m.setRotationDegrees(rot); // current rotation
n.setRotationDegrees(angle); // rotation to add
m *= n;
// find out new position
m.rotateVect(newPos);
// get it absolute
newPos += origin;
// get new rotation of node
core::vector3df newRot = m.getRotationDegrees();
// set position
node->setPosition(newPos);
// set rotation
node->setRotation(newRot);
cout << "X: " << newRot.X << ", Y: " << newRot.Y << ", Z: " << newRot.Z
<<endl;
}
// receiver for key imput
class MEventReceiver : public IEventReceiver
{
public:
bool Left;
bool Right;
bool Up;
bool Down;
bool RollLeft;
bool RollRight;
MEventReceiver()
{
Left = false;
Right = false;
Up = false;
Down = false;
RollLeft = false;
RollRight = false;
}
virtual bool OnEvent(const SEvent &event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
switch(event.KeyInput.Key)
{
case KEY_RIGHT: Right = event.KeyInput.PressedDown; break;
case KEY_LEFT: Left = event.KeyInput.PressedDown; break;
case KEY_UP: Up = event.KeyInput.PressedDown; break;
case KEY_DOWN: Down = event.KeyInput.PressedDown; break;
case KEY_KEY_Q: RollLeft = event.KeyInput.PressedDown; break;
case KEY_KEY_W: RollRight = event.KeyInput.PressedDown; break;
default: break;
}
return true;
}
return false;
}
}Receiver;
int main()
{
IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
core::dimension2d<s32>(640, 480), 16, false, false, false, &Receiver);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
// node to rotate
scene::ISceneNode *node = smgr->addCubeSceneNode();
node->getMaterial(0).setFlag(video::EMF_LIGHTING, false);
node->getMaterial(0).setFlag(video::EMF_WIREFRAME, true);
// node to show origin
scene::ISceneNode *origin = smgr->addSphereSceneNode(1.0f);
origin->getMaterial(0).setFlag(video::EMF_LIGHTING, false);
origin->getMaterial(0).setFlag(video::EMF_WIREFRAME, true);
// place node and origin in such a way that node lies in front of origin
// that is on Z axis
// this is what this tutorial considers as default rotation 0,0,0
node->setPosition(core::vector3df(10,0,50));
origin->setPosition(core::vector3df(10,0,0));
smgr->addCameraSceneNode(0, core::vector3df(10,70,-70),
core::vector3df(10,0,0));
f32 speed = 0.1; // rotation speed
while(device->run())
{
driver->beginScene(true, true, video::SColor(0,200,200,200));
// get imput and rotate
// replace it with rotateAround2 function to see difference
if(Receiver.Left)
rotateAround1(node, origin->getPosition(), core::vector3df(0,speed,0));
if(Receiver.Right)
rotateAround1(node, origin->getPosition(),core::vector3df(0,-speed,0));
if(Receiver.Up)
rotateAround1(node, origin->getPosition(),core::vector3df(-speed,0,0));
if(Receiver.Down)
rotateAround1(node, origin->getPosition(), core::vector3df(speed,0,0));
if(Receiver.RollLeft)
rotateAround1(node, origin->getPosition(),core::vector3df(0,0,-speed));
if(Receiver.RollRight)
rotateAround1(node, origin->getPosition(), core::vector3df(0,0,speed));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}