Code: Select all
#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")
#include <fstream>
using namespace std;
//ofstream out("out.txt");
enum
{
GUI_ID_DRAWWALL_BUTTON = 101,
CAMERA_FPS = 201,
CAMERA_DOWN = 202
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SETTINGS /////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// setup key engine objects
IrrlichtDevice* device = createDevice(EDT_OPENGL,dimension2d<s32>(1004,612),32,false,false,false);
IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
ICursorControl* CursorControl;
scene::ISceneNode* selectedNode = 0;
// 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 = 0;
f32 cameraAngle = 10;
f32 leftCameraDistance = 150;
f32 cameraDistanceOld = leftCameraDistance;
f32 cameraOrbitOld = 0;
f32 cameraAngleOld = 0;
f32 cameraXPos = 0;
f32 cameraZPos = 0;
core::vector3df pos;
core::line3df line;
core::line3df lineOld;
bool lineFlag = false;
bool btnFlag = true;
core::vector3df movingPoint;
core::array<core::vector3df> pointArray;
scene::ICameraSceneNode* lookDownCamera = smgr->addCameraSceneNode(0,core::vector3df(cameraXPos,leftCameraDistance,cameraZPos),core::vector3df(0,0,0),CAMERA_DOWN);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS : MyEventReceiver //////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
return false;
}
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
// left mouse button state check
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
mouseDownL = 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;
//smgr->setActiveCamera((scene::ICameraSceneNode*)(smgr->getSceneNodeFromId(CAMERA_DOWN)));
lineOld = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(
core::position2d<s32>(cursorOld.X ,cursorOld.Y),
smgr->getActiveCamera());
s32 a = smgr->getActiveCamera()->getID();
pointArray.push_back(lineOld.end);
//out<<lineOld.end.X<<" "<<5<<" "<<lineOld.end.Z<<endl;
movingPoint = lineOld.end;
lineFlag = 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)
{
cameraDistanceOld = leftCameraDistance;
leftCameraDistance -= event.MouseInput.Wheel * (leftCameraDistance / 20) * 2;
if (leftCameraDistance < 5)
{
leftCameraDistance = 5;
}
if (leftCameraDistance > 200)
{
leftCameraDistance = 200;
}
f32 zCamDist = (tan((lookDownCamera->getFOV()/2.0))*(cameraDistanceOld - leftCameraDistance));
f32 xCamDist = zCamDist * lookDownCamera->getAspectRatio() ;
cameraXPos -= xCamDist;
cameraZPos += zCamDist;
lookDownCamera->setPosition(core::vector3df(cameraXPos,leftCameraDistance,cameraZPos));
lookDownCamera->setTarget(core::vector3df(cameraXPos,0,cameraZPos));
}
// 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 (lineFlag)
{
if (pointArray.size() > 1)
{
pointArray.clear();
}
lineFlag = false;
}
}
if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) mouseDownR = false;
// mouse move check
if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
if (lineFlag)
{
cursor.X = (f32)event.MouseInput.X;
cursor.Y = (f32)event.MouseInput.Y;
line = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2d<s32>(cursor.X ,cursor.Y ),smgr->getActiveCamera());
movingPoint = line.end;
}
}
return false;
}
if (event.EventType == EET_GUI_EVENT )
{
s32 id = event.GUIEvent.Caller->getID();
if (id == GUI_ID_DRAWWALL_BUTTON)
{
lineFlag = true;
}
}
return false;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS : CMySampleSceneNode ///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CMySampleSceneNode : public ISceneNode
{
private:
static const s32 tileResolution = 20; // how many segments to have down each edge of the tile
static const s32 cellSize = 20; // 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
public:
/////////////////
// constructor //
/////////////////
CMySampleSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) : ISceneNode(parent, mgr, id)
{
// put link to videoDriver into already prepared var of type IVideoDriver
// 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(0,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) SceneManager->registerNodeForRendering(this);
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;
}
u32 getCellSize()
{
return cellSize;
}
u32 getTileResolution()
{
return tileResolution;
}
};
stringw float2string(float floatToConvert){
char temp[50];
sprintf_s(temp,"%.1f",floatToConvert);
return temp;
}
int main()
{
// setup event receiver
MyEventReceiver rv;
device->setEventReceiver(&rv);
device->setWindowCaption(L"Irrlicht Custom Scene Node!");
//core::position2d<s32> posScreen = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(core::vector3df(0,0,0),smgr->getActiveCamera());
lookDownCamera->setUpVector(core::vector3df(0,0,1));
lookDownCamera->setFarValue(leftCameraDistance + 0.1);
gui::IGUIFont* font = device->getGUIEnvironment()->getFont("aa.png");
// create references to our custom nodes
CMySampleSceneNode* myNode = new CMySampleSceneNode(smgr->getRootSceneNode(),smgr,1);
f32 xMove,zMove;
f32 cellSize = (f32)myNode->getCellSize();
f32 cellNum = (f32)myNode->getTileResolution();
xMove = -(f32)(myNode->getTileResolution()*myNode->getCellSize())/2;
zMove = -(f32)(myNode->getTileResolution()*myNode->getCellSize())/2;
SMaterial mat;
mat.Lighting = false;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEVICE : main loop ///////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
while(device->run()) {
lookDownCamera->setFarValue(leftCameraDistance+0.1);
driver->setMaterial(mat);
driver->setTransform(video::ETS_WORLD, core::matrix4());
driver->beginScene(true, true, SColor(255,120,120,120));
core::vector3df pos = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2d<s32>(40,30),lookDownCamera).end;
pos.Z = pos.Z - cellNum*cellSize;
//pos.X = pos.X - 20;
myNode->setPosition(pos);
core::vector3df origionPos = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2d<s32>(40,30),lookDownCamera).end;
core::vector3df currentPos;
for (int i = 0; i < cellNum; i ++)
{
currentPos = origionPos + core::vector3df(cellSize*i,0,0);
core::position2d<s32> posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(currentPos,smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X,posScreen1.Y - 10),posScreen1);
currentPos = origionPos + core::vector3df(0,0,-cellSize*i);
if(font)
font->draw(float2string(i).c_str(),core::rect<s32>(posScreen1.X-10,posScreen1.Y - 25,posScreen1.X + 10,posScreen1.Y-12),video::SColor(255,255,255,255));
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(currentPos,smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X-10,posScreen1.Y),posScreen1);
if(font)
font->draw(float2string(i).c_str(),core::rect<s32>(posScreen1.X-35,posScreen1.Y-7,posScreen1.X,posScreen1.Y+5),video::SColor(255,255,255,255));
if (leftCameraDistance <= 130 && leftCameraDistance >= 60 )
{
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(cellSize*i + cellSize/2,0,0),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X,posScreen1.Y - 7),posScreen1);
driver->draw3DLine(origionPos + core::vector3df(cellSize*i + cellSize/2,0,0),origionPos+core::vector3df(cellSize*i + cellSize/2,0,-(cellSize*cellNum)));
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(0,0,-(cellSize*i + cellSize/2)),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X-7,posScreen1.Y),posScreen1);
driver->draw3DLine(origionPos + core::vector3df(0,0,-(cellSize*i + cellSize/2)),origionPos+core::vector3df(cellSize*cellNum,0,-(cellSize*i + cellSize/2)));
}
if (leftCameraDistance < 60 && leftCameraDistance >=10)
{
f32 onetotenCellSize = cellSize / 10;
for (int j = 2;j < 10; j += 2)
{
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X,posScreen1.Y- 7),posScreen1);
if(font)
font->draw(float2string(i+j/10.0).c_str(),core::rect<s32>(posScreen1.X-10,posScreen1.Y - 25,posScreen1.X + 10,posScreen1.Y),video::SColor(255,255,255,255));
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X-7,posScreen1.Y),posScreen1);
if(font)
font->draw(float2string(i+j/10.0).c_str(),core::rect<s32>(posScreen1.X - 35,posScreen1.Y-7,posScreen1.X,posScreen1.Y+5),video::SColor(255,255,255,255));
driver->draw3DLine(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),origionPos+core::vector3df(cellSize*i + j*onetotenCellSize,0,-cellSize*cellNum));
driver->draw3DLine(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),origionPos+core::vector3df(cellSize*cellNum,0,-(cellSize*i+j*onetotenCellSize)));
}
}
if (leftCameraDistance < 20 && leftCameraDistance >=10)
{
f32 onetotenCellSize = cellSize / 10;
for (int j = 1;j < 10; j += 2)
{
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X,posScreen1.Y- 7),posScreen1);
if(font)
font->draw(float2string(i+j/10.0).c_str(),core::rect<s32>(posScreen1.X-10,posScreen1.Y - 25,posScreen1.X + 10,posScreen1.Y),video::SColor(255,255,255,255));
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X-7,posScreen1.Y),posScreen1);
if(font)
font->draw(float2string(i+j/10.0).c_str(),core::rect<s32>(posScreen1.X - 35,posScreen1.Y-7,posScreen1.X,posScreen1.Y+5),video::SColor(255,255,255,255));
driver->draw3DLine(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),origionPos+core::vector3df(cellSize*i + j*onetotenCellSize,0,-cellSize*cellNum));
driver->draw3DLine(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),origionPos+core::vector3df(cellSize*cellNum,0,-(cellSize*i+j*onetotenCellSize)));
}
}
if (leftCameraDistance < 10)
{
f32 onetotenCellSize = cellSize / 100;
for (int j = 2;j < 100; j += 2)
{
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X,posScreen1.Y- 7),posScreen1);
if (j % 10 == 0)
{
if(font)
font->draw(float2string(i+j/100.0).c_str(),core::rect<s32>(posScreen1.X-10,posScreen1.Y - 25,posScreen1.X + 10,posScreen1.Y),video::SColor(255,255,255,255));
}
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X-7,posScreen1.Y),posScreen1);
if (j % 10 == 0)
{
if(font)
font->draw(float2string(i+j/100.0).c_str(),core::rect<s32>(posScreen1.X - 35,posScreen1.Y-7,posScreen1.X,posScreen1.Y+5),video::SColor(255,255,255,255));
}
driver->draw3DLine(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),origionPos+core::vector3df(cellSize*i + j*onetotenCellSize,0,-cellSize*cellNum));
driver->draw3DLine(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),origionPos+core::vector3df(cellSize*cellNum,0,-(cellSize*i+j*onetotenCellSize)));
}
}
if (leftCameraDistance <= 5)
{
f32 onetotenCellSize = cellSize / 100;
for (int j = 1;j < 100; j += 2)
{
posScreen1 = smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),smgr->getActiveCamera());
driver->draw2DLine(core::position2d<s32>(posScreen1.X,posScreen1.Y- 7),posScreen1);
driver->draw3DLine(origionPos + core::vector3df(cellSize*i + j*onetotenCellSize,0,0),origionPos+core::vector3df(cellSize*i + j*onetotenCellSize,0,-cellSize*cellNum));
driver->draw3DLine(origionPos + core::vector3df(0,0,-(cellSize*i+j*onetotenCellSize)),origionPos+core::vector3df(cellSize*cellNum,0,-(cellSize*i+j*onetotenCellSize)));
}
}
}
smgr->drawAll();
device->sleep(15);
driver->endScene();
}
device->drop();
return 0;
}