Cant get ray collision/picks working

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!
Post Reply
d4nm4n
Posts: 33
Joined: Fri Oct 09, 2009 11:28 pm

Cant get ray collision/picks working

Post by d4nm4n »

Can anyone help with this? i have turned off things like cameras and have set a cube to "1<<2" and the pick ID to the same but the entity is always returned null.
I have even tried hardcoding a ray that intersects the cube and still no joy. What am i doing wrong?

Code: Select all

   bbEntity* ScreenPick (s32 x,s32 y,s32 id,bool includeDebugObjects)
    {
          scene::ISceneCollisionManager* collMan = irrSmgr->getSceneCollisionManager();
          //bbLine3d ray = collMan->getRayFromScreenCoordinates(irrDevice->getCursorControl()->getPosition());
          core::line3d<f32> ray;
                ray.start = bbVector3d(-100,0,-100);

                ray.end = bbVector3d(0,0,0);
            irrDriver->draw3DLine(ray.start,ray.end);
          bbVector3d intersection;
          bbTriangle hitTriangle;
         scene::ISceneNode * selectedSceneNode =  collMan->getSceneNodeAndCollisionPointFromRay(
                                        ray,
                                        intersection, // This will be the position of the collision
                                        hitTriangle, // This will be the triangle hit in the collision
                                        id, // This ensures that only nodes that we have
                                                        // set up to be pickable are considered
                                        0
                                        ,includeDebugObjects); // Check the entire scene (this is actually the implicit default)

                                        std::cout<<intersection.X;
            return (bbEntity*)selectedSceneNode;
    }
Memorial76
Posts: 103
Joined: Mon Aug 10, 2009 8:22 pm
Location: France

Post by Memorial76 »

I'm quite beginner with that but why don't you try the "getSceneNodeFromScreenCoordinatesBB()" function and make sure you call it each time you move your mouse.

I have this code that works:

Code: Select all

if( event.EventType == EET_MOUSE_INPUT_EVENT )
	{
			switch (event.MouseInput.Event)
			{
				case EMIE_MOUSE_MOVED:
				{
					//Récupere le sceneNode sous le curseur
					scene::ISceneNode* pHoveredSceneNode = m_pSceneMgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(
						m_pDevice->getCursorControl()->getPosition(),
						0,
						true,
						0);

					break;
				}
                       default:
				break;

			}//switch (event.MouseInput.Event)
	return false;
}
d4nm4n
Posts: 33
Joined: Fri Oct 09, 2009 11:28 pm

Post by d4nm4n »

Thanks for the reply, unfortunately I did try that one but it only works on bounding boxes which is not what i need.
Memorial76
Posts: 103
Joined: Mon Aug 10, 2009 8:22 pm
Location: France

Post by Memorial76 »

You are right,

My quesion ight seem stupid but: Are you sure to call your screenPick function each time you move youre mouse?
My Gui/Event receiver Architecture Pattern (GERAP):
http://irrgerap.sourceforge.net/

My Blog about my "ProjectOne"
http://memorial76-project-one.blogspot.fr/
d4nm4n
Posts: 33
Joined: Fri Oct 09, 2009 11:28 pm

Post by d4nm4n »

yes the screenpick is being called.

I have managed to pick up a node using getCollisionPoint instead but the end point of the ray returned from the screenCoords is 0,0,0.

However, when i look at the console out of the following it seems the ray is always from world 0 rather than a relative point XYZ in the distance of direction of view.

Here is the code:

Code: Select all

    bbEntity* ScreenPick (s32 x,s32 y,scene::ITriangleSelector* selector)
    {
          scene::ISceneCollisionManager* collMan = irrSmgr->getSceneCollisionManager();
          bbLine3d ray = collMan->getRayFromScreenCoordinates(bbPosition2d(x,y));
          std::cout << ray.start.X<<" "<<ray.end.X<<" ";
          std::cout << ray.start.Y<<" "<<ray.end.Y<<" ";
          std::cout << ray.start.Z<<" "<<ray.end.Z<<"\n";


         if (!selector) selector = irrGlobalSceneryMetaSelector;
          irr::core::vector3df intersection;
          irr::core::triangle3df hitTriangle;
         const scene::ISceneNode * selectedSceneNode=0;
         collMan->getCollisionPoint(  ray,
                                        selector,
                                        intersection,
                                        hitTriangle,
                                        selectedSceneNode);

            return (bbEntity*)selectedSceneNode;
    }
blAaarg
Posts: 94
Joined: Tue Mar 02, 2010 9:11 pm
Location: SoCal

Post by blAaarg »

It appears getRayFromScreenCoordinates() returns the camera's position as the ray.start member of the line3d it returns. The ray.end should be a position on the far frustum and those are the values this code is going to print out. Is your camera at the world origin 0?

Then your intersection and hitTriangle appear to be created local to the ScreenPick function and so they "evaporate" when it returns, leaving you with only an ISceneNode cast as a bbEntity pointer to work with. I'm not sure what that little guy's supposed to do but it doesn't appear to store those objects before returning, if that's what you're going for. :)
"Computers don't make mistakes! What they do they do on purpose!!"

-Dale Gribble
d4nm4n
Posts: 33
Joined: Fri Oct 09, 2009 11:28 pm

Post by d4nm4n »

bbEntity is a custom scenenode, and eventually i will need the other values, but mostly want node mesh specific picking from a screen position but nothing seems to work as i would expect.

This seems to work kind of but it is not right. The resulting node seems to jump between them, almost as if it is clipping them wrongly.

Code: Select all

         collMan->getCollisionPoint(  ray,
                                        selector,
                                        intersection,
                                        hitTriangle,
                                        selectedSceneNode);
std::cout<<selectedSceneNode<<'\n';
This seems a bit better but still not right, it also seems to be only using bounding boxes.

Code: Select all

            selectedSceneNode = collMan->getSceneNodeFromRayBB(ray,1<<2,true,0);
std::cout<<selectedSceneNode<<'\n';
This one doesnt seem to work at all.

Code: Select all

            selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay(
								ray,
								intersection,
								hitTriangle,
								1<<2,
								0,
								true);
            std::cout<<selectedSceneNode<<'\n';
d4nm4n
Posts: 33
Joined: Fri Oct 09, 2009 11:28 pm

Post by d4nm4n »

Solved it :D

The first ones of the above work but it has to be a precision mesh tri selector!. I was using octree!

(not quite sure what the point in the 3rd one is though it seems to do the same as the first.. except actually work :))
Post Reply