from my understanding, Euler angles are applied one after the outher, so i dont know why this isn't working. all movement code is located in the move_ball method of the movable_ball class
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace std;
// ball
class movable_ball {
scene::ISceneNode *ball;
core::vector3df old_loc;
float angle_step;
int switchh;
public:
// constructor
movable_ball()
{
ball = NULL;
old_loc = core::vector3df(0,0,0);
angle_step = NULL;
}
//overloaded constructor
movable_ball(scene::ISceneManager* smgr, video::IVideoDriver* driver, core::vector3df sloc)
{
angle_step = (4 * 3.142) / 360;
ball = smgr->addSphereSceneNode();
int switchh = 0;
if (ball)
{
ball->setPosition(sloc);
ball->setScale(core::vector3df(0.4,0.4,0.4));
ball->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
ball->setMaterialFlag(video::EMF_LIGHTING, false);
}
}
void move_ball(core::vector3df loc)
{
if(switchh == 0)
switchh = 1;
else
switchh = 0;
// set position
ball->setPosition(loc);
// calculate movement delta
core::vector3df mov_delta = loc - old_loc;
// calculate rotation for X accsis
if(switchh == 1)
{
for(int angle = -30; angle < 31; angle ++)
{
float dist_moved_min = angle_step * angle;
float dist_moved_max = angle_step * (angle +1);
if(mov_delta.X > dist_moved_min && mov_delta.X < dist_moved_max)
{
// fix speed bug when angle is negative
if(mov_delta.X < 0)
angle += 1;
// apply rotation
core::vector3df ball_rot = ball->getRotation();
ball->setRotation(core::vector3df(ball_rot.X,ball_rot.Y,ball_rot.Z -= angle));
break;
}
}
} // end
else
{
// calculate rotation for Y accsis
for(int angle = -30; angle < 31; angle ++)
{
float dist_moved_min = angle_step * angle;
float dist_moved_max = angle_step * (angle +1);
if(mov_delta.Z > dist_moved_min && mov_delta.Z < dist_moved_max)
{
// fix speed bug when angle is negative
if(mov_delta.Z < 0)
angle += 1;
// apply rotation
core::vector3df ball_rot = ball->getRotation();
ball->setRotation(core::vector3df(ball_rot.X += angle,ball_rot.Y,ball_rot.Z));
break;
}
}
old_loc = loc;
}
}
};
// main function
int main()
{
IrrlichtDevice* device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480),
16, false, false, false, 0/*&receiver*/);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
movable_ball ball = movable_ball(smgr, driver,core::vector3df(0,0,0));
// camera
scene::ICameraSceneNode * cam = smgr->addCameraSceneNode();
cam -> setPosition(core::vector3df(0,40,0));
cam -> setTarget(core::vector3df(0,39,0.1));
// main loop
int lastFPS = -1;
core::vector3df loc(0,0,0);
core::vector3df accselaration(0.1,0,0.06);
while(device->run())
{
loc += accselaration;
if(loc.Z > 30)
{
accselaration.Z -= accselaration.Z*2;
}
if(loc.Z < -20)
{
accselaration.Z -= accselaration.Z*2;
}
if(loc.X > 35)
{
accselaration.X -= accselaration.X*2;
}
if(loc.X < -35)
{
accselaration.X -= accselaration.X*2;
}
// move ball
ball.move_ball(loc);
// render
driver->beginScene(true, true, video::SColor(255,0,0,0));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}