It has a skydome so you can see the rotation of the camera better aswell.
Download that here!
I'm so proud of myself this thing was a pain to get working.
Well anyways I decided to share it. hooray me!
I owe vitek some credit for the math calculations but I added the mouse control for it which is a bit unfinished but useful.
you can view that here also contains the keyboard version in that thread.
Code: Select all
#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
using namespace gui;
using namespace core;
using namespace scene;
using namespace video;
IrrlichtDevice *device;
ISceneManager* smgr;
IVideoDriver* driver;
ICursorControl* CursorControl;
position2d<f32> Cursor;
position2d<f32> OldCursor;
position2d<f32> CursorDiff;
ISceneNode* box;
ICameraSceneNode* cam;
u32 now;
u32 oldNow;
f32 Elapsed;
vector3df offset;
f32 Radius;
f32 Theta; // degrees
f32 Phi; // degrees
f32 LinearVelocity = 5.f;
f32 AngularVelocity = 5.f;
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(){}
virtual ~MyEventReceiver(){}
// you may need to change the parameter type depending on your Irrlicht version
virtual bool OnEvent(SEvent event)
{
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
Cursor.X = event.MouseInput.X;
Cursor.Y = event.MouseInput.Y;
}
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
}
}
return false;
}
};
int main()
{
// create device otherwise quit if creation failed
device = createDevice(EDT_OPENGL, dimension2d<s32>(800, 600), 32, false, false, false);
if (device == 0)
return false; // could not create selected driver.
MyEventReceiver receiver;
device->setEventReceiver(&receiver);
driver = device->getVideoDriver();
smgr = device->getSceneManager();
// the thing we want to look at
box = smgr->addCubeSceneNode();
// add camera
cam = smgr->addCameraSceneNode(box);
cam->setTarget( box->getAbsolutePosition() );
Radius = 20.f;
Theta = 180.f; // degrees
Phi = 90.f; // degrees
// add a dynamic light
smgr->addLightSceneNode(0, core::vector3df(-20, 0, 0), video::SColorf(1.f, 0.f, 0.f, 1.f));
smgr->addLightSceneNode(0, core::vector3df(0, -20, 0), video::SColorf(0.f, 1.f, 0.f, 1.f));
smgr->addLightSceneNode(0, core::vector3df(0, 0, -20), video::SColorf(0.f, 0.f, 1.f, 1.f));
oldNow = device->getTimer()->getRealTime();
while(device->run())
{
// calculate elapsed time as fractional seconds
now = device->getTimer()->getRealTime();
Elapsed = (now - oldNow) / 1000.f;
oldNow = now;
// window is active, so render scene
if (device->isWindowActive())
{
//everything before this is prerender
if (driver->beginScene(true, true, video::SColor(255, 0, 0, 100)))
{
smgr->drawAll();
//everything after this is post render
driver->endScene();
}
// // adjust camera position based on current key input
// if (zoom in)
// Radius -= (LinearVelocity * Elapsed);
// if (zoom out)
// Radius += (LinearVelocity * Elapsed);
if(Cursor.X != OldCursor.X)
{
Theta += ((AngularVelocity * Elapsed) + (Cursor.X - OldCursor.X) / 2);
}
if(Cursor.Y != OldCursor.Y)
{
Phi += ((AngularVelocity * Elapsed) + (Cursor.Y - OldCursor.Y) / 2);
}
OldCursor = Cursor;
// if (reset)
// {
// Theta = 180.f;
// Phi = 90.f;
// }
// prevent camera from walking into our box
float MinZoom = 10.f;
if (Radius < MinZoom)
Radius = MinZoom;
// lame ***** gimble lock prevention. if you don't want to do this
// you need to adjust the up vector of the camera so it never is
// parallel to the look at vector
if (Phi < 1.f)
Phi = 2.f;
else if (179.f < Phi)
Phi = 178.f;
if (Theta < 0.f)
Theta = 360.f;
else if (360.f < Theta)
Theta = 0.f;
f32 sinOfPhi = sinf(Phi * DEGTORAD);
f32 cosOfPhi = cosf(Phi * DEGTORAD);
f32 sinOfTheta = sinf(Theta * DEGTORAD);
f32 cosOfTheta = cosf(Theta * DEGTORAD);
// these are switched around a little from what i posted above
offset.X = Radius * sinOfTheta * sinOfPhi;
offset.Y = Radius * cosOfPhi;
offset.Z = Radius * cosOfTheta * sinOfPhi;
// camera is a child of the cube, so our offset is actually
// the position of the camera
cam->setPosition(offset);
cam->setTarget( box->getAbsolutePosition() );
cam->updateAbsolutePosition();
wchar_t caption[128];
swprintf(caption, 128, L"r=%f theta=%f phi=%f", Radius, Theta, Phi);
device->setWindowCaption(caption);
}
}
device->drop();
return 0;
}