[help] ray scene query

ryak2002

12-10-2006 22:08:34

EDIT: Appearently, setting the plain mask to 4 makes it work. What exactly does the querytypemask do if it doesn't limit the results?

I'm trying to determine the point on the terrain where the user clicks and place a knot there. But the ray scene query is always wrongly returning a point directly below the camera and exactly 4 entity intersections. (why is it returning entities anyway with the world geometry mask?)

The ray is always pointed in the correct direction. In fact, the location returned isn't even on the ray.


mRaySceneQuery = mSceneMgr->createRayQuery( Ray() );
mRaySceneQuery->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
mRaySceneQuery->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION);



// Setup the ray scene query
Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() );
mRaySceneQuery->setRay( mouseRay );

// Execute query
RaySceneQueryResult &result = mRaySceneQuery->execute();
RaySceneQueryResult::iterator itr = result.begin( );

// Get results, create a node/entity on the position
if ( itr != result.end() && itr->worldFragment )
{
char name[16];
sprintf( name, "Point%d", mCount++ );
Entity *ent = mSceneMgr->createEntity( name, "knot.mesh" );
mCurrentObject = mSceneMgr->getRootSceneNode( )->createChildSceneNode( String(name) + "Node", itr->worldFragment->singleIntersection );
mCurrentObject->attachObject( ent );
mCurrentObject->setScale( 0.1f, 0.1f, 0.1f );
mWalkList.push_back(String(name));
} // if

kungfoomasta

14-10-2006 08:22:06

You know, I never did quite understand why the tutorials use an if statement. Iterators usually iterate through some sort of container, so wouldn't it seem like a loop should be used? Anyhow, I will post my code, which seems to work. It's a .net app, and the mouse coordinates are given to me, which I use to create the query.


// Setup the ray scene query
System::Double mMouseXCoord = (MouseXPos / (System::Double)(this->RenderPanel->Width));
System::Double mMouseYCoord = (MouseYPos / (System::Double)(this->RenderPanel->Height));

Ogre::Camera* cam = mFreeFormCamera->getCamera();
Ogre::Ray mouseRay = cam->getCameraToViewportRay( mMouseXCoord, mMouseYCoord );
Ogre::RaySceneQuery* rsq = mSceneManager->createRayQuery(mouseRay);
rsq->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK);
rsq->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION);

// Execute query
Ogre::RaySceneQueryResult &result = rsq->execute();
Ogre::RaySceneQueryResult::iterator itr = result.begin();

while( itr != result.end() )
{
if(itr->worldFragment)
{
mSelectedEntity->setPosition(itr->worldFragment->singleIntersection);
break;
}

++itr;
}

delete rsq;


Hope this helps.

KungFoomasta

OvermindDL1

15-10-2006 11:01:36

Because there is no need to construct the loop test code when you are only testing where it hits the terrain first.

kungfoomasta

16-10-2006 05:08:36

well that's fine to leave it that way, but I prefer my method, which leaves room for other possibilities, and searches the entire list for the first listed terrain hit. :wink: It wasn't like I added tons more code.. and all ray scene queries I use will follow the same structure, regardless of what I'm looking for.

KungFooMasta

tuan kuranes

16-10-2006 10:55:32

@ryak2002 : your code should be working. Are you using latest PLSM2 ?
4 entity intersections. (why is it returning entities anyway with the world geometry mask?)
it should not do that using current plsm2 code that's why I suggest either old PLSM2 code (using its own flags) or scenequery setting flags elsewhere, or memory corruption, giving strange results.

@kungfoomasta: if you specify Ogre::SceneQuery::WFT_SINGLE_INTERSECTION it has to be a single result returned, no more.