position of a vertex in a meshwhich is hovered by mouse

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
FreeFrags
Posts: 16
Joined: Thu Mar 25, 2010 2:04 pm

position of a vertex in a meshwhich is hovered by mouse

Post by FreeFrags »

Hi

Im trying to get the position of a vertex in a mesh buffer which is hovered by the mouse.

I tried the following code:

Code: Select all

		irr::scene::ISceneNode* node = m_smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(m_device->getCursorControl()->getPosition());
		if(node != NULL)
		{
			irr::core::vector3df pos = node->getAbsolutePosition();
			TRACE("coordinates mouse: x: %d y: %d z: %d \n", pos.X, pos.Y, pos.Z);		
		}
This however doesn't work. I read that there is also a function:

Code: Select all

getSceneNodeFromRayBB()
But if i understand correctly this function would give the same result as getSceneNodeFromScreenCoordinatesBB() but i would have to provide this function with a ray which originates from the mouse cursor?

Can some one help me in the right direction?
FreeFrags
Posts: 16
Joined: Thu Mar 25, 2010 2:04 pm

Post by FreeFrags »

Hi

I did another attempt to solve my problem. I found that the collision example is almost doing the same thing. so i tried implementing that code. unfortunately im still doing something wrong.

Code: Select all

irr::scene::IMeshSceneNode* meshSceneNode = m_smgr->addMeshSceneNode(pMesh);
				
irr::scene::ITriangleSelector* selector = m_smgr->createTriangleSelector(pMesh ,meshSceneNode);
meshSceneNode->setTriangleSelector(selector);
selector->drop();

// Tracks the current intersection point with the level or a mesh
		irr::core::vector3df intersection;
		// Used to show with triangle has been hit
		irr::core::triangle3df hitTriangle;
		irr::core::vector2d<irr::s32> mousePosition = m_device->getCursorControl()->getPosition();

		irr::core::line3d<irr::f32> ray = m_smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(mousePosition, m_smgr->getActiveCamera()); 

irr::scene::ISceneNode * selectedSceneNode =
			m_smgr->getSceneCollisionManager()->getSceneNodeAndCollisionPointFromRay(
					ray,
					intersection, 
					hitTriangle,
					0, 			
					0); 
		
if(selectedSceneNode != NULL)
{
	//irr::core::vector3df pos = node->getAbsolutePosition();
	TRACE("coordinates mouse: x: %d y: %d z: %d \n", intersection.X, intersection.Y, intersection.Z);		
}
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

FreeFrags
Posts: 16
Joined: Thu Mar 25, 2010 2:04 pm

Post by FreeFrags »

Yet another attempt :smile:

I cant seem to get the result i would expect. I would expect when hovering the first added point the coordinate 0,0,0 would be traced.

I noticed the code in the topic linked above uses a animated mesh but this isnt the problem is it?

let me show you what i have so far

Adding data:

Code: Select all

void AddDataIrrlicht()
{
	//return;
	irr::video::SMaterial Material; 
	Material.Lighting = false; 
	Material.Wireframe = false; 
	Material.PointCloud = true; 
	Material.Thickness = 5;
	
	irr::scene::SMesh* smesh = new irr::scene::SMesh(); 

	const unsigned int numberOfPoints = 50000; 
	for(int id = 0; id < 40; id++) 
	{ 
	  irr::scene::SMeshBuffer *buffer = new irr::scene::SMeshBuffer(); 
	  buffer->Material = Material; 
	  buffer->Vertices.reallocate(numberOfPoints);

	  for(int pointCounter = 0; pointCounter < numberOfPoints; ++pointCounter) 
	  { 
		  irr::video::S3DVertex pointVertex = irr::video::S3DVertex(pointCounter, 0, id, 
																	0, 0, -1, 
																	irr::video::SColor(255,0,0,0), 
																	0, 1); 
		 buffer->Vertices.push_back(pointVertex); 

		 buffer->Indices.push_back(id * pointCounter + pointCounter -1); 
	  }
	  buffer->recalculateBoundingBox();
	  smesh->addMeshBuffer(buffer); 
	}

	smesh->recalculateBoundingBox();
	//EHM_STREAM
	smesh->setHardwareMappingHint(irr::scene::EHM_STATIC, irr::scene::EBT_VERTEX_AND_INDEX); 
	
	m_smgr->addMeshSceneNode(smesh); 
}
Collision detection:

Code: Select all

while(m_device->run())
	{
		irr::core::position2di initialCursorPosition; 
		irr::core::position2di initialObjectPosition;

		irr::scene::ISceneNode* SelectedNode = m_smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(m_device->getCursorControl()->getPosition(),0,false); 

		//If we selected a node 
		if(SelectedNode) 
		{ 
			irr::core::plane3df const planeXZ(SelectedNode->getAbsolutePosition(), irr::core::vector3df(0.f, 1.f, 0.f)); 
			irr::core::position2di currentCursorPosition(m_device->getCursorControl()->getPosition()); 
			irr::core::line3df ray(m_smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(currentCursorPosition, m_smgr->getActiveCamera())); 
			irr::core::vector3df intersectWithPlane; 
			
			if(planeXZ.getIntersectionWithLine(ray.start, ray.getVector(), intersectWithPlane)) 
			{ 
				TRACE("Object pos: %d %d %d \n", intersectWithPlane.X, intersectWithPlane.Y, intersectWithPlane.Z);
			} 
		} 

		m_driver->beginScene(true, true, irr::video::SColor(255,200,200,200));
		m_smgr->drawAll(); 
		m_driver->endScene(); 	
	}
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

if you copy / paste the code from that link and compile it, does it run? and if so, does it do what you need?

also, TRACE("Object pos: %d %d %d \n", intersectWithPlane.X, intersectWithPlane.Y, intersectWithPlane.Z); should be floats
blAaarg
Posts: 94
Joined: Tue Mar 02, 2010 9:11 pm
Location: SoCal

Post by blAaarg »

This is something like what I was eventually going to try myself, casting a ray through a mesh to find specific vertices. I haven't quite started so hopefully someone can help with this before too long.:)

If I'm correct, the points returned by the getIntersection/Collision functions are position vectors and not vertices. Also, I think triangle selectors only work with meshes that have triangles and the mesh you built isn't constructed to have them. I don't know if that was just for testing purposes or if that's the kind of structure you eventually plan on using so I'm not sure what to suggest.

The intersection with plane should work though! But, again, it's only going to give you a position in space that isn't necessarily on a vertex. Finding vertices or specific points in world space is hard because the rays that come from the screen are built from integers that translate into floating point space. This makes you miss a lot of points in space that fall in between the rays cast by adjacent pixels. Your vertices might be hiding in those points. And on a perspective cam, the problem gets worse as you get closer to the far part of the frustum. I've been trying to think of a way around this myself. :?

In your case, maybe you could interpolate or even just round off the collision point to find which vertex was the closest and then decide if the ray was close enough to count as a hit? :roll: :?: But if the user starts moving the vertices around that becomes a problem...
:(
"Computers don't make mistakes! What they do they do on purpose!!"

-Dale Gribble
FreeFrags
Posts: 16
Joined: Thu Mar 25, 2010 2:04 pm

Post by FreeFrags »

Seven:
- yes the code posted in the other post compiles
- It however does much more than i need

all i want to do is determine the position of the vertex om the screen. my goal is not to move the vertex. i just want to display the position and maybe give the hovered vertex a different color.

blAaarg:
- The mesh i created doesnt contain vertexbuffers with triangles. only 1 row of points.
- so i guess the triangleselectors wont be able to help us out here.
- but like you said finding the closest point to the collision point is what i need.
- how ever the code i pasted above doesnt even give me realistic collision points

The collisions i get from this code are greater than 1000 even if i change numberOfPoints to 10 so it draws a rectangle of points 10 X 40.

This way i would expect the intersection point never to have a coordinate greater than 40. as these points are all drawn from the origin 0,0,0
FreeFrags
Posts: 16
Joined: Thu Mar 25, 2010 2:04 pm

Post by FreeFrags »

Changed my TRACE:

Code: Select all

TRACE("Object pos: %lf %lf %lf \n", intersectWithPlane.X, intersectWithPlane.Y, intersectWithPlane.Z);
I now get coordinates which seem plausible. But i realized when i zoom out the returned collision point changes. I think the coordinates are now relative to my camera? i just want the coordinate in space.
Post Reply