3D Rotational Movement?
3D Rotational Movement?
I was wondering how it would be possible to do 3D Rotational Movement with Irrlicht. I found this link: http://www.allegro.cc/forums/thread/594212/712639. In the second post it talks about using the sin and cos functions, but it's for 2D rotational movement. How would I translate this to 3D coordinates? I've been fiddling around with it for a while, but just can't get my node to move the direction it's facing. All thanks is appreciated, and sorry if the answer is an easy one.
-
- Posts: 199
- Joined: Tue Dec 09, 2008 2:55 am
If you want to be able to move the node, a certain direction, such as forward, you can use a function i made:
you will need to define:
i believe this works, but i havn't used the function in a while.
The function returns the position of the node, after it moved, or if you input "move" as true, it will move it for you.
edit: it only moves it along the x and z axis, unless you are moving forward, then it moves it on all 3 axis.
Code: Select all
vector3df move(ISceneNode* node,int direction,float speed,bool move){
vector3df newPos;
if(direction==FORWARD){
vector3df facing( sin( ( node->getRotation().Y + 0.0f ) * PI/180.0f ), -tan( (node->getRotation().X + 0.0f ) * PI/180.0f ), cos( ( node->getRotation().Y + 0.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(direction==BACK){
vector3df facing( sin( ( node->getRotation().Y + 180.0f ) * PI/180.0f ), 0, cos( (node->getRotation().Y + 180.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(direction==RIGHT){
vector3df facing( sin( (node->getRotation().Y + 90.0f ) * PI/180.0f ),0, cos( (node->getRotation().Y + 90.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(direction==LEFT){
vector3df facing( sin( ( node->getRotation().Y - 90.0f ) * PI/180.0f ), 0, cos( (node->getRotation().Y - 90.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(move) node->setPosition(newPos);
return newPos;
}
Code: Select all
const int BACK=1;
const int LEFT=2;
const int FORWARD=3;
const int RIGHT=4;
The function returns the position of the node, after it moved, or if you input "move" as true, it will move it for you.
edit: it only moves it along the x and z axis, unless you are moving forward, then it moves it on all 3 axis.
while(signatureEmpty){cout<<wittyComment();}
Thanks
Thanks, I'll see if I can get it to work. Be right back
Ok, after compiling it, it kind of works. My camera is looking from behind the character's head, and this looks like it's meant for an overhead view. Also, simply turning moves the character forward. I got to go to bed, so I'll leave my code so you can see if anything is wrong.
Ok, after compiling it, it kind of works. My camera is looking from behind the character's head, and this looks like it's meant for an overhead view. Also, simply turning moves the character forward. I got to go to bed, so I'll leave my code so you can see if anything is wrong.
Code: Select all
#include <irrlicht.h>
#include <math.h>
#include <stdio.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
const int BACK=1;
const int LEFT=2;
const int FORWARD=3;
const int RIGHT=4;
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
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:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
vector3df move(ISceneNode* node,int direction,float speed,bool move){
vector3df newPos;
if(direction==FORWARD){
vector3df facing( sin( ( node->getRotation().Y + 0.0f ) * PI/180.0f ), -tan( (node->getRotation().X + 0.0f ) * PI/180.0f ), cos( ( node->getRotation().Y + 0.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(direction==BACK){
vector3df facing( sin( ( node->getRotation().Y + 180.0f ) * PI/180.0f ), 0, cos( (node->getRotation().Y + 180.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(direction==RIGHT){
vector3df facing( sin( (node->getRotation().Y + 90.0f ) * PI/180.0f ),0, cos( (node->getRotation().Y + 90.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(direction==LEFT){
vector3df facing( sin( ( node->getRotation().Y - 90.0f ) * PI/180.0f ), 0, cos( (node->getRotation().Y - 90.0f ) * PI/180.0f ) );
facing.normalize();
newPos = (facing*speed) + node->getPosition();
}
if(move) node->setPosition(newPos);
return newPos;
}
int main(int argc, char** argv)
{
MyEventReceiver receiver;
//Create the main device for the game
IrrlichtDevice *device =
createDevice(EDT_OPENGL, dimension2d<s32>(640, 480), 16,
false, false, false, &receiver);
//Set the window caption
device->setWindowCaption(L"Psychic Demo");
//Create all of the environments for the game
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
//Create the head
ISceneNode* head = smgr->addSphereSceneNode();
//Create the body
ISceneNode* body = smgr->addSphereSceneNode();
//Create one hand
ISceneNode* hand1 = smgr->addSphereSceneNode();
//Create the other hand
ISceneNode* hand2 = smgr->addSphereSceneNode();
//Create one foot
ISceneNode* foot1 = smgr->addSphereSceneNode();
//Create the other foot
ISceneNode* foot2 = smgr->addSphereSceneNode();
//Test cube
ISceneNode* cube = smgr->addCubeSceneNode();
cube->setPosition(vector3df(30, 0, 0));
//Set stuff for head
if (head)
{
head->setMaterialFlag(EMF_LIGHTING, true);
head->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
head->setScale(vector3df(0.8, 0.8, 0.8));
head->setPosition(vector3df(0,0,0));
}
//Set stuff for the body
if (body)
{
body->setParent(head);
body->setMaterialFlag(EMF_LIGHTING, true);
body->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
body->setScale(vector3df(1, 1.8, 1));
body->setPosition(head->getPosition() + vector3df(0, -15, 0));
}
//Stuff for hand1
if (hand1)
{
hand1->setParent(head);
hand1->setMaterialFlag(EMF_LIGHTING, true);
hand1->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
hand1->setScale(vector3df(0.5, 0.5, 0.5));
hand1->setPosition(head->getPosition() + vector3df(0, -16, -8));
}
//Stuff for hand2
if (hand2)
{
hand2->setParent(head);
hand2->setMaterialFlag(EMF_LIGHTING, true);
hand2->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
hand2->setScale(vector3df(0.5, 0.5, 0.5));
hand2->setPosition(head->getPosition() + vector3df(0, -16, 8));
}
//Stuff for foot1
if (foot1)
{
foot1->setParent(head);
foot1->setMaterialFlag(EMF_LIGHTING, true);
foot1->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
foot1->setScale(vector3df(0.5, 0.5, 0.5));
foot1->setPosition(head->getPosition() + vector3df(0, -27, 6));
}
//Stuff for foot2
if (foot2)
{
foot2->setParent(head);
foot2->setMaterialFlag(EMF_LIGHTING, true);
foot2->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
foot2->setScale(vector3df(0.5, 0.5, 0.5));
foot2->setPosition(head->getPosition() + vector3df(0, -27, -6));
}
//Create the camera
ICameraSceneNode* camera = smgr->addCameraSceneNode(0, vector3df(-50, 0, 0), vector3df(head->getPosition()));
camera->setParent(head);
camera->setTarget(head->getPosition());
//Hide or show the mouse cursor
device->getCursorControl()->setVisible(true);
while(device->run())
{
//Detect mouse key presses
if (receiver.IsKeyDown(KEY_KEY_W))
{
head->setPosition(move(head, FORWARD ,0.5, true));
}
if (receiver.IsKeyDown(KEY_KEY_S))
{
head->setPosition(move(head, BACK, 0.5, true));
}
if (receiver.IsKeyDown(KEY_KEY_A))
{
head->setRotation(move(head, LEFT, 0.5, true));
}
if (receiver.IsKeyDown(KEY_KEY_D))
{
head->setRotation(move(head, RIGHT, 0.5, true));
}
camera->setTarget(head->getPosition());
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Irrlicht 1.5 has vector3d::rotationToDirection() which will turn 3 Euler angles (i.e. an Irrlicht rotation) into a direction vector.
You can specify which way is "forwards". We've assumed that your models are facing towards +Z (i.e. 0,0,1) but you can specify any forward orientation that you like.
You can specify which way is "forwards". We've assumed that your models are facing towards +Z (i.e. 0,0,1) but you can specify any forward orientation that you like.
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: 69
- Joined: Fri Feb 22, 2008 6:47 pm
- Location: montreal
- Contact:
Found only one way to do complete 3d rotation
Hi,
I worked a LOT on 3d rotation independant on all axis, the only way is to use matrix with small steps rotations, you cannot call a final rotation because of gimbal lock.
look at this sample code from this thread:
http://irrlicht.sourceforge.net/phpBB2 ... p?t=31866
If you need any further infos, tell me.
Robert
I worked a LOT on 3d rotation independant on all axis, the only way is to use matrix with small steps rotations, you cannot call a final rotation because of gimbal lock.
look at this sample code from this thread:
http://irrlicht.sourceforge.net/phpBB2 ... p?t=31866
Code: Select all
//Update of events action on rotation of vaissel
irr::core::vector3df rolls(0.f,0.f,0.f);
...
switch (key)
{
...
///acitvate attitude controls
case KEY_LEFT: {log_str.append(L"thrustinL",15);
rolls.Z+=roll_speed;
actual_rot.Z+=roll_speed;
rotate(rolls,vaisseau);
make_thrust(ps[1]);break;}
...other keys
//to make actual rotation on vaissel node
void vaissel::rotate(irr::core::vector3df &rotation, scene::ISceneNode * node)
{ irr::core::matrix4 m;
m.setRotationDegrees(node->getRotation());
irr::core::matrix4 n;
n.setRotationDegrees(rotation);
m *= n;
node->setRotation( m.getRotationDegrees() );
node->updateAbsolutePosition();
}
Robert
If it can't be writen, it can't exist
OK
How could I use the rotationToDirection function? It seems pretty basic and promising. Thanks for all the help so far!
EDIT
Muahahaha! I got it to work! My code is as follows:
EDIT
Muahahaha! I got it to work! My code is as follows:
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
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:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
int main(int argc, char** argv)
{
MyEventReceiver receiver;
//Create the main device for the game
IrrlichtDevice *device =
createDevice(EDT_OPENGL, dimension2d<s32>(640, 480), 16,
false, false, false, &receiver);
//Set the window caption
device->setWindowCaption(L"Psychic Demo");
//Create all of the environments for the game
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
//Create the head
ISceneNode* head = smgr->addSphereSceneNode();
//Create the body
ISceneNode* body = smgr->addSphereSceneNode();
//Create one hand
ISceneNode* hand1 = smgr->addSphereSceneNode();
//Create the other hand
ISceneNode* hand2 = smgr->addSphereSceneNode();
//Create one foot
ISceneNode* foot1 = smgr->addSphereSceneNode();
//Create the other foot
ISceneNode* foot2 = smgr->addSphereSceneNode();
//Test cube
ISceneNode* cube = smgr->addCubeSceneNode();
cube->setPosition(vector3df(30, 0, 0));
//Set stuff for head
if (head)
{
head->setMaterialFlag(EMF_LIGHTING, true);
head->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
head->setScale(vector3df(0.8, 0.8, 0.8));
head->setPosition(vector3df(0,0,0));
}
//Set stuff for the body
if (body)
{
body->setParent(head);
body->setMaterialFlag(EMF_LIGHTING, true);
body->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
body->setScale(vector3df(1, 1.8, 1));
body->setPosition(head->getPosition() + vector3df(0, -15, 0));
}
//Stuff for hand1
if (hand1)
{
hand1->setParent(head);
hand1->setMaterialFlag(EMF_LIGHTING, true);
hand1->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
hand1->setScale(vector3df(0.5, 0.5, 0.5));
hand1->setPosition(head->getPosition() + vector3df(0, -16, -8));
}
//Stuff for hand2
if (hand2)
{
hand2->setParent(head);
hand2->setMaterialFlag(EMF_LIGHTING, true);
hand2->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
hand2->setScale(vector3df(0.5, 0.5, 0.5));
hand2->setPosition(head->getPosition() + vector3df(0, -16, 8));
}
//Stuff for foot1
if (foot1)
{
foot1->setParent(head);
foot1->setMaterialFlag(EMF_LIGHTING, true);
foot1->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
foot1->setScale(vector3df(0.5, 0.5, 0.5));
foot1->setPosition(head->getPosition() + vector3df(0, -27, 6));
}
//Stuff for foot2
if (foot2)
{
foot2->setParent(head);
foot2->setMaterialFlag(EMF_LIGHTING, true);
foot2->setMaterialTexture(0, driver->getTexture("./textures/dummy.bmp"));
foot2->setScale(vector3df(0.5, 0.5, 0.5));
foot2->setPosition(head->getPosition() + vector3df(0, -27, -6));
}
//Create the camera
ICameraSceneNode* camera = smgr->addCameraSceneNode(0, vector3df(0, -50, 0), vector3df(head->getPosition()));
camera->setParent(head);
camera->setTarget(head->getPosition());
//Hide or show the mouse cursor
device->getCursorControl()->setVisible(true);
while(device->run())
{
vector3df headrotation = head->getRotation();
float vx = cos((headrotation.Y + 90) / 180 * 3.14159265) * 1;
float vy = sin((headrotation.Y + 90) / 180 * 3.14159265) * 1;
//Detect mouse key presses
if (receiver.IsKeyDown(KEY_KEY_W))
{
head->setPosition(head->getPosition() + vector3df(vy, 0, vx));
}
if (receiver.IsKeyDown(KEY_KEY_S))
{
head->setPosition(head->getPosition() + vector3df(vy * -1, 0, vx * -1));
}
if (receiver.IsKeyDown(KEY_KEY_A))
{
head->setRotation(head->getRotation() + vector3df(0, 1, 0));
}
if (receiver.IsKeyDown(KEY_KEY_D))
{
head->setRotation(head->getRotation() + vector3df(0, -1, 0));
}
camera->setTarget(head->getPosition());
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}