Rotating around an arbitrary axis
Rotating around an arbitrary axis
So what i want is for the camera to rotate a full 360 degrees completely around the origin in the game.
the problem i was having with doing it by the camera rotation based of a parent dummy node was the gimble lock it would get at the top.
to combat this, i decided to leave the camera at the centre and move all the world objects around it. now there is no gimble lock and the y rotation is fine
the problem is the x rotation!!!!
at the start it's rotation is fine and the objects pass over and under the camera, when you move the y axis however and then rotate, it still rotates around the x axis and the objects just spin there to the left or the right at varying radius's depending on how far around the y axis i am instead of going under you.
i think what i want to do is get the difference of the two nodes (the root node and the camera) and create an arbitrary X axis for the objects to rotate around i think???
How do i do this, if you guys understand please help!!!
the problem i was having with doing it by the camera rotation based of a parent dummy node was the gimble lock it would get at the top.
to combat this, i decided to leave the camera at the centre and move all the world objects around it. now there is no gimble lock and the y rotation is fine
the problem is the x rotation!!!!
at the start it's rotation is fine and the objects pass over and under the camera, when you move the y axis however and then rotate, it still rotates around the x axis and the objects just spin there to the left or the right at varying radius's depending on how far around the y axis i am instead of going under you.
i think what i want to do is get the difference of the two nodes (the root node and the camera) and create an arbitrary X axis for the objects to rotate around i think???
How do i do this, if you guys understand please help!!!
Why not just use quaternions?
-wyrmmage
-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
To add, irrlicht has an implementation here
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
tried the quaternions and they are a no go for me anyway,
this is a snippet of code that is meant to rotate around the centre but
all it does is snap the items back to the front and then does nothing, not very helpful.
i tried quaternions before and that is why i decided to move the whole world instead of the camera because irrlicht quaternion class just didn't seem to have what i needed to actually rotate the bugger!!!! just a whole lot of snapping the camera and being stubborn.
if anyone know how to actually ROTATE the camera instead of just snapping it. please feel free to give me a kick up the butt for winging!!!!
this is a snippet of code that is meant to rotate around the centre but
all it does is snap the items back to the front and then does nothing, not very helpful.
Code: Select all
core::quaternion rotation;
core::vector3df axis(0,0,0); axis.normalize();
core::vector3df final;
rotation.fromAngleAxis( 45*core::PI/180.0, axis );
rotation.toEuler(final);
CentreNode->setRotation(final);
if anyone know how to actually ROTATE the camera instead of just snapping it. please feel free to give me a kick up the butt for winging!!!!
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Breathe into the bag. In. Out. In. Out. Now, sloooowly.
It's stubbornly doing exactly what you're telling it to do. Can we back up a bit and examine the requirements, rather than the current solution?Tubby2877 wrote: i tried quaternions before and that is why i decided to move the whole world instead of the camera because irrlicht quaternion class just didn't seem to have what i needed to actually rotate the bugger!!!! just a whole lot of snapping the camera and being stubborn.
Do you want the camera at the origin looking out, or do you want it orbiting around the origin, looking in at the origin? I think you want the former, but I can't be sure.Tubby2877 wrote:So what i want is for the camera to rotate a full 360 degrees completely around the origin in the game.
If so, then here's a quaternion based solution that rotates both the forward and up axes of the camera to remove gimbal lock. (CAVEAT: this is usually where Vitek appears to explain a 2 line replacement for this method).
If this doesn't do what you want, then let's go back to your requirements so that we can be sure that we're solving the same problem.
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
// Standard event receiver
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
virtual bool IsKeyDown(EKEY_CODE keyCode) const { return KeyIsDown[keyCode]; }
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
void rotateVectorAroundAxis(vector3df & vector, const vector3df & axis, f32 radians)
{
quaternion MrQuaternion;
matrix4 MrMatrix;
(void)MrQuaternion.fromAngleAxis(radians, axis);
MrQuaternion.getMatrix(MrMatrix);
MrMatrix.rotateVect(vector);
}
int main()
{
MyEventReceiver receiver;
IrrlichtDevice *device =
createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 32,
false, false, false, &receiver);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
// Place some random billboards to give us something to look at.
for(int i = 0; i < 100; ++i)
{
scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialFlag(video::EMF_ZBUFFER, false);
bill->setPosition(vector3df((f32)(rand()%500) - 250.f, (f32)(rand()%500) - 250.f, (f32)(rand()%500) - 250.f));
}
ICameraSceneNode * camera = smgr->addCameraSceneNode();
u32 then = device->getTimer()->getTime();
while(device->run())
{
u32 const now = device->getTimer()->getTime();
const f32 moveSpeed = (f32)(now - then) / 500.f; // Let's rotate at a framerate independent speed
then = now;
// Work out the 3 axes for the camera.
vector3df forward = (camera->getTarget() - camera->getAbsolutePosition()).normalize();
vector3df up = camera->getUpVector();
vector3df right = forward.crossProduct(up);
// yaw around the up axis
if(receiver.IsKeyDown(KEY_KEY_D))
rotateVectorAroundAxis(forward, up, moveSpeed);
else if(receiver.IsKeyDown(KEY_KEY_A))
rotateVectorAroundAxis(forward, up, -moveSpeed);
// pitch around the right axis (we need to change both forward AND up)
if(receiver.IsKeyDown(KEY_KEY_S)) // S == pitch up, i.e. we're simulating moving a joystick.
{
rotateVectorAroundAxis(forward, right, moveSpeed);
rotateVectorAroundAxis(up, right, moveSpeed);
}
else if(receiver.IsKeyDown(KEY_KEY_W))
{
rotateVectorAroundAxis(forward, right, -moveSpeed);
rotateVectorAroundAxis(up, right, -moveSpeed);
}
// roll around the forward axis
if(receiver.IsKeyDown(KEY_KEY_Q))
rotateVectorAroundAxis(up, forward, moveSpeed);
else if(receiver.IsKeyDown(KEY_KEY_E))
rotateVectorAroundAxis(up, forward, -moveSpeed);
// And re-orient the camera to face along the foward and up axes.
camera->setTarget(camera->getAbsolutePosition() + forward);
camera->setUpVector(up);
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
ok so that does the camera moving in a 360 degrees looking mode,
but i want to be able to MOVE the camera in a 360 degree motion as well.
i'm sorry if that wasn't clear.
what i am havning is an object in the centre, at the origin
from there i want to be able to move the camera in and out from it and around in a sphere like shape so it is always a certain zoom radius from the centre, the camera will have an independent settarget function like the one that rogerborg described, but that only allows to LOOK 360 degrees which is helpful but only half the problem.
the idea now is to move in 360 degrees around the centre in a sphere like mode. and that is what is stuffing up.
because the xaxis isn't changing when we are not on the x = 0 for the rotation, the rotation is smaller as the y gets further and further from x = 0;
Hope this helps you figure it out lol
but i want to be able to MOVE the camera in a 360 degree motion as well.
i'm sorry if that wasn't clear.
what i am havning is an object in the centre, at the origin
from there i want to be able to move the camera in and out from it and around in a sphere like shape so it is always a certain zoom radius from the centre, the camera will have an independent settarget function like the one that rogerborg described, but that only allows to LOOK 360 degrees which is helpful but only half the problem.
the idea now is to move in 360 degrees around the centre in a sphere like mode. and that is what is stuffing up.
because the xaxis isn't changing when we are not on the x = 0 for the rotation, the rotation is smaller as the y gets further and further from x = 0;
Hope this helps you figure it out lol
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Then just position the camera by moving it back along its view axis. This isn't rocket science, although we could add some rockets if you like.
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
// Standard event receiver
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
virtual bool IsKeyDown(EKEY_CODE keyCode) const { return KeyIsDown[keyCode]; }
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
void rotateVectorAroundAxis(vector3df & vector, const vector3df & axis, f32 radians)
{
quaternion MrQuaternion;
matrix4 MrMatrix;
(void)MrQuaternion.fromAngleAxis(radians, axis);
MrQuaternion.getMatrix(MrMatrix);
MrMatrix.rotateVect(vector);
}
int main()
{
MyEventReceiver receiver;
IrrlichtDevice *device =
createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 32,
false, false, false, &receiver);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
// Place some random billboards to give us something to look at.
for(int i = 0; i < 100; ++i)
{
IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialFlag(video::EMF_ZBUFFER, false);
bill->setPosition(vector3df((f32)(rand()%500) - 250.f, (f32)(rand()%500) - 250.f, (f32)(rand()%500) - 250.f));
}
// Place a target node that orbits around 10, 20, 30 to demonstrate that we can
// orbit around any position, even a moving one.
IBillboardSceneNode * targetNode = smgr->addBillboardSceneNode();
targetNode->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
targetNode->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp"));
targetNode->setMaterialFlag(video::EMF_LIGHTING, false);
targetNode->setMaterialFlag(video::EMF_ZBUFFER, false);
targetNode->setPosition(vector3df(10, 20, 30));
ISceneNodeAnimator * animator = smgr->createFlyCircleAnimator(vector3df(10, 20, 30), 40, .001f, vector3df(1, 2, 3).normalize());
targetNode->addAnimator(animator);
animator->drop();
animator = 0;
ICameraSceneNode * camera = smgr->addCameraSceneNode();
f32 orbitDistance = 100.f;
u32 then = device->getTimer()->getTime();
while(device->run())
{
u32 const now = device->getTimer()->getTime();
const f32 moveSpeed = (f32)(now - then) / 500.f; // Let's rotate at a framerate independent speed
then = now;
// Work out the 3 axes for the camera.
vector3df forward = (camera->getTarget() - camera->getAbsolutePosition()).normalize();
vector3df up = camera->getUpVector();
vector3df right = forward.crossProduct(up);
// yaw around the up axis
if(receiver.IsKeyDown(KEY_KEY_D))
rotateVectorAroundAxis(forward, up, -moveSpeed);
else if(receiver.IsKeyDown(KEY_KEY_A))
rotateVectorAroundAxis(forward, up, +moveSpeed);
// pitch around the right axis (we need to change both forward AND up)
if(receiver.IsKeyDown(KEY_KEY_W))
{
rotateVectorAroundAxis(forward, right, -moveSpeed);
rotateVectorAroundAxis(up, right, -moveSpeed);
}
else if(receiver.IsKeyDown(KEY_KEY_S))
{
rotateVectorAroundAxis(forward, right, +moveSpeed);
rotateVectorAroundAxis(up, right, +moveSpeed);
}
// roll around the forward axis
if(receiver.IsKeyDown(KEY_KEY_Q))
rotateVectorAroundAxis(up, forward, +moveSpeed);
else if(receiver.IsKeyDown(KEY_KEY_E))
rotateVectorAroundAxis(up, forward, -moveSpeed);
if(receiver.IsKeyDown(KEY_KEY_Z))
orbitDistance = max_(10.f, orbitDistance - moveSpeed * 100.f);
else if(receiver.IsKeyDown(KEY_KEY_X))
orbitDistance = min_(200.f, orbitDistance + moveSpeed * 100.f);
// Move BACK up the forward axis of the camera to place it in its orbit.
camera->setPosition(targetNode->getAbsolutePosition() - (forward * orbitDistance));
// Point the camera at the target node, and align its up axis correctly.
camera->setTarget(targetNode->getAbsolutePosition());
camera->setUpVector(up);
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Again this only helps for one of the axis
now the camera will roll over the top all fine (pressing w and s)
but pressing a and d, the camera will do that it was doing before
So what i want is for both axis to use 0,0,0 as there centre and for them both to rotate around that centre point, at the moment i can either get one doing it or the other.
the solution vitek put up was helpful but just switched the problem from one axis to the other
i have the camera's look at all fine, it is positioning the camera the is causing the problem at the moment
like i am walking along the surface of the sphere from point to point.
now the camera will roll over the top all fine (pressing w and s)
but pressing a and d, the camera will do that it was doing before
So what i want is for both axis to use 0,0,0 as there centre and for them both to rotate around that centre point, at the moment i can either get one doing it or the other.
the solution vitek put up was helpful but just switched the problem from one axis to the other
i have the camera's look at all fine, it is positioning the camera the is causing the problem at the moment
like i am walking along the surface of the sphere from point to point.
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
I honestly have no idea what functionality you require. The 2nd code example above provides roll (Q and E), and orbitting using the camera's right and up vectors. This allows you to move it to any point on the surface of a sphere centred on its its look-at position.Tubby2877 wrote:but pressing a and d, the camera will do that it was doing before
[...]
like i am walking along the surface of the sphere from point to point.
Can you explain your requirements using commonly understood idioms? Are there any existing well known applications that display the behaviour that you require? Can you express it in an example, using terms like latitude and longitude, or polar coordinates?
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
It sounds like he wants continuous movement in all directions. So if he presses buttons to go up/down on the sphere, he doesn't want it to stop at the top, but to start going back down the other side of the sphere.
I don't see where this issue would come up in your code, but the code that I posted would definitely do it. I intentionally limit Phi to prevent looking straight up/down. But recalculating the up vector (as described in my comments and done in your example) should resolve the problem.
Travis
I don't see where this issue would come up in your code, but the code that I posted would definitely do it. I intentionally limit Phi to prevent looking straight up/down. But recalculating the up vector (as described in my comments and done in your example) should resolve the problem.
Travis
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Yup, there's no gimbal lock in my code; all 3 axes are free.
I'm wondering if he wants A and D to produce rotation in XZ around a circle of latitude (i.e. decreasing to nil at the +/-Y 'poles'), rather than to orbit around the camera's right vector.
I'm wondering if he wants A and D to produce rotation in XZ around a circle of latitude (i.e. decreasing to nil at the +/-Y 'poles'), rather than to orbit around the camera's right vector.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
Maybe what he is looking for is an orbiting camera, using the mouse input rather than keyboard presses.
Something like this maybe ?
http://au.youtube.com/watch?v=BkT3fzxlfUw
Anton
Something like this maybe ?
http://au.youtube.com/watch?v=BkT3fzxlfUw
Anton