cameraOrbit = (f32)((int)(cameraOrbitOld + cursorDelta.X) % 360);
cameraAngle = (f32)((int)(cameraAngleOld + cursorDelta.Y) % 360);cameraOrbit = fmod( (cameraOrbitOld + cursorDelta.X), 360);
cameraAngle = fmod( (cameraAngleOld + cursorDelta.Y), 360);

#include <iostream>
#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")
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SETTINGS /////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// setup key engine objects
IrrlichtDevice* device = createDevice(EDT_OPENGL,dimension2d<u32>(800,600),32,false,false,false);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
ICursorControl* CursorControl;
// keyboard registry
bool keys[irr::KEY_KEY_CODES_COUNT];
// mouse registry
bool mouseDownL;
bool mouseDownM;
bool mouseDownR;
f32 lastWheelMovement;
position2d<f32> cursor;
position2d<f32> cursorOld;
position2d<f32> cursorDelta;
position2d<f32> cursorDeltaOld;
// camera registry
f32 cameraOrbit = 135;
f32 cameraAngle = 35;
f32 cameraDistance = 6;
f32 cameraOrbitOld = 0;
f32 cameraAngleOld = 0;
// player registry
f32 playerX = 12;
f32 playerY = 0;
f32 playerZ = 15;
f32 playerCompass = 0;
f32 playerTurnTo = 0;
f32 playerTurnSpeed = 1;
f32 playerMoveSpeed = 0.01f;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS : MyEventReceiver //////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
// left mouse button state check
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) mouseDownL = true;
if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) mouseDownL = false;
// middle mouse button state check
if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN) mouseDownM = true;
if(event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP) mouseDownM = false;
if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)
{
cameraDistance -= event.MouseInput.Wheel * (cameraDistance / 20) * 2;
if(cameraDistance < 6) cameraDistance = 6;
if(cameraDistance > 12) cameraDistance = 12;
}
// right mouse button state check
if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
{
mouseDownR = true;
cursorOld.X = (f32)event.MouseInput.X;
cursorOld.Y = (f32)event.MouseInput.Y;
cursorDelta.X = 0;
cursorDelta.Y = 0;
cursorDeltaOld.X = 0;
cursorDeltaOld.Y = 0;
cameraOrbitOld = cameraOrbit;
cameraAngleOld = cameraAngle;
}
if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) mouseDownR = false;
// mouse move check
if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
// add condition that right mouse button be down
if(mouseDownR == true){
cursor.X = (f32)event.MouseInput.X;
cursor.Y = (f32)event.MouseInput.Y;
cursorDelta.X = (f32)((cursor.X - cursorOld.X) * 1.0);
cursorDelta.Y = (f32)((cursor.Y - cursorOld.Y) * 1.0);
if (cursorDelta.Y > (88 - cameraAngleOld)) {
cursorOld.Y += (cursorDelta.Y - cursorDeltaOld.Y);
cursorDelta.Y = 88 - cameraAngleOld;
}
if (cursorDelta.Y < (-88 - cameraAngleOld)) {
cursorOld.Y += (cursorDelta.Y - cursorDeltaOld.Y);
cursorDelta.Y = -88 - cameraAngleOld;
}
cursorDeltaOld.X = cursorDelta.X;
cursorDeltaOld.Y = cursorDelta.Y;
cameraOrbit = (f32)((int)(cameraOrbitOld + cursorDelta.X) % 360);
cameraAngle = (f32)((int)(cameraAngleOld + cursorDelta.Y) % 360);
if(cameraAngle > 88) cameraAngle = 88;
if(cameraAngle < 18) cameraAngle = 18;
}
}
return false;
}
return false;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS : CMySampleSceneNode ///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CMySampleSceneNode : public ISceneNode
{
private:
static const s32 tileResolution = 32; // how many segments to have down each edge of the tile
static const s32 cellSize = 2; // how many units square will each cell of the tile be?
aabbox3d<f32> Box; // [A]xis [A]ligned [B]ounding [B]ox in [3D] space
S3DVertex Vertices[((tileResolution+1) * (tileResolution+1))]; // An array where each cell is of type S3DVertex
u16 indices[(tileResolution * tileResolution) * 6]; // number of cells * 6 (each cell has two tris, each tri has 3 indices)
SMaterial Material; // A material object of type SMaterial
IVideoDriver *driver; // A link through to the driver object
public:
/////////////////
// constructor //
/////////////////
CMySampleSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) : ISceneNode(parent, mgr, id)
{
// put link to videoDriver into already prepared var of type IVideoDriver
driver = SceneManager->getVideoDriver();
// set material settings
Material.Wireframe = true;
Material.Lighting = false;
Material.BackfaceCulling = false;
// create vertex objects in vertex array
s32 vIndex = 0;
for (f32 i=0; i<(tileResolution+1); i++){
for (f32 j=0; j<(tileResolution+1); j++){
Vertices[vIndex] = S3DVertex((j*cellSize),0,(i*cellSize), 0,0,1, SColor(255,0,255,255),j,i);
// std :: cout << vIndex << ":" << j << "," << i << "\n";
vIndex++;
}
}
// reposition the bounding box to the first vertex
Box.reset(Vertices[0].Pos);
// add the defined vertices to Box
for (s32 i=0; i<vIndex; i++)
Box.addInternalPoint(Vertices[i].Pos);
// setup indices
s32 iIndex = 0;
for (s32 i=0; i<tileResolution; i++){
for (s32 j=0; j<tileResolution; j++){
s32 currentVertex = (i*(tileResolution+1)) + j;
indices[iIndex + 0] = currentVertex;
indices[iIndex + 1] = currentVertex+1;
indices[iIndex + 2] = currentVertex+tileResolution+1;
indices[iIndex + 3] = currentVertex+1;
indices[iIndex + 4] = currentVertex+tileResolution+2;
indices[iIndex + 5] = currentVertex+tileResolution+1;
iIndex = iIndex + 6;
}
}
}
/////////////////////////
// OnRegisterSceneNode //
/////////////////////////
virtual void OnRegisterSceneNode()
{
if (IsVisible)
ISceneNode::OnRegisterSceneNode();
}
///////////////
// OnAnimate //
///////////////
virtual void OnAnimate(u32 timeMs)
{
ISceneNode::OnAnimate(timeMs);
}
////////////
// render //
////////////
virtual void render()
{
driver->setMaterial(Material);
driver->setTransform(ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0],(tileResolution+1) * (tileResolution+1),&indices[0],((tileResolution*tileResolution)*2));
}
////////////////////
// getBoundingBox //
////////////////////
virtual const aabbox3d<f32>& getBoundingBox() const
{
return Box;
}
//////////////////////
// getMaterialCount //
//////////////////////
virtual u32 getMaterialCount()
{
return 1;
}
/////////////////
// getMaterial //
/////////////////
virtual SMaterial& getMaterial(s32 i)
{
return Material;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION : sphericalXYZ //////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
vector3df sphericalXYZ(f32 compassAngle, f32 elevationAngle, f32 radius){
compassAngle = compassAngle * -1;
elevationAngle = elevationAngle * -1;
elevationAngle = elevationAngle + 90;
f32 x = radius * cos(compassAngle * PI/180.0f ) * sin(elevationAngle * PI/180.0f );
f32 z = radius * sin(compassAngle * PI/180.0f ) * sin(elevationAngle * PI/180.0f );
f32 y = radius * cos(elevationAngle * PI/180.0f );
vector3df result;
result.X = x;
result.Y = y;
result.Z = z;
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION : int2string ////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
stringw int2string(int intToConvert){
char temp[50];
sprintf(temp,"%d",intToConvert);
return temp;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// MAIN /////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
// setup event receiver
MyEventReceiver rv;
device->setEventReceiver(&rv);
for(int x=0; x<irr::KEY_KEY_CODES_COUNT; x++) keys[x] = false;
// setup screen display elements
device->setWindowCaption(L"First Game");
IGUIStaticText* debug_panel = guienv->addStaticText(L"Debug Panel",rect<s32>(5, 5, 200, 200),false,true,0,-1,false);
// setup the "player"
ISceneNode* cPivot1 = smgr->addCubeSceneNode(0.5,0,-1,vector3df(playerX,playerY,playerZ));
cPivot1->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot2 = smgr->addCubeSceneNode(2,cPivot1,-1,vector3df(0,1,0));
cPivot2->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot2->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot3 = smgr->addCubeSceneNode(1,cPivot2,-1,vector3df(0,1.5,0));
cPivot3->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot3->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot4 = smgr->addCubeSceneNode(1,cPivot2,-1,vector3df(0,0,1.5));
cPivot4->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot4->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot5 = smgr->addCubeSceneNode(0.5,cPivot2,-1,vector3df(0,0,2.2));
cPivot5->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot5->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot6 = smgr->addCubeSceneNode(0.5,cPivot2,-1,vector3df(1.25,0.7,0.7));
cPivot6->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot6->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot7 = smgr->addCubeSceneNode(0.5,cPivot2,-1,vector3df(1.25,-0.7,0.7));
cPivot7->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot7->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot8 = smgr->addCubeSceneNode(0.5,cPivot2,-1,vector3df(-1.25,0.7,0.7));
cPivot8->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot8->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot9 = smgr->addCubeSceneNode(0.5,cPivot2,-1,vector3df(-1.25,-0.7,0.7));
cPivot9->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot9->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot10 = smgr->addCubeSceneNode(0.7,cPivot2,-1,vector3df(0,-0.6,-1.25));
cPivot10->setMaterialTexture(0,driver->getTexture("wall.bmp"));
cPivot10->setMaterialFlag(video::EMF_LIGHTING, false);
// setup the camera
ICameraSceneNode* myCamera = smgr->addCameraSceneNode(cPivot1, sphericalXYZ(cameraOrbit,cameraAngle,cameraDistance), cPivot1->getPosition());
// create references to our custom nodes
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(),smgr,1);
myNode->setPosition(vector3df(0,0,0));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEVICE : main loop ///////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
while(device->run()) {
/////////////////////////
// keyboard management //
/////////////////////////
// system keys
if(keys[KEY_ESCAPE]){
device->closeDevice();
}
// player keys
if(keys[KEY_KEY_W]){
// player movement vector
vector3df playerStep = sphericalXYZ(cameraOrbit,0,playerMoveSpeed);
playerX -= playerStep.X;
playerY -= playerStep.Y;
playerZ -= playerStep.Z;
// player rotation brain torture
playerTurnTo = cameraOrbit - 90;
if(playerTurnTo < 0) playerTurnTo += 360;
if(playerTurnTo >= 360) playerTurnTo -= 360;
if(playerCompass < 0) playerCompass += 360;
if(playerCompass >= 360) playerCompass -= 360;
f32 playerTurnDir = 0;
f32 playerTurnDelta = 0;
if(playerCompass > playerTurnTo)
{
if(playerCompass - playerTurnTo < 180){
playerTurnDir = -1;
playerTurnDelta = playerCompass - playerTurnTo;
} else {
playerTurnDir = 1;
playerTurnDelta = (360 - playerCompass) + playerTurnTo;
}
}
if(playerCompass < playerTurnTo)
{
if(playerTurnTo - playerCompass < 180){
playerTurnDir = 1;
playerTurnDelta = playerTurnTo - playerCompass;
} else {
playerTurnDir = -1;
playerTurnDelta = (360 - playerTurnTo) + playerCompass;
}
}
f32 playerTurnAmount;
if(playerTurnDelta < playerTurnSpeed){
playerTurnAmount = playerTurnDelta;
} else {
playerTurnAmount = playerTurnSpeed;
}
playerCompass += (playerTurnAmount * playerTurnDir);
cPivot1->setPosition(vector3df(playerX,playerY,playerZ));
cPivot2->setRotation(vector3df(0,playerCompass,0));
myCamera->setTarget(vector3df(playerX,playerY,playerZ));
}
if(keys[KEY_KEY_S]){
// player movement vector
vector3df playerStep = sphericalXYZ(cameraOrbit,0,playerMoveSpeed);
playerX += playerStep.X;
playerY -= playerStep.Y;
playerZ += playerStep.Z;
// player rotation brain torture
playerTurnTo = cameraOrbit + 90;
if(playerTurnTo < 0) playerTurnTo += 360;
if(playerTurnTo >= 360) playerTurnTo -= 360;
if(playerCompass < 0) playerCompass += 360;
if(playerCompass >= 360) playerCompass -= 360;
f32 playerTurnDir = 0;
f32 playerTurnDelta = 0;
if(playerCompass > playerTurnTo)
{
if(playerCompass - playerTurnTo < 180){
playerTurnDir = -1;
playerTurnDelta = playerCompass - playerTurnTo;
} else {
playerTurnDir = 1;
playerTurnDelta = (360 - playerCompass) + playerTurnTo;
}
}
if(playerCompass < playerTurnTo)
{
if(playerTurnTo - playerCompass < 180){
playerTurnDir = 1;
playerTurnDelta = playerTurnTo - playerCompass;
} else {
playerTurnDir = -1;
playerTurnDelta = (360 - playerTurnTo) + playerCompass;
}
}
f32 playerTurnAmount;
if(playerTurnDelta < playerTurnSpeed){
playerTurnAmount = playerTurnDelta;
} else {
playerTurnAmount = playerTurnSpeed;
}
playerCompass += (playerTurnAmount * playerTurnDir);
cPivot1->setPosition(vector3df(playerX,playerY,playerZ));
cPivot2->setRotation(vector3df(0,playerCompass,0));
myCamera->setTarget(vector3df(playerX,playerY,playerZ));
}
if(keys[KEY_KEY_D]){
// player movement vector
vector3df playerStep = sphericalXYZ(cameraOrbit,0,playerMoveSpeed);
playerX -= playerStep.X;
playerY -= playerStep.Y;
playerZ += playerStep.Z;
// player rotation brain torture
playerTurnTo = cameraOrbit;
if(playerTurnTo < 0) playerTurnTo += 360;
if(playerTurnTo >= 360) playerTurnTo -= 360;
if(playerCompass < 0) playerCompass += 360;
if(playerCompass >= 360) playerCompass -= 360;
f32 playerTurnDir = 0;
f32 playerTurnDelta = 0;
if(playerCompass > playerTurnTo)
{
if(playerCompass - playerTurnTo < 180){
playerTurnDir = -1;
playerTurnDelta = playerCompass - playerTurnTo;
} else {
playerTurnDir = 1;
playerTurnDelta = (360 - playerCompass) + playerTurnTo;
}
}
if(playerCompass < playerTurnTo)
{
if(playerTurnTo - playerCompass < 180){
playerTurnDir = 1;
playerTurnDelta = playerTurnTo - playerCompass;
} else {
playerTurnDir = -1;
playerTurnDelta = (360 - playerTurnTo) + playerCompass;
}
}
f32 playerTurnAmount;
if(playerTurnDelta < playerTurnSpeed){
playerTurnAmount = playerTurnDelta;
} else {
playerTurnAmount = playerTurnSpeed;
}
playerCompass += (playerTurnAmount * playerTurnDir);
cPivot1->setPosition(vector3df(playerX,playerY,playerZ));
cPivot2->setRotation(vector3df(0,playerCompass,0));
myCamera->setTarget(vector3df(playerX,playerY,playerZ));
}
if(keys[KEY_KEY_A]){
// player movement vector
vector3df playerStep = sphericalXYZ(cameraOrbit,0,playerMoveSpeed);
playerX += playerStep.X;
playerY -= playerStep.Y;
playerZ -= playerStep.Z;
// player rotation brain torture
playerTurnTo = cameraOrbit - 180;
if(playerTurnTo < 0) playerTurnTo += 360;
if(playerTurnTo >= 360) playerTurnTo -= 360;
if(playerCompass < 0) playerCompass += 360;
if(playerCompass >= 360) playerCompass -= 360;
f32 playerTurnDir = 0;
f32 playerTurnDelta = 0;
if(playerCompass > playerTurnTo)
{
if(playerCompass - playerTurnTo < 180){
playerTurnDir = -1;
playerTurnDelta = playerCompass - playerTurnTo;
} else {
playerTurnDir = 1;
playerTurnDelta = (360 - playerCompass) + playerTurnTo;
}
}
if(playerCompass < playerTurnTo)
{
if(playerTurnTo - playerCompass < 180){
playerTurnDir = 1;
playerTurnDelta = playerTurnTo - playerCompass;
} else {
playerTurnDir = -1;
playerTurnDelta = (360 - playerTurnTo) + playerCompass;
}
}
f32 playerTurnAmount;
if(playerTurnDelta < playerTurnSpeed){
playerTurnAmount = playerTurnDelta;
} else {
playerTurnAmount = playerTurnSpeed;
}
playerCompass += (playerTurnAmount * playerTurnDir);
cPivot1->setPosition(vector3df(playerX,playerY,playerZ));
cPivot2->setRotation(vector3df(0,playerCompass,0));
myCamera->setTarget(vector3df(playerX,playerY,playerZ));
}
// orient camera
myCamera->setPosition(sphericalXYZ(cameraOrbit,cameraAngle,cameraDistance));
// debug display
stringw s(L"FPS : "); s+= int2string(driver->getFPS());
s += L"\nleft mouse button : "; s+= mouseDownL;
s += L"\nmiddle mouse button : "; s+= mouseDownM;
s += L"\nright mouse button : "; s+= mouseDownR;
s += L"\nlast wheel movement : "; s+= lastWheelMovement;
s += L"\ncursor x : "; s+= cursor.X;
s += L"\ncursor y : "; s+= cursor.Y;
s += L"\ncursorOld x : "; s+= cursorOld.X;
s += L"\ncursorOld y : "; s+= cursorOld.Y;
s += L"\ncursorDelta x : "; s+= cursorDelta.X;
s += L"\ncursorDelta y : "; s+= cursorDelta.Y;
s += L"\ncamera orbit : "; s+= cameraOrbit;
s += L"\ncamera angle : "; s+= cameraAngle;
s += L"\nplayer compass : "; s+= playerCompass;
s += L"\nplayer turn to : "; s+= playerTurnTo;
debug_panel->setText(s.c_str());
//////////////////
// render scene //
//////////////////
driver->beginScene(true, true, SColor(0,120,120,120));
myNode->render();
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}


player = smgr->getMesh("Modelos/Soldado/meshes/soldier_lod0.b3d");
if (!player) { device->drop(); }
player_node = smgr->addAnimatedMeshSceneNode(player, 0, -1, core::vector3df(playerX,playerY,playerZ));
player_node2 = smgr->addAnimatedMeshSceneNode(player, player_node, 1, core::vector3df(0,1,0));
myCamera = smgr->addCameraSceneNode(player_node, sphericalXYZ(cameraOrbit,cameraAngle,cameraDistance), player_node->getPosition());
// ...
if(keys[KEY_KEY_W]){
/// ...
player_node->setPosition(core::vector3df(playerX,playerY,playerZ));
player_node2->setRotation(core::vector3df(0,playerCompass,0));
}
#include <iostream>
#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")
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS : MyEventReceiver //////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class MyEventReceiver : public IEventReceiver
{
private:
IrrlichtDevice* Device;
public:
// keyboard registry
bool keys[irr::KEY_KEY_CODES_COUNT];
// mouse registry
bool mouseDownL;
bool mouseDownM;
bool mouseDownR;
f32 lastWheelMovement;
position2d<f32> cursor;
position2d<f32> cursorOld;
position2d<f32> cursorDelta;
// camera registry
f32 cameraOrbit;
f32 cameraAngle;
f32 cameraDistance;
f32 cameraOrbitOld;
f32 cameraAngleOld;
// player registry
f32 playerX;
f32 playerY;
f32 playerZ;
f32 playerCompass;
f32 playerTurnTo;
f32 playerTurnSpeed;
f32 playerMoveSpeed;
public:
/// constructor
MyEventReceiver( IrrlichtDevice* device )
: Device(device), mouseDownL(false), mouseDownM(false), mouseDownR(false), lastWheelMovement(0.f)
, cursor(0.f,0.f), cursorOld(0.f,0.f), cursorDelta(0.f,0.f), cameraOrbit(45.f), cameraAngle(0.f)
, cameraDistance(30.f), cameraOrbitOld(0.f), cameraAngleOld(0.f), playerX(0.f), playerY(0.f), playerZ(0.f)
, playerCompass(30.f), playerTurnTo(0.f), playerTurnSpeed(1.f), playerMoveSpeed(0.01f)
{
for(u32 i=0; i<KEY_KEY_CODES_COUNT; i++)
keys[i] = false;
if (Device)
Device->setEventReceiver( this );
}
/// destructor
virtual ~MyEventReceiver()
{
// empty
}
virtual bool OnEvent(const SEvent& event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
// left mouse button state check
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) mouseDownL = true;
if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) mouseDownL = false;
// middle mouse button state check
if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN) mouseDownM = true;
if(event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP) mouseDownM = false;
if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)
{
cameraDistance -= event.MouseInput.Wheel * (cameraDistance / 20) * 2;
if(cameraDistance < 10) cameraDistance = 10;
if(cameraDistance > 100) cameraDistance = 100;
}
// right mouse button state check
if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
{
mouseDownR = true;
cursorOld.X = event.MouseInput.X;
cursorOld.Y = event.MouseInput.Y;
cursorDelta.X = 0;
cursorDelta.Y = 0;
cameraOrbitOld = cameraOrbit;
cameraAngleOld = cameraAngle;
}
if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) mouseDownR = false;
// mouse move check
if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
// add condition that right mouse button be down
if(mouseDownR == true)
{
cursor.X = event.MouseInput.X;
cursor.Y = event.MouseInput.Y;
cursorDelta.X = cursor.X - cursorOld.X;
cursorDelta.Y = cursor.Y - cursorOld.Y;
if(cursorDelta.Y > 100) cursorDelta.Y = 100;
if(cursorDelta.Y < -100) cursorDelta.Y = -100;
cameraOrbit = (int)(cameraOrbitOld + cursorDelta.X) % 360;
cameraAngle = (int)(cameraAngleOld + cursorDelta.Y) % 360;
if(cameraAngle > 88) cameraAngle = 88;
if(cameraAngle < -88) cameraAngle = -88;
}
}
return false;
}
return false;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS : CMySampleSceneNode ///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CMySampleSceneNode : public ISceneNode
{
private:
static const s32 tileResolution = 32; // how many segments to have down each edge of the tile
static const s32 cellSize = 2; // how many units square will each cell of the tile be?
aabbox3d<f32> Box; // [A]xis [A]ligned [B]ounding [B]ox in [3D] space
S3DVertex Vertices[((tileResolution+1) * (tileResolution+1))]; // An array where each cell is of type S3DVertex
u16 indices[(tileResolution * tileResolution) * 6]; // number of cells * 6 (each cell has two tris, each tri has 3 indices)
SMaterial Material; // A material object of type SMaterial
IVideoDriver *driver; // A link through to the driver object
public:
/////////////////
// constructor //
/////////////////
CMySampleSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) : ISceneNode(parent, mgr, id)
{
// put link to videoDriver into already prepared var of type IVideoDriver
IVideoDriver* driver = SceneManager->getVideoDriver();
// set material settings
Material.Wireframe = true;
Material.Lighting = false;
Material.BackfaceCulling = false;
// create vertex objects in vertex array
s32 vIndex = 0;
for (f32 i=0; i<(tileResolution+1); i++)
{
for (f32 j=0; j<(tileResolution+1); j++)
{
Vertices[vIndex] = S3DVertex((j*cellSize),0,(i*cellSize), 0,0,1, SColor(255,0,255,255),j,i);
// std :: cout << vIndex << ":" << j << "," << i << "\n";
vIndex++;
}
}
// reposition the bounding box to the first vertex
Box.reset(Vertices[0].Pos);
// add the defined vertices to Box
for (s32 i=0; i<vIndex; i++)
Box.addInternalPoint(Vertices[i].Pos);
// setup indices
s32 iIndex = 0;
for (s32 i=0; i<tileResolution; i++)
{
for (s32 j=0; j<tileResolution; j++)
{
s32 currentVertex = (i*(tileResolution+1)) + j;
indices[iIndex + 0] = currentVertex;
indices[iIndex + 1] = currentVertex+1;
indices[iIndex + 2] = currentVertex+tileResolution+1;
indices[iIndex + 3] = currentVertex+1;
indices[iIndex + 4] = currentVertex+tileResolution+2;
indices[iIndex + 5] = currentVertex+tileResolution+1;
iIndex = iIndex + 6;
}
}
}
/////////////////////////
// OnRegisterSceneNode //
/////////////////////////
virtual void OnRegisterSceneNode()
{
if (IsVisible)
ISceneNode::OnRegisterSceneNode();
}
///////////////
// OnAnimate //
///////////////
virtual void OnAnimate(u32 timeMs)
{
ISceneNode::OnAnimate(timeMs);
}
////////////
// render //
////////////
virtual void render()
{
IVideoDriver * driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0],(tileResolution+1) * (tileResolution+1),&indices[0],((tileResolution*tileResolution)*2));
}
////////////////////
// getBoundingBox //
////////////////////
virtual const aabbox3d<f32>& getBoundingBox() const
{
return Box;
}
//////////////////////
// getMaterialCount //
//////////////////////
virtual u32 getMaterialCount()
{
return 1;
}
/////////////////
// getMaterial //
/////////////////
virtual SMaterial& getMaterial(s32 i)
{
return Material;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION : sphericalXYZ //////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
vector3df sphericalXYZ(f32 compassAngle, f32 elevationAngle, f32 radius)
{
compassAngle = compassAngle * -1;
elevationAngle = elevationAngle * -1;
elevationAngle = elevationAngle + 90;
f32 x = radius * cos(compassAngle * PI/180.0f ) * sin(elevationAngle * PI/180.0f );
f32 z = radius * sin(compassAngle * PI/180.0f ) * sin(elevationAngle * PI/180.0f );
f32 y = radius * cos(elevationAngle * PI/180.0f );
vector3df result;
result.X = x;
result.Y = y;
result.Z = z;
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// MAIN /////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
// setup key engine objects
IrrlichtDevice* device = createDevice(EDT_OPENGL,dimension2d<u32>(800,600),24,false,false,false);
if (!device)
{
return -1;
}
// setup event receiver
MyEventReceiver rv(device);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
ICursorControl* CursorControl = device->getCursorControl();
// setup screen display elements
device->setWindowCaption(L"Irrlicht Custom Scene Node!");
IGUIStaticText* debug_panel = guienv->addStaticText(L"Hello World",rect<s32>(5, 5, 200, 200),false,true,0,-1,false);
// setup the "player"
ISceneNode* cPivot1 = smgr->addCubeSceneNode(0.5,0,-1,vector3df(rv.playerX,rv.playerY,rv.playerZ));
cPivot1->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));
cPivot1->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot2 = smgr->addCubeSceneNode(2,cPivot1,-1,vector3df(0,1,0));
cPivot2->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));
cPivot2->setMaterialFlag(video::EMF_LIGHTING, false);
ISceneNode* cPivot3 = smgr->addCubeSceneNode(1,cPivot2,-1,vector3df(0,0,2));
cPivot3->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));
cPivot3->setMaterialFlag(video::EMF_LIGHTING, false);
// setup the camera
ICameraSceneNode* myCamera = smgr->addCameraSceneNode(cPivot1, sphericalXYZ(rv.cameraOrbit,rv.cameraAngle,rv.cameraDistance), cPivot1->getPosition());
// create references to our custom nodes
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(),smgr,1);
myNode->setPosition(vector3df(0,0,0));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEVICE : main loop ///////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
while(device->run() && device->isWindowActive())
{
/////////////////////////
// keyboard management //
/////////////////////////
// system keys
if(rv.keys[KEY_ESCAPE])
{
device->closeDevice();
}
// player keys
if(rv.keys[KEY_KEY_W])
{
// player movement vector
vector3df playerStep = sphericalXYZ(rv.cameraOrbit,0.f,rv.playerMoveSpeed);
rv.playerX -= playerStep.X;
rv.playerY -= playerStep.Y;
rv.playerZ -= playerStep.Z;
// player rotation brain torture
rv.playerTurnTo = rv.cameraOrbit - 90.f;
if(rv.playerTurnTo < 0.f) rv.playerTurnTo += 360.f;
if(rv.playerTurnTo >= 360.f) rv.playerTurnTo -= 360.f;
if(rv.playerCompass < 0.f) rv.playerCompass = rv.playerCompass + 360.f;
if(rv.playerCompass >= 360.f) rv.playerCompass = rv.playerCompass - 360.f;
f32 playerTurnDir = 0.f;
f32 playerTurnDelta = 0.f;
if(rv.playerCompass > rv.playerTurnTo)
{
if(rv.playerCompass - rv.playerTurnTo < 180.f)
{
playerTurnDir = -1.f;
playerTurnDelta = rv.playerCompass - rv.playerTurnTo;
}
else
{
playerTurnDir = 1.f;
playerTurnDelta = (360.f - rv.playerCompass) + rv.playerTurnTo;
}
}
if(rv.playerCompass < rv.playerTurnTo)
{
if(rv.playerTurnTo - rv.playerCompass < 180.f)
{
playerTurnDir = 1;
playerTurnDelta = rv.playerTurnTo - rv.playerCompass;
}
else
{
playerTurnDir = -1;
playerTurnDelta = (360.f - rv.playerTurnTo) + rv.playerCompass;
}
}
f32 playerTurnAmount;
if(playerTurnDelta < rv.playerTurnSpeed)
{
playerTurnAmount = playerTurnDelta;
}
else
{
playerTurnAmount = rv.playerTurnSpeed;
}
rv.playerCompass += (playerTurnAmount * playerTurnDir);
cPivot1->setPosition(vector3df(rv.playerX,rv.playerY,rv.playerZ));
cPivot2->setRotation(vector3df(0,rv.playerCompass,0));
myCamera->setTarget(vector3df(rv.playerX,rv.playerY,rv.playerZ));
}
// orient camera
myCamera->setPosition(sphericalXYZ(rv.cameraOrbit,rv.cameraAngle,rv.cameraDistance));
// debug display
stringw txt(L"FPS : ");
txt += driver->getFPS();
txt += L"\n";
txt += L"left mouse button : ";
txt += rv.mouseDownL;
txt += L"\n";
txt += L"middle mouse button : ";
txt += rv.mouseDownM;
txt += L"\n";
txt += L"right mouse button : ";
txt += rv.mouseDownR;
txt += L"\n";
txt += L"last wheel movement : ";
txt += rv.lastWheelMovement;
txt += L"\n";
txt += L"cursor x : ";
txt += rv.cursor.X;
txt += L"\n";
txt += L"cursor y : ";
txt += rv.cursor.Y;
txt += L"\n";
txt += L"cursorOld x : ";
txt += rv.cursorOld.X;
txt += L"\n";
txt += L"cursorOld y : ";
txt += rv.cursorOld.Y;
txt += L"\n";
txt += L"cursorDelta x : ";
txt += rv.cursorDelta.X;
txt += L"\n";
txt += L"cursorDelta y : ";
txt += rv.cursorDelta.Y;
txt += L"\n";
txt += L"camera orbit : ";
txt += rv.cameraOrbit;
txt += L"\n";
txt += L"camera angle : ";
txt += rv.cameraAngle;
txt += L"\n";
txt += L"player compass : ";
txt += rv.playerCompass;
txt += L"\n";
txt += L"player turn to : ";
txt += rv.playerTurnTo;
txt += L"\n";
debug_panel->setText( txt.c_str());
//////////////////
// render scene //
//////////////////
driver->beginScene(true, true, SColor(0,120,120,120));
myNode->render();
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
// setup the "player"
ISceneNode* cPivot1 = smgr->addCubeSceneNode(0.5,0,-1,vector3df(rv.playerX,rv.playerY,rv.playerZ)); ISceneNode* cPivot1 = smgr->addCubeSceneNode(2.0,0,-1,vector3df(rv.playerX,rv.playerY,rv.playerZ));Users browsing this forum: No registered users and 1 guest