Ray casting and tiles

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

Before doing any collisions. createTriangleSelector creates the collision geometery (triangles for your mesh polygons) which is needed for checking collisions later.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

done

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;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

OK, cool :)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

no no. not done yet.
Now I need to add a collision and I have no idea how to do it.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

What is colliding and what's the collision supposed to do?
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

Collision mouse cursor with hexTile and then texture of hexTile changed
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

Didn't the code you have already return the tile? As in selectedSceneNode should be one of your tiles?
Changing texture is done via the material. You seem to know quite a bit programming, so I guess you'll figure it out. I have to sleep.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

no, I'm not good. the collision I wrote doesn't work.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

You seem to set ray-end to some other values. Don't do that.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

ok, done. I think I'm calculating the ray incorrectly

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
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

Hm, ray looks good to me (if your cursor is in the middle then ray.start should be pretty close to your camera position).

Do you call createTriangleSelector each frame? It should only be set once - after creating the nodes. Thought it should still work (just massive memory leak and slow). Also drop the selector after setTriangleSelector (always needed if you created it with a function starting with name "create" if you don't use the pointer yourself anymore). Again not causing the bug, but memory leak.

tile->getMesh does return your mesh?
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

ray.start has a value like camera.
ok added selector drop.
yes, tile->getMesh() return the mesh of the hexTile.

now main.cpp :

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;
}
Last edited by tBane on Thu Feb 22, 2024 4:51 pm, edited 1 time in total.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Ray casting and tiles

Post by CuteAlien »

I don't see anything wrong. Did you check if it actually goes in the loop with hexMap->tiles? So you don't accidentally have an empty copy of that variable or something like that?

edit: Minor side-note unrelated to your problem: You are not working with opengl, but the simplest software renderer - don't use that one for rendering anything real (it's fine for 2d UI and some simple stuff). Pass EDT_OPENGL in createDevice for using opengl
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

Everything works. Thank you very much for help :-)
tBane
Posts: 33
Joined: Wed Feb 21, 2024 2:25 pm
Location: Poland

Re: Ray casting and tiles

Post by tBane »

Hi. I have a next problem. I work with this mesh and I would like highlighting hexTiles. I use this but but not work:

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