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

[Irrlicht] Zwracanie klikniętego pola na mapie

Ostatnio zmodyfikowano 2024-02-22 20:11
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[Irrlicht] Zwracanie klikniętego pola na mapie
» 2024-02-19 20:59:10
Witam.
Piszę "Edytor Mapy". Potrzebuję uzyskać informacje, które pole zostało naduszone, aby móc za pomocą kliknięć myszy edytować mapę.


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

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<set>

// 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.
int cam_x, cam_y, cam_z;

// 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 * sceneManager;
IGUIEnvironment * GUI;

// 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;


// Buttons ID's
enum
{
   
// World
   
GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD,
   
   
// Help
   
GUI_TUTORIAL, GUI_INFO,
   
   
// bar
   
BAR_BUTTON_WATER, BAR_BUTTON_SANDS, BAR_BUTTON_GRASS, BAR_BUTTON_ROCKS, BAR_BUTTON_HIGHLANDS, BAR_BUTTON_DARKNESS
};

float outerRadius = 10.0f;
float innerRadius = outerRadius * 0.866025404f;
float heighStep = 0.8f;

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
};

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

float hexToGlobalX( float x, float z )
{
   
return x * 2.0f * innerRadius +( int( z ) % 2 ) * innerRadius;
}

float hexToGlobalZ( float z )
{
   
return z * 1.5f * outerRadius;
}

enum class terrainType { water, sands, grass, rocks, highlands, darkness };

terrainType paint = terrainType::grass;

ITexture * getTexture( terrainType ttype )
{
   
ITexture * tex = 0;
   
   
if( ttype == terrainType::sands )
       
 tex = driver->getTexture( "Media/Terrains/sands.png" );
   
   
if( ttype == terrainType::grass )
       
 tex = driver->getTexture( "Media/Terrains/grass.png" );
   
   
return tex;
}

class HexTile
    : public scene::ISceneNode
{
   
   
aabbox3d < f32 > Box;
   
S3DVertex Vertices[ 8 ];
   
SMaterial Material;
   
   
public:
   
terrainType ttype;
   
   
HexTile( ISceneNode * parent, ISceneManager * mgr, s32 id );
   
virtual void OnRegisterSceneNode();
   
virtual void render();
   
virtual const aabbox3d < f32 > & getBoundingBox() const;
   
virtual u32 getMaterialCount() const;
   
virtual SMaterial & getMaterial( u32 i );
   
void setTexture( ITexture * );
   
void setTerrainType( terrainType );
};

HexTile::HexTile( ISceneNode * parent, ISceneManager * mgr, s32 id )
    :
ISceneNode( parent, mgr, id )
{
   
ttype = terrainType::grass;
   
   
/////////////////////////////////////////////////
   
Material.Wireframe = false;
   
Material.Lighting = false;
   
Material.setTexture( 0, getTexture( ttype ) );
   
   
SColor color = SColor( 255, 255, 255, 255 );
   
   
// vertices of hexagons
   
for( int i = 0; i < 7; i++ )
       
 Vertices[ i + 1 ] = S3DVertex( hexVertices[ 2 * i ], 0, hexVertices[ 2 * i + 1 ], 0, 0, 0, color, texture_uv[ 2 * i ], texture_uv[ 2 * i + 1 ] );
   
   
Box.reset( Vertices[ 0 ].Pos );
   
for( s32 i = 1; i < 7; ++i )
       
 Box.addInternalPoint( Vertices[ i ].Pos );
   
}

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

void HexTile::render()
{
   
u16 indices[ ] = { 0, 1, 2, /**/ 0, 2, 3, /**/ 0, 3, 4, /**/ 0, 4, 5, /**/ 0, 5, 6, /**/ 0, 6, 7 };
   
IVideoDriver * driver = SceneManager->getVideoDriver();
   
driver->setMaterial( Material );
   
driver->setTransform( video::ETS_WORLD, AbsoluteTransformation );
   
driver->drawVertexPrimitiveList( & Vertices[ 0 ], 3, & indices[ 0 ], 6, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT );
   
}

const aabbox3d < f32 > & HexTile::getBoundingBox() const
{
   
return Box;
}

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

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

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

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

class HexMap
{
public:
   
std::set < HexTile * > tiles;
   
   
HexMap();
   
~HexMap();
   
void addTile( HexTile * );
};

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

HexMap::~HexMap()
{
   
}

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

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()
{
   
std::cout << "created new world" << std::endl;
   
thisIsNotBuildYet();
   
}

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

void saveWorld()
{
   
std::cout << "save world" << std::endl;
   
thisIsNotBuildYet();
}

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 )
{
   
// 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 )
                   
 paint = terrainType::water;
               
               
if( id == BAR_BUTTON_SANDS )
                   
 paint = terrainType::sands;
               
               
if( id == BAR_BUTTON_GRASS )
                   
 paint = terrainType::grass;
               
               
if( id == BAR_BUTTON_ROCKS )
                   
 paint = terrainType::rocks;
               
               
if( id == BAR_BUTTON_HIGHLANDS )
                   
 paint = terrainType::highlands;
               
               
if( id == BAR_BUTTON_DARKNESS )
                   
 paint = terrainType::darkness;
               
               
std::cout << "setted a paint" << std::endl;
               
           
}
           
break;
           
           
default:
           
break;
       
}
    }
   
   
return false;
}

bool MyEventReceiver::IsKeyDown( EKEY_CODE keyCode )
{
   
return KeyIsDown[ keyCode ];
} //#include "HexTile.hpp"

int main()
{
   
MyEventReceiver receiver;
   
// CREATE DEVICE ( OpenGL )
   
device = createDevice( EDT_SOFTWARE, 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
   
sceneManager = 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
   
   
    // STYLES FOR GUI
   
IGUISkin * GUIskin = GUI->getSkin();
   
GUIskin->setFont( boldFont );
   
   
for( s32 i = 0; i < gui::EGDC_COUNT; ++i )
   
{
       
GUIskin->setColor(( EGUI_DEFAULT_COLOR ) i, SColor( 255, 96, 96, 96 ) ); // coloring the Background
       
GUIskin->setColor( EGDC_BUTTON_TEXT, SColor( 255, 224, 224, 224 ) ); // coloring the Text
       
GUIskin->setColor( EGDC_HIGH_LIGHT_TEXT, SColor( 255, 128, 48, 48 ) ); // coloring the Highlighed Text
   
}
   
   
// CREATE MAIN MENU
   
IGUIContextMenu * menu = GUI->addMenu();
   
menu->addItem( L"World", - 1, true, true );
   
menu->addItem( L"Help", - 1, true, true );
   
   
// Create World Menu
   
IGUIContextMenu * 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
   
IGUIContextMenu * helpMenu = menu->getSubMenu( 1 );
   
helpMenu->addItem( L"Tutorial", GUI_TUTORIAL );
   
helpMenu->addItem( L"Info", GUI_INFO );
   
   
//
   
gui::IGUIToolBar * bar = GUI->addToolBar();
   
bar->setMinSize( dimension2du( screenWidth, 48 ) );
   
IGUIButton * water = bar->addButton( BAR_BUTTON_WATER, 0, L"water", driver->getTexture( "Media/GUI/water.png" ), 0, false, true );
   
IGUIButton * sands = bar->addButton( BAR_BUTTON_SANDS, 0, L"sands", driver->getTexture( "Media/GUI/sands.png" ), 0, false, true );
   
IGUIButton * grass = bar->addButton( BAR_BUTTON_GRASS, 0, L"grass", driver->getTexture( "Media/GUI/grass.png" ), 0, false, true );
   
IGUIButton * rocks = bar->addButton( BAR_BUTTON_ROCKS, 0, L"rocks", driver->getTexture( "Media/GUI/rocks.png" ), 0, false, true );
   
IGUIButton * highlands = bar->addButton( BAR_BUTTON_HIGHLANDS, 0, L"highlands", driver->getTexture( "Media/GUI/highlands.png" ), 0, false, true );
   
IGUIButton * darkness = bar->addButton( BAR_BUTTON_DARKNESS, 0, L"darkness", driver->getTexture( "Media/GUI/darkness.png" ), 0, false, true );
   
   
// LOAD THE "TW Editor Logo"
   
TWTexture = driver->getTexture( "Media/TW.png" );
   
   
// ADD CAMERA
   
cam_x = 0;
   
cam_y = 100;
   
cam_z = - 40;
   
   
ICameraSceneNode * cam = sceneManager->addCameraSceneNode( 0, vector3df( cam_x, 30, cam_z ), vector3df( 0, 5, 0 ) );
   
cam->setTarget( vector3df( cam_x, cam_y, cam_z ) );
   
cam->setUpVector( vector3df( cam_x, cam_y, cam_z ) );
   
   
// CURSOR IS HIDDEN
   
device->getCursorControl()->setVisible( true );
   
   
// LOAD THE MODEL
   
modelMesh = sceneManager->getMesh( modelPathfile.c_str() );
   
if( !modelMesh )
       
 device->drop();
   
   
   
animModel1 = sceneManager->addAnimatedMeshSceneNode( modelMesh ); // Add Model1
   
animModel1->setScale( vector3df( 10, 10, 10 ) );
   
animModel1->setPosition( vector3df( hexToGlobalX( 0, 0 ), 0, hexToGlobalZ( 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 = sceneManager->addAnimatedMeshSceneNode( modelMesh ); // Add Model2
   
animModel2->setScale( vector3df( 10, 10, 10 ) );
   
animModel2->setPosition( vector3df( hexToGlobalX( 3, 4 ), 0, hexToGlobalZ( 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 = sceneManager->addAnimatedMeshSceneNode( modelMesh ); // Add Model3
   
animModel3->setScale( vector3df( 10, 10, 10 ) );
   
animModel3->setPosition( vector3df( hexToGlobalX( 7, 5 ), 0, hexToGlobalZ( 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() ) );
   
   
// Create HexMap
   
HexMap * hexMap = new HexMap();
   
   
for( int z = 0; z < 40; z++ )
   
{
       
for( int x = 0; x < 40; x++ )
       
{
           
HexTile * tile = new HexTile( sceneManager->getRootSceneNode(), sceneManager, - 1 );
           
           
tile->setPosition( vector3df( hexToGlobalX( x, z ), 0, hexToGlobalZ( z ) ) );
           
           
hexMap->addTile( tile );
       
}
    }
   
   
// MAIN "TW Editor" LOOP
   
while( device->run() )
   
{
       
if( device->isWindowActive() )
       
{
           
           
// UPDATE
           
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;
           
           
           
cam->setPosition( vector3df( cam_x, cam_y, cam_z ) );
           
cam->setTarget( vector3df( cam_x, 30, cam_z + 50 ) );
           
           
// RENDER
           
driver->beginScene( true, true, SColor( clear_a, clear_r, clear_g, clear_b ) ); // clear screen
           
sceneManager->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.1", 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-180840
DejaVu
» 2024-02-19 21:45:27
Zapisz sobie w zmiennej 'jaki jest aktualny pędzel'. Najprostszym przykładem jest Paint. Odpal go sobie, kliknij na kolor. Widzisz jaki jest aktywny kolor (osobna zmienna), a gdy klikasz myszką na obszarze rysowania to używany jest ten kolor.
P-180845
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-19 21:48:31
Tą pierwszą część zrobiłem. A tą drugą .. to nie mam pojęcia jak odczytać naduszone pole.

C/C++
// ...
terrainType paint = terrainType::grass;
// ...
P-180846
DejaVu
» 2024-02-19 21:54:52
Zmienna nie powinna być lokalna, tylko 'globalna', abyś mógł się do niej jakoś dostać z innego miejsca niż przycisk.
P-180848
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-19 21:56:57
Przecież jest globalna.
P-180849
DejaVu
» 2024-02-19 22:21:10
Chodzi Ci o identyfikację, które pole na mapie zostało kliknięte, aby je zmienić? Musisz zobaczyć jak się nazywa metoda w Irrlicht, która umożliwia Ci identyfikację punktu nad którym znajduje się kursor myszy (jeżeli jest taka metoda). To są problemy, które dochodzą z perspektywą. ChatGPT:

W Irrlicht Engine istnieje funkcjonalność, która pozwala na obliczenie promienia (ray) od kamery do punktu wskazywanego przez kursor myszy. Możesz wykorzystać tę funkcję do wykrywania, na które pole kafelkowej mapy terenu wskazuje kursor, nawet jeśli kamera jest ustawiona pod kątem. Proces ten, znany jako "ray casting", jest często używany do interakcji z obiektami 3D w scenie.

Oto kroki, jak to zrobić:

1. Oblicz Promień od Kamery do Kursora
Musisz przekształcić pozycję kursora myszy na ekranie do przestrzeni 3D, tworząc promień (ray) wychodzący z kamery.

C/C++
core::line3d < f32 > calculateRayFromScreenCoordinates( const core::position2d < s32 > & mousePos, ISceneManager * smgr ) {
   
// Zamień pozycję kursora myszy na współrzędne na ekranie na promień w przestrzeni 3D
   
const scene::ICameraSceneNode * camera = smgr->getActiveCamera();
   
core::line3d < f32 > ray;
   
if( camera ) {
       
ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( mousePos, camera );
   
}
   
return ray;
}
2. Wykryj Kolizję Promienia z Terenem
Następnie, użyj wyliczonego promienia do znalezienia punktu na terenie, w który promień się wbija. Irrlicht posiada narzędzia do detekcji kolizji, które możesz wykorzystać do tego celu.

C/C++
core::vector3df getIntersectionWithTerrain( const core::line3d < f32 > & ray, ISceneManager * smgr ) {
   
core::vector3df intersection;
   
core::triangle3df hitTriangle;
   
   
scene::ISceneNode * terrainNode = smgr->getSceneNodeFromType( scene::ESNT_TERRAIN );
   
scene::ITriangleSelector * selector = 0;
   
   
if( terrainNode ) {
       
selector = smgr->createTriangleSelectorFromBoundingBox( terrainNode );
   
}
   
   
if( selector ) {
       
scene::ISceneCollisionManager * collMan = smgr->getSceneCollisionManager();
       
if( collMan->getCollisionPoint( ray, selector, intersection, hitTriangle, terrainNode ) ) {
           
// Punkt przecięcia został znaleziony
           
selector->drop(); // Nie zapomnij zwolnić selektora
           
return intersection;
       
}
       
selector->drop(); // Nie zapomnij zwolnić selektora
   
}
   
return core::vector3df( 0, 0, 0 ); // Zwróć domyślny wektor, jeśli nie ma kolizji
}
3. Przelicz Punkt Przecięcia na Koordynaty Kafelka
Po znalezieniu punktu przecięcia na terenie, musisz przeliczyć ten punkt 3D na koordynaty twojej kafelkowej mapy. To wymaga znajomości rozmiaru kafelków i struktury mapy.

C/C++
core::vector2di convert3DPositionToTileCoordinates( const core::vector3df & position, f32 tileSize ) {
   
int x =( int ) floor( position.X / tileSize );
   
int z =( int ) floor( position.Z / tileSize );
   
return core::vector2di( x, z );
}
Przykładowe Użycie
C/C++
void update() {
   
ISceneManager * smgr = device->getSceneManager();
   
IVideoDriver * driver = device->getVideoDriver();
   
   
core::position2d < s32 > mousePos = device->getCursorControl()->getPosition();
   
core::line3d < f32 > ray = calculateRayFromScreenCoordinates( mousePos, smgr );
   
core::vector3df intersection = getIntersectionWithTerrain( ray, smgr );
   
core::vector2di tileCoords = convert3DPositionToTileCoordinates( intersection, TILE_SIZE );
   
   
// Teraz masz koordynaty kafelka, na który wskazuje kursor
}
Warto zauważyć, że potrzebujesz znać TILE_SIZE, czyli rozmiar kafelka na twojej mapie, aby prawidłowo przeliczyć pozycję 3D na koordynaty kafelka.

Podsumowując, używając funkcji detekcji kolizji Irrlichta i odpowiednich przeliczeń, możesz wykryć, na który kafel kursor myszy wskazuje, nawet jeśli kamera jest pod kątem.
P-180851
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-20 14:58:15
nie zadziałało niestety :-/  wypisuje mi tileCoords jako [0,0]

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

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<set>
#include<vector>

// 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.
int cam_x, cam_y, cam_z;

// 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;

// 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;


// Buttons ID's
enum
{
   
// World
   
GUI_CREATEWORLD, GUI_LOADWORLD, GUI_SAVEWORLD, GUI_GENERATEWORLD,
   
   
// Help
   
GUI_TUTORIAL, GUI_INFO,
   
   
// bar
   
BAR_BUTTON_WATER, BAR_BUTTON_SANDS, BAR_BUTTON_GRASS, BAR_BUTTON_ROCKS, BAR_BUTTON_HIGHLANDS, BAR_BUTTON_DARKNESS
};

float outerRadius = 10.0f;
float innerRadius = outerRadius * 0.866025404f;
float heighStep = 0.8f;

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
};

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

float hexToGlobalX( float x, float z )
{
   
return x * 2.0f * innerRadius +( int( z ) % 2 ) * innerRadius;
}

float hexToGlobalZ( float z )
{
   
return z * 1.5f * outerRadius;
}

enum class terrainType { water, sands, grass, rocks, highlands, darkness };

terrainType paint = terrainType::grass;

ITexture * getTexture( terrainType ttype )
{
   
ITexture * tex = 0;
   
   
if( ttype == terrainType::water )
       
 tex = driver->getTexture( "Media/Terrains/water.png" );
   
   
if( ttype == terrainType::sands )
       
 tex = driver->getTexture( "Media/Terrains/sands.png" );
   
   
if( ttype == terrainType::grass )
       
 tex = driver->getTexture( "Media/Terrains/grass.png" );
   
   
if( ttype == terrainType::rocks )
       
 tex = driver->getTexture( "Media/Terrains/rocks.png" );
   
   
if( ttype == terrainType::highlands )
       
 tex = driver->getTexture( "Media/Terrains/highlands.png" );
   
   
if( ttype == terrainType::darkness )
       
 tex = driver->getTexture( "Media/Terrains/darkness.png" );
   
   
return tex;
}

class HexTile
    : public scene::ISceneNode
{
   
   
aabbox3d < f32 > Box;
   
S3DVertex Vertices[ 8 ];
   
SMaterial Material;
   
   
public:
   
terrainType ttype;
   
   
HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id );
   
virtual void OnRegisterSceneNode();
   
virtual void render();
   
virtual const aabbox3d < f32 > & getBoundingBox() const;
   
virtual u32 getMaterialCount() const;
   
virtual SMaterial & getMaterial( u32 i );
   
void setTexture( ITexture * );
   
void setTerrainType( terrainType );
};

HexTile::HexTile( ISceneNode * parent, ISceneManager * smgr, s32 id )
    :
ISceneNode( parent, smgr, id )
{
   
ttype = terrainType::grass;
   
   
/////////////////////////////////////////////////
   
Material.Wireframe = false;
   
Material.Lighting = false;
   
Material.setTexture( 0, getTexture( ttype ) );
   
   
SColor color = SColor( 255, 255, 255, 255 );
   
   
// vertices of hexagons
   
for( int i = 0; i < 7; i++ )
       
 Vertices[ i + 1 ] = S3DVertex( hexVertices[ 2 * i ], 0.0f, hexVertices[ 2 * i + 1 ], 0, 0, 0, color, texture_uv[ 2 * i ], texture_uv[ 2 * i + 1 ] );
   
   
Box.reset( Vertices[ 0 ].Pos );
   
for( s32 i = 1; i < 7; ++i )
       
 Box.addInternalPoint( Vertices[ i ].Pos );
   
}

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

void HexTile::render()
{
   
u16 indices[ ] = { 0, 1, 2, /**/ 0, 2, 3, /**/ 0, 3, 4, /**/ 0, 4, 5, /**/ 0, 5, 6, /**/ 0, 6, 7 };
   
IVideoDriver * driver = smgr->getVideoDriver();
   
driver->setMaterial( Material );
   
driver->setTransform( video::ETS_WORLD, AbsoluteTransformation );
   
driver->drawVertexPrimitiveList( & Vertices[ 0 ], 3, & indices[ 0 ], 6, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT );
   
}

const aabbox3d < f32 > & HexTile::getBoundingBox() const
{
   
return Box;
}

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

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

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

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

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

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 );
   
}

HexMap * hexMap;

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()
{
   
std::cout << "created new world" << std::endl;
   
thisIsNotBuildYet();
}

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

void saveWorld()
{
   
std::cout << "save world" << std::endl;
   
thisIsNotBuildYet();
}

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 )
{
   
// 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 )
               
{
                   
paint = terrainType::water;
                   
hexMap->setTerrainType( paint );
                   
std::cout << "setted a water to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_SANDS )
               
{
                   
paint = terrainType::sands;
                   
hexMap->setTerrainType( paint );
                   
std::cout << "setted a sands to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_GRASS )
               
{
                   
paint = terrainType::grass;
                   
hexMap->setTerrainType( paint );
                   
std::cout << "setted a grass to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_ROCKS )
               
{
                   
paint = terrainType::rocks;
                   
hexMap->setTerrainType( paint );
                   
std::cout << "setted a rocks to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_HIGHLANDS )
               
{
                   
paint = terrainType::highlands;
                   
hexMap->setTerrainType( paint );
                   
std::cout << "setted a highlands to paint" << std::endl;
               
}
               
               
if( id == BAR_BUTTON_DARKNESS )
               
{
                   
paint = terrainType::darkness;
                   
hexMap->setTerrainType( paint );
                   
std::cout << "setted a darkness to paint" << std::endl;
               
}
            }
           
break;
           
           
default:
           
break;
       
}
    }
   
   
return false;
}

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

line3d < f32 > calculateRayFromScreenCoordinates( const position2d < s32 > & mousePos, ISceneManager * smgr )
{
   
// Zamień pozycję kursora myszy na współrzędne na ekranie na promień w przestrzeni 3D
   
ICameraSceneNode * camera = smgr->getActiveCamera();
   
line3d < f32 > ray;
   
if( camera ) {
       
ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( mousePos, camera );
   
}
   
return ray;
}

vector3df getIntersectionWithTerrain( const core::line3d < f32 > & ray, ISceneManager * smgr )
{
   
vector3df intersection;
   
triangle3df hitTriangle;
   
   
ISceneNode * terrainNode = smgr->getSceneNodeFromType( scene::ESNT_TERRAIN );
   
ITriangleSelector * selector = 0;
   
   
if( terrainNode ) {
       
selector = smgr->createTriangleSelectorFromBoundingBox( terrainNode );
   
}
   
   
if( selector ) {
       
scene::ISceneCollisionManager * collMan = smgr->getSceneCollisionManager();
       
if( collMan->getCollisionPoint( ray, selector, intersection, hitTriangle, terrainNode ) ) {
           
// Punkt przecięcia został znaleziony
           
selector->drop(); // Nie zapomnij zwolnić selektora
           
return intersection;
       
}
       
selector->drop(); // Nie zapomnij zwolnić selektora
   
}
   
return vector3df( 0, 0, 0 ); // Zwróć domyślny wektor, jeśli nie ma kolizji
}

vector2di convert3DPositionToTileCoordinates( const core::vector3df & position, f32 tileSize )
{
   
int x =( int ) floor( position.X / tileSize );
   
int z =( int ) floor( position.Z / tileSize );
   
return vector2di( x, z );
}

int main()
{
   
MyEventReceiver receiver;
   
// CREATE DEVICE ( OpenGL )
   
device = createDevice( EDT_SOFTWARE, 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
   
   
    // STYLES FOR GUI
   
IGUISkin * GUIskin = GUI->getSkin();
   
GUIskin->setFont( boldFont );
   
   
for( s32 i = 0; i < gui::EGDC_COUNT; ++i )
   
{
       
GUIskin->setColor(( EGUI_DEFAULT_COLOR ) i, SColor( 255, 96, 96, 96 ) ); // coloring the Background
       
GUIskin->setColor( EGDC_BUTTON_TEXT, SColor( 255, 224, 224, 224 ) ); // coloring the Text
       
GUIskin->setColor( EGDC_HIGH_LIGHT_TEXT, SColor( 255, 128, 48, 48 ) ); // coloring the Highlighed Text
   
}
   
   
// CREATE MAIN MENU
   
IGUIContextMenu * menu = GUI->addMenu();
   
menu->addItem( L"World", - 1, true, true );
   
menu->addItem( L"Help", - 1, true, true );
   
   
// Create World Menu
   
IGUIContextMenu * 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
   
IGUIContextMenu * helpMenu = menu->getSubMenu( 1 );
   
helpMenu->addItem( L"Tutorial", GUI_TUTORIAL );
   
helpMenu->addItem( L"Info", GUI_INFO );
   
   
//
   
gui::IGUIToolBar * bar = GUI->addToolBar();
   
bar->setMinSize( dimension2du( screenWidth, 48 ) );
   
IGUIButton * water = bar->addButton( BAR_BUTTON_WATER, 0, L"water", driver->getTexture( "Media/GUI/water.png" ), 0, false, true );
   
IGUIButton * sands = bar->addButton( BAR_BUTTON_SANDS, 0, L"sands", driver->getTexture( "Media/GUI/sands.png" ), 0, false, true );
   
IGUIButton * grass = bar->addButton( BAR_BUTTON_GRASS, 0, L"grass", driver->getTexture( "Media/GUI/grass.png" ), 0, false, true );
   
IGUIButton * rocks = bar->addButton( BAR_BUTTON_ROCKS, 0, L"rocks", driver->getTexture( "Media/GUI/rocks.png" ), 0, false, true );
   
IGUIButton * highlands = bar->addButton( BAR_BUTTON_HIGHLANDS, 0, L"highlands", driver->getTexture( "Media/GUI/highlands.png" ), 0, false, true );
   
IGUIButton * darkness = bar->addButton( BAR_BUTTON_DARKNESS, 0, L"darkness", driver->getTexture( "Media/GUI/darkness.png" ), 0, false, true );
   
   
// LOAD THE "TW Editor Logo"
   
TWTexture = driver->getTexture( "Media/TW.png" );
   
   
// ADD CAMERA
   
cam_x = 0;
   
cam_y = 100;
   
cam_z = - 40;
   
   
ICameraSceneNode * 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();
   
   
   
animModel1 = smgr->addAnimatedMeshSceneNode( modelMesh ); // Add Model1
   
animModel1->setScale( vector3df( 10, 10, 10 ) );
   
animModel1->setPosition( vector3df( hexToGlobalX( 0, 0 ), 0, hexToGlobalZ( 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( vector3df( hexToGlobalX( 3, 4 ), 0, hexToGlobalZ( 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( vector3df( hexToGlobalX( 7, 5 ), 0, hexToGlobalZ( 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() ) );
   
   
// Create HexMap
   
hexMap = new HexMap();
   
for( int z = 0; z < 60; z++ )
   
{
       
for( int x = 0; x < 60; x++ )
       
{
           
HexTile * tile = new HexTile( smgr->getRootSceneNode(), smgr, - 1 );
           
tile->setPosition( vector3df( hexToGlobalX( x, z ), 0, hexToGlobalZ( z ) ) );
           
hexMap->addTile( tile );
       
}
    }
   
   
// MAIN "TW 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 -= 2.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_D ) || receiver.IsKeyDown( irr::KEY_RIGHT ) ) cam_x += 2.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_W ) || receiver.IsKeyDown( irr::KEY_UP ) ) cam_z += 2.0f;
           
           
if( receiver.IsKeyDown( irr::KEY_KEY_S ) || receiver.IsKeyDown( irr::KEY_DOWN ) ) cam_z -= 2.0f;
           
           
// UPDATE
           
cam->setPosition( vector3df( cam_x, cam_y, cam_z ) );
           
cam->setTarget( vector3df( cam_x, 30, cam_z + 50 ) );
           
           
position2d < s32 > mousePos = device->getCursorControl()->getPosition();
           
std::cout << mousePos.X << "," << mousePos.Y << std::endl;
           
line3d < f32 > ray = calculateRayFromScreenCoordinates( mousePos, smgr );
           
vector3df intersection = getIntersectionWithTerrain( ray, smgr );
           
vector2di tileCoords = convert3DPositionToTileCoordinates( intersection, 100 );
           
std::cout << tileCoords.X << ", " << tileCoords.Y << std::endl << std::endl;
           
           
// 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.1", 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-180856
DejaVu
» 2024-02-20 19:59:04
No to sprawdź w kursach Irrlichta na oficjalnej stronie - zapewne tam jest pokazane jak to osiągnąć. Wiesz przynajmniej czego szukać.
P-180857
« 1 » 2
  Strona 1 z 2 Następna strona