void MovementAnimation::addTime( Ogre::Real timeSinceLastFrame ) { if( mMoving ) { Ogre::Real move = mSpeed * timeSinceLastFrame; Ogre::Vector3 position = mNode->getPosition(); if( position.distance( mDestination ) < move ) { position = mDestination; } else { // We work out direction each time, as the node may have been re-positioned by other code. Ogre::Vector3 direction = mDestination - position; direction.normalise(); position += direction * move; } mNode->setPosition( position ); } }
/* * Calculates sound level by getting the distance of two vectors and mapping it between 0 and 255 * using a given range (5000) */ int SoundManager::calcDistance(Ogre::Vector3 camPosition, Ogre::Vector3 soundPosition) { Ogre::Real distance = camPosition.distance(soundPosition); //get the distance between sound and camera if(distance > 5500) distance = 5500; int dist = distance/5500 * 255; //1500 should be the max range. return dist; }
//------------------------------------------------------------------------------- bool PortalEditor::snapTpPortal(PortalEditor* dest,bool bAllowMove ) { //reposition & realign this portal (and its parent zone) //to connect with this portal. //Before snapping portals togther, we should check that the zone is //not already locked into position by another portal join. //However, even if this is the case, we can still join portals if //they are already in the correct position. //get current position data: Ogre::Quaternion qZone = mParentZone->getDerivedOrientation(); Ogre::Quaternion qDest = dest->getDerivedOrientation(); Ogre::Quaternion qPortal = this->getOrientation(); Ogre::Vector3 vDest = dest->getDerivedPosition(); Ogre::Vector3 vPortal = this->getDerivedPosition(); const Ogre::Real DIST_EPSILON(0.01f);//fudge factor const Ogre::Radian ANG_EPSILON(0.01f); if(vPortal.distance(vDest)<DIST_EPSILON && qPortal.equals(qDest*Ogre::Quaternion(0,0,1,0),ANG_EPSILON))return true; if(!bAllowMove)return false; //orientation Ogre::Quaternion qNew = (qDest*Ogre::Quaternion(0,0,1,0))*qPortal.Inverse(); mParentZone->setDerivedOrientation(qNew); //position Ogre::Vector3 vZone = mParentZone->getDerivedPosition(); vPortal = this->getDerivedPosition(); mParentZone->setDerivedPosition( (vDest - (vPortal-vZone))); return true; }
/* * Returns true if the given point is visible from the given viewpoint. * * A point is visible if it will be on screen, and if it is not occluded by * other objects. * * Input: * point: The point whose visibility we want to check. * viewpoint: The viewpoint to check from. * * Returns: True if the point is visible from the viewpoint. */ bool VisibilityChecker::IsVisible(const Ogre::Vector3& point, const Viewpoint& viewpoint) { float screen_x; float screen_y; auto old_position = camera_->getPosition(); auto old_direction = camera_->getDirection(); camera_->setPosition(viewpoint.position()); camera_->lookAt(viewpoint.focus()); GetScreenPosition(point, &screen_x, &screen_y); bool result = false; if (IsOnScreen(screen_x, screen_y)) { Ogre::Ray ray; camera_->getCameraToViewportRay(screen_x, screen_y, &ray); Ogre::Vector3 hit; if (RaycastAABB(ray, &hit)) { auto dist = point.distance(hit); if (dist < kOcclusionThreshold) { result = true; } else { // Hit something, but too far away from the target. result = false; } } else { // No hits. The ray should hit the target, but if it doesn't, that usually // indicates visibility. This is because if the target is occluded, the // ray is likely to have hit the occluding object. result = true; } } else { // Not on screen result= false; } camera_->setPosition(old_position); camera_->setDirection(old_direction); return result; }
void IKChain::PushOgreBone(Ogre::Bone* OgreBone) { Ogre::Bone* oBone = OgreBone; Ogre::Vector3 vecBonePos = oBone->getPosition(); oBone->setManuallyControlled(true); IKJoint* oJoint = NULL; if ( mLastPush == NULL ) { // Root oJoint = new IKJoint(oBone, NULL, oBone->getPosition().x + mMeshNode->getPosition().x, oBone->getPosition().y + mMeshNode->getPosition().y, oBone->getPosition().z + mMeshNode->getPosition().z); mIKRoot = oJoint; mJointCount = 1; } else { // Not root Ogre::Vector3 vecParent = mLastPush->GetOgreBone()->_getDerivedPosition(); Ogre::Vector3 vecDerived = oBone->_getDerivedPosition(); Ogre::Vector3 vecJointPos = oBone->_getDerivedPosition() + mMeshNode->getPosition(); oJoint = new IKJoint(oBone, mLastPush, vecJointPos.x, vecJointPos.y, vecJointPos.z); mLastPush->SetChild(oJoint); mJointCount++; mChainLength += vecParent.distance(oBone->_getDerivedPosition()); } mLastPush = oJoint; mIKEffector = oJoint; cout << "Joint count " << mJointCount << endl; }
float Animation::calcAnimVelocity(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const Ogre::Vector3 &accum, const std::string &groupname) { const std::string start = groupname+": start"; const std::string loopstart = groupname+": loop start"; const std::string loopstop = groupname+": loop stop"; const std::string stop = groupname+": stop"; float starttime = std::numeric_limits<float>::max(); float stoptime = 0.0f; NifOgre::TextKeyMap::const_iterator keyiter(keys.begin()); while(keyiter != keys.end()) { if(keyiter->second == start || keyiter->second == loopstart) starttime = keyiter->first; else if(keyiter->second == loopstop || keyiter->second == stop) { stoptime = keyiter->first; break; } keyiter++; } if(stoptime > starttime) { Ogre::Vector3 startpos = nonaccumctrl->getTranslation(starttime) * accum; Ogre::Vector3 endpos = nonaccumctrl->getTranslation(stoptime) * accum; return startpos.distance(endpos) / (stoptime - starttime); } return 0.0f; }
void IKChain::SolveForTargetXInv(Ogre::Vector3 Target, double Pitch, double Yaw, double Roll) { double dRate = Target.distance(GetEffectorPosition()) / mChainLength; for ( int i = 0; i < 5; i++ ) { mIKRoot->GetEffector()->DoSolverIterationXInv(Target, dRate, Pitch, Yaw, Roll); dRate = dRate / 1.5; } }
void IKChain::SolveForTargetYInv(Ogre::Vector3 Target) { double dRate = Target.distance(GetEffectorPosition()) / mChainLength; for ( int i = 0; i < 5; i++ ) { mIKRoot->GetEffector()->DoSolverIterationYInv(Target, dRate); dRate = dRate / 1.5; } }
bool Team::isSafeGoingThroughOpponent(const Ogre::Vector3& from, const Ogre::Vector3& target, float force, Player* opponent) { Ogre::Vector3 to_target = target - from; Ogre::Vector3 to_opponent = Vector3To2(opponent->getPosition() - from); // If opponent if behind this player if (to_target.dotProduct(to_opponent) < 0) { return true; } // If Distance(opponent, from) > Distance(from, target), pass if (opponent->getPosition().distance(from) > from.distance(target)) { return true; } // If the opponent can intercept the ball float x = to_target.z; float z = -to_target.x; Ogre::Vector3 oppo_pos = Vector3To2(opponent->getPosition()); Ogre::Vector3 oppo_pos_away = oppo_pos + Ogre::Vector3(x, 0, z).normalisedCopy() * 300.f; Ogre::Vector3 intersect_point; if (GeometryHelper::get().lineSegmentIntersect(from, target, oppo_pos, oppo_pos_away, intersect_point)) { float oppo_to_intersect = oppo_pos.distance(intersect_point); float ball_to_intersect = from.distance(intersect_point); float time = mBall->getTimeToCoverDistance(ball_to_intersect, force); if (time <= 0 || oppo_to_intersect / opponent->getMaxSpeed() < time) { return false; } } return true; }
bool Team::isSafeGoingThroughAllOpponents(const Ogre::Vector3& from, const Ogre::Vector3& target, float force) { std::vector<Player*>& opponents = getOpponent()->getPlayers(); const std::vector<Ogre::Vector3>& points = mPitch->getPassSafePolygon(); for (int i = 0; i < points.size(); ++i) { mPassSafePolygon[i] = GetRotationThroughHeading(target - from) * points[i] + from; } int num_in_polygon = 0; for (auto it = opponents.begin(); it != opponents.end(); ++it) { // If Distance(opponent, from) > Distance(from, target), pass if (from.distance((*it)->getPosition()) > from.distance(target)) { continue; } if (GeometryHelper::get().isInPolygon((*it)->getPosition(), mPassSafePolygon)) { ++num_in_polygon; } } // No one in this region, pass is safe if (!num_in_polygon) { return true; } //return false; // Enforce to pass the ball return WithPossibility(0.01 / (num_in_polygon * num_in_polygon)); }
void BulletHelixOperator::operateBulletEventSystem(Real timeElapsed) { BulletEventSystem::BulletSystemVecotor::iterator it = m_parent->getActiveBulletSystem().begin(); while(it != m_parent->getActiveBulletSystem().end()) { BulletSystem* pBulletSystem = *it; if(pBulletSystem && pBulletSystem->getIsCreated()) { // 步骤:[6/2/2010 陈军龙] // 1.计算朝向 // 2.将时间映射到曲线函数Sin (映射公式: (2 * PI) / (1 / Frequency) = x / Age ) // 3.计算绕螺旋的旋转轴的旋转偏移量 // (绕任意轴旋转公式:v' = (v - (v 。n) 。n) * cosx + (v * n) * sinx + (v 。n)。n // 其中的 。代表点乘 * 代表叉乘,v是要旋转的向量,n是旋转轴,x是旋转的角度) // 4.根据到目标的百分比设置振幅,更新子弹位置 static Ogre::Vector3 startpos = pBulletSystem->getCurrentPosition(); Ogre::Vector3 direction = pBulletSystem->getTargetPosition() - startpos; direction.normalise(); Real fCumulateTime = pBulletSystem->getAge(); Real sinvalue = Ogre::Math::Sin(fCumulateTime * Ogre::Math::TWO_PI * m_frequency); Real cosvalue = Ogre::Math::Cos(fCumulateTime * Ogre::Math::TWO_PI * m_frequency); Ogre::Vector3 absoffset, vdelta; vdelta = Ogre::Vector3::UNIT_Y;//此次设置为Y轴,也可以设置为其它 // v' = (v - (v 。n) 。n) * cosx + (v * n) * sinx + (v 。n)。n absoffset = (vdelta - (vdelta.dotProduct(direction)) * direction) * cosvalue + (vdelta.crossProduct(direction)) * sinvalue + (vdelta.dotProduct(direction)) *direction; Real oridistance = startpos.distance(pBulletSystem->getTargetPosition()); Real curdistance = pBulletSystem->getCurrentPosition().distance(pBulletSystem->getTargetPosition()); Real percent = Ogre::Math::RealEqual(oridistance, 0) ? 1 : curdistance/oridistance; TransformInfo info; info = pBulletSystem->getTransformInfo(); Ogre::Vector3 vBulletPosition = info.mPosition; vBulletPosition += (m_amplitude * absoffset * percent); info.mPosition = vBulletPosition; pBulletSystem->setTransformInfo(info); pBulletSystem->setPosition(info.mPosition); } it ++; } }
int WalkabilityMap::getNearestNode(Ogre::Vector3 position) { int nearestNode=-1; double minDistance=-1; double currentDistance; boost::graph_traits<Graph>::vertex_iterator vit,vend; for (tie(vit, vend) = vertices(mGraph); vit != vend; ++vit) { currentDistance=position.distance(mGraph[*vit].mSceneNode->getPosition()); if(minDistance==-1 || minDistance>currentDistance) { minDistance=currentDistance; nearestNode=*vit; } } return nearestNode; }
float Team::_getScoreOfPosition(const Ogre::Vector3& position) { // Closer to opponent's goal float score = 9.f * fabs((position - mGoal->getCenter()).x) / (2 * Prm.HalfPitchWidth); // 距离控球队员的距离 float best_dist = 8.f; float dist_to_ctrl = fabs(position.distance(getControllingPlayer()->getPosition())); if (dist_to_ctrl > best_dist) { score += 4.f * (best_dist / (1.1 * dist_to_ctrl)); } else { score += 4.f * (dist_to_ctrl / best_dist); } return score; }
void EnemyAIModelHunt::makeDecision(MOC::CollisionTools *mCollisionTools, const Ogre::FrameEvent& evt, Enemy *enemy, ZombiePack **zombies, int nZombies) { if (aux >= rate) { double x, z; movModel->calculateMove(enemy, zombies, nZombies, &x, &z); // Calculamos si está demasiado cerca: Ogre::Vector3 myPos = enemy->node->getPosition(); if (myPos.distance(Ogre::Vector3(x, myPos.y, z)) < enemy->range*0.5) { x = 2 * myPos.x - x; z = 2 * myPos.z - z; } enemy->move(x, z); } enemy->update(mCollisionTools, evt, zombies); }
void IKChain::Initialize() { // Get skeleton root Ogre::Bone Ogre::Bone* oBoneRoot = mOgreSkeleton->getRootBone(); Ogre::Vector3 vecBonePos = oBoneRoot->getPosition(); oBoneRoot->setManuallyControlled(true); // Create IK root mIKRoot = new IKJoint(oBoneRoot, NULL, oBoneRoot->getPosition().x + mMeshNode->getPosition().x, oBoneRoot->getPosition().y + mMeshNode->getPosition().y, oBoneRoot->getPosition().z + mMeshNode->getPosition().z); // Keep track of previously processed Ogre::Bone IKJoint* oLastIKJoint = mIKRoot; // Current Ogre::Bone Ogre::Bone* oCurrentBone = oBoneRoot; cout << "Current Ogre::Bone: " << oCurrentBone->getName() << endl; mJointCount = 1; // Ogre::Bone iterator Ogre::Node::ChildNodeIterator oIterator = oCurrentBone->getChildIterator(); Ogre::Vector3 vecParent = oBoneRoot->_getDerivedPosition(); while ( oIterator.hasMoreElements() ) { oCurrentBone = (Ogre::Bone*)oIterator.getNext(); oCurrentBone->setManuallyControlled(true); cout << "Current Ogre::Bone: " << oCurrentBone->getName() << endl; Ogre::Vector3 vecDerived = oCurrentBone->_getDerivedPosition(); Ogre::Vector3 vecJointPos = oCurrentBone->_getDerivedPosition() + mMeshNode->getPosition(); vecBonePos = oCurrentBone->getPosition(); IKJoint* oNewJoint = new IKJoint(oCurrentBone, oLastIKJoint, vecJointPos.x, vecJointPos.y, vecJointPos.z); oLastIKJoint->SetChild(oNewJoint); oLastIKJoint = oNewJoint; oIterator = oCurrentBone->getChildIterator(); mJointCount++; mChainLength += vecParent.distance(oCurrentBone->_getDerivedPosition()); vecParent = oCurrentBone->_getDerivedPosition(); } mChainLength = mChainLength; mIKEffector = oLastIKJoint; cout << "Ogre::Bone count is " << mJointCount << endl; }
//---------------------------------------------------------------------------------------- bool PortalEditor::update(float timePassed) { //TODO: check for proximity to positioning tools in parent mesh //trigger snap-to when close enough. bool bModified = false;//return value for Ogitor if (getSelected()&& (!mFreeMove)) { bool snapped = false; ZoneDesignTools* tools = this->mParentZone->getTools(); //Check against tools->mHoles std::vector<HoleSnapPoint>::iterator itr; for(itr = tools->mHoles.begin();itr != tools->mHoles.end() && !snapped ;++itr) { //get current position data: Ogre::Vector3 vDest = (*itr).first; Ogre::Vector3 vPortal = this->getPosition(); Ogre::Quaternion qDest = (*itr).second; Ogre::Quaternion qPortal = this->getOrientation(); //check portal proximity Ogre::Real d = vPortal.distance(vDest); if(d<1.0f) { this->setPosition(vDest);//move into position this->setOrientation(qDest);//adjust orientation snapped = true; } } bModified = true; } return bModified; }
void GamePlanet::cameraPositionChanged(IngameCamera* camera) { Ogre::Vector3 camPos = camera->GetPosition(); Ogre::Vector3 planetPos = node->getPosition(); double dist = camPos.distance(planetPos) - radius; if(dist < 0) { dist = 0; } double pixelSize = camera->mPerspectiveScallingFactor * (2 * radius) / dist; PlanetLOD lodLevel; if (pixelSize <= 1) { //LOD_Invisible is used when the planet is extremely far away, and would normally be smaller than one pixel unloadLOD(LOD_Sprite); unloadLOD(LOD_Simple); unloadLOD(LOD_Complex); lodLevel = LOD_Invisible; loadLOD(LOD_Invisible); } else { if(pixelSize <= 10) { //LOD_Sprite is for long distances, where only a few pixels are rendered for the planet //At this LOD, all other LOD levels should be unloaded because the most likely won't be needed soon. unloadLOD(LOD_Simple); unloadLOD(LOD_Complex); lodLevel = LOD_Sprite; loadLOD(LOD_Sprite); // if (fullyLoadedPlanet == &planet) fullyLoadedPlanet = NULL; } else { if (pixelSize <= 750) { //LOD_Simple is for medium-ranged planets, needing moderate orbital-perspective detail, but not surface detail. lodLevel = LOD_Simple; //Load not only LOD_Simple, but also ensure LOD_Sprite is loaded loadLOD(LOD_Sprite); loadLOD(LOD_Simple); } else { if (pixelSize > 750) { //LOD_Complex is the highest level of detail, which loads everything on the planet for surface view. //If this LOD has not been loaded yet, the planet should use LOD_Medium until it is. lodLevel = LOD_Complex; //Ensure LOD_Simple and LOD_Sprite are loaded - until LOD_Complex can load, it will fall back on these loadLOD(LOD_Sprite); loadLOD(LOD_Simple); loadLOD(LOD_Complex); } } } } /* while (lodLevel < LOD_Invisible && !isloadedLOD(lodLevel)) { lodLevel = (GamePlanet::PlanetLOD)(((uint32)lodLevel) + 1); } */ setLOD(lodLevel); }
void ActorSceneCanvas::OnMouseMove(wxMouseEvent& e) { ShowPos(e.GetX(), e.GetY()); if (!GetSceneManipulator()) return; if (m_pCameraManip) { wxASSERT(mDragButton != wxMOUSE_BTN_NONE); m_pCameraManip->onMotion(e.GetX(), e.GetY()); } if (mDragStarted && e.LeftIsDown()) { mDragCurrent =Ogre::Vector2(e.GetX(), e.GetY()) ; mDragDelta = mDragCurrent - mDragOrigin; mDragOrigin = mDragCurrent; if (Fairy::CDataManipulator::GetDataManipulator() && mCanManipulateAxis) { Ogre::Camera* camera = GetSceneManipulator()->getCamera(); assert (camera); Ogre::Vector3 oldPos = camera->getPosition(); Fairy::LogicModel* pModel = GetDataManipulator()->m_pObjTemplate; if (pModel) { Ogre::Vector3 objPos = pModel->getPosition(); Ogre::Real distance = oldPos.distance(objPos); Ogre::Real factor = distance*0.1/150.0; Ogre::Vector3 pos=Fairy::CDataManipulator::m_baseNode->getPosition(); Ogre::Vector3 fdeltaxi = Ogre::Vector3::ZERO; Ogre::Quaternion qRot = Fairy::CDataManipulator::m_baseNode->getOrientation(); //david-<< if(mXax) fdeltaxi = /*qRot**/(mDragDelta.x*0.1*Ogre::Vector3::UNIT_X); if(mYax) fdeltaxi = /*qRot**/(mDragDelta.x*0.1*Ogre::Vector3::UNIT_Y); if(mZax) fdeltaxi = /*qRot**/(mDragDelta.x*0.1*Ogre::Vector3::UNIT_Z); //david->> Fairy::CDataManipulator::GetDataManipulator()->_updateCurLocatorTrans(fdeltaxi,Ogre::Quaternion::IDENTITY,true); } } } if(mDragRightStarted && e.RightIsDown()) { mDragCurrent =Ogre::Vector2(e.GetX(), e.GetY()) ; mDragDelta = mDragCurrent - mDragOrigin; mDragOrigin = mDragCurrent; // Ogre::Radian x = Ogre::Degree(mDragDelta.val[0]); // Ogre::Radian y = Ogre::Degree(mDragDelta.val[1]); // Fairy::CDataManipulator::m_axex->yaw(y); // Fairy::CDataManipulator::m_axex->pitch(x); if ( Fairy::CDataManipulator::GetDataManipulator() &&(mXax || mYax || mZax) && mCanManipulateAxis) { Ogre::Vector3 fBaseAxis = Ogre::Vector3::ZERO; Ogre::Quaternion fBaseRot = Fairy::CDataManipulator::m_baseNode->getOrientation(); if(mXax) fBaseAxis =/* fBaseRot**/Ogre::Vector3::UNIT_X; if(mYax) fBaseAxis =/* fBaseRot**/Ogre::Vector3::UNIT_Y; if(mZax) fBaseAxis =/* fBaseRot**/Ogre::Vector3::UNIT_Z; //david-<< Ogre::Radian angle = Ogre::Degree(mDragDelta.y); //david->> Ogre::Quaternion rot(angle, fBaseAxis); if(mRotFirst) { Fairy::CDataManipulator::GetDataManipulator()->_updateCurLocatorTrans(Ogre::Vector3::ZERO, rot, false); } else { Fairy::CDataManipulator::GetDataManipulator()->_updateCurLocatorRot(rot); } } } if (GetActiveAction()) { //GetActiveAction()->onMotion(e.GetX(), e.GetY()); if (e.ControlDown()) { GetActiveAction()->setParameter("FUNC_KEY", "CTRL"); } if(e.AltDown()) { GetActiveAction()->setParameter("FUNC_KEY", "ATL"); } if(e.ShiftDown()) { GetActiveAction()->setParameter("FUNC_KEY", "SHIFT"); } } else { //GetSceneManipulator()->getHitIndicator("IntersectPoint")->setHitPoint(e.GetX(), e.GetY()); } // 显示标准模型 //if ( GetSceneManipulator()->getShowStandardModel() ) // GetSceneManipulator()->getHitIndicator("StandardModelIndicator")->setHitPoint(0.5,0.5); //else // GetSceneManipulator()->getHitIndicator("StandardModelIndicator")->hide(); m_CurrentMousePos.x = e.GetX(); m_CurrentMousePos.y = e.GetY(); Ogre::Vector3 position; bool hit = GetSceneManipulator()->getTerrainIntersects(m_CurrentMousePos.x, m_CurrentMousePos.y, position); std::pair<int, int> gridCoord = GetSceneManipulator()->getTerrainData()->getGrid(position.x, position.z); if (hit) { mParentFrame->SetStatusText("World Coordinate : " + Ogre::StringConverter::toString((int)(position.x)) + " " + Ogre::StringConverter::toString((int)(position.y)) + " " + Ogre::StringConverter::toString((int)(position.z)), 0); mParentFrame->SetStatusText("Grid Coordinate : " + Ogre::StringConverter::toString(gridCoord.first) + " " + Ogre::StringConverter::toString(gridCoord.second), 1); } }
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; }