Skip to main content

History: ThreeDeeObjectPicking

Source of version: 5

Copy to clipboard
            !!Example 1
This could be used for 3D object picking from a Win32 aplication, I use it from a OnMouseMove callback :
{CODE(wrap="1", colors="c++")} RECT rc;
 this->GetClientRect(&rc);
 int width    = rc.right - rc.left;
 int height    = rc.bottom - rc.top;
 float tx = (float)(1.0f / width) * cpt.x;
 float ty = (float)(1.0f / height) * cpt.y;
 Camera *pCam = ogreEngine::getSingletonPtr()->getCurrentCamera();
 // calc the ray using normalised screen coordinates [0-1]
 Ray ray = pCam->getCameraToViewportRay(tx - 0.5, 0.5 - ty);
 // Set up the ray query
 if (!mpRayQuery)
     mpRayQuery = ogreEngine::getSingletonPtr()->getSceneManager()->createRayQuery(ray);
 else
     mpRayQuery->setRay(ray); // update ray
 // Sort by distance, and say we're only interested in the first hit
 mpRayQuery->setSortByDistance(true, 1);
 // Execute
 RaySceneQueryResult res = mpRayQuery->execute();
 RaySceneQueryResult::iterator it = res.begin();
 if (it != res.end())
 {
     mCurrMO = it->movable;
     this->updateProgressListeners("mouse : " + mCurrMO->getName());
 }
 else
 {
     this->updateProgressListeners("mouse : " + StringConverter::toString(tx) + "x" + StringConverter::toString(ty));
     mCurrMO = NULL;
 }
 mpRayQuery->clearResults();
{CODE}

!!Example 2
Quick background: I was trying to do some simple 3D object-picking-and-dragging, and this article helped me a lot; also, [http://www.ogre3d.org/forums/viewtopic.php?f=2&t=63705&p=422174&hilit=screen+to+world+space#p422264|this forum thread] helped me a lot.  But there were a few hitches that I had to overcome even with those code samples, so I offer my version of 3D object picking & dragging, with an explanation for my rationale.

Note: my code is fairly sloppy, so don't expect the best design decisions to be reflected in it. :)

!!!Pick Function
{CODE(wrap="1", colors="c++")}
void MyClassName::MouseClicky(unsigned int absoluteX, unsigned int absoluteY) {
  float width = (float) this->mCam->getViewport()->getActualWidth(); // viewport width
  float height = (float) this->mCam->getViewport()->getActualHeight(); // viewport height

  Ray ray = this->mCam->getCameraToViewportRay((float) absoluteX / width, (float) absoluteY / height);

  // Set up the ray query - you will probably not want to create this every time
  RaySceneQuery * rq = this->mSceneMan->createRayQuery(ray);

  // Sort by distance, and say we're only interested in the first hit; also, only pick entities
  rq->setSortByDistance(true, 1);
  rq->setQueryTypeMask(Ogre::SceneManager::ENTITY_TYPE_MASK);

  // Execute
  RaySceneQueryResult res = rq->execute();
  RaySceneQueryResult::iterator it = res.begin();

  // these two things should probably be encapsulated in their own class/struct
  this->mSelectedEntity = NULL;
  this->mSelectedEntityDist = 0.0f; 

  if (it != res.end())
  {
    this->mSelectedEntity = it->movable;
    this->mSelectedEntityDist = it->distance;
    printf("clicked: %s\n", this->mSelectedEntity ->getName().c_str());
  }
  else 
  {
    printf("cleared selection.\n");
  }

  this->mSceneMan->destroyQuery(rq);
}
{CODE}

Rationale:
#text Much like in Example 1

        

History

Information Version
Thu 22 of Mar, 2012 14:30 GMT-0000 gr1ever Added my version of 3d-object picking and an example of dragging 7
Sat 02 of Jan, 2010 08:11 GMT-0000 jacmoe [rollback version 4] 6
Thu 22 of Mar, 2012 14:05 GMT-0000 gr1ever 5
Fri 25 of Dec, 2009 01:35 GMT-0000 jacmoe 3
Fri 25 of Dec, 2009 01:35 GMT-0000 jacmoe 2
Sun 19 of Oct, 2008 10:47 GMT-0000 Spacegaier Added category 1