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 );
    }
}
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
//-------------------------------------------------------------------------------
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;
}
Exemple #4
0
/*
 * 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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
	}
}
Exemple #8
0
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;
	}
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #13
0
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);
}
Exemple #15
0
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;
}
Exemple #16
0
//----------------------------------------------------------------------------------------
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;
}
Exemple #17
0
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);
}
Exemple #18
0
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;
}