Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Irrlicht] Usuwanie Mesh

Ostatnio zmodyfikowano 2024-02-26 19:45
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[Irrlicht] Usuwanie Mesh
» 2024-02-25 17:59:59
Witam.
Tworzę Edytor Map i mam problem z Mesh. Gdy tworzę nową mapę, należy poprzednią usunąć jeśli takowa istnieje i nie wiem jak to zrobić.
Problematyczna funkcja createWorld() oraz scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
Wrzucam cały kod, bo nie da się wyciąć sensownego fragmentu:

C/C++
#include <irrlicht.h>

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

using namespace irr; // I don't want to use it irr::

using namespace core; // also ( irr::core:: )
using namespace scene; // also ( irr::scene::)
using namespace video; // also ...
using namespace io; // ...
using namespace gui; // ...

#include<iostream>
#include<vector>
#include<set>
#include <fstream>
using namespace std;

// device
int screenWidth = 1080;
int screenHeight = 720;
int bitsPerPixel = 32;
bool fullscreen = false;
bool stencilbuffer = false; // Specifies if we want to use the stencil buffer (for drawing shadows)
bool vsync = false; // Specifies if we want to have vsync enabled, this is only useful in fullscreen mode.
float cam_x, cam_y, cam_z;
bool mousePress = false;
position2d < s32 > mousePos; // Mouse Position

// clearing screen colors
int clear_r = 48;
int clear_g = 48;
int clear_b = 48;
int clear_a = 256;

// Basic things
IrrlichtDevice * device;
IVideoDriver * driver;
ISceneManager * smgr;
IGUIEnvironment * GUI;
ICameraSceneNode * cam;

// Fonts
IGUIFont * basicFont;
IGUIFont * boldFont;

// Textures
ITexture * TWTexture;

// Model pathfiles
std::string modelPathfile = "Media/TT_RTS_Demo_Character.obj";
std::string modelTexturePathfile = "Media/TT_RTS_Units_blue.png";

// Meshes
IAnimatedMesh * modelMesh; // mesh

// Animators
IAnimatedMeshSceneNode * animModel1; // model1
IAnimatedMeshSceneNode * animModel2; // model2
IAnimatedMeshSceneNode * animModel3; // model3

// Textures
ITexture * modelTexture;

ITexture * darknessTexture;
ITexture * waterTexture;
ITexture * beachTexture;
ITexture * grassTexture;
ITexture * rocksTexture;
ITexture * highlandsTexture;
ITexture * swampTexture;
ITexture * desertTexture;


// Buttons ID's
enum
{
   
// World
   
GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD,
   
   
// Help
   
GUI_TUTORIAL, GUI_INFO,
   
   
// bar
   
BAR_BUTTON_WATER, BAR_BUTTON_BEACH, BAR_BUTTON_GRASS, BAR_BUTTON_ROCKS, BAR_BUTTON_HIGHLANDS, BAR_BUTTON_DARKNESS, BAR_BUTTON_SWAMP, BAR_BUTTON_DESERT,
   
   
// INCREASE / DECREASE BRUSH SIZE
   
BAR_BUTTON_DECREASE, BAR_BUTTON_INCREASE
};

gui::IGUIToolBar * terrainBar; // Menu ToolBar
std::vector < IGUIButton * > toolbarButtons; // Menu ToolBar buttons
IGUIContextMenu * menu;
IGUIContextMenu * worldMenu;
IGUIContextMenu * helpMenu;

float outerRadius = 10.0f;
float innerRadius = outerRadius * 0.866025404f;
float heightStep = 2.0f;

float hexVertices[ ] =
{
   
0.0f, outerRadius,
   
innerRadius, outerRadius * 0.5f,
   
innerRadius, - outerRadius * 0.5f,
   
0.0f, - outerRadius,
   
- innerRadius, - outerRadius * 0.5f,
   
- innerRadius, outerRadius * 0.5f,
   
0.0f, outerRadius
};

const u16 hexIndices[ 18 ] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 };

float texture_uv[ ]
{
   
0.0f, 0.5f,
   
0.5f, 0.25f,
   
0.5f, - 0.25f,
   
0.0f, - 0.5f,
   
- 0.5f, - 0.25f,
   
- 0.5f, 0.25f,
   
0.0f, 0.5f,
};


vector3df hexToGlobal( float x, float z )
{
   
vector3df pos;
   
pos.X = x * 2.0f * innerRadius +( int( z ) % 2 ) * innerRadius;
   
pos.Y = 0.0f;
   
pos.Z = z * 1.5f * outerRadius;
   
return pos;
}

vector2di globalToHex( float x, float y )
{
   
vector2di hex;
   
   
float xx =( x /( 2.0f * innerRadius ) ) -(( int( y /( 1.5f * outerRadius ) ) ) % 2 ) / 2.f;
   
float yy = y /( 1.5f * outerRadius );
   
   
hex.X =( xx + 0.5f );
   
hex.Y =( yy + 0.5f );
   
   
return hex;
}

enum class terrainType { water, beach, grass, rocks, highlands, darkness, swamp, desert };

// BRUSH

terrainType brushTerrain = terrainType::grass;
int brushHeight = 0;
int brushSize = 0;
int maxBrushSize = 4;

void loadTextures()
{
   
waterTexture = driver->getTexture( "Media/Terrains/water.png" );
   
beachTexture = driver->getTexture( "Media/Terrains/beach.png" );
   
grassTexture = driver->getTexture( "Media/Terrains/grass.png" );
   
rocksTexture = driver->getTexture( "Media/Terrains/rocks.png" );
   
highlandsTexture = driver->getTexture( "Media/Terrains/highlands.png" );
   
darknessTexture = driver->getTexture( "Media/Terrains/darkness.png" );
   
swampTexture = driver->getTexture( "Media/Terrains/swamp.png" );
   
desertTexture = driver->getTexture( "Media/Terrains/desert.png" );
   
   
TWTexture = driver->getTexture( "Media/GUI/TW.png" );
   
}

ITexture * getTexture( terrainType ttype )
{
   
ITexture * tex = 0;
   
   
if( ttype == terrainType::water )
       
 tex = waterTexture;
   
   
if( ttype == terrainType::beach )
       
 tex = beachTexture;
   
   
if( ttype == terrainType::grass )
       
 tex = grassTexture;
   
   
if( ttype == terrainType::rocks )
       
 tex = rocksTexture;
   
   
if( ttype == terrainType::highlands )
       
 tex = highlandsTexture;
   
   
if( ttype == terrainType::darkness )
       
 tex = darknessTexture;
   
   
if( ttype == terrainType::swamp )
       
 tex = swampTexture;
   
   
if( ttype == terrainType::desert )
       
 tex = desertTexture;
   
   
return tex;
}

int terrainTypeToInt( terrainType ttype )
{
   
if( ttype == terrainType::water ) return 0;
   
   
if( ttype == terrainType::beach ) return 1;
   
   
if( ttype == terrainType::grass ) return 2;
   
   
if( ttype == terrainType::rocks ) return 3;
   
   
if( ttype == terrainType::highlands ) return 4;
   
   
if( ttype == terrainType::darkness ) return 5;
   
   
if( ttype == terrainType::swamp ) return 6;
   
   
if( ttype == terrainType::desert ) return 7;
   
}

class HexTile
    : public scene::ISceneNode
{
public:
   
SMesh * mesh;
   
SMeshBuffer * meshBuffer;
   
   
   
int x, z;
   
terrainType ttype;
   
int height;
   
HexTile * neighbours[ 6 ]; // NE, E, SE, SW, W, WE
   
   
HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id, float, float );
   
virtual void OnRegisterSceneNode();
   
virtual void render();
   
virtual const aabbox3d < f32 > & getBoundingBox() const;
   
virtual u32 getMaterialCount() const;
   
virtual SMaterial & getMaterial( u32 i );
   
void setTexture( ITexture * );
   
SMesh * getMesh();
   
   
void setTerrainType( terrainType );
   
void setHeight( int );
};

HexTile::HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id, float x, float z )
    :
ISceneNode( parent, smgr, id )
{
   
this->x = x;
   
this->z = z;
   
ttype = terrainType::grass;
   
height = 0;
   
   
   
////////////////////////////////////////////////////////////////////////////////
   
   
meshBuffer = new SMeshBuffer();
   
   
// SET THE INDICES
   
meshBuffer->Indices.set_used( 18 );
   
for( u32 i = 0; i < 18; ++i )
       
 meshBuffer->Indices[ i ] = hexIndices[ i ];
   
   
// SET THE VERTICES
   
SColor color = SColor( 255, 255, 255, 255 );
   
   
meshBuffer->Vertices.push_back( S3DVertex( 0, 0, 0, 0, 0, 0, color, 0, 0 ) );
   
for( int i = 0; i < 7; i++ )
   
{
       
meshBuffer->Vertices.push_back( S3DVertex( hexVertices[ 2 * i ], 0.0f, hexVertices[ 2 * i + 1 ], 0, 0, 0, color, texture_uv[ 2 * i ], texture_uv[ 2 * i + 1 ] ) );
   
}
   
   
// SET THE BOUNDING BOX
   
meshBuffer->BoundingBox.reset( vector3df( hexVertices[ 0 ], 0, hexVertices[ 1 ] ) );
   
for( s32 i = 1; i < 7; ++i )
       
 meshBuffer->BoundingBox.addInternalPoint( vector3df( hexVertices[ 2 * i ], 0, hexVertices[ 2 * i + 1 ] ) );
   
   
   
// SET THE MATERIAL
   
meshBuffer->Material.Wireframe = false;
   
meshBuffer->Material.Lighting = false;
   
meshBuffer->Material.setTexture( 0, getTexture( ttype ) );
   
   
mesh = new SMesh();
   
mesh->addMeshBuffer( meshBuffer );
   
mesh->recalculateBoundingBox();
   
   
vector3df pos = hexToGlobal( x, z );
   
pos.Y = height * heightStep;
   
setPosition( pos );
}

void HexTile::OnRegisterSceneNode()
{
   
if( IsVisible )
       
 SceneManager->registerNodeForRendering( this );
   
   
ISceneNode::OnRegisterSceneNode();
}

void HexTile::render()
{
   
IVideoDriver * driver = smgr->getVideoDriver();
   
driver->setMaterial( meshBuffer->Material );
   
driver->setTransform( video::ETS_WORLD, AbsoluteTransformation );
   
driver->drawMeshBuffer( meshBuffer );
   
}

const aabbox3d < f32 > & HexTile::getBoundingBox() const
{
   
return meshBuffer->BoundingBox;
}

u32 HexTile::getMaterialCount() const
{
   
return 1;
}

SMaterial & HexTile::getMaterial( u32 i )
{
   
return meshBuffer->Material;
}

void HexTile::setTexture( ITexture * tex )
{
   
meshBuffer->Material.setTexture( 0, tex );
}

SMesh * HexTile::getMesh()
{
   
return mesh;
}

void HexTile::setTerrainType( terrainType ttype )
{
   
this->ttype = ttype;
   
setTexture( getTexture( ttype ) );
}

void HexTile::setHeight( int height )
{
   
this->height = height;
   
   
vector3df pos = hexToGlobal( x, z );
   
pos.Y = float( height ) * heightStep;
   
setPosition( pos );
}

std::set < HexTile * > highlightedHexTiles;

class HexMap
{
public:
   
std::vector < HexTile * > tiles;
   
   
HexMap();
   
~HexMap();
   
void addTile( HexTile * );
   
void setTerrainType( terrainType );
   
HexTile * getHexTile( int, int );
};

HexMap::HexMap()
{
   
tiles.clear();
}

HexMap::~HexMap()
{
   
}

void HexMap::addTile( HexTile * tile )
{
   
tiles.push_back( tile );
}

void HexMap::setTerrainType( terrainType ttype )
{
   
for( auto & t: tiles )
       
 t->setTerrainType( ttype );
   
}

HexTile * HexMap::getHexTile( int x, int z )
{
   
HexTile * tile = nullptr;
   
for( auto & t: tiles )
   
{
       
if( t->x == x && t->z == z )
           
 tile = t;
       
   
}
   
   
return tile;
}

HexMap * hexMap;

void setStylesForGUI()
{
   
IGUISkin * GUIskin = GUI->getSkin();
   
GUIskin->setFont( boldFont );
   
   
for( s32 i = 0; i < gui::EGDC_COUNT; ++i )
       
 GUIskin->setColor(( EGUI_DEFAULT_COLOR ) i, SColor( 255, 64, 64, 64 ) ); // coloring the Background
   
    // MENU
   
GUIskin->setColor( EGDC_BUTTON_TEXT, SColor( 255, 224, 224, 224 ) ); // coloring the Text
   
GUIskin->setColor( EGDC_HIGH_LIGHT_TEXT, SColor( 255, 160, 64, 64 ) ); // coloring the Highlighed Text
   
    // TOOL TIP (MENU BAR)
   
GUIskin->setColor( EGDC_TOOLTIP_BACKGROUND, SColor( 255, 64, 64, 64 ) ); // coloring the Background
   
GUIskin->setColor( EGDC_TOOLTIP, SColor( 255, 224, 224, 224 ) ); // coloring the Text
}

void createGUI()
{
   
// CREATE MAIN MENU
   
menu = GUI->addMenu();
   
menu->addItem( L"World", - 1, true, true );
   
menu->addItem( L"Help", - 1, true, true );
   
   
// CREATE WORLD MENU
   
worldMenu = menu->getSubMenu( 0 );
   
worldMenu->addItem( L"Create World", GUI_CREATEWORLD );
   
worldMenu->addItem( L"Load World", GUI_LOADWORLD );
   
worldMenu->addItem( L"Save world", GUI_SAVEWORLD );
   
worldMenu->addItem( L"Generate World", GUI_GENERATEWORLD );
   
   
// CREATE HELP MENU
   
helpMenu = menu->getSubMenu( 1 );
   
helpMenu->addItem( L"Tutorial", GUI_TUTORIAL );
   
helpMenu->addItem( L"Info", GUI_INFO );
   
   
// MENU TOOL BAR
   
terrainBar = GUI->addToolBar();
   
terrainBar->setMinSize( dimension2du( screenWidth, 40 ) );
   
toolbarButtons.clear();
   
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_WATER, 0, L"water", driver->getTexture( "Media/GUI/water.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_BEACH, 0, L"beach", driver->getTexture( "Media/GUI/beach.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_GRASS, 0, L"grass", driver->getTexture( "Media/GUI/grass.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_ROCKS, 0, L"rocks", driver->getTexture( "Media/GUI/rocks.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_HIGHLANDS, 0, L"highlands", driver->getTexture( "Media/GUI/highlands.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_DARKNESS, 0, L"darkness", driver->getTexture( "Media/GUI/darkness.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_SWAMP, 0, L"swamp", driver->getTexture( "Media/GUI/swamp.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_DESERT, 0, L"desert", driver->getTexture( "Media/GUI/desert.png" ), 0, false, true ) );
   
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_DECREASE, 0, L"decrease", driver->getTexture( "Media/GUI/decrease.png" ), 0, false, true ) );
   
toolbarButtons.push_back( terrainBar->addButton( BAR_BUTTON_INCREASE, 0, L"increase", driver->getTexture( "Media/GUI/increase.png" ), 0, false, true ) );
   
}

bool buttonsFromToolbarClicked()
{
   
bool result = false;
   
for( auto & b: toolbarButtons )
   
if( b->isPressed() )
       
 result = true;
   
   
return result;
}

bool GUIisHover()
{
   
if( menu->isPointInside( mousePos ) )
       
 return true;
   
   
if( worldMenu->isPointInside( mousePos ) )
       
 return true;
   
   
if( helpMenu->isPointInside( mousePos ) )
       
 return true;
   
   
if( terrainBar->isPointInside( mousePos ) )
       
 return true;
   
   
return false;
}

void createAnimModels()
{
   
animModel1 = smgr->addAnimatedMeshSceneNode( modelMesh ); // Add Model1
   
animModel1->setScale( vector3df( 10, 10, 10 ) );
   
animModel1->setPosition( hexToGlobal( 0, 0 ) );
   
animModel1->setRotation( vector3df( 0, 180, 0 ) );
   
animModel1->setMaterialFlag( EMF_LIGHTING, false );
   
animModel1->setMD2Animation( scene::EMAT_STAND );
   
animModel1->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) );
   
   
animModel2 = smgr->addAnimatedMeshSceneNode( modelMesh ); // Add Model2
   
animModel2->setScale( vector3df( 10, 10, 10 ) );
   
animModel2->setPosition( hexToGlobal( 3, 4 ) );
   
animModel2->setRotation( vector3df( 0, 180, 0 ) );
   
animModel2->setMaterialFlag( EMF_LIGHTING, false );
   
animModel2->setMD2Animation( scene::EMAT_STAND );
   
animModel2->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) );
   
   
animModel3 = smgr->addAnimatedMeshSceneNode( modelMesh ); // Add Model3
   
animModel3->setScale( vector3df( 10, 10, 10 ) );
   
animModel3->setPosition( hexToGlobal( 7, 5 ) );
   
animModel3->setRotation( vector3df( 0, 180, 0 ) );
   
animModel3->setMaterialFlag( EMF_LIGHTING, false );
   
animModel3->setMD2Animation( scene::EMAT_STAND );
   
animModel3->setMaterialTexture( 0, driver->getTexture( modelTexturePathfile.c_str() ) );
}

void createHexMap( int width, int length )
{
   
hexMap = new HexMap();
   
for( int z = 0; z < length; z++ )
   
{
       
for( int x = 0; x < width; x++ )
       
{
           
HexTile * tile = new HexTile( smgr->getRootSceneNode(), smgr, - 1, x, z );
           
tile->setHeight( 0 );
           
hexMap->addTile( tile );
       
}
    }
   
   
// ADDING TRIANGLE SELECTOR TO MAP
   
ITriangleSelector * selector;
   
for( auto & tile: hexMap->tiles )
   
{
       
selector = smgr->createTriangleSelector( tile->getMesh(), tile );
       
tile->setTriangleSelector( selector );
       
selector->drop();
   
}
   
   
// SET THE NEIGHBOURS FOR ANY TILE
   
for( auto & tile: hexMap->tiles )
   
{
       
tile->neighbours[ 0 ] = hexMap->getHexTile( tile->x +( tile->z % 2 ), tile->z + 1 );
       
tile->neighbours[ 1 ] = hexMap->getHexTile( tile->x + 1, tile->z );
       
tile->neighbours[ 2 ] = hexMap->getHexTile( tile->x +( tile->z % 2 ), tile->z - 1 );
       
tile->neighbours[ 3 ] = hexMap->getHexTile( tile->x +( tile->z % 2 ) - 1, tile->z - 1 );
       
tile->neighbours[ 4 ] = hexMap->getHexTile( tile->x - 1, tile->z );
       
tile->neighbours[ 5 ] = hexMap->getHexTile( tile->x +( tile->z % 2 ) - 1, tile->z + 1 );
   
}
}

void getNeighbours( std::set < HexTile * > & tiles, HexTile * tile, int radius )
{
   
if( tile != nullptr )
   
{
       
tiles.insert( tile );
       
       
if( radius > 0 )
       
{
           
getNeighbours( tiles, tile->neighbours[ 0 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 1 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 2 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 3 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 4 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 5 ], radius - 1 );
       
}
    }
}

void highlightingtHexTiles()
{
   
// CALCULATE THE RAY TO COLLISION
   
core::line3d < f32 > ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( mousePos, cam );
   
   
// COLLISION
   
core::vector3df intersection;
   
core::triangle3df hitTriangle;
   
scene::ISceneCollisionManager * collMan = smgr->getSceneCollisionManager(); // HERE IS PROBLEM
   
   
if( collMan != 0 )
   
{
       
scene::ISceneNode * selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay( ray, intersection, hitTriangle );
       
       
// CLEAR OLD HIGHLIGHTED HEX TILES
       
for( auto & t: highlightedHexTiles )
           
 t->meshBuffer->Material.MaterialType = EMT_SOLID;
       
       
if( selectedSceneNode != nullptr )
       
{
           
vector2di tilePos = globalToHex( selectedSceneNode->getPosition().X, selectedSceneNode->getPosition().Z );
           
           
highlightedHexTiles.clear();
           
getNeighbours( highlightedHexTiles, hexMap->getHexTile( tilePos.X, tilePos.Y ), brushSize );
           
           
for( auto & t: highlightedHexTiles )
               
 t->meshBuffer->Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
           
       
}
    }
}

void editHexTiles()
{
   
for( auto & t: highlightedHexTiles )
       
 t->setTerrainType( brushTerrain );
   
}

void thisIsNotBuildYet()
{
   
int rectWidth = 300;
   
int rectHeight = 300;
   
int x1 =( screenWidth - rectWidth ) / 2;
   
int x2 =( screenWidth + rectWidth ) / 2;
   
int y1 =( screenHeight - rectHeight ) / 2;
   
int y2 =( screenHeight + rectHeight ) / 2;
   
   
rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 );
   
   
IGUIWindow * window = GUI->addWindow( rectangle );
   
   
const wchar_t * t = L"This section is not build yed";
   
IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true );
   
text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER );
   
}

void createWorld()
{
   
   
if( hexMap != nullptr ) // HERE IS PROBLEM
   
{
       
for( auto & t: hexMap->tiles )
       
{
           
t->meshBuffer->drop();
           
t->mesh->drop();
           
t->drop();
       
}
    }
   
   
createHexMap( 40, 40 ); // create new HexMap(width, height)
   
std::cout << "created new world" << std::endl;
}

void loadWorld()
{
   
   
std::cout << "load new world" << std::endl;
   
thisIsNotBuildYet();
}

void saveWorld()
{
   
std::cout << "save world" << std::endl;
   
thisIsNotBuildYet();
   
ofstream file( "world.hexmap" );
   
   
for( auto & t: hexMap->tiles )
   
{
       
file << "hexTile";
       
file << t->x;
       
file << t->z;
       
file << terrainTypeToInt( t->ttype );
       
//file << waterTypeToInt(t->wtype);
   
}
   
   
file.close();
   
}

void generateWorld()
{
   
std::cout << "generate world" << std::endl;
   
thisIsNotBuildYet();
}

void tutorial()
{
   
std::cout << "tutorial" << std::endl;
   
thisIsNotBuildYet();
}

void info()
{
   
std::cout << "info" << std::endl;
   
   
int rectWidth = 300;
   
int rectHeight = 300;
   
int x1 =( screenWidth - rectWidth ) / 2;
   
int x2 =( screenWidth + rectWidth ) / 2;
   
int y1 =( screenHeight - rectHeight ) / 2;
   
int y2 =( screenHeight + rectHeight ) / 2;
   
   
rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 );
   
   
IGUIWindow * window = GUI->addWindow( rectangle );
   
const wchar_t * t = L"Program created by tBane";
   
   
IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true );
   
text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER );
}

class MyEventReceiver
    : public IEventReceiver
{
public:
   
bool KeyIsDown[ KEY_KEY_CODES_COUNT ];
   
   
MyEventReceiver();
   
virtual bool OnEvent( const SEvent & );
   
virtual bool IsKeyDown( EKEY_CODE );
   
bool OnMenuItemSelected( IGUIContextMenu * menu );
};


MyEventReceiver::MyEventReceiver()
{
   
for( u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i )
       
 KeyIsDown[ i ] = false;
   
}

bool MyEventReceiver::OnEvent( const SEvent & event )
{
   
if( event.EventType == irr::EET_MOUSE_INPUT_EVENT )
   
{
       
switch( event.MouseInput.Event )
       
{
       
case EMIE_LMOUSE_PRESSED_DOWN:
           
mousePress = true;
           
break;
           
       
case EMIE_LMOUSE_LEFT_UP:
           
mousePress = false;
           
break;
           
           
/*
  case EMIE_MOUSE_MOVED:
   MouseState.Position.X = event.MouseInput.X;
   MouseState.Position.Y = event.MouseInput.Y;
   break;
  */
       
default:
           
// We won't use the wheel
           
break;
       
}
    }
   
   
// Remember whether each key is down or up
   
if( event.EventType == irr::EET_KEY_INPUT_EVENT )
   
{
       
KeyIsDown[ event.KeyInput.Key ] = event.KeyInput.PressedDown;
       
return true;
   
}
   
   
if( event.EventType == EET_GUI_EVENT )
   
{
       
switch( event.GUIEvent.EventType )
       
{
       
case EGET_MENU_ITEM_SELECTED: // main menu events
           
{
               
IGUIContextMenu * menu =( IGUIContextMenu * ) event.GUIEvent.Caller;
               
s32 id = menu->getItemCommandId( menu->getSelectedItem() );
               
               
if( id == GUI_CREATEWORLD )
                   
 createWorld();
               
               
if( id == GUI_LOADWORLD )
                   
 loadWorld();
               
               
if( id == GUI_SAVEWORLD )
                   
 saveWorld();
               
               
if( id == GUI_GENERATEWORLD )
                   
 generateWorld();
               
               
if( id == GUI_TUTORIAL )
                   
 tutorial();
               
               
if( id == GUI_INFO )
                   
 info();
               
           
}
           
break;
           
       
case EGET_BUTTON_CLICKED:
           
{
               
s32 id = event.GUIEvent.Caller->getID();
               
               
if( id == BAR_BUTTON_WATER )
               
{
                   
brushTerrain = terrainType::water;
                   
std::cout << "setted a water to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_BEACH )
               
{
                   
brushTerrain = terrainType::beach;
                   
std::cout << "setted a beach to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_GRASS )
               
{
                   
brushTerrain = terrainType::grass;
                   
std::cout << "setted a grass to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_ROCKS )
               
{
                   
brushTerrain = terrainType::rocks;
                   
std::cout << "setted a rocks to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_HIGHLANDS )
               
{
                   
brushTerrain = terrainType::highlands;
                   
std::cout << "setted a highlands to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_DARKNESS )
               
{
                   
brushTerrain = terrainType::darkness;
                   
std::cout << "setted a darkness to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_SWAMP )
               
{
                   
brushTerrain = terrainType::swamp;
                   
std::cout << "setted a swamp to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_DESERT )
               
{
                   
brushTerrain = terrainType::desert;
                   
std::cout << "setted a desert to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_INCREASE )
               
{
                   
if( brushSize < maxBrushSize )
                       
 brushSize++;
                   
               
}
               
               
if( id == BAR_BUTTON_DECREASE )
               
{
                   
if( brushSize > 0 )
                       
 brushSize--;
                   
               
}
            }
           
break;
           
           
default:
           
break;
       
}
    }
   
   
return false;
}

bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode )
{
   
return KeyIsDown[ keyCode ];
}

int main()
{
   
MyEventReceiver receiver;
   
// CREATE DEVICE ( OpenGL )
   
device = createDevice( EDT_OPENGL, dimension2d < u32 >( screenWidth, screenHeight ), bitsPerPixel, fullscreen, stencilbuffer, vsync, & receiver );
   
   
if( !device ) // if no Device then error
       
 return 1;
   
   
// GET THE BASIC THINGS
   
driver = device->getVideoDriver(); // get the Video Driver
   
smgr = device->getSceneManager(); // get the Scene
   
GUI = device->getGUIEnvironment(); // get the GUI Manager
   
    // LOAD THE FONTS
   
basicFont = device->getGUIEnvironment()->getBuiltInFont(); // get the Default Font
   
boldFont = device->getGUIEnvironment()->getFont( "Media/fonthaettenschweiler.bmp" ); // get the Bold Font
   
    // LOAD TEXTURES
   
loadTextures();
   
   
// CREATE GUI
   
setStylesForGUI();
   
createGUI();
   
   
// ADD CAMERA
   
cam_x = 0;
   
cam_y = 100;
   
cam_z = - 40;
   
cam = smgr->addCameraSceneNode( 0, vector3df( cam_x, 30, cam_z ), vector3df( 0, 5, 0 ) );
   
cam->setTarget( vector3df( cam_x, cam_y, cam_z ) );
   
   
// CURSOR IS HIDDEN
   
device->getCursorControl()->setVisible( true );
   
   
// LOAD THE MODEL
   
modelMesh = smgr->getMesh( modelPathfile.c_str() );
   
if( !modelMesh )
       
 device->drop();
   
   
createHexMap( 60, 60 );
   
   
// MAIN "TW World Editor" LOOP
   
while( device->run() )
   
{
       
if( device->isWindowActive() )
       
{
           
           
// EVENTS
           
if( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) // if press ESCAPE then exit
           
{
               
device->drop();
               
return 0;
           
}
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_A ) || receiver.IsKeyDown( irr::KEY_LEFT ) ) cam_x -= 1.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_D ) || receiver.IsKeyDown( irr::KEY_RIGHT ) ) cam_x += 1.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_W ) || receiver.IsKeyDown( irr::KEY_UP ) ) cam_z += 1.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_S ) || receiver.IsKeyDown( irr::KEY_DOWN ) ) cam_z -= 1.0f;
           
           
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // UPDATE
            //
           
            // CAMERA POSITIONING
           
cam->setPosition( vector3df( cam_x, cam_y, cam_z ) );
           
cam->setTarget( vector3df( cam_x, 30, cam_z + 50 ) );
           
           
// GET THE MOUSE POSITION
           
mousePos = device->getCursorControl()->getPosition();
           
           
highlightingtHexTiles();
           
if(
            !
GUIisHover() && mousePress )
           
{
               
editHexTiles();
           
}
           
           
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // RENDER
           
driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); // clear screen
           
smgr->drawAll(); // render scene
           
driver->draw2DImage( TWTexture, position2d < s32 >( 0, screenHeight - 128 - 20 ), rect < s32 >( 0, 0, 128, 128 ) ); // render TW Logo
           
boldFont->draw( L"TW World Editor v0.3", recti( 20, screenHeight - 20, 100, screenHeight ), SColor( 255, 128, 48, 48 ), true, true ); // render text on bottom
           
GUI->drawAll(); // render GUI
           
position2d < s32 > m = device->getCursorControl()->getPosition(); // render cursor
           
driver->endScene(); // render submit
           
            // FPS
           
int currentFPS = driver->getFPS();
           
core::stringw str = L"FPS: ";
           
str += currentFPS;
           
device->setWindowCaption( str.c_str() );
       
}
       
else
           
 device->yield(); // if window is inactive not use CPU
       
   
}
   
   
// In the end, delete the Irrlicht device.
   
device->drop();
   
return 0;
}
P-180875
pekfos
» 2024-02-25 18:43:58
Nie widzę żebyś usuwał mapę ze sceny, ISceneNode::remove().
P-180876
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-25 18:59:39
myślałem, że od usuwania jest drop(). Następnym razem dokładniej sprawdzę dokumentację.
Dziękuję @pekfos za pomoc.

Rozwiązanie:
C/C++
if( hexMap != nullptr )
{
   
for( auto & t: hexMap->tiles )
       
 t->remove();
   
}
P-180877
pekfos
» 2024-02-25 20:43:12
Rozwiązanie to remove() i drop(). Zdecydowanie sprawdź w dokumentacji co robią te metody.
P-180878
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-25 21:51:30
z drop() generuje mi błędy odczytu pamięci.
P-180879
pekfos
» 2024-02-25 22:39:35
Kod
P-180880
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-26 13:39:54
C/C++
#include <irrlicht.h>

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

using namespace irr; // I don't want to use it irr::

using namespace core; // also ( irr::core:: )
using namespace scene; // also ( irr::scene::)
using namespace video; // also ...
using namespace io; // ...
using namespace gui; // ...

#include<iostream>
#include<vector>
#include<set>
#include<fstream>

using namespace std;

// device
int screenWidth = 1080;
int screenHeight = 720;
int bitsPerPixel = 32;
bool fullscreen = false;
bool stencilbuffer = false; // Specifies if we want to use the stencil buffer (for drawing shadows)
bool vsync = false; // Specifies if we want to have vsync enabled, this is only useful in fullscreen mode.
int eventReceiver = 0; // An object to receive events.We do not want to use this parameter here, and set it to 0.
float cam_x, cam_y, cam_z;
bool mousePress = false;
position2d < s32 > mousePos; // Mouse Position

// clearing screen colors
int clear_r = 48;
int clear_g = 48;
int clear_b = 48;
int clear_a = 256;

// Basic things
IrrlichtDevice * device;
IVideoDriver * driver;
ISceneManager * smgr;
IGUIEnvironment * GUI;
ICameraSceneNode * cam;

// Fonts
IGUIFont * basicFont;
IGUIFont * boldFont;

// Textures
ITexture * TWTexture;

// Model pathfiles
std::string modelPathfile = "Media/TT_RTS_Demo_Character.obj";
std::string modelTexturePathfile = "Media/TT_RTS_Units_blue.png";

// Meshes
IAnimatedMesh * modelMesh; // mesh

// Animators
IAnimatedMeshSceneNode * animModel1; // model1
IAnimatedMeshSceneNode * animModel2; // model2
IAnimatedMeshSceneNode * animModel3; // model3

// Textures
ITexture * modelTexture;

ITexture * darknessTexture;
ITexture * waterTexture;
ITexture * beachTexture;
ITexture * grassTexture;
ITexture * rocksTexture;
ITexture * highlandsTexture;
ITexture * swampTexture;
ITexture * desertTexture;

// GUI
IGUIContextMenu * menu;
IGUIContextMenu * worldMenu;
IGUIContextMenu * helpMenu;
IGUIToolBar * terrainBar;
std::set < IGUIButton * > terrainBarButtons;

// Buttons ID's
enum
{
   
// World
   
GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD,
   
   
// Help
   
GUI_TUTORIAL, GUI_INFO,
   
   
// bar
   
BAR_BUTTON_WATER, BAR_BUTTON_BEACH, BAR_BUTTON_GRASS, BAR_BUTTON_ROCKS, BAR_BUTTON_HIGHLANDS, BAR_BUTTON_DARKNESS, BAR_BUTTON_SWAMP, BAR_BUTTON_DESERT,
   
   
// INCREASE / DECREASE BRUSH SIZE
   
BAR_BUTTON_DECREASE, BAR_BUTTON_INCREASE
};

float outerRadius = 10.0f;
float innerRadius = outerRadius * 0.866025404f;
float heightStep = 2.0f;

float hexVertices[ ] =
{
   
0.0f, outerRadius,
   
innerRadius, outerRadius * 0.5f,
   
innerRadius, - outerRadius * 0.5f,
   
0.0f, - outerRadius,
   
- innerRadius, - outerRadius * 0.5f,
   
- innerRadius, outerRadius * 0.5f,
   
0.0f, outerRadius
};

const u16 hexIndices[ 18 ] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 };

float texture_uv[ ]
{
   
0.0f, 0.5f,
   
0.5f, 0.25f,
   
0.5f, - 0.25f,
   
0.0f, - 0.5f,
   
- 0.5f, - 0.25f,
   
- 0.5f, 0.25f,
   
0.0f, 0.5f,
};


vector3df hexToGlobal( float x, float z )
{
   
vector3df pos;
   
pos.X = x * 2.0f * innerRadius +( int( z ) % 2 ) * innerRadius;
   
pos.Y = 0.0f;
   
pos.Z = z * 1.5f * outerRadius;
   
return pos;
}

vector2di globalToHex( float x, float y )
{
   
vector2di hex;
   
   
float xx =( x /( 2.0f * innerRadius ) ) -(( int( y /( 1.5f * outerRadius ) ) ) % 2 ) / 2.f;
   
float yy = y /( 1.5f * outerRadius );
   
   
hex.X =( xx + 0.5f );
   
hex.Y =( yy + 0.5f );
   
   
return hex;
}

enum class terrainType { water, beach, grass, rocks, highlands, darkness, swamp, desert };

int terrainTypeToInt( terrainType ttype )
{
   
if( ttype == terrainType::water ) return 0;
   
else if( ttype == terrainType::beach ) return 1;
   
else if( ttype == terrainType::grass ) return 2;
   
else if( ttype == terrainType::rocks ) return 3;
   
else if( ttype == terrainType::highlands ) return 4;
   
else if( ttype == terrainType::darkness ) return 5;
   
else if( ttype == terrainType::swamp ) return 6;
   
else if( ttype == terrainType::desert ) return 7;
   
else return 2;
   
}

terrainType intToTerrainType( int ttype )
{
   
if( ttype == 0 ) return terrainType::water;
   
else if( ttype == 1 ) return terrainType::beach;
   
else if( ttype == 2 ) return terrainType::grass;
   
else if( ttype == 3 ) return terrainType::rocks;
   
else if( ttype == 4 ) return terrainType::highlands;
   
else if( ttype == 5 ) return terrainType::darkness;
   
else if( ttype == 6 ) return terrainType::swamp;
   
else if( ttype == 7 ) return terrainType::desert;
   
else return terrainType::grass;
   
}

// BRUSH

terrainType brushTerrain = terrainType::grass;
int brushHeight = 0;
int brushSize = 0;
int maxBrushSize = 4;

void loadTextures()
{
   
waterTexture = driver->getTexture( "Media/Terrains/water.png" );
   
beachTexture = driver->getTexture( "Media/Terrains/beach.png" );
   
grassTexture = driver->getTexture( "Media/Terrains/grass.png" );
   
rocksTexture = driver->getTexture( "Media/Terrains/rocks.png" );
   
highlandsTexture = driver->getTexture( "Media/Terrains/highlands.png" );
   
darknessTexture = driver->getTexture( "Media/Terrains/darkness.png" );
   
swampTexture = driver->getTexture( "Media/Terrains/swamp.png" );
   
desertTexture = driver->getTexture( "Media/Terrains/desert.png" );
   
   
TWTexture = driver->getTexture( "Media/GUI/TW.png" );
   
}

ITexture * getTexture( terrainType ttype )
{
   
ITexture * tex = 0;
   
   
if( ttype == terrainType::water )
       
 tex = waterTexture;
   
   
if( ttype == terrainType::beach )
       
 tex = beachTexture;
   
   
if( ttype == terrainType::grass )
       
 tex = grassTexture;
   
   
if( ttype == terrainType::rocks )
       
 tex = rocksTexture;
   
   
if( ttype == terrainType::highlands )
       
 tex = highlandsTexture;
   
   
if( ttype == terrainType::darkness )
       
 tex = darknessTexture;
   
   
if( ttype == terrainType::swamp )
       
 tex = swampTexture;
   
   
if( ttype == terrainType::desert )
       
 tex = desertTexture;
   
   
return tex;
}

class HexTile
    : public scene::ISceneNode
{
public:
   
SMesh * mesh;
   
SMeshBuffer * meshBuffer;
   
   
   
int x, z;
   
terrainType ttype;
   
int height;
   
HexTile * neighbours[ 6 ]; // NE, E, SE, SW, W, WE
   
   
HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id, int, int );
   
virtual void OnRegisterSceneNode();
   
virtual void render();
   
virtual const aabbox3d < f32 > & getBoundingBox() const;
   
virtual u32 getMaterialCount() const;
   
virtual SMaterial & getMaterial( u32 i );
   
void setTexture( ITexture * );
   
SMesh * getMesh();
   
   
void setTerrainType( terrainType );
   
void setHeight( int );
};

HexTile::HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id, int x, int z )
    :
ISceneNode( parent, smgr, id )
{
   
this->x = x;
   
this->z = z;
   
ttype = terrainType::grass;
   
height = 0;
   
   
   
////////////////////////////////////////////////////////////////////////////////
   
   
meshBuffer = new SMeshBuffer();
   
   
// SET THE INDICES
   
meshBuffer->Indices.set_used( 18 );
   
for( u32 i = 0; i < 18; ++i )
       
 meshBuffer->Indices[ i ] = hexIndices[ i ];
   
   
// SET THE VERTICES
   
SColor color = SColor( 255, 255, 255, 255 );
   
   
meshBuffer->Vertices.push_back( S3DVertex( 0, 0, 0, 0, 0, 0, color, 0, 0 ) );
   
for( int i = 0; i < 7; i++ )
   
{
       
meshBuffer->Vertices.push_back( S3DVertex( hexVertices[ 2 * i ], 0.0f, hexVertices[ 2 * i + 1 ], 0, 0, 0, color, texture_uv[ 2 * i ], texture_uv[ 2 * i + 1 ] ) );
   
}
   
   
// SET THE BOUNDING BOX
   
meshBuffer->BoundingBox.reset( vector3df( hexVertices[ 0 ], 0, hexVertices[ 1 ] ) );
   
for( s32 i = 1; i < 7; ++i )
       
 meshBuffer->BoundingBox.addInternalPoint( vector3df( hexVertices[ 2 * i ], 0, hexVertices[ 2 * i + 1 ] ) );
   
   
   
// SET THE MATERIAL
   
meshBuffer->Material.Wireframe = false;
   
meshBuffer->Material.Lighting = false;
   
meshBuffer->Material.setTexture( 0, getTexture( ttype ) );
   
   
mesh = new SMesh();
   
mesh->addMeshBuffer( meshBuffer );
   
mesh->recalculateBoundingBox();
   
   
vector3df pos = hexToGlobal( x, z );
   
pos.Y = height * heightStep;
   
setPosition( pos );
}

void HexTile::OnRegisterSceneNode()
{
   
if( IsVisible )
       
 SceneManager->registerNodeForRendering( this );
   
   
ISceneNode::OnRegisterSceneNode();
}

void HexTile::render()
{
   
IVideoDriver * driver = smgr->getVideoDriver();
   
driver->setMaterial( meshBuffer->Material );
   
driver->setTransform( video::ETS_WORLD, AbsoluteTransformation );
   
driver->drawMeshBuffer( meshBuffer );
   
}

const aabbox3d < f32 > & HexTile::getBoundingBox() const
{
   
return meshBuffer->BoundingBox;
}

u32 HexTile::getMaterialCount() const
{
   
return 1;
}

SMaterial & HexTile::getMaterial( u32 i )
{
   
return meshBuffer->Material;
}

void HexTile::setTexture( ITexture * tex )
{
   
meshBuffer->Material.setTexture( 0, tex );
}

SMesh * HexTile::getMesh()
{
   
return mesh;
}

void HexTile::setTerrainType( terrainType ttype )
{
   
this->ttype = ttype;
   
setTexture( getTexture( ttype ) );
}

void HexTile::setHeight( int height )
{
   
this->height = height;
   
   
vector3df pos = hexToGlobal( x, z );
   
pos.Y = float( height ) * heightStep;
   
setPosition( pos );
}

std::set < HexTile * > highlightedHexTiles; // highlighted HexTiles

class HexMap
{
public:
   
std::vector < HexTile * > tiles;
   
   
HexMap();
   
~HexMap();
   
void addTile( HexTile * );
   
void setTerrainType( terrainType );
   
HexTile * getHexTile( int, int );
   
void destroy();
   
void create( int, int );
   
void saveAsFile( std::string );
   
void loadFromFile( std::string );
};

HexMap::HexMap()
{
   
tiles.clear();
}

HexMap::~HexMap()
{
   
}

void HexMap::addTile( HexTile * tile )
{
   
tiles.push_back( tile );
}

void HexMap::setTerrainType( terrainType ttype )
{
   
for( auto & t: tiles )
       
 t->setTerrainType( ttype );
   
}

HexTile * HexMap::getHexTile( int x, int z )
{
   
HexTile * tile = nullptr;
   
for( auto & t: tiles )
   
{
       
if( t->x == x && t->z == z )
           
 tile = t;
       
   
}
   
   
return tile;
}

void HexMap::destroy()
{
   
// remove old tiles
   
for( auto & t: tiles )
   
{
       
t->remove();
   
}
   
   
tiles.clear();
}

void HexMap::create( int width, int length )
{
   
tiles.clear();
   
   
for( int z = 0; z < 40; z++ )
   
{
       
for( int x = 0; x < 40; x++ )
       
{
           
HexTile * tile = new HexTile( smgr->getRootSceneNode(), smgr, - 1, x, z );
           
tile->setHeight( 0 );
           
addTile( tile );
       
}
    }
   
   
// ADDING TRIANGLE SELECTOR TO MAP
   
ITriangleSelector * selector;
   
for( auto & t: tiles )
   
{
       
selector = smgr->createTriangleSelector( t->getMesh(), t );
       
t->setTriangleSelector( selector );
       
selector->drop();
   
}
   
   
// SET THE NEIGHBOURS FOR ANY TILE
   
for( auto & t: tiles )
   
{
       
t->neighbours[ 0 ] = getHexTile( t->x +( t->z % 2 ), t->z + 1 );
       
t->neighbours[ 1 ] = getHexTile( t->x + 1, t->z );
       
t->neighbours[ 2 ] = getHexTile( t->x +( t->z % 2 ), t->z - 1 );
       
t->neighbours[ 3 ] = getHexTile( t->x +( t->z % 2 ) - 1, t->z - 1 );
       
t->neighbours[ 4 ] = getHexTile( t->x - 1, t->z );
       
t->neighbours[ 5 ] = getHexTile( t->x +( t->z % 2 ) - 1, t->z + 1 );
   
}
}

void HexMap::saveAsFile( std::string name )
{
   
name = name + ".hexmap";
   
ofstream file;
   
file.open( name.c_str() );
   
   
for( auto & t: tiles )
   
{
       
file << t->x;
       
file << t->z;
       
file << terrainTypeToInt( t->ttype );
   
}
   
   
file.close();
}

void HexMap::loadFromFile( std::string name )
{
   
name = name + ".hexmap";
   
   
ifstream file;
   
file.open( name.c_str() );
   
int x, z, ttype;
   
while( !file.eof() )
   
{
       
file >> x;
       
file >> z;
       
file >> ttype;
       
       
HexTile * tile = new HexTile( smgr->getRootSceneNode(), smgr, - 1, x, z );
       
tile->setTerrainType( intToTerrainType( ttype ) );
       
addTile( tile );
       
cout << tile->x << ", " << tile->z << " - " << terrainTypeToInt( tile->ttype ) << "\n";
   
}
   
   
file.close();
}

HexMap * hexMap;

void setStylesForGUI()
{
   
IGUISkin * GUIskin = GUI->getSkin();
   
GUIskin->setFont( boldFont );
   
   
for( s32 i = 0; i < gui::EGDC_COUNT; ++i )
       
 GUIskin->setColor(( EGUI_DEFAULT_COLOR ) i, SColor( 255, 64, 64, 64 ) ); // coloring the Background
   
    // MENU
   
GUIskin->setColor( EGDC_BUTTON_TEXT, SColor( 255, 224, 224, 224 ) ); // coloring the Text
   
GUIskin->setColor( EGDC_HIGH_LIGHT_TEXT, SColor( 255, 160, 64, 64 ) ); // coloring the Highlighed Text
   
    // TOOL TIP (MENU BAR)
   
GUIskin->setColor( EGDC_TOOLTIP_BACKGROUND, SColor( 255, 64, 64, 64 ) ); // coloring the Background
   
GUIskin->setColor( EGDC_TOOLTIP, SColor( 255, 224, 224, 224 ) ); // coloring the Text
}

void createGUI()
{
   
// CREATE MAIN MENU
   
menu = GUI->addMenu();
   
menu->addItem( L"World", - 1, true, true );
   
menu->addItem( L"Help", - 1, true, true );
   
   
// CREATE WORLD MENU
   
worldMenu = menu->getSubMenu( 0 );
   
worldMenu->addItem( L"Create World", GUI_CREATEWORLD );
   
worldMenu->addItem( L"Load World", GUI_LOADWORLD );
   
worldMenu->addItem( L"Save world", GUI_SAVEWORLD );
   
worldMenu->addItem( L"Generate World", GUI_GENERATEWORLD );
   
   
// CREATE HELP MENU
   
helpMenu = menu->getSubMenu( 1 );
   
helpMenu->addItem( L"Tutorial", GUI_TUTORIAL );
   
helpMenu->addItem( L"Info", GUI_INFO );
   
   
// MENU BAR
   
terrainBar = GUI->addToolBar();
   
terrainBar->setMinSize( dimension2du( screenWidth, 48 ) );
   
terrainBarButtons.clear();
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_WATER, 0, L"water", driver->getTexture( "Media/GUI/water.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_BEACH, 0, L"beach", driver->getTexture( "Media/GUI/beach.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_GRASS, 0, L"grass", driver->getTexture( "Media/GUI/grass.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_ROCKS, 0, L"rocks", driver->getTexture( "Media/GUI/rocks.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_HIGHLANDS, 0, L"highlands", driver->getTexture( "Media/GUI/highlands.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_DARKNESS, 0, L"darkness", driver->getTexture( "Media/GUI/darkness.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_SWAMP, 0, L"swamp", driver->getTexture( "Media/GUI/swamp.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_DESERT, 0, L"desert", driver->getTexture( "Media/GUI/desert.png" ), 0, false, true ) );
   
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_DECREASE, 0, L"decrease", driver->getTexture( "Media/GUI/decrease.png" ), 0, false, true ) );
   
terrainBarButtons.insert( terrainBar->addButton( BAR_BUTTON_INCREASE, 0, L"increase", driver->getTexture( "Media/GUI/increase.png" ), 0, false, true ) );
   
}

void getNeighbours( std::set < HexTile * > & tiles, HexTile * tile, int radius )
{
   
if( tile != nullptr )
   
{
       
tiles.insert( tile );
       
       
if( radius > 0 )
       
{
           
getNeighbours( tiles, tile->neighbours[ 0 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 1 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 2 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 3 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 4 ], radius - 1 );
           
getNeighbours( tiles, tile->neighbours[ 5 ], radius - 1 );
       
}
    }
}

void highlightHexTiles()
{
   
for( auto & t: highlightedHexTiles )
       
 t->meshBuffer->Material.MaterialType = EMT_SOLID;
   
   
// CALCULATE THE RAY TO COLLISION
   
core::line3d < f32 > ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( mousePos, cam );
   
   
// COLLISION
   
core::vector3df intersection;
   
core::triangle3df hitTriangle;
   
scene::ISceneCollisionManager * collMan = smgr->getSceneCollisionManager();
   
   
scene::ISceneNode * selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay( ray, intersection, hitTriangle );
   
   
if( selectedSceneNode != nullptr )
   
{
       
highlightedHexTiles.clear();
       
       
vector2di tilePos = globalToHex( selectedSceneNode->getPosition().X, selectedSceneNode->getPosition().Z );
       
getNeighbours( highlightedHexTiles, hexMap->getHexTile( tilePos.X, tilePos.Y ), brushSize );
       
       
for( auto & t: highlightedHexTiles )
           
 t->meshBuffer->Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
       
   
}
}

void editHexTiles()
{
   
for( auto & t: highlightedHexTiles )
       
 t->setTexture( getTexture( brushTerrain ) );
   
}

void thisIsNotBuildYet()
{
   
int rectWidth = 300;
   
int rectHeight = 300;
   
int x1 =( screenWidth - rectWidth ) / 2;
   
int x2 =( screenWidth + rectWidth ) / 2;
   
int y1 =( screenHeight - rectHeight ) / 2;
   
int y2 =( screenHeight + rectHeight ) / 2;
   
   
rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 );
   
   
IGUIWindow * window = GUI->addWindow( rectangle );
   
   
const wchar_t * t = L"This section is not build yed";
   
IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true );
   
text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER );
   
}

void createWorld()
{
   
if( hexMap != nullptr )
       
 hexMap->destroy();
   
   
hexMap->create( 40, 40 );
   
std::cout << "created new world" << std::endl;
   
   
}

void loadWorld()
{
   
hexMap->destroy();
   
hexMap->loadFromFile( "world" );
   
   
std::cout << "load world" << std::endl;
}

void saveWorld()
{
   
hexMap->saveAsFile( "world" );
   
std::cout << "save world" << std::endl;
}

void generateWorld()
{
   
std::cout << "generate world" << std::endl;
   
thisIsNotBuildYet();
}

void tutorial()
{
   
std::cout << "tutorial" << std::endl;
   
thisIsNotBuildYet();
}

void info()
{
   
std::cout << "info" << std::endl;
   
   
int rectWidth = 300;
   
int rectHeight = 300;
   
int x1 =( screenWidth - rectWidth ) / 2;
   
int x2 =( screenWidth + rectWidth ) / 2;
   
int y1 =( screenHeight - rectHeight ) / 2;
   
int y2 =( screenHeight + rectHeight ) / 2;
   
   
rect < s32 > rectangle = rect < s32 >( x1, y1, x2, y2 );
   
   
IGUIWindow * window = GUI->addWindow( rectangle );
   
const wchar_t * t = L"Program created by tBane";
   
   
IGUIStaticText * text = GUI->addStaticText( t, rect < s32 >( 0, 20, rectWidth, rectHeight ), true, true, window, - 1, true );
   
text->setTextAlignment( EGUIA_CENTER, EGUIA_CENTER );
}

bool GUIisHover()
{
   
   
if( menu->isPointInside( mousePos ) )
       
 return true;
   
   
if( worldMenu->isPointInside( mousePos ) )
       
 return true;
   
   
if( helpMenu->isPointInside( mousePos ) )
       
 return true;
   
   
if( terrainBar->isPointInside( mousePos ) )
       
 return true;
   
   
return false;
}

class MyEventReceiver
    : public IEventReceiver
{
public:
   
bool KeyIsDown[ KEY_KEY_CODES_COUNT ];
   
   
MyEventReceiver();
   
virtual bool OnEvent( const SEvent & );
   
virtual bool IsKeyDown( EKEY_CODE );
   
bool OnMenuItemSelected( IGUIContextMenu * menu );
};


MyEventReceiver::MyEventReceiver()
{
   
for( u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i )
       
 KeyIsDown[ i ] = false;
   
}

bool MyEventReceiver::OnEvent( const SEvent & event )
{
   
if( event.EventType == irr::EET_MOUSE_INPUT_EVENT )
   
{
       
switch( event.MouseInput.Event )
       
{
       
case EMIE_LMOUSE_PRESSED_DOWN:
           
mousePress = true;
           
break;
           
       
case EMIE_LMOUSE_LEFT_UP:
           
mousePress = false;
           
break;
           
           
/*
  case EMIE_MOUSE_MOVED:
   MouseState.Position.X = event.MouseInput.X;
   MouseState.Position.Y = event.MouseInput.Y;
   break;
  */
       
default:
           
// We won't use the wheel
           
break;
       
}
    }
   
   
// Remember whether each key is down or up
   
if( event.EventType == irr::EET_KEY_INPUT_EVENT )
   
{
       
KeyIsDown[ event.KeyInput.Key ] = event.KeyInput.PressedDown;
       
return true;
   
}
   
   
if( event.EventType == EET_GUI_EVENT )
   
{
       
switch( event.GUIEvent.EventType )
       
{
       
case EGET_MENU_ITEM_SELECTED: // main menu events
           
{
               
IGUIContextMenu * menu =( IGUIContextMenu * ) event.GUIEvent.Caller;
               
s32 id = menu->getItemCommandId( menu->getSelectedItem() );
               
               
if( id == GUI_CREATEWORLD )
                   
 createWorld();
               
               
if( id == GUI_LOADWORLD )
                   
 loadWorld();
               
               
if( id == GUI_SAVEWORLD )
                   
 saveWorld();
               
               
if( id == GUI_GENERATEWORLD )
                   
 generateWorld();
               
               
if( id == GUI_TUTORIAL )
                   
 tutorial();
               
               
if( id == GUI_INFO )
                   
 info();
               
           
}
           
break;
           
       
case EGET_BUTTON_CLICKED:
           
{
               
s32 id = event.GUIEvent.Caller->getID();
               
               
if( id == BAR_BUTTON_WATER )
               
{
                   
brushTerrain = terrainType::water;
                   
std::cout << "setted a water to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_BEACH )
               
{
                   
brushTerrain = terrainType::beach;
                   
std::cout << "setted a beach to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_GRASS )
               
{
                   
brushTerrain = terrainType::grass;
                   
std::cout << "setted a grass to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_ROCKS )
               
{
                   
brushTerrain = terrainType::rocks;
                   
std::cout << "setted a rocks to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_HIGHLANDS )
               
{
                   
brushTerrain = terrainType::highlands;
                   
std::cout << "setted a highlands to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_DARKNESS )
               
{
                   
brushTerrain = terrainType::darkness;
                   
std::cout << "setted a darkness to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_SWAMP )
               
{
                   
brushTerrain = terrainType::swamp;
                   
std::cout << "setted a swamp to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_DESERT )
               
{
                   
brushTerrain = terrainType::desert;
                   
std::cout << "setted a desert to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_INCREASE )
               
{
                   
if( brushSize < maxBrushSize )
                       
 brushSize++;
                   
               
}
               
               
if( id == BAR_BUTTON_DECREASE )
               
{
                   
if( brushSize > 0 )
                       
 brushSize--;
                   
               
}
            }
           
break;
           
           
default:
           
break;
       
}
    }
   
   
return false;
}

bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode )
{
   
return KeyIsDown[ keyCode ];
}

int main()
{
   
MyEventReceiver receiver;
   
// CREATE DEVICE ( OpenGL )
   
device = createDevice( EDT_OPENGL, dimension2d < u32 >( screenWidth, screenHeight ), bitsPerPixel, fullscreen, stencilbuffer, vsync, & receiver );
   
   
if( !device ) // if no Device then error
       
 return 1;
   
   
// GET THE BASIC THINGS
   
driver = device->getVideoDriver(); // get the Video Driver
   
smgr = device->getSceneManager(); // get the Scene
   
GUI = device->getGUIEnvironment(); // get the GUI Manager
   
    // LOAD THE FONTS
   
basicFont = device->getGUIEnvironment()->getBuiltInFont(); // get the Default Font
   
boldFont = device->getGUIEnvironment()->getFont( "media/fonthaettenschweiler.bmp" ); // get the Bold Font
   
    // LOAD TEXTURES
   
loadTextures();
   
   
// CREATE GUI
   
setStylesForGUI();
   
createGUI();
   
   
// ADD CAMERA
   
cam_x = 0;
   
cam_y = 100;
   
cam_z = - 40;
   
cam = smgr->addCameraSceneNode( 0, vector3df( cam_x, 30, cam_z ), vector3df( 0, 5, 0 ) );
   
cam->setTarget( vector3df( cam_x, cam_y, cam_z ) );
   
   
// CURSOR IS HIDDEN
   
device->getCursorControl()->setVisible( true );
   
   
// LOAD THE MODEL
   
modelMesh = smgr->getMesh( modelPathfile.c_str() );
   
if( !modelMesh )
       
 device->drop();
   
   
// CREATE THE HEXMAP
   
hexMap = new HexMap();
   
hexMap->create( 40, 40 );
   
   
// MAIN "TW World Editor" LOOP
   
while( device->run() )
   
{
       
if( device->isWindowActive() )
       
{
           
// MOUSE POSITION
           
mousePos = device->getCursorControl()->getPosition();
           
           
// EVENTS
           
if( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) // if press ESCAPE then exit
           
{
               
device->drop();
               
return 0;
           
}
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_A ) || receiver.IsKeyDown( irr::KEY_LEFT ) ) cam_x -= 1.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_D ) || receiver.IsKeyDown( irr::KEY_RIGHT ) ) cam_x += 1.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_W ) || receiver.IsKeyDown( irr::KEY_UP ) ) cam_z += 1.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_S ) || receiver.IsKeyDown( irr::KEY_DOWN ) ) cam_z -= 1.0f;
           
           
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // UPDATE
           
           
            // CAMERA POSITIONING
           
cam->setPosition( vector3df( cam_x, cam_y, cam_z ) );
           
cam->setTarget( vector3df( cam_x, 30, cam_z + 50 ) );
           
           
highlightHexTiles();
           
           
if( !GUIisHover() && mousePress )
               
 editHexTiles();
           
           
           
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // RENDER
           
driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); // clear screen
           
smgr->drawAll(); // render scene
           
driver->draw2DImage( TWTexture, position2d < s32 >( 0, screenHeight - 128 - 20 ), rect < s32 >( 0, 0, 128, 128 ) ); // render TW Logo
           
boldFont->draw( L"TW World Editor v0.4", recti( 20, screenHeight - 20, 100, screenHeight ), SColor( 256, 128, 48, 48 ), true, true ); // render text on bottom
           
GUI->drawAll(); // render GUI
           
position2d < s32 > m = device->getCursorControl()->getPosition(); // render cursor
           
driver->endScene(); // render submit
           
            // FPS
           
int currentFPS = driver->getFPS();
           
core::stringw str = L"FPS: ";
           
str += currentFPS;
           
device->setWindowCaption( str.c_str() );
       
}
       
else
           
 device->yield(); // if window is inactive not use CPU
       
   
}
   
   
// In the end, delete the Irrlicht device.
   
device->drop();
   
return 0;
}
P-180881
pekfos
» 2024-02-26 18:33:14
Jeśli to jest taki problem podawać kod z którym jest problem, to rób jak ci działa... Obiekty irr::ISceneNode mają zliczane referencje. Jeśli faktycznie jest poprawnie, to usunięcie mapy powinno wywołać destruktory HexTile. Jeśli nie, masz wyciek pamięci. Mając kryterium oceny poprawności, dalej sobie poradzisz sam.
P-180884
« 1 » 2
  Strona 1 z 2 Następna strona