Actually, the reason for looking at the nodes.size() is that my program has runtime error when I delete an object and I am wondering if nodes.size() causes the error. Here is my complete program code.
Code: Select all
#include <irrlicht.h>
#include <stdlib.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
IrrlichtDevice *Device = 0;
IVideoDriver *driver = 0;
ISceneManager *smgr = 0;
IGUIEnvironment *env = 0;
ICameraSceneNode *camera = 0;
ISceneCollisionManager *CollMan = 0;
IMetaTriangleSelector * meta = 0;
core::stringw fileName("");
core::stringc filePath("");
core::stringc lastFilePath("");
IGUIWindow *window =0;
#define ID_TRANSLATE 102
#define ID_ROTATE 103
#define ID_SCALE 104
#define ID_ADDBOX 105
enum
{
// I use this ISceneNode ID to indicate a scene node that is
// not pickable by getSceneNodeAndCollisionPointFromRay()
ID_IsNotPickable = 0,
// I use this flag in ISceneNode IDs to indicate that the
// scene node can be picked by ray selection.
IDFlag_IsPickable = 1 << 0,
// I use this flag in ISceneNode IDs to indicate that the
// scene node can be highlighted. In this example, the
// homonids can be highlighted, but the level mesh can't.
IDFlag_IsHighlightable = 1 << 1
};
enum
{
GUI_ID_DIALOG_ROOT_WINDOW = 0x10000,
GUI_ID_X_SCALE,
GUI_ID_Y_SCALE,
GUI_ID_Z_SCALE,
GUI_ID_NEW_MODEL,
GUI_ID_LOAD_FLOOR_PLAN,
GUI_ID_SAVE_FLOOR_PLAN,
GUI_ID_SAVEAS_FLOOR_PLAN,
GUI_ID_SAVE_BUTTON,
GUI_ID_SAVE_DIR,
GUI_ID_SAVE_WINDOW,
GUI_ID_SKY_BOX_VISIBLE,
GUI_ID_TOGGLE_DEBUG_INFO,
GUI_ID_DEBUG_OFF,
GUI_ID_DEBUG_BOUNDING_BOX,
GUI_ID_DEBUG_NORMALS,
GUI_ID_DEBUG_SKELETON,
GUI_ID_DEBUG_WIRE_OVERLAY,
GUI_ID_DEBUG_HALF_TRANSPARENT,
GUI_ID_DEBUG_BUFFERS_BOUNDING_BOXES,
GUI_ID_DEBUG_ALL,
GUI_ID_MODEL_MATERIAL_SOLID,
GUI_ID_MODEL_MATERIAL_TRANSPARENT,
GUI_ID_MODEL_MATERIAL_REFLECTION,
GUI_ID_CAMERA_MAYA,
GUI_ID_CAMERA_FIRST_PERSON,
GUI_ID_POSITION_TEXT,
GUI_ID_ABOUT,
GUI_ID_QUIT,
GUI_ID_TEXTUREFILTER,
GUI_ID_SKIN_TRANSPARENCY,
GUI_ID_SKIN_ANIMATION_FPS,
GUI_ID_BUTTON_GEN_ROOM,
GUI_ID_BUTTON_LU,
GUI_ID_BUTTON_LB,
GUI_ID_BUTTON_RU,
GUI_ID_BUTTON_RB,
GUI_ID_BUTTON_OPEN_MODEL,
GUI_ID_BUTTON_SHOW_ABOUT,
GUI_ID_BUTTON_SHOW_TOOLBOX,
GUI_ID_BUTTON_SELECT_ARCHIVE,
};
enum EditorMode
{
MODE_NONE,
MODE_QUIT,
MODE_TRANSLATE,
MODE_ROTATE,
MODE_SCALE,
};
position2di initialCursorPosition; // where mouse cursor started
position2di initialObjectPosition; // where ray from camera to object intersected screen
ISceneNode* SelectedNode = 0; // the selected node
bool ShiftIsPressed = 0; // is the shift key pressed?
bool LMouseButtonDown = 0; // is the left mouse button down?
EditorMode Mode = MODE_TRANSLATE;
float RotateSpeed = 0.01f;
float ScaleSpeed = 0.01f;
f32 camFOV = 1.0f;
ISceneNode* flat =0;
core::vector3df flatEdges[8];
void clearBoundingBox()
{
core::array<scene::ISceneNode *> nodes;
smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // Find all nodes
for (u32 i=0; i < nodes.size(); ++i)
{
ISceneNode * node = nodes[i];
node->setDebugDataVisible(scene::EDS_OFF);
}
}
void saveAs()
{
window = env->addWindow(core::rect<s32>(100,100,500,230), true, L"Save to...", 0, GUI_ID_SAVE_WINDOW);
if (filePath.size()==0)
env->addEditBox(L"", core::rect<s32>(20, 30, 380, 60), true, window, GUI_ID_SAVE_DIR);
else
env->addEditBox(fileName.c_str(), core::rect<s32>(20, 30, 380, 60), true, window, GUI_ID_SAVE_DIR);
env->addButton(core::rect<s32>(100, 80, 300, 110), window, GUI_ID_SAVE_BUTTON, L"Save");
}
//f32 minX(ISceneNode* node)
//{
// core::vector3df edges[8];
// node->getTransformedBoundingBox().getEdges(edges);
// f32 minX = edges[0].X;
//
// for (int i=1; i<=7; i++)
// {
// if (minX > edges[i].X)
// minX = edges[i].X;
// }
// return minX;
//}
//
//f32 maxX(ISceneNode* node)
//{
// core::vector3df edges[8];
// node->getTransformedBoundingBox().getEdges(edges);
// f32 maxX = edges[0].X;
//
// for (int i=1; i<=7; i++)
// {
// if (maxX < edges[i].X)
// maxX = edges[i].X;
// }
// return maxX;
//}
//
//f32 minY(ISceneNode* node)
//{
// core::vector3df edges[8];
// node->getTransformedBoundingBox().getEdges(edges);
// f32 minY = edges[0].Y;
//
// for (int i=1; i<=7; i++)
// {
// if (minY > edges[i].Y)
// minY = edges[i].Y;
// }
// return minY;
//}
//
//f32 maxY(ISceneNode* node)
//{
// core::vector3df edges[8];
// node->getTransformedBoundingBox().getEdges(edges);
// f32 maxY = edges[0].Y;
//
// for (int i=1; i<=7; i++)
// {
// if (maxY < edges[i].Y)
// maxY = edges[i].Y;
// }
// return maxY;
//}
//
//f32 minZ(ISceneNode* node)
//{
// core::vector3df edges[8];
// node->getTransformedBoundingBox().getEdges(edges);
// f32 minZ = edges[0].Z;
//
// for (int i=1; i<=7; i++)
// {
// if (minZ > edges[i].Z)
// minZ = edges[i].Z;
// }
// return minZ;
//}
//
//f32 maxZ(ISceneNode* node)
//{
// core::vector3df edges[8];
// node->getTransformedBoundingBox().getEdges(edges);
// f32 maxZ = edges[0].Z;
//
// for (int i=1; i<=7; i++)
// {
// if (maxZ < edges[i].Z)
// maxZ = edges[i].Z;
// }
// return maxZ;
//}
//
//
//vector3df getIntersectionPoint(ISceneNode* wall, ISceneNode* flat)
//{
// vector3df point;
//
//
// //X
// if (maxX(wall) < maxX(flat))
// point.X = maxX(wall);
// else
// point.X = maxX(flat);
//
// //Y
// if (maxY(wall) < maxY(flat))
// point.Y = maxY(wall);
// else
// point.Y = maxY(flat);
// //Z
// if (minZ(wall) > minZ(flat))
// point.Z = minZ(wall);
// else
// point.Z = minZ(flat);
//
// return point;
//
//}
void OnMenuItemSelected( IGUIContextMenu* menu )
{
s32 id = menu->getItemCommandId(menu->getSelectedItem());
IGUIEnvironment* env = Device->getGUIEnvironment();
switch(id)
{
case GUI_ID_SAVE_FLOOR_PLAN:
if (filePath.size()==0)
saveAs();
else
smgr->saveScene(fileName);
break;
case GUI_ID_SAVEAS_FLOOR_PLAN:
saveAs();
break;
case GUI_ID_LOAD_FLOOR_PLAN:
env->addFileOpenDialog(L"Please select a floor plan file (*.irr) to open");
break;
}
}
void loadFloorPlan(const c8* fn, IGUIFileOpenDialog* dialog)
{
fileName = fn;
core::stringc extension;
core::getFileNameExtension(extension, fileName);
extension.make_lower();
if (extension==".irr")
{
Device->getSceneManager()->loadScene(fileName);
filePath = core::stringc(dialog->getDirectoryName().c_str());
return;
}
Device->getGUIEnvironment()->addMessageBox(
L"Warning!", L"The file could not be loaded. " \
L"Maybe it is not a supported file format.");
}
void clearAxes()
{
core::array<scene::ISceneNode *> nodes;
smgr->getSceneNodesFromType(scene::ESNT_ANIMATED_MESH, nodes); // Find all nodes
for (u32 i=0; i < nodes.size(); ++i)
{
ISceneNode * node = nodes[i];
node->remove();
}
}
void updateAxes(ISceneNode* node)
{
//clear previous axes
clearAxes();
ISceneNode * arrowX = smgr->addAnimatedMeshSceneNode(smgr->addArrowMesh("arrowZ",
SColor(255, 255, 0, 0), SColor(255, 255, 0, 0),4,8,1.0f,0.6f,0.05f,0.2f));
arrowX->setMaterialFlag(video::EMF_LIGHTING, true);
arrowX->setScale(vector3df(10, 10, 10));
arrowX->setRotation(vector3df(0,0,-90));
ISceneNode * arrowY = smgr->addAnimatedMeshSceneNode(smgr->addArrowMesh("arrowY",
SColor(255, 0, 255, 0), SColor(255, 0, 255, 0),4,8,1.0f,0.6f,0.05f,0.2f));
arrowY->setMaterialFlag(video::EMF_LIGHTING, true);
arrowY->setRotation(vector3df(0,90,0));
arrowY->setScale(vector3df(10, 10, 10));
ISceneNode * arrowZ = smgr->addAnimatedMeshSceneNode(smgr->addArrowMesh("arrowX",
SColor(255, 0, 0, 255), SColor(255, 0, 0, 255),4,8,1.0f,0.6f,0.05f,0.2f));
arrowZ->setMaterialFlag(video::EMF_LIGHTING, true);
arrowZ->setScale(vector3df(10, 10, 10));
arrowZ->setRotation(vector3df(90,0,0));
vector3df pos = node->getPosition();
arrowX->setPosition(pos);
arrowY->setPosition(pos);
arrowZ->setPosition(pos);
//Move the arrows to the front
}
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
switch(event.EventType)
{
case EET_GUI_EVENT:
{
switch (event.GUIEvent.EventType)
{
case EGET_MENU_ITEM_SELECTED:
// a menu item was clicked
OnMenuItemSelected( (IGUIContextMenu*)event.GUIEvent.Caller );
break;
case EGET_FILE_SELECTED:
{
// load the model file, selected in the file open dialog
IGUIFileOpenDialog* dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
loadFloorPlan(core::stringc(dialog->getFileName()).c_str(), dialog);
}
break;
case EGET_BUTTON_CLICKED:
{
switch (event.GUIEvent.Caller->getID())
{
case ID_TRANSLATE : { Mode = MODE_TRANSLATE; } break;
case ID_ROTATE : { Mode = MODE_ROTATE; } break;
case ID_SCALE : { Mode = MODE_SCALE; } break;
case ID_ADDBOX :
{
ISceneNode* box = smgr->addCubeSceneNode();
box->setMaterialTexture(0, driver->getTexture("fire.bmp"));
box->setMaterialFlag(video::EMF_LIGHTING, false);
box->setMaterialFlag(video::EMF_FOG_ENABLE,false);
/*ITriangleSelector * selector = smgr->createTriangleSelectorFromBoundingBox(box);;
meta->addTriangleSelector(selector);*/
} break;
case GUI_ID_SAVE_BUTTON:
{
IGUIElement* root = env->getRootGUIElement();
core::stringc s;
s = root->getElementFromId(GUI_ID_SAVE_DIR, true)->getText();
core::stringc extension;
core::getFileNameExtension(extension, s);
extension.make_lower();
if (extension != ".irr")
env->addMessageBox(L"Warning!", L"The file extension must be .irr!", true);
else if (!smgr->saveScene(s,0))
env->addMessageBox(L"Warning!", L"The file path you input is not valid!", true);
else //when saving succeeds
{
if (s.findLast('/'))
{
filePath = s.subString(0,s.findLast('/')+1);
fileName = s;
}
else
{
filePath = core::stringc(Device->getFileSystem()->getWorkingDirectory().c_str()); //bug
fileName = core::stringw(filePath + s);
}
}
window->remove();
} break;
case GUI_ID_BUTTON_GEN_ROOM:
{
f32 flatHeight = flatEdges[3].Y-flatEdges[2].Y;
//set the wall to one of the corner
ISceneNode* wall_1 = smgr->addCubeSceneNode(flatHeight,0,-1,core::vector3df(flatEdges[0].X,flatHeight/2,flatEdges[0].Z),core::vector3df(0,0,0),core::vector3df(0.3f,1.0f,0.3f));
wall_1->setPosition(core::vector3df(flatEdges[0].X+(wall_1->getTransformedBoundingBox().MaxEdge.X-wall_1->getTransformedBoundingBox().MinEdge.X)/2,
flatHeight/2,
flatEdges[0].Z+(wall_1->getTransformedBoundingBox().MaxEdge.Z-wall_1->getTransformedBoundingBox().MinEdge.Z)/2));
//set the position and scale of the wall
vector3df pos = wall_1->getPosition();
vector3df scale = wall_1->getScale();
core::vector3df wallEdges1[8];
core::vector3df wallEdges2[8];
wall_1->setPosition(core::vector3df(pos.X+50, pos.Y, pos.Z));
wall_1->updateAbsolutePosition();
wall_1->getTransformedBoundingBox().getEdges(wallEdges1);
wall_1->setScale(core::vector3df(scale.X, scale.Y, 5*scale.Z));
////reset the position of the wall to be inside the flat
wall_1->updateAbsolutePosition();
pos = wall_1->getPosition();
wall_1->getTransformedBoundingBox().getEdges(wallEdges2);
//wall_1->getTransformedBoundingBox().getEdges(wallEdges);
wall_1->setPosition(core::vector3df(pos.X, pos.Y, pos.Z+wallEdges1[4].Z-wallEdges2[4].Z+1));
//ITriangleSelector * selector = smgr->createTriangleSelectorFromBoundingBox(wall_1);;
//meta->addTriangleSelector(selector);
//set the wall to one of the corner
ISceneNode* wall_2 = smgr->addCubeSceneNode(flatHeight,0,-1,core::vector3df(flatEdges[0].X,flatHeight/2,flatEdges[0].Z),core::vector3df(0,0,0),core::vector3df(0.3f,1.0f,0.3f));
wall_2->setPosition(core::vector3df(flatEdges[0].X+(wall_2->getTransformedBoundingBox().MaxEdge.X-wall_2->getTransformedBoundingBox().MinEdge.X)/2,
flatHeight/2,
flatEdges[0].Z+(wall_2->getTransformedBoundingBox().MaxEdge.Z-wall_2->getTransformedBoundingBox().MinEdge.Z)/2));
//set the position and scale of the wall
pos = wall_2->getPosition();
scale = wall_2->getScale();
wall_2->setPosition(core::vector3df(pos.X, pos.Y, pos.Z+50));
wall_2->updateAbsolutePosition();
wall_2->getTransformedBoundingBox().getEdges(wallEdges1);
wall_2->setScale(core::vector3df(6*scale.X, scale.Y, scale.Z));
////reset the position of the wall to be inside the flat
wall_2->updateAbsolutePosition();
pos = wall_2->getPosition();
wall_2->getTransformedBoundingBox().getEdges(wallEdges2);
wall_2->setPosition(core::vector3df(pos.X+wallEdges1[0].X-wallEdges2[0].X+1, pos.Y, pos.Z));
}
break;
}
} break;
}
} break;
case EET_KEY_INPUT_EVENT :
{
//check if "Shift" key is pressed
if (event.KeyInput.Shift)
ShiftIsPressed = true;
else
ShiftIsPressed = false;
if (event.KeyInput.Key == KEY_DELETE)
{
if(SelectedNode && SelectedNode->getID() !=ID_IsNotPickable)
SelectedNode->remove();
}
switch (event.KeyInput.Char)
{
case 'm':
Mode = MODE_TRANSLATE;
break;
case 'r':
Mode = MODE_ROTATE;
break;
case 's':
Mode = MODE_SCALE;
break;
}
} break;
// if it is a mouse event
case EET_MOUSE_INPUT_EVENT :
{
// based upon the mouse event type
switch (event.MouseInput.Event)
{
case EMIE_LMOUSE_PRESSED_DOWN :
{
LMouseButtonDown = true;
// check for a node being selected
SelectedNode = CollMan->getSceneNodeFromScreenCoordinatesBB(Device->getCursorControl()->getPosition(),0,true);
//!need to check the node type
// If we selected a node
if(SelectedNode && SelectedNode->getID() !=ID_IsNotPickable)
{
clearBoundingBox();
//clearAxes();
// Remember where the node and cursor were when it was clicked on
initialCursorPosition = Device->getCursorControl()->getPosition();
initialObjectPosition = CollMan->getScreenCoordinatesFrom3DPosition(SelectedNode->getAbsolutePosition(), camera);
//Add a bounding box around the selected object
SelectedNode->setDebugDataVisible(scene::EDS_BBOX);
//Add XYZ axes on the object
//updateAxes(SelectedNode);
/*if (Mode==MODE_ROTATE)
{
if (SelectedNode)
{
vector3df rot = SelectedNode->getRotation();
rot.Y +=45;
SelectedNode->setRotation(rot);
}
}*/
}
return false;
} break;
case EMIE_LMOUSE_LEFT_UP :
{
LMouseButtonDown = false;
//if (SelectedNode) SelectedNode->setDebugDataVisible(scene::EDS_OFF);
//SelectedNode = 0;
return false;
} break;
case EMIE_RMOUSE_LEFT_UP :
{
if (camera)
{
camera->setInputReceiverEnabled(!camera->isInputReceiverEnabled());
Device->getCursorControl()->setVisible(!camera->isInputReceiverEnabled());
//if (camera->isInputReceiverEnabled()) Mode = MODE_NONE;
}
} break;
case EMIE_MOUSE_WHEEL:
{
if (event.MouseInput.Wheel == -1.0f) camFOV+=0.1f;
else if (event.MouseInput.Wheel == 1.0f) camFOV-=0.1f;
// clip the value
#define maxFOV 2.8f
#define minFOV 0.1f
if (camFOV < minFOV) camFOV = minFOV;
if (camFOV > maxFOV) camFOV = maxFOV;
camera->setFOV(camFOV);
} break;
case EMIE_MOUSE_MOVED :
{
if (!LMouseButtonDown) return false;
if (Mode == MODE_TRANSLATE)
{
if (SelectedNode && SelectedNode->getID() !=ID_IsNotPickable)
{
vector3df p = SelectedNode->getPosition();
if (ShiftIsPressed)
{
plane3df const planeXY(SelectedNode->getAbsolutePosition(), vector3df(0.f, 0.f, 1.f));
position2di currentCursorPosition(Device->getCursorControl()->getPosition());
position2di effectiveObjectPosition = initialObjectPosition + currentCursorPosition - initialCursorPosition;
line3df ray(CollMan->getRayFromScreenCoordinates(effectiveObjectPosition, camera));
vector3df intersectWithPlane;
vector3df oldPos = SelectedNode->getAbsolutePosition();
if(planeXY.getIntersectionWithLine(ray.start, ray.getVector(), intersectWithPlane))
{
intersectWithPlane.X = oldPos.X;
intersectWithPlane.Z = oldPos.Z;
SelectedNode->setPosition(intersectWithPlane);
}
}
else
{
plane3df const planeXZ(SelectedNode->getAbsolutePosition(), vector3df(0.f, 1.f, 0.f));
position2di currentCursorPosition(Device->getCursorControl()->getPosition());
position2di effectiveObjectPosition = initialObjectPosition + currentCursorPosition - initialCursorPosition;
line3df ray(CollMan->getRayFromScreenCoordinates(effectiveObjectPosition, camera));
vector3df intersectWithPlane;
if(planeXZ.getIntersectionWithLine(ray.start, ray.getVector(), intersectWithPlane))
SelectedNode->setPosition(intersectWithPlane);
}
//SelectedNode->setMaterialFlag(video::EMF_ZBUFFER, false);
updateAxes(SelectedNode);
}
} // end mode translate
else
if (Mode == MODE_ROTATE)
{
if (SelectedNode && SelectedNode->getID() !=ID_IsNotPickable)
{
vector3df rot = SelectedNode->getRotation();
position2di currentCursorPosition(Device->getCursorControl()->getPosition());
if (ShiftIsPressed)
{
if (initialObjectPosition.X < currentCursorPosition.X) rot.X -= RotateSpeed;
if (initialObjectPosition.X > currentCursorPosition.X) rot.X += RotateSpeed;
}
else
{
// if (initialObjectPosition.X < currentCursorPosition.X) rot.Y -= RotateSpeed;
//if (initialObjectPosition.X > currentCursorPosition.X) rot.Y += RotateSpeed;
if (initialObjectPosition.X < currentCursorPosition.X) rot.Y -= 1;
if (initialObjectPosition.X > currentCursorPosition.X) rot.Y += 1;
if (initialObjectPosition.Y < currentCursorPosition.Y) rot.X -= 1;
if (initialObjectPosition.Y > currentCursorPosition.Y) rot.X += 1;
}
initialObjectPosition = currentCursorPosition;
SelectedNode->setRotation(rot);
}
}
else
if (Mode == MODE_SCALE)
{
if (SelectedNode && SelectedNode->getID() !=ID_IsNotPickable)
{
vector3df scale = SelectedNode->getScale();
position2di currentCursorPosition(Device->getCursorControl()->getPosition());
if (initialObjectPosition.X > currentCursorPosition.X)
{
scale.X -= ScaleSpeed;
scale.Y -= ScaleSpeed;
scale.Z -= ScaleSpeed;
}
if (initialObjectPosition.X < currentCursorPosition.X)
{
scale.X += ScaleSpeed;
scale.Y += ScaleSpeed;
scale.Z += ScaleSpeed;
}
initialObjectPosition = currentCursorPosition;
SelectedNode->setScale(scale);
}
}
} break;
}
}
}
return false;
}
};
void createToolBox()
{
// remove tool box if already there
IGUIElement* root = env->getRootGUIElement();
IGUIElement* e = root->getElementFromId(GUI_ID_DIALOG_ROOT_WINDOW, true);
if (e)
e->remove();
// create the toolbox window
IGUIWindow* wnd = env->addWindow(core::rect<s32>(700,95,1000,530),
false, L"Toolset", 0, GUI_ID_DIALOG_ROOT_WINDOW);
// create tab control and tabs
IGUITabControl* tab = env->addTabControl(
core::rect<s32>(2,20,800-502,480-7), wnd, true, true);
IGUITab* t1 = tab->addTab(L"Config");
// add some edit boxes and a button to tab one
env->addStaticText(L"Wall:",
core::rect<s32>(10,20,60,45), false, false, t1);
env->addButton(core::rect<s32>(10,134,90,165), t1, GUI_ID_BUTTON_GEN_ROOM, L"Generate room");
// quick scale buttons
env->addButton(core::rect<s32>(40,20,115,40), t1, GUI_ID_BUTTON_LU, L"Left-up");
env->addButton(core::rect<s32>(125,20,200,40), t1, GUI_ID_BUTTON_RU, L"Right-up");
env->addButton(core::rect<s32>(40,50,115,70), t1, GUI_ID_BUTTON_LB, L"Left-bottom");
env->addButton(core::rect<s32>(125,50,200,70), t1, GUI_ID_BUTTON_RB, L"Right-bottom");
// UpdateScaleInfo(Model);
}
void GUI()
{
// add my little plug
int x = 10;
int y = 60;
int width = 100;
int height = 20;
int space = 5;
env->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_TRANSLATE,L"Translate");
y += height + space;
env->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_ROTATE,L"Rotate");
y += height + space;
env->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_SCALE,L"Scale");
y += height + space;
env->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_ADDBOX,L"Add A Box");
// set a nicer font
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
// create menu
gui::IGUIContextMenu* menu = env->addMenu();
menu->addItem(L"File", -1, true, true);
menu->addItem(L"Edit", -1, true, true);
menu->addItem(L"View", -1, true, true);
menu->addItem(L"Camera", -1, true, true);
menu->addItem(L"Help", -1, true, true);
gui::IGUIContextMenu* submenu;
submenu = menu->getSubMenu(0);
submenu->addItem(L"New project", GUI_ID_NEW_MODEL);
submenu->addItem(L"Load 3D floor plan", GUI_ID_LOAD_FLOOR_PLAN);
submenu->addItem(L"Save 3D floor plan", GUI_ID_SAVE_FLOOR_PLAN);
submenu->addItem(L"Save as...", GUI_ID_SAVEAS_FLOOR_PLAN);
submenu->addSeparator();
submenu->addItem(L"Quit", GUI_ID_QUIT);
submenu = menu->getSubMenu(3);
submenu->addItem(L"Maya Style", GUI_ID_CAMERA_MAYA);
submenu->addItem(L"First Person", GUI_ID_CAMERA_FIRST_PERSON);
submenu = menu->getSubMenu(4);
submenu->addItem(L"About", GUI_ID_ABOUT);
/*
Below the menu we want a toolbar, onto which we can place colored
buttons and important looking stuff like a senseless combobox.
*/
// create toolbar
gui::IGUIToolBar* bar = env->addToolBar();
IVideoDriver* driver = Device->getVideoDriver();
video::ITexture* image = driver->getTexture("open.png");
bar->addButton(GUI_ID_BUTTON_OPEN_MODEL, 0, L"Open a model",image, 0, true, true);
image = driver->getTexture("tools.png");
bar->addButton(GUI_ID_BUTTON_SHOW_TOOLBOX, 0, L"Open Toolset",image, 0, false, true);
image = driver->getTexture("zip.png");
bar->addButton(GUI_ID_BUTTON_SELECT_ARCHIVE, 0, L"Set Model Archive",image, 0, false, true);
image = driver->getTexture("help.png");
bar->addButton(GUI_ID_BUTTON_SHOW_ABOUT, 0, L"Open Help", image, 0, false, true);
// create a combobox with some senseless text
gui::IGUIComboBox* box = env->addComboBox(core::rect<s32>(250,4,350,23), bar, GUI_ID_TEXTUREFILTER);
/*
To make the editor look a little bit better, we disable transparent gui
elements, and add an Irrlicht Engine logo. In addition, a text showing
the current frames per second value is created and the window caption is
changed.
*/
// disable alpha
for (s32 i=0; i<gui::EGDC_COUNT ; ++i)
{
video::SColor col = env->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);
col.setAlpha(255);
env->getSkin()->setColor((gui::EGUI_DEFAULT_COLOR)i, col);
}
// add a tabcontrol
createToolBox();
}
int main(int argc, char* argv[])
{
// create device and exit if creation failed
MyEventReceiver receiver;
Device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(1024, 768),
16, false, false, false, &receiver);
if (Device == 0)
return 1; // could not create selected driver.
Device->setResizable(true);
Device->setWindowCaption(L"3D Floor Plan Creator - New floor plan");
driver = Device->getVideoDriver();
env = Device->getGUIEnvironment();
smgr = Device->getSceneManager();
smgr->getParameters()->setAttribute(scene::COLLADA_CREATE_SCENE_INSTANCES, true);
CollMan = smgr->getSceneCollisionManager();
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
smgr->addLightSceneNode(0, core::vector3df(200,200,200),
video::SColorf(1.0f,1.0f,1.0f),2000,ID_IsNotPickable);
smgr->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f));
// add media directory as "search path"
Device->getFileSystem()->addFolderFileArchive("../../media/");
GUI();
// add a camera
camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .1f, ID_IsNotPickable, 0, 0, false, 3.f);
camera->setPosition(vector3df(80,100,-220));
camera->setTarget(vector3df(80,-30,30));
camera->setIsDebugObject(true);
camera->setInputReceiverEnabled(false);
/*IMesh* mesh = smgr->getMesh("../../media/flat.irrmesh");
if (!mesh)
{
Device->drop();
return 1;
}
flat = smgr->addMeshSceneNode(mesh,0,ID_IsNotPickable);
flat->setScale(flat->getScale() * 0.1f);*/
//smgr->loadScene("zzz.irr");
// Create a meta triangle selector to hold several triangle selectors.
meta = smgr->createMetaTriangleSelector();
/*
Now we will find all the nodes in the scene and create triangle
selectors for all suitable nodes. Typically, you would want to make a
more informed decision about which nodes to performs collision checks
on; you could capture that information in the node name or Id.
*/
core::array<scene::ISceneNode *> nodes;
smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // Find all nodes
for (u32 i=0; i < nodes.size(); ++i)
{
ISceneNode * node = nodes[i];
ITriangleSelector * selector = 0;
switch(node->getType())
{
case ESNT_CUBE:
case ESNT_ANIMATED_MESH:
// Because the selector won't animate with the mesh,
// and is only being used for camera collision, we'll just use an approximate
// bounding box instead of ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0)
selector = smgr->createTriangleSelectorFromBoundingBox(node);
break;
case ESNT_MESH:
case ESNT_SPHERE: // Derived from IMeshSceneNode
selector = smgr->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
break;
case ESNT_TERRAIN:
selector = smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node);
break;
case ESNT_OCTREE:
selector = smgr->createOctreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
break;
default:
// Don't create a selector for this node type
break;
}
if(selector)
{
// Add it to the meta selector, which will take a reference to it
meta->addTriangleSelector(selector);
// And drop my reference to it, so that the meta selector owns it.
selector->drop();
}
}
/*
Now that the mesh scene nodes have had triangle selectors created and added
to the meta selector, create a collision response animator from that meta selector.
*/
ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
meta, camera, core::vector3df(5,5,5),
core::vector3df(0,0,0));
meta->drop();
camera->addAnimator(anim);
anim->drop();
while(Device->run())
{
driver->beginScene(true, true, SColor(255,100,101,140));
//if (SelectedNode && Mode != MODE_SCALE)
//{
// /*SMaterial material;
// material.Lighting=false;
// material.Thickness = 10;
// driver->setMaterial(material);
// driver->setTransform(video::ETS_WORLD, core::matrix4());
// driver->draw3DLine(SelectedNode->getAbsolutePosition(), SelectedNode->getAbsolutePosition() + vector3df(abs(SelectedNode->getBoundingBox().MaxEdge.X - SelectedNode->getBoundingBox().getCenter().X)+10,0,0), SColor(255,255,0,0));
// driver->draw3DLine(SelectedNode->getAbsolutePosition(), SelectedNode->getAbsolutePosition() + vector3df(0,abs(SelectedNode->getBoundingBox().MaxEdge.Y - SelectedNode->getBoundingBox().getCenter().Y)+10,0), SColor(255,0,255,0));
// driver->draw3DLine(SelectedNode->getAbsolutePosition(), SelectedNode->getAbsolutePosition() + vector3df(0,0,abs(SelectedNode->getBoundingBox().MaxEdge.Z - SelectedNode->getBoundingBox().getCenter().Z)+10), SColor(255,0,0,255)); */
//}
smgr->drawAll();
env->drawAll();
//flat->getTransformedBoundingBox().getEdges(flatEdges);
//core::stringw str = L"";
//str += wallEdges1[4].Z;
//str+= " ";
//str+=wallEdges2[4].Z;
//Device->setWindowCaption(str.c_str());
driver->endScene();
if (lastFilePath != filePath)
{
core::stringw str = L"3D Floor Plan Creator - ";
str += Device->getFileSystem()->getFileBasename(fileName, false);
Device->setWindowCaption(str.c_str());
lastFilePath = filePath;
}
}
Device->drop();
return 0;
}
To see the bug, you need to add a box, click it, then press delete button.