3D Picking and the Various Scene Managers

Problems building or running the engine, queries about how to use features etc.
Post Reply
Mdobele
Halfling
Posts: 55
Joined: Mon Jun 07, 2004 11:01 am
Contact:

3D Picking and the Various Scene Managers

Post by Mdobele »

I am attempting to do 3D picking of a Mesh Entity and have run into some problems.

First. Am I able to even use the RaySceneQuery method using the generic ST_GENERIC scene manager.

This is my picking method which was found from another forum post.

Code: Select all

// Start a new ray query 
	Ogre::Ray cameraRay = PrimedEngine::Instance().GetCamera()->getCameraToViewportRay( m_mouseX, m_mouseY ); 
	Ogre::RaySceneQuery *raySceneQuery = PrimedEngine::Instance().GetSceneManager()->createRayQuery( cameraRay ); 
	raySceneQuery->execute( ); 
	Ogre::RaySceneQueryResult result = raySceneQuery->getLastResults( ); 

	Ogre::MovableObject *closestObject = NULL; 
	float closestDistance = LONG_MAX; //used to be real

	std::list< Ogre::RaySceneQueryResultEntry >::iterator rayIterator; 

	for ( rayIterator = result.begin( ); rayIterator != result.end( ); rayIterator++ ) 
	{ 

		if ( ( *rayIterator ).distance < closestDistance ) 
		{ 
			closestObject = ( *rayIterator ).movable; 
			closestDistance = ( *rayIterator ).distance; 
		} 

	} 
	// No object clicked 
	if ( closestObject == NULL ) 
	{    
		PrimedEngine::Instance().GetRenderWindow()->setDebugText( "Nothing" );
	}
	else
	{ 
		Ogre::Entity *TestEntity = NULL;

		PrimedEngine::Instance().GetRenderWindow()->setDebugText( closestObject->getMovableType() );


		if(closestObject->getMovableType()=="Entity") 
		{ 
			TestEntity = (Entity *)closestObject; 
		}

	} 

	raySceneQuery->clearResults( ); 
	PrimedEngine::Instance().GetSceneManager( )->destroyQuery( raySceneQuery ); 
Problem is this ONLY ever returns a "SimpleRenderable" text no matter where i am looking.

When using ST_EXTERIOR_FAR or ST_EXTERIOR_REAL_FAR the picking method works and detects the entity but then I get a second problem where my CEGUI mouse pointer dissapers from the screen LOL.

I read that RaySceneQuery will only work with certain Scene Managers but Which Ones? I want to use the Generic one as it appears thats the best for the default Octree occlusion I want for all my meshes.

I am using 0.15.1 version of OGER. All i have in my scene is 1 ninja.mesh and thats it.
PrimedGames
www.PrimedGames.com

Email Me At
Mdobele( AT )primedgames.com
// Replace AT with @ of course
Mdobele
Halfling
Posts: 55
Joined: Mon Jun 07, 2004 11:01 am
Contact:

Post by Mdobele »

Hmmm i feel like an Idiot :D

My ray was too close and I was picking up the Mouse Cursor. LOL
Its all good now. Thanks to Kojack for his help finding that out.

So for anyone interested I just ignore the close stuff.

Code: Select all

if ( ( *rayIterator ).distance < closestDistance && ( rayIterator ).distance > 0.1f )
PrimedGames
www.PrimedGames.com

Email Me At
Mdobele( AT )primedgames.com
// Replace AT with @ of course
McSwan
Greenskin
Posts: 122
Joined: Tue May 11, 2004 5:40 am
x 1

Post by McSwan »

Hi,

Your code works fine - but I'm having issues with particle effects. It can select the particle effects, but it crashes on occassion when I click the mouse.

The reason I believe is that I'm deleting the particle effects. Or could it be onCreation of the effects?
I think aabb aren;t made until a scenemanager render?

I'm using ogre 15.0.

It crashes on an assert Here.

Code: Select all

inline const Vector3* getAllCorners(void) const
	    {
		    assert( !mNull && "Can't get corners of a null AAB" );
		    return (const Vector3*)mCorners;
	    }
I fairly sure I'm deleing my particle effects properly:

Code: Select all

// Creates a particle effect
// Todo - move to the init function.
bool ParticleEffect::Init(String aEffectName, String aIdentifier, Ogre::String aLuaClassName,
                          ObjectBase *aParent)
{
	 m_pSys = ParticleSystemManager::getSingleton().createSystem(
		aIdentifier, aEffectName);

   //Hack to fix a selection bug ?
  m_pSys->setQueryFlags(0);


  if (aParent == NULL)
  {
  	SetSceneNode(Application::Instance().GetSceneManager()->getRootSceneNode()->createChildSceneNode());
  }
  else
  {

    SetSceneNode(aParent->GetSceneNode()->createChildSceneNode());
  }
	GetSceneNode()->attachObject(m_pSys);

   return true;
}



// Called just before objects deletion
bool ParticleEffect::Done()
{

  // this isn;t necessary, but I'm paranoid - GetSceneNode()->detachAllObjects()
  // in objectbase::Done() removes it anyway
  GetSceneNode()->detachObject(m_pSys->getName()); 
 
  if (m_pSys)
  {

    ParticleSystemManager::getSingleton().destroySystem(m_pSys);
    m_pSys = NULL;
  }
   ObjectBase::Done();
  return true;
}


// Called just before objects deletion
bool ObjectBase::Done()
{

  // destroy the associated Action
  ActionManager::Instance().DestroyAction(GetClientObjectId());

  if(GetEntity())
  {
    Application::Instance().GetSceneManager()->removeEntity(GetEntity());
    SetEntity(NULL);
  }

  // TODO: fix Node deleteion
  // from Sinbad
  // If you actually want to destroy a node, the API only provides functions to do that
  // for a single node (SceneManager::destroySceneNode), or for all nodes in the scene 
  // (SceneManager::clearScene). If you use the former you have to make sure you 
  // remove the node from it's parent first. 
  if (GetSceneNode())
  {
    GetSceneNode()->detachAllObjects();
    GetSceneNode()->removeAllChildren();
    GetSceneNode()->getParent()->removeChild(GetSceneNode()->getName());
    Application::Instance().GetSceneManager()->destroySceneNode(GetSceneNode()->getName());
    SetSceneNode(NULL);
  }

}
McSwan
Greenskin
Posts: 122
Joined: Tue May 11, 2004 5:40 am
x 1

Post by McSwan »

I've cludge fixed it for now. It's something about the effects not being properly dead when I pick them, maybe they kill themselves on the next update or something. I'll look into it soon.

Code: Select all

inline const Vector3* getAllCorners(void) const
	    {
        static const Vector3 dummy(0,0,0);
        if (mNull == true)
          return &dummy;
		      //assert( !mNull && "Can't get corners of a null AAB" );
		    return (const Vector3*)mCorners;
	    }
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

I believe this is fixed in 0.15.2 anyway.
MadLion
Halfling
Posts: 97
Joined: Wed Aug 25, 2004 8:14 am
Location: Germany

Post by MadLion »

Can someone confirm or maybe correct me, that RaySceneQuery doesn't work with TSM?
I'm not able to select meshes.
User avatar
Emmeran
Goblin
Posts: 272
Joined: Wed Jun 02, 2004 11:47 am
Location: Erlangen
Contact:

Post by Emmeran »

it works fine for me.
about particle systems: i submitted a patch weeks ago, but i don't know if it has been aligned
MadLion
Halfling
Posts: 97
Joined: Wed Aug 25, 2004 8:14 am
Location: Germany

Post by MadLion »

Emmeran wrote:it works fine for me.
Do you use 0.15.2 or CVS?
User avatar
Emmeran
Goblin
Posts: 272
Joined: Wed Jun 02, 2004 11:47 am
Location: Erlangen
Contact:

Post by Emmeran »

0.15.2 ... but it worked eralier too
MadLion
Halfling
Posts: 97
Joined: Wed Aug 25, 2004 8:14 am
Location: Germany

Post by MadLion »

I'm using the CVS and have the problem.

Maybe i did a mistake. I'm doing somethink like:

Code: Select all

Ogre::MovableObject *mCurrMO;
	    
	Ogre::Ray ray = mCamera->getCameraToViewportRay(e->getX(), e->getY());
	// Set up the ray query
	Ogre::RaySceneQuery *mRaySceneQuery2 = mSceneMgr->createRayQuery(ray);
	// Sort by distance, and say we're only interested in the first hit
	mRaySceneQuery2->setSortByDistance(true, 1);
	// Execute
	RaySceneQueryResult res = mRaySceneQuery2->execute();
	RaySceneQueryResult::iterator it = res.begin();
	if (it != res.end())
	{
		mCurrMO = it->movable;
		mWindow->setDebugText("mouse : " + mCurrMO->getName());
	}
	else
	{
		mWindow->setDebugText("mouse : x " + StringConverter::toString(e->getX()) + " y " + StringConverter::toString(e->getY()));
		mCurrMO = NULL;
	}
	mRaySceneQuery2->clearResults();
User avatar
Emmeran
Goblin
Posts: 272
Joined: Wed Jun 02, 2004 11:47 am
Location: Erlangen
Contact:

Post by Emmeran »

hm I don't see any mistake... I pick this way:

Code: Select all

	Object::ObjectType Listener::_pick3D(Real relX, Real relY)
	{
		Ray pickRay = System::getSingleton().mCamera->getCameraToViewportRay(relX, relY); 
		RaySceneQuery* query = System::getSingleton().mSceneMgr->createRayQuery(pickRay); 
		query->setQueryMask( Unit::MASK | Building::MASK );

		RaySceneQueryResult& result = query->execute(); 

		MovableObject *closestObject = NULL; 
		Real closestDistance = -1; 

		RaySceneQueryResult::iterator rayIterator; 
		mLastPicked = NULL;

		for ( rayIterator = result.begin( ); rayIterator != result.end( ); rayIterator++ ) 
		{
			if ( ( *rayIterator ).movable != NULL ) 
			{ 
				if ( ( *rayIterator ).distance < closestDistance || closestDistance < 0 ) 
				{ 
					closestObject   = ( *rayIterator ).movable; 
					closestDistance = ( *rayIterator ).distance; 
				}
			} 
		} 


		// No object clicked 
		if ( closestObject != NULL )   
			mLastPicked = (Object*)closestObject->getUserObject();

		else
			mLastPicked = NULL;

		query->clearResults( ); 
		System::getSingleton().mSceneMgr->destroyQuery( query ); 
		return (mLastPicked == NULL) ? Object::NOTHING : mLastPicked->getObjectType();
	}

what output do you get, if u try to pick?
MadLion
Halfling
Posts: 97
Joined: Wed Aug 25, 2004 8:14 am
Location: Germany

Post by MadLion »

I found my misstake, i didn't set the query flags/mask right.
Now it works fine. ^^

Thanks
Post Reply