bool BaselinePattern::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { Ogre::Ray ray = OgreFramework::getSingletonPtr()->getCursorRay(); Ogre::RaySceneQuery* query = OgreFramework::getSingletonPtr()->m_pSceneMgr->createRayQuery(ray); query->setSortByDistance(true); Ogre::RaySceneQueryResult result = query->execute(); //Handle Selection if (stage->selected == NULL) { if (result.size() > 0 && result[0].movable != NULL) { for (int i = 0; i < stage->poppies.size(); ++i) if ( stage->poppies[i]->hasEntity( (Ogre::Entity*)result[0].movable ) ) { stage->poppies[i]->setColor(getRandomPotColor()); stage->selected = stage->poppies[i]; stage->poppies[i]->deactivateJump(); //soundPickUp->play(); } for (int i = 0; i < stage->pots.size(); ++i) if (stage->pots[i]->hasEntity( (Ogre::Entity*)result[0].movable) ) stage->pots[i]->setColor(getRandomPotColor()); } } return true; }
//该函数不支持多线程 string BaseManager::pickMovableObject( int x,int y ){ //如果相同的帧同时相同的x,y就直接返回结果 if( mPickFrameCount == getFrameCount() && mPickX == x && mPickY == y ){ return mPickName; } mRay = mCamera->getCameraToViewportRay( (Ogre::Real)x/(Ogre::Real)mWindow->getWidth(), (Ogre::Real)y/(Ogre::Real)mWindow->getHeight() ); mSceneQuery->setRay( mRay ); //距离排序 mSceneQuery->setSortByDistance(true); Ogre::RaySceneQueryResult result = mSceneQuery->execute(); //execute不能执行像素级的查询,它仅仅是和包围盒进行比较 //可以考虑使用渲染到纹理,使用1x1的纹理来对查询结果进行像素级别的查询 //这里使用逐个求交点的办法 Ogre::MovableObject* pmo = nullptr; Ogre::Real dis; for( size_t i = 0;i < result.size();++i ){ if( result[i].movable && result[i].movable->isVisible() && //不可见的 result[i].movable->isInScene() ){ //不在场景中的 mIntersect = false; result[i].movable->visitRenderables(this); if( mIntersect ){ //考虑到同一帧中间有多个地方的代码需要调用该函数 //这样使用内存换速度 if( !pmo || dis>mIntersectDistance ){ dis = mIntersectDistance; pmo = result[i].movable; } } } } if( pmo ){ mPickX = x; mPickY = y; mPickFrameCount = getFrameCount(); mPickName = pmo->getName(); return mPickName; } //返回一个空字串表示没有 return ""; }
bool BaselinePattern::mouseMoved(const OIS::MouseEvent &evt) { Ogre::Ray ray = OgreFramework::getSingletonPtr()->getCursorRay(); Ogre::RaySceneQuery* query = OgreFramework::getSingletonPtr()->m_pSceneMgr->createRayQuery(ray); query->setSortByDistance(true); Ogre::RaySceneQueryResult result = query->execute(); if (stage->selected && stage->selected->getType() == Selectable::TYPE_POPPY) for (int i = 0; i < result.size(); ++i) if (stage->ground->hasEntity( (Entity*)result[i].movable )) { Poppy* toMove = (Poppy*)stage->selected; Vector3 hoverPos = ray * result[i].distance; hoverPos.y = poppyRadius; toMove->setPosition(hoverPos); } return true; }
void QOgreWindow::mouseReleaseEvent(QMouseEvent *e) { if (camMan) camMan->injectMouseUp(*e); QPoint pos = e->pos(); Ogre::Ray mouseRay = oCam->getCameraToViewportRay( (Ogre::Real)pos.x() / oWin->getWidth(), (Ogre::Real)pos.y() / oWin->getHeight()); Ogre::RaySceneQuery* sceneQuery = oSceneMgr->createRayQuery(mouseRay); sceneQuery->setSortByDistance(true); Ogre::RaySceneQueryResult vResult = sceneQuery->execute(); for (size_t ui = 0; ui < vResult.size(); ui++) { if (vResult[ui].movable) { if (vResult[ui].movable->getMovableType().compare("Entity") == 0) { emit entitySelected((Ogre::Entity*)vResult[ui].movable); } } } oSceneMgr->destroyQuery(sceneQuery); }
bool BaselinePattern::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { Ogre::Ray ray = OgreFramework::getSingletonPtr()->getCursorRay(); Ogre::RaySceneQuery* query = OgreFramework::getSingletonPtr()->m_pSceneMgr->createRayQuery(ray); query->setSortByDistance(true); Ogre::RaySceneQueryResult result = query->execute(); if (stage->selected != NULL && stage->selected->getType() == Selectable::TYPE_POPPY && result.size() > 0) { Poppy* old = (Poppy*)stage->selected; stage->selected = NULL; Vector3 placeDest = ray * result[0].distance; placeDest.y = poppyRadius; old->setPosition(placeDest); old->activateJump(); } return true; }
void NPCCharacter::_actionLook(const Ogre::Vector3& target) { Ogre::Bone* headBone; std::string n = _node->getName(); Ogre::Skeleton* skel = static_cast<Ogre::Entity*>(_movableObject)->getSkeleton(); headBone = skel->getBone("Bip01_Head"); headBone->setManuallyControlled(true); headBone->setInheritOrientation(true); int nAnim = skel->getNumAnimations(); //have to do this to allow the head to turn properly. for(int i = 0; i < nAnim; ++i) { skel->getAnimation(i)->destroyNodeTrack(headBone->getHandle()); } Ogre::Vector3 test = headBone->_getDerivedPosition() * CHARACTER_SCALE_FACTOR + _node->getPosition(); Ogre::Vector3 dir = target - test; Ogre::Quaternion nodeRot,boneRot; Ogre::Euler boneEuler; boneEuler.setDirection(dir,true,false); /*boneRot = _node->convertLocalToWorldOrientation(_node->getOrientation()) * headBone->_getDerivedOrientation(); Ogre::Vector3 boneTest = boneRot * Ogre::Vector3::UNIT_Z;*/ //Ogre::Vector3 boneTest = headBone->getOrientation() * Ogre::Vector3::UNIT_Z; //turns the direction vector into a 2D normalized vector on the X/Z axis. dir.y = 0; dir.normalise(); //All of this ray query stuff is to make sure that the AI can "see" the target before attempting to look at it. Ogre::SceneManager* scene = _node->getCreator(); Ogre::Ray ray(headBone->_getDerivedPosition() * CHARACTER_SCALE_FACTOR + _node->getPosition(),dir); Ogre::RaySceneQuery* query = scene->createRayQuery(ray); query->setSortByDistance(true); query->setQueryMask(CHARACTER_MASK | SCENERY_MASK); Ogre::RaySceneQueryResult results = query->execute(); bool withinView = false; if(results.size() == 0) { withinView = true; } else { if(results.begin()->movable->getParentNode()->getName() == getName()) { if(results.size() == 1) { withinView = true; } } if(!withinView && results.size() > 1 && std::next(results.begin())->distance > test.distance(target)) { withinView = true; } } scene->destroyQuery(query); if(withinView) { Ogre::Euler node; Ogre::Euler t = headOrientation.getRotationTo(dir); t.limitYaw(Ogre::Radian(3.0)); t.limitPitch(Ogre::Radian(0.0)); headOrientation = headOrientation + t; headOrientation.limitYaw(Ogre::Degree(100)); headOrientation.limitPitch(Ogre::Degree(60)); headBone->setOrientation(headOrientation); /*headBone->rotate(boneTest.getRotationTo(dir),Ogre::Node::TS_WORLD); Ogre::Quaternion boneRotation = _node->convertLocalToWorldOrientation(_node->getOrientation()) * headBone->_getDerivedOrientation() * (Ogre::Quaternion(Ogre::Degree(180),Ogre::Vector3::UNIT_Y)); Ogre::Quaternion nodeRotation = _node->_getDerivedOrientation(); Ogre::Quaternion diff = nodeRotation.Inverse() * boneRotation;*/ } _isActFinished = true; }