Re: Ray casting and tiles
Posted: Wed Feb 21, 2024 10:22 pm
Before doing any collisions. createTriangleSelector creates the collision geometery (triangles for your mesh polygons) which is needed for checking collisions later.
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
Code: Select all
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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
position2d < s32 > mousePos = device->getCursorControl()->getPosition();
cout << "mouse position: " << mousePos.X << ", " << mousePos.Y<<endl;
// TRIANGLE SELECTOR
ITriangleSelector* selector;
for (auto& tile : hexMap->tiles)
{
selector = smgr->createTriangleSelector(tile->getMesh(), tile);
tile->setTriangleSelector(selector);
}
// CALCULATE THE RAY TO COLLISION
core::line3d<f32> ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(mousePos, cam);
cout << "ray start: " << ray.start.X << ", " << ray.start.Y << ", " << ray.start.Z << endl;
ray.end.X = 0;
ray.end.Y = -10;
ray.end.Z = 0;
cout << "ray end: " << ray.end.X << ", " << ray.end.Y << ", " << ray.end.Z << endl;
core::vector3df intersection;
core::triangle3df hitTriangle;
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
if (collMan != nullptr)
cout << "collMan ok "<<endl;
else
cout << "collMaan is nullptr "<<endl;
scene::ISceneNode* selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay( ray, intersection, hitTriangle);
if (selectedSceneNode != nullptr)
cout << "collision node position: " << selectedSceneNode->getPosition().X << ", " << selectedSceneNode->getPosition().Y << endl;
else
cout << "collision node is null\n";
cout << endl;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Code: Select all
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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
position2d < s32 > mousePos = device->getCursorControl()->getPosition();
cout << "mouse position: " << mousePos.X << ", " << mousePos.Y<<endl;
// TRIANGLE SELECTOR
ITriangleSelector* selector;
for (auto& tile : hexMap->tiles)
{
selector = smgr->createTriangleSelector(tile->getMesh(), tile);
tile->setTriangleSelector(selector);
}
// CALCULATE THE RAY TO COLLISION
core::line3d<f32> ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(mousePos, cam);
cout << "ray start: " << ray.start.X << ", " << ray.start.Y << ", " << ray.start.Z << endl;
cout << "ray end: " << ray.end.X << ", " << ray.end.Y << ", " << ray.end.Z << endl;
core::vector3df intersection;
core::triangle3df hitTriangle;
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
if (collMan != nullptr)
cout << "collMan ok "<<endl;
else
cout << "collMaan is nullptr "<<endl;
scene::ISceneNode* selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay( ray, intersection, hitTriangle);
if (selectedSceneNode != nullptr)
cout << "collision node position: " << selectedSceneNode->getPosition().X << ", " << selectedSceneNode->getPosition().Y << endl;
else
cout << "collision node is null\n";
cout << endl;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Code: Select all
mouse position: 264, 211
ray start: 0, 30, -40
ray end: -1671.13, 902.167, 3000.14
collMan ok
collision node is null
mouse position: 265, 211
ray start: 0, 100, -40
ray end: -1665.15, -1817.04, 2438.17
collMan ok
collision node is null
mouse position: 265, 211
ray start: 0, 100, -40
ray end: -1665.15, -1817.04, 2438.17
collMan ok
collision node is null
Code: Select all
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
loadTextures();
setTheStylesForGUI();
createGUI();
// 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();
createHexMap();
// ADDING TRIANGLE SELECTOR TO MAP
ITriangleSelector* selector;
for (auto& tile : hexMap->tiles)
{
selector = smgr->createTriangleSelector(tile->getMesh(), tile);
tile->setTriangleSelector(selector);
selector->drop();
}
// 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 -= 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
position2d < s32 > mousePos = device->getCursorControl()->getPosition();
cout << "mouse position: " << mousePos.X << ", " << mousePos.Y<<endl;
// CALCULATE THE RAY TO COLLISION
core::line3d<f32> ray = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(mousePos, cam);
cout << "ray start: " << ray.start.X << ", " << ray.start.Y << ", " << ray.start.Z << endl;
cout << "ray end: " << ray.end.X << ", " << ray.end.Y << ", " << ray.end.Z << endl;
// COLLISION
core::vector3df intersection;
core::triangle3df hitTriangle;
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
if (collMan != nullptr)
cout << "collMan ok "<<endl;
else
cout << "collMaan is nullptr "<<endl;
scene::ISceneNode* selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay( ray, intersection, hitTriangle);
if (selectedSceneNode != nullptr)
cout << "collision node position: " << selectedSceneNode->getPosition().X << ", " << selectedSceneNode->getPosition().Z << endl;
else
cout << "collision node is null\n";
cout << 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;
}
Code: Select all
if (selectedSceneNode != nullptr)
{
vector2di tilePos = globalToHex(selectedSceneNode->getPosition().X, selectedSceneNode->getPosition().Z);
for (auto& t : highlightedHexTiles)
t->meshBuffer->Material.Lighting = false;
highlightedHexTiles.clear();
getNeighbours(highlightedHexTiles, hexMap->getHexTile(tilePos.X, tilePos.Y), brushSize);
for (auto& t : highlightedHexTiles)
t->meshBuffer->Material.Lighting = true;
}