History: ThreeDeeObjectPicking
Preview of version: 5
Example 1
This could be used for 3D object picking from a Win32 aplication, I use it from a OnMouseMove callback :
Copy to clipboard
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();
Example 2
Quick background: I was trying to do some simple 3D object-picking-and-dragging, and this article helped me a lot; also, 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
Copy to clipboard
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); }
Rationale:
- text Much like in Example 1