Exemple #1
0
	void PointStarfield::addRandomStars (int count)
	{
		for (int i = 0; i < count; ++i) {
			// Generate a vector inside a sphere
			Ogre::Vector3 pos;
			do {
				pos.x = randReal(-1, 1);
				pos.y = randReal(-1, 1);
				pos.z = randReal(-1, 1);
			} while (pos.squaredLength () >= 1);

			// Convert to rasc/decl angles.
			LongReal rasc, decl, dist;
			Astronomy::convertRectangularToSpherical(
					pos.x, pos.y, pos.z,
					rasc, decl, dist);

			Star s;
			s.RightAscension = Ogre::Degree (rasc);
			s.Declination = Ogre::Degree (decl);
			// This distribution is wrong.
			s.Magnitude = 6 * pos.squaredLength () + 1.5;
			mStars.push_back(s);
		}
		notifyStarVectorChanged ();
	}
void GPUBillboardSet::updateBoundingBoxAndSphereFromBillboards(const std::vector<PhotoSynth::Vertex>& vertices)
{
	Ogre::AxisAlignedBox box = calculateBillboardsBoundingBox(vertices);
	setBoundingBox(box);

	Ogre::Vector3 vmax = box.getMaximum();
	Ogre::Vector3 vmin = box.getMinimum();
	Ogre::Real sqLen = std::max(vmax.squaredLength(), vmin.squaredLength());
	mBBRadius = Ogre::Math::Sqrt(sqLen);
}
    void 
    IntersectGrid::fillPosition( const PositionArray &posArray )
    {
        size_t posCount = posArray.size();

        if ( posCount <= 0 )
            return;

    //    if ( posCount > mCurrentVertexCount )
    //   {   
            // 如果缓冲区不够用了,就扩容一倍
        //    mCurrentVertexCount = posCount<<1;
            // 如果不每帧创建缓冲区的话,由于lock时用的是discard,所以上次缓冲区中的内容还是会被显示
            mCurrentVertexCount = posCount;
            _createBuffer();
     //   }

        Ogre::Vector3 vmax = posArray[posCount-1];
        Ogre::Vector3 vmin = posArray[0];

        vmin.y -= 100.0f;
        vmax.y += 100.0f;

        Real sqLen = std::max(vmax.squaredLength(), vmin.squaredLength());
        mRadius = Ogre::Math::Sqrt(sqLen);//

        mBox.setExtents(vmin,vmax);//

        getParentNode()->needUpdate();//

        float *vertexPos = static_cast<float*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));

        for (size_t i = 0; i < posCount; ++i)
        {
            *vertexPos++ = posArray[i].x;
            *vertexPos++ = posArray[i].y+1;
            *vertexPos++ = posArray[i].z;

            Ogre::RGBA *pCol;
            pCol = static_cast<Ogre::RGBA*>(static_cast<void*>(vertexPos));
            // 用diffuse来做为alpha来源
            Ogre::Root::getSingleton().convertColourValue(mGridsColour, pCol++ ) ;

            vertexPos = static_cast<float*>(static_cast<void*>(pCol));
        }

        vbuf->unlock();     
    }
Exemple #4
0
void CharacterController::UpdateAI(float dt)
{
	_CurrentPathAge += dt;
	//std::cerr << _CurrentPathIndex << " / " << _CurrentPath.size() << "\n";
	if (_CurrentPathIndex + 2 <= _CurrentPath.size())
	{
		Ogre::Vector3 const & a = _CurrentPath[_CurrentPathIndex];
		Ogre::Vector3 const & b = _CurrentPath[_CurrentPathIndex+1];
		Ogre::Vector3 const & m = GetPosition();
		Ogre::Vector3 const ab = b - a;
		Ogre::Vector3 const am = m - a;
		Ogre::Vector3 const mb = b - m;
		Ogre::Vector3 const mb_unit = mb.normalisedCopy();
		
		float remaining = mb.length();
		for(size_t i = _CurrentPathIndex + 1; i + 2 <= _CurrentPath.size(); ++i)
		{
			remaining += _CurrentPath[i].distance(_CurrentPath[i+1]);
		}
		//std::cerr << "Remaining distance: " << remaining << " m\n";
		
		float lambda = am.dotProduct(ab) / ab.squaredLength();
		
		//const float tau = 0.1;
		
		SetVelocity(_CurrentVelocity * mb_unit);
		
		if (lambda > 1) _CurrentPathIndex++;
		/*if (_CurrentPathIndex + 1 == _CurrentPath.size())
			SetVelocity(Ogre::Vector3(0.));*/
	}
}
Exemple #5
0
void GameState::EnergyExplosion(Ogre::Vector3 location,Ogre::Real size, double EnergyAdjustment,const std::string& Material)
{
	float sqSize = size*size;

	auto it = _actors.begin();
	while(it != _actors.end())
	{
		Ogre::Vector3 diff = (*it)->GetLocation() - location;

		if(diff.squaredLength() <= sqSize)
			(*it)->AdjustEnergy(EnergyAdjustment);

		++it;
	}

	if(Material != "")
	{
		_billboardManager->AddBillboard(
			location,
			Material,
			Ogre::Vector2(1.0f,1.0f)*size*EnergyExplosionSizeFactor,
			Ogre::ColourValue(1.0f,1.0f,1.0f,1.0f),
			EnergyExplosionDuration,
			BillboardManager::OPTIONS_FADE_OUT | BillboardManager::OPTIONS_ALIGNED | BillboardManager::OPTIONS_SCALE_UP,
			Ogre::Vector2(1.0f,1.0f)*size*EnergyExplosionSizeFactor);
	}
}
	Object* ObjectManager::collisionAABB(const Ogre::Vector3& fromPoint, const Ogre::Vector3& toPoint, int queryMask)
	{
		Ogre::Vector3 direction = toPoint - fromPoint;
		Ogre::Ray ray(fromPoint, direction);
		mRayQuery->setRay(ray);
		mRayQuery->setQueryMask(queryMask);
		// The rays are sorted by the distance query set, [very important]
		mRayQuery->setSortByDistance(true);

		Ogre::RaySceneQueryResult& result = mRayQuery->execute();
		Ogre::RaySceneQueryResult::iterator itr = result.begin();

		// Just get the nearest object
		if (itr != result.end() && itr->movable)
		{
			Ogre::MovableObject *object =  itr->movable;
			Ogre::Vector3 pos = object->getParentSceneNode()->getPosition();
			// If the current starting point of an object in the distance is less than a predetermined range
			// then return this obj
			// Avoid using the square root operation squaredLength
			if ((pos - fromPoint).squaredLength() <= direction.squaredLength())
				return getObject(itr->movable->getName());
		}

		return NULL;
	}
Ogre::Real DeferredLight::getSquaredViewDepth(const Ogre::Camera* camera) const {
    if (ignoreWorld) {
        return 0.0;
    } else {
        Ogre::Vector3 dist = camera->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition();
        return dist.squaredLength();
    }
}
Cell* NavigationMesh::findCell(const Ogre::Vector3& pos) {
    Ogre::Vector3 v;
    Ogre::Vector3 minDistance = Ogre::Vector3(500.0, 500.0, 500.0);
    Cell* closestCell = 0;
    
    for (Cells::iterator i = _cells.begin(); i != _cells.end(); ++i) {
        if ((*i)->containsPoint(pos)) {
            return *i;
        }
	
	v = (*i)->getCenter() - pos;
	if (v.squaredLength() < minDistance.squaredLength()) {
	    minDistance = v;
	    closestCell = (*i);
	}
    }

    return closestCell;
}
bool CEditor::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	// manually call sample callback to ensure correct order
	mGuiMgr->frameRenderingQueued(evt);

	if ( mHaveLevel )
	{
		// build our acceleration vector based on keyboard input composite
		Ogre::Vector3 accel = Ogre::Vector3::ZERO;
		if (mGoingForward) 
			accel += mCamera->getDirection();
		if (mGoingBack) 
			accel -= mCamera->getDirection();
		if (mGoingRight)
			accel += mCamera->getRight();
		if (mGoingLeft)
			accel -= mCamera->getRight();
		if (mGoingUp) 
			accel += mCamera->getUp();
		if (mGoingDown) 
			accel -= mCamera->getUp();

		// if accelerating, try to reach top speed in a certain time
		Ogre::Real topSpeed = mTopSpeed;
		if (accel.squaredLength() != 0)
		{
			accel.normalise();
			mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10;
		}
		// if not accelerating, try to stop in a certain time
		else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10;

		Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon();

		// keep camera velocity below top speed and above epsilon
		if (mVelocity.squaredLength() > topSpeed * topSpeed)
		{
			mVelocity.normalise();
			mVelocity *= topSpeed;
		}
		else if (mVelocity.squaredLength() < tooSmall * tooSmall)
			mVelocity = Ogre::Vector3::ZERO;

		if (mVelocity != Ogre::Vector3::ZERO)
		{
			mCamera->move(mVelocity * evt.timeSinceLastFrame);
		}
		else
		{
			mpEntityMgr->UpdatePageManager();
		}
	}

	return true;
}
//-----------------------------------------------------------------------
inline void GravityAffector::_affect(ParticleTechnique* particleTechnique, Particle* particle, Ogre::Real timeElapsed)
{
    /** Applying Newton's law of universal gravitation.	*/
    Ogre::Vector3 distance = mDerivedPosition - particle->position;
    Ogre::Real length = distance.squaredLength();
    if (length > 0)
    {
        Ogre::Real force = (mGravity * particle->mass * mass) / length;
        particle->direction += force * distance * timeElapsed * _calculateAffectSpecialisationFactor(particle);
    }
}
Exemple #11
0
bool CameraMan::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
  CameraStyle mStyle = getCameraStyle();
  if (mStyle == CS_FREELOOK)
  {
    // build our acceleration vector based on keyboard input composite
    Ogre::Vector3 accel = Ogre::Vector3::ZERO;
    if (mGoingForward)
      accel += mCamera->getDirection();
    if (mGoingBack)
      accel -= mCamera->getDirection();
    if (mGoingRight)
      accel += mCamera->getRight();
    if (mGoingLeft)
      accel -= mCamera->getRight();
    if (mGoingUp)
      accel += mCamera->getUp();
    if (mGoingDown)
      accel -= mCamera->getUp();

    // if accelerating, try to reach top speed in a certain time
    Ogre::Real topSpeed = mFastMove ? mTopSpeed * mFastFactor : mTopSpeed;
    if (accel.squaredLength() != 0)
    {
      accel.normalise();
      mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10;
    }
    // if not accelerating, try to stop in a certain time
    else
    {
      Ogre::Vector3 dir = mVelocity;
      mVelocity -= mVelocity * evt.timeSinceLastFrame * 10;
      if (mVelocity.dotProduct(dir) < 0.)
        mVelocity = Ogre::Vector3::ZERO;

    }

    Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon();

    // keep camera velocity below top speed and above epsilon
    if (mVelocity.squaredLength() > topSpeed * topSpeed)
    {
      mVelocity.normalise();
      mVelocity *= topSpeed;
    }
    else if (mVelocity.squaredLength() < tooSmall * tooSmall)
      mVelocity = Ogre::Vector3::ZERO;

    if (mVelocity != Ogre::Vector3::ZERO)
      mCamera->move(mVelocity * evt.timeSinceLastFrame);
  }
  return true;
}
      /*
        distance(target_positon+t*target_speed) = t*interceptor_speed
        formal solver gives :
          
        delta = 
            (-target_positon.y^2-target_positon.x^2)*target_speed.z^2
            +(2*target_positon.y*target_positon.z*target_speed.y+2*target_positon.x*target_positon.z*target_speed.x)*target_speed.z
            +(-target_positon.z^2-target_positon.x^2)*target_speed.y^2
            +2*target_positon.x*target_positon.y*target_speed.x*target_speed.y
            +(-target_positon.z^2-target_positon.y^2)*target_speed.x^2
            +interceptor_speed^2*target_positon.z^2
            +interceptor_speed^2*target_positon.y^2
            +interceptor_speed^2*target_positon.x^2
        
        if delta > 0
        t = (sqrt(delta)
              -target_positon.z*target_speed.z-target_positon.y*target_speed.y-target_positon.x*target_speed.x)
            /(target_speed.z^2+target_speed.y^2+target_speed.x^2-laser_speed^2)
        
        special case for delta=0 when equation becomes linear
      */
      std::pair<bool,float> calculateInterceptionTime(
          const Ogre::Vector3& target_position,
          const Ogre::Vector3& target_speed,
          const float& interceptor_speed)
      {
        
        // result ;
        float time = 0 ;
        
        if (target_speed.length() != 0)
        {
          
          float delta = 
                  (-pow(target_position.y,2)-pow(target_position.x,2))*pow(target_speed.z,2)
                  +(2*target_position.y*target_position.z*target_speed.y+2*target_position.x*target_position.z*target_speed.x)*target_speed.z
                  +(-pow(target_position.z,2)-pow(target_position.x,2))*pow(target_speed.y,2)
                  +2*target_position.x*target_position.y*target_speed.x*target_speed.y
                  +(-pow(target_position.z,2)-pow(target_position.y,2))*pow(target_speed.x,2)
                  +pow(interceptor_speed,2)*pow(target_position.z,2)
                  +pow(interceptor_speed,2)*pow(target_position.y,2)
                  +pow(interceptor_speed,2)*pow(target_position.x,2) ;

          float divisor = target_speed.squaredLength()-pow(interceptor_speed,2) ;
          
          if (delta > 0 && fabs(divisor) > 1e-10)
          {
            float b = -target_position.z*target_speed.z-target_position.y*target_speed.y-target_position.x*target_speed.x ;
            time = (sqrt(delta)+b)/divisor ;
            if (time < 0)
              time = (-sqrt(delta)+b)/divisor ;
          }
          else
          {
            /// no real solution : target is unreachable by interceptor
            return std::pair<bool,float>(false,0) ;
          }
        }
        else
        {
          time = target_position.length()/interceptor_speed ;
        }
        
        return std::pair<bool,float>(true,time) ;
      }
void BubbleController::Update(float dt){
	if (m_apply_impulse){
		Ogre::Vector3 impulse = (m_impulse_direction * m_velocity) * dt;
		m_messenger->Notify(MSG_RIGIDBODY_APPLY_IMPULSE, &impulse, "body");
		m_apply_impulse = false;
		if (m_owner->GetType() == GAME_OBJECT_PINK_BUBBLE){
			m_distance -= impulse.squaredLength();
		}
	}
	if (m_owner->GetType() == GAME_OBJECT_PINK_BUBBLE){
		float percent = m_max_distance * 0.5f;
		if (m_distance < percent){
			Ogre::SceneNode* node = NULL;
			m_messenger->Notify(MSG_NODE_GET_NODE, &node);
			if (node){
				float scale_inc = (m_scale_increment * (percent / m_distance)) * dt;
				if (m_scale_state == 0) {    // increase size
					Ogre::Vector3 scale = node->getScale() + scale_inc;
					node->setScale(scale);
					if (node->getScale().y > m_max_scale){
						node->setScale(Ogre::Vector3(m_max_scale));
						m_scale_state = 1;
					}
				}
				else if (m_scale_state == 1){    // decrease size
					Ogre::Vector3 scale = node->getScale() - scale_inc;
					node->setScale(scale);
					if (node->getScale().y < m_original_scale){
						node->setScale(Ogre::Vector3(m_original_scale));
						m_scale_state = 0;
					}
				}
			}
		}
		if (m_distance <= 0.0f){
			SoundData2D pop_sound = m_owner->GetGameObjectManager()->GetSoundManager()->Create2DData("Bubble_Burst", false, false, false, false, 1.0, 1.0);
			m_owner->GetGameObjectManager()->GetGameObject("Player")->GetComponentMessenger()->Notify(MSG_SFX2D_PLAY, &pop_sound);
			m_owner->RemoveGameObject(m_owner);
		}
	}
}
//-----------------------------------------------------------------------
bool Plane::intersect(const Plane& other, Line& outputLine) const
	{		
		//TODO : handle the case where the plane is perpendicular to T
		Ogre::Vector3 point1;
		Ogre::Vector3 direction = normal.crossProduct(other.normal);
		if (direction.squaredLength() < 1e-08)
			return false;
		
		Ogre::Real denom = 1./(normal.x*other.normal.y-other.normal.x*normal.y);
		{
			Ogre::Real d1 = d;
			Ogre::Real d2 = other.d;
			point1.x = (normal.y*d2-other.normal.y*d1)*denom;
			point1.y = (other.normal.x*d1-normal.x*d2)*denom;
			point1.z = 0;
		}
		
		outputLine = Line(point1, direction);

		return true;
	}
BoundingSphere::BoundingSphere(const BoundingSphere &one,
                               const BoundingSphere &two)
{
	Ogre::Vector3 centerOffset = two.center - one.center;
    real distance = centerOffset.squaredLength();
    real radiusDiff = two.radius - one.radius;
	
    // Check if the larger sphere encloses the small one
    if (radiusDiff*radiusDiff >= distance)
    {
        if (one.radius > two.radius)
        {
            center = one.center;
            radius = one.radius;
        }
        else
        {
            center = two.center;
            radius = two.radius;
        }
    }
	
    // Otherwise we need to work with partially
    // overlapping spheres
    else
    {
        distance = Ogre::Math::Sqrt(distance);
        radius = (distance + one.radius + two.radius) * ((real)0.5);
		
        // The new centre is based on one's centre, moved towards
        // two's centre by an ammount proportional to the spheres'
        // radii.
        center = one.center;
        if (distance > 0)
        {
            center += centerOffset * ((radius - one.radius)/distance);
        }
    }	
}
Exemple #16
0
void CameraMan::frameRendered(const Ogre::FrameEvent &evt)
{
    if (mStyle == CS_FREELOOK)
    {
        // build our acceleration vector based on keyboard input composite
        Ogre::Vector3 accel = Ogre::Vector3::ZERO;
        Ogre::Matrix3 axes = mCamera->getLocalAxes();
        if (mGoingForward) accel -= axes.GetColumn(2);
        if (mGoingBack) accel += axes.GetColumn(2);
        if (mGoingRight) accel += axes.GetColumn(0);
        if (mGoingLeft) accel -= axes.GetColumn(0);
        if (mGoingUp) accel += axes.GetColumn(1);
        if (mGoingDown) accel -= axes.GetColumn(1);

        // if accelerating, try to reach top speed in a certain time
        Ogre::Real topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed;
        if (accel.squaredLength() != 0)
        {
            accel.normalise();
            mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10;
        }
        // if not accelerating, try to stop in a certain time
        else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10;

        Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon();

        // keep camera velocity below top speed and above epsilon
        if (mVelocity.squaredLength() > topSpeed * topSpeed)
        {
            mVelocity.normalise();
            mVelocity *= topSpeed;
        }
        else if (mVelocity.squaredLength() < tooSmall * tooSmall)
            mVelocity = Ogre::Vector3::ZERO;

        if (mVelocity != Ogre::Vector3::ZERO) mCamera->translate(mVelocity * evt.timeSinceLastFrame);
    }
}
float ogreVectorLength(Ogre::Vector3 v)
{
  return v.squaredLength();
}
Exemple #18
0
bool PhysicsEngine::PerformSphereSphereCollisionTest(const Ogre::FrameEvent &fe, PhysicsEntity *sphere1, PhysicsEntity *sphere2)
{
	float overlapMagnitude = (sphere1->GetRadius() + sphere2->GetRadius()) - sphere1->getPosition().distance(sphere2->getPosition());
	if (overlapMagnitude >= 0.0f)
	{
		Ogre::Vector3 d = sphere2->getPosition() - sphere1->getPosition();
		Ogre::Vector3 relativeVelocity = d * (d.dotProduct(sphere1->GetVelocity() - sphere2->GetVelocity()) / d.squaredLength());
		
		Ogre::Vector3 impulse1 = (((sphere2->GetRestitution() + 1.0f) * relativeVelocity) /
			((1 / sphere1->GetMass()) + (1 / sphere2->GetMass())));
		Ogre::Vector3 impulse2 = -(((sphere1->GetRestitution() + 1.0f) * relativeVelocity) /
			((1 / sphere1->GetMass()) + (1 / sphere2->GetMass())));
		
		//Ogre::Vector3 currentImpulse1 = d * (d.dotProduct(sphere1->GetAppliedForce()) / d.squaredLength());
		//Ogre::Vector3 currentImpulse2 = -d * (d.dotProduct(sphere2->GetAppliedForce()) / d.squaredLength());
		
		if (sphere1->GetBodyType() == ENTITY_BODY_SPHERE && sphere2->GetBodyType() == ENTITY_BODY_SPHERE)
		{
			sphere1->translate(-d.normalisedCopy() * (overlapMagnitude / 2.0f));
			sphere2->translate(d.normalisedCopy() * (overlapMagnitude / 2.0f));

			sphere2->ApplyForce(impulse1);// + currentImpulse1);
			sphere1->ApplyForce(impulse2);// + currentImpulse2);
		}

		sphere1->Collide(fe, sphere2);
		sphere2->Collide(fe, sphere1);

		return true;
	}

	return false;
}
Exemple #19
0
void PhysicsEngine::Update(const Ogre::FrameEvent &fe)
{
	std::vector<PhysicsEntity *> gravitationalEntities;
	std::vector<PhysicsEntity *> dynamicEntities;
	std::vector<PhysicsEntity *> collidableEntities;

	for (std::vector<PhysicsEntity *>::iterator it = physicsEntities.begin(); it != physicsEntities.end(); ++it)
	{
		if ((*it)->isAlive())
		{
			if ((*it)->IsGravitational())
			{
				gravitationalEntities.push_back(*it);
			}
			if ((*it)->IsDynamic())
			{
				dynamicEntities.push_back(*it);
			}
			if ((*it)->GetBodyType() != ENTITY_BODY_METAPHYSICAL)
			{
				collidableEntities.push_back(*it);
			}
		}
	}
	for (std::vector<PhysicsEntity *>::iterator it = dynamicEntities.begin(); it != dynamicEntities.end(); ++it)
	{
		for (std::vector<PhysicsEntity *>::iterator gr = gravitationalEntities.begin(); gr != gravitationalEntities.end(); ++gr)
		{
			if (*it != *gr)
			{
				Ogre::Vector3 distance = (*gr)->getPosition() - (*it)->getPosition();
				if (distance.squaredLength() != 0.0f)
				{
					Ogre::Vector3 force = distance.normalisedCopy() *
						gravitationalConstant * (((*it)->GetMass() * (*gr)->GetMass()) /
						((*gr)->IsAbsoluteGravitationalPull() ? ((*gr)->GetRadius() + (*it)->GetRadius()) : distance.squaredLength()));
					(*it)->ApplyForce(force);
					if ((*gr)->IsDynamic())
					{
						(*gr)->ApplyForce(force);
					}
				}
			}
		}
	}
	while (collidableEntities.size() > 0)
	{
		PhysicsEntity *i = collidableEntities.back();

		for (std::vector<PhysicsEntity *>::reverse_iterator it = collidableEntities.rbegin(); it != collidableEntities.rend(); ++it)
		{
			if (i != (*it) && i->isAlive() && (*it)->isAlive() && 
				//i->GetObjectID() != (*it)->GetObjectID() && i->GetParentID() != (*it)->GetParentID() &&
				i->GetObjectID() != (*it)->GetParentID() && i->GetParentID() != (*it)->GetObjectID())
			{
				if (i->GetBodyType() == ENTITY_BODY_SPHERE || i->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE)
				{
					if ((*it)->GetBodyType() == ENTITY_BODY_SPHERE || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE)
					{
						PerformSphereSphereCollisionTest(fe, i, *it);
					}
					else if ((*it)->GetBodyType() == ENTITY_BODY_RAY || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_RAY)
					{
						PerformRaySphereCollisionTest(fe, *it, i);
					}
				}
				else if (i->GetBodyType() == ENTITY_BODY_RAY || i->GetBodyType() == ENTITY_BODY_METAPHYSICAL_RAY)
				{
					if ((*it)->GetBodyType() == ENTITY_BODY_SPHERE || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE)
					{
						PerformRaySphereCollisionTest(fe, i, *it);
					}
				}
			}
		}
		collidableEntities.pop_back();
	}
}
void AIFlyNAttack1Strategy::Step(unsigned timeMs)
{		
    /*
     смотрим существует ли цель
     если режим исходный:
     устанавливаем режим подхода
     если режим подхода:
     если цель критически близко - строим вектор отхода за цель (по собств. скорости), не стреляем, смотрим по ходу движения, у подчиненных включаем стратегию смотреть по ходу движения и включаем режим отхода
     если цель на подходящем расстоянии - подходим прямо на нее и атакуем
     если режим отхода:
     если цель на подходящем расстоянии включаем режим подхода
     если цель близко - корректируем вектор скорости
     */
    #ifdef FNAS1_DEBUG
    char log[100];
    #endif
    
    IPhysical *phys = Parent->GetPhysical();
    IScenable *scen = Parent->GetScenable();
	
	if (TargetID<0)
	{		
		return;
	}
	if (TargetID==0)
	{
		if (Owner)
		{
			TargetID = Owner->SelectTargetID();			
		}
		if (TargetID<=0)
		{
			TargetID=-1;
			IEquipped *eq = Parent->GetEquipped();
            if (eq)
            {
                eq->SetTargetPosition(Ogre::Vector3::ZERO);
                eq->SetShooting(false);
            }			
			return;
		}
	}

    IAAObject *obj = CommonDeclarations::GetIDObject(TargetID);
    if (NULL==obj)
    {		
        TargetID=0;
        return;
    }
    IScenable* Target;	
    Target = obj->GetScenable();
    if (NULL==Target)
        return;

	#ifdef FNAS1_DEBUG
    sprintf(log,"start: %d\n", (int)FlyNAttack1State);
    Debugging::Log("fnas",log);
	#endif

    if (FA1_NONE == FlyNAttack1State)
        FlyNAttack1State = FA1_SEEKING;

	Ogre::Vector3 tpos = Target->GetPosition();
	int tradius=300;
    Ogre::Vector3 target_pos = tpos, own_pos = Parent->GetPosition();
    Ogre::Vector3 direction = target_pos - own_pos;
    Ogre::Vector3 orient_direction=Ogre::Vector3::ZERO;
    int actual_rotation_fps = RotationSpeed;
    AIPathFinderStrategy *pf = Owner->GetPathFinder();

	bool is_out_of_rooms = false, is_target_out_of_rooms = false;

	IRoomable *rmbl = obj->GetRoomable();
	if (rmbl)
	{
		IRoomable::RoomsPool *pool = rmbl->GetRooms();
		if (pool->IsEmpty())
			is_target_out_of_rooms = true;
	}

	rmbl = Parent->GetRoomable();
	if (rmbl)
	{
		IRoomable::RoomsPool *pool = rmbl->GetRooms();
		if (pool->IsEmpty())
			is_out_of_rooms = true;
	}

	if (is_out_of_rooms || is_target_out_of_rooms)
	{	
		SwarmStrategy.Step(timeMs);
		return;
	}

	
	{
		PrevState = FlyNAttack1State;

		switch(FlyNAttack1State) {
		case FA1_SEEKING:
			//if (FA1_SEEKING == FlyNAttack1State)
			{
				FleeingTime=0;
				//Ogre::Vector3 target_pos = Target->GetPosition(), own_pos = Parent->GetPosition();
				//Ogre::Vector3 direction = target_pos - own_pos;
				if (direction.squaredLength()<MinDistance*MinDistance)
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"seek close\n");
					Debugging::Log("fnas",log);
					#endif
					FlyNAttack1State = FA1_SEEKING2FLEEING;

					Ogre::Vector3 BoundingPoints[8];
					Target->GetBoundingPoints(Target->GetBoundingBox(false).getSize().z+phys->GetRadius()*2, BoundingPoints);

					IEquipped *eq = Parent->GetEquipped();
					if (eq)
					{
						eq->SetTargetPosition(Ogre::Vector3::ZERO);
						eq->SetShooting(false);
					}

					if (pf)
					{
						Ogre::Vector3 target_point = BoundingPoints[int(7*AAUtilities::Rand())];
						pf->SetTargetPoint(target_point);
						FleeingDirection = target_point - own_pos;
						//orient_direction = target_point - own_pos;
					}
				} else
				{            
					if (direction.squaredLength()<MaxDistance*MaxDistance)
					{
						#ifdef FNAS1_DEBUG
						sprintf(log,"seek go on\n");
						Debugging::Log("fnas",log);
						#endif
						//std::pair<bool, Ogre::Real> intersection_res;
	                    
						IPhysical *phys = obj->GetPhysical();
						IEquipped *eq = Parent->GetEquipped();
						if (phys)
						{
							tpos = eq->CalculateTargetPosition(obj->GetPosition(), phys->GetLastVelocity()/PHYSICS_UPDATE_INTERVAL_MS);
							tradius = phys->GetRadius();
						}                    
						eq->TryToShoot(tpos, tradius);
						Ogre::Vector3 sight_origin = eq->GetSightOrigin();
						sight_origin.z=0;
						tpos -= scen->GetOrientation()*sight_origin;
						direction = tpos - own_pos;
					}      
					if (pf)
					{					
						pf->SetTargetPoint(tpos);
					}
					orient_direction = direction;
					actual_rotation_fps = actual_rotation_fps/4;
				}        
			}
    		break;
		case FA1_SEEKING2FLEEING:
			//if (FA1_SEEKING2FLEEING == FlyNAttack1State)
			{
				FleeingTime+=timeMs;
				if (phys)
					orient_direction = FleeingDirection; //-phys->GetForwardDirection().normalisedCopy();
				/*if (FleeingTime>MaxFleeingTime)
				{
	#ifdef FNAS1_DEBUG
					sprintf(log,"seek2flee to breakaway\n");
					Debugging::Log("fnas",log);
	#endif
					FlyNAttack1State = FA1_BREAKAWAY;
					FleeingTime=0;
				} else*/
				if (direction.squaredLength()>(MinDistance+BufferZone)*(MinDistance+BufferZone))
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"seek2flee switch off\n");
					Debugging::Log("fnas",log);
					#endif
					FlyNAttack1State = FA1_FLEEING;
				} else
				{
					//AIPathFinderStrategy *pf = Owner->GetPathFinder();
					#ifdef FNAS1_DEBUG
					sprintf(log,"seek2flee go on\n");
					Debugging::Log("fnas",log);
					#endif
					//actual_rotation_fps = actual_rotation_fps*4;
					if (pf)
					{
						Ogre::Vector3 target_point = own_pos+orient_direction*100000;
						pf->SetTargetPoint(target_point);                
					}
				}                
			}
    		break;
		case FA1_FLEEING:
			//if (FA1_FLEEING == FlyNAttack1State)
			{
				FleeingTime+=timeMs;
				if (phys)
					orient_direction = -phys->GetForwardDirection();

				//AIPathFinderStrategy *pf = Owner->GetPathFinder();

				if (direction.squaredLength()>(MaxDistance+BufferZone)*(MaxDistance+BufferZone))
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"flee far\n");
					Debugging::Log("fnas",log);
					#endif
					FlyNAttack1State = FA1_FLEEING2SEEKING;                            
				} else
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"flee go on\n");
					Debugging::Log("fnas",log);
					#endif
					if (pf)
					{
						Ogre::Vector3 target_point = own_pos+orient_direction*10000;
						pf->SetTargetPoint(target_point);                
					}
				}
			}
			break;
		case FA1_FLEEING2SEEKING:
			//if (FA1_FLEEING2SEEKING == FlyNAttack1State)
			{
				FleeingTime = 0;
				if (direction.squaredLength()<MaxDistance*MaxDistance)
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"flee2seek switch off\n");
					Debugging::Log("fnas",log);
					#endif
					FlyNAttack1State = FA1_SEEKING;

					/*if (pf)
					{
					Ogre::Vector3 target_point = target_pos;
					pf->SetTargetPoint(target_point);                
					orient_direction = target_point - own_pos;
					}*/
				} else
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"flee2seek go on\n");
					Debugging::Log("fnas",log);
					#endif
					actual_rotation_fps = actual_rotation_fps*5;
					
					if (pf)
					{                
						orient_direction = direction;					
						Ogre::Vector3 target_point = Ogre::Vector3::NEGATIVE_UNIT_Z*10000;
						Ogre::Quaternion orientation = scen->GetOrientation();
						target_point = orientation * target_point;
						target_point = own_pos + target_point;
						pf->SetTargetPoint(target_point);                
					}
					
				}
				//if (phys)
				//    orient_direction = -phys->GetForwardDirection();
			}
			break;    
		case FA1_BREAKAWAY:
			//if (FA1_FLEEING2SEEKING == FlyNAttack1State)
			{
				FleeingTime = 0;
				if (direction.squaredLength()>(MinDistance+BufferZone)*(MinDistance+BufferZone))
				{
					#ifdef FNAS1_DEBUG
					sprintf(log,"BREAKAWAY switch off\n");
					Debugging::Log("fnas",log);
					#endif
					FlyNAttack1State = FA1_FLEEING;
				} else
				{
	#ifdef FNAS1_DEBUG
					sprintf(log,"BREAKAWAY go on\n");
					Debugging::Log("fnas",log);
	#endif
					actual_rotation_fps = actual_rotation_fps*5;

					if (pf)
					{                
						orient_direction = direction;					
						Ogre::Vector3 target_point = Ogre::Vector3::NEGATIVE_UNIT_Z*10000;
						Ogre::Quaternion orientation = scen->GetOrientation();
						target_point = orientation * target_point;
						target_point = own_pos + target_point;
						pf->SetTargetPoint(target_point);                
					}

				}
				//if (phys)
				//    orient_direction = -phys->GetForwardDirection();
			}
			break;
		};

		#ifdef FNAS1_DEBUG
		sprintf(log,"end: %d\n", (int)FlyNAttack1State);
		Debugging::Log("fnas",log);		
		#endif
	}/* else
		{
			actual_rotation_fps = actual_rotation_fps*5;

			if (pf)
			{                
				orient_direction = direction;					
				Ogre::Vector3 target_point = Ogre::Vector3::NEGATIVE_UNIT_Z*10000;
				Ogre::Quaternion orientation = scen->GetOrientation();
				target_point = orientation * target_point;
				target_point = own_pos + target_point;
				pf->SetTargetPoint(target_point);                
			}
		}*/
	
    if (!orient_direction.isZeroLength() && PrevOrientDirection != orient_direction)
    {
        Ogre::Quaternion OurOrientation = scen->GetOrientation();

        //Ogre::Vector3 direction = Target->GetPosition()-scen->GetPosition();

        orient_direction.normalise();

        Ogre::Vector3 up =CommonDeclarations::GetUpVector();
        
        Vector3 xVec = up.crossProduct(orient_direction);
        xVec.normalise();
        Vector3 yVec = orient_direction.crossProduct(xVec);
        yVec.normalise();
        Quaternion unitZToTarget = Quaternion(xVec, yVec, orient_direction);

        Quaternion targetOrientation = Quaternion(-unitZToTarget.y, -unitZToTarget.z, unitZToTarget.w, unitZToTarget.x);

        PrevOrientDirection = orient_direction;        
        RotationUnit.StartRotation(OurOrientation, targetOrientation, actual_rotation_fps);
    }
	
	if(RotationUnit.mRotating)
	{
		RotationUnit.Step();
		if(RotationUnit.mRotating)                                // Process timed rotation
		{				
			Ogre::Quaternion delta = RotationUnit.Slerp();	
			scen->SetOrientation(delta);
		}
	}   
}
Exemple #21
0
void PhysicalCamera::grasp()
{
    if (!mGraspedObject)
    {
        // Fire a ray into the scene to find an object to grasp.  If
        // an object is found, attach it to the grasping Motor and,
        // if using long range grasping mode, store the intersection
        // position relative to the camera as the grasp offset.

        // First update the ray casting Sensor's ray.
        Ogre::Vector3 camForward = mOgreCamera->getDerivedDirection();
        if (0 != camForward.squaredLength())
        {
            camForward.normalise();
        }
        opal::Vec3r rayDir(camForward[0], camForward[1],
                           camForward[2]);
        if (PHYSICAL == mType)
        {
            // The ray's origin will be updated automatically since
            // it is attached to the camera's Solid.  Its direction
            // should be set manually here because we constantly
            // reset the camera's orientation.
            opal::Point3r dummyPoint;
            opal::Rayr r(dummyPoint, rayDir);
            mGraspingSensor->setRay(r);
        }
        else
        {
            // The ray should start at the camera's position and fire
            // straight forward into the scene.
            Ogre::Vector3 ogreCamPos = mOgreCamera->getDerivedPosition();
            opal::Point3r opalCamPos(ogreCamPos[0], ogreCamPos[1],
                                     ogreCamPos[2]);
            opal::Rayr r(opalCamPos, rayDir);
            mGraspingSensor->setRay(r);
        }

        // Fire the ray.
        opal::RaycastResult result =
            mGraspingSensor->fireRay(mMaxReach);

        if (result.solid) // && !result.solid->isStatic())
        {
            // Store the grasped object.
            mGraspedObject = result.solid;

            // Initialize the grasping Motor with the new data.
            opal::SpringMotorData data;
            data.solid = result.solid;
            data.mode = mGraspingMotorMode;
            data.linearKs = mGraspingLinearKs;
            data.linearKd = mGraspingLinearKd;
            data.angularKs = mGraspingAngularKs;
            data.angularKd = mGraspingAngularKd;

            opal::Matrix44r solidTransform = result.solid->getTransform();
            //data.desiredUp = solidTransform.getUp();
            //data.desiredForward = solidTransform.getForward();
            //data.desiredRight = solidTransform.getRight();
            // Desired position will be updated in the "update"
            // function.
            mGraspingMotor->init(data);

            if (PHYSICAL == mType)
            {
                //// Grab it where the ray intersected it.
                //mGraspingMotor->setGlobalAttachPoint(result.intersection);

                // Just grab it in the middle.
                mGraspingMotor->setGlobalAttachPoint(result.solid->
                                                     getPosition());
            }
            else
            {
                mGraspingMotor->setGlobalAttachPoint(result.intersection);

                // Set the offset (from the camera) to be the same distance
                // as when it was grasped.
                mPhysicalGraspOffset.set(0, 0, -result.distance);
            }

            // Compute the grasped object's offset transform from the camera
            // which is only used for desired orientation.
            Ogre::Matrix4 ogreMat;
            mOgreCamera->getParentSceneNode()->getWorldTransforms(&ogreMat);
            opal::Matrix44r camTransform(
                ogreMat[0][0], ogreMat[1][0], ogreMat[2][0], ogreMat[3][0],
                ogreMat[0][1], ogreMat[1][1], ogreMat[2][1], ogreMat[3][1],
                ogreMat[0][2], ogreMat[1][2], ogreMat[2][2], ogreMat[3][2],
                ogreMat[0][3], ogreMat[1][3], ogreMat[2][3], ogreMat[3][3]);
            camTransform.invert();
            opal::Matrix44r objTransInv = mGraspedObject->getTransform();
            objTransInv.invert();
            mGraspedObjectOffsetTransform = objTransInv * camTransform;

            // Set the desired transform for orientation only (the position
            // part should be overwritten below).
            opal::Matrix44r desiredObjTransform = mGraspedObjectOffsetTransform *
                                                  camTransform;
            desiredObjTransform.invert();
            mGraspingMotor->setDesiredTransform(desiredObjTransform);

            // Update the the desired position.
            mGraspingMotor->setDesiredPosition(getGraspGlobalPos());

            // Apply extra angular damping.
            result.solid->setAngularDamping(3);
        }
    }
}
Exemple #22
0
bool RoomsManager::UpdateObject(Room::ObjectType* object)
{    
    bool updated=false, inrooms=false;
    Room *room;

    //std::vector<Room*>::iterator iPos=Rooms.begin(), iEnd=Rooms.end();
	inrooms=false;
    //for (size_t i=0;i<Rooms.Size;++i)
    Ogre::AxisAlignedBox box = object->GetRoomable()->GetBoundingBox(), *RoomBox;
    
	//assert()

	for (RoomsPool::ListNode *pos = Rooms.GetBegin(); pos!=NULL; pos=pos->Next)
    {
        room = pos->Value;        
        RoomBox = room->GetBox();
        if (RoomBox->intersects(box))
        {
            updated = room->UpdateObject(object);
            if (updated)
		    {           
			    inrooms=true;			
		    }
        }
    }

	if (!inrooms)
	{
		/*char log[100];
		sprintf(log,"Rooms 1: empty room set for object %d\n",object->GetScriptable()->GetID());
		Debugging::Log("Warnings.log",log);*/		
				
		IRoomable *rmbl = object->GetRoomable();
		IPhysical *phys = object->GetPhysical();
		if (rmbl)
		{
			rmbl->RemoveFromRooms();
			rmbl->GetRooms()->Clear();			
			switch (rmbl->GetRoomOnly())
			{
				case IRoomable::ROM_RESTORE:
					{						
						for (RoomsPool::ListNode *pos = Rooms.GetBegin(); pos!=NULL; pos=pos->Next)
						{
							Ogre::AxisAlignedBox *box = pos->Value->GetBox();
							Ogre::Vector3 center = box->getCenter();
							Ogre::Vector3 position = object->GetPosition();
							Ogre::Vector3 dist = position - center;

							int sqradius = AAUtilities::f2i(box->getHalfSize().squaredLength())+3*phys->GetRadius();
														
							int sqdist = AAUtilities::f2i(dist.squaredLength());
							if (sqradius>sqdist)
							{
								//GetPhysical()->SetForwardDirection(GetOrientation()*Vector3::UNIT_Z);
								//object->GetPhysical();
								//object->RestoreBackupPosition();								
								//Ogre::Vector3 newdir=phys->GetLastVelocity();
								//phys->Stop();
								phys->SetReplacingDirection(-dist.normalisedCopy()*10);
								break;
							}
						}
						AddOuterObject(object);
						//object->RestoreBackupPosition();
						break;
					}					
				case IRoomable::ROM_DESTROY:
					{
						CommonDeclarations::DeleteObjectRequest(object);
						break;
					}					
				case IRoomable::ROM_SCRIPT:
					{
						IScriptable *scr = object->GetScriptable();
						if (scr && scr->GetID()>0)
							ScriptManager::GetInstance()->Call("OnOutOfRooms", "i", false, object->GetScriptable()->GetID());
						break;
					}
				case IRoomable::ROM_NONE:
					{
						AddOuterObject(object);
						break;
					}

			};
		}
		
	}
    
    return inrooms;
}
Exemple #23
0
bool CameraMan::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	// update accelerations
	Ogre::Vector3 accel = calculateAccelerations();

	// if accelerating, try to reach top speed in a certain time
	Ogre::Real topSpeed = mFastMove ? mTopSpeed * 2 : mTopSpeed;
	double y_tmp = mVelocity.y;
	if (accel.squaredLength() != 0)
	{
		accel.normalise();
		mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10;
	}
	// if not accelerating, try to stop in a certain time
	else 
	{
		mVelocity -= mVelocity * evt.timeSinceLastFrame * 10;
	}
	mVelocity.y = y_tmp;

	// vertical movement
	if (mJump) mVelocity.y = jumpSpeed;
	mJump = false;
	mVelocity.y -= gravityAccel * evt.timeSinceLastFrame;

	Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon();

	y_tmp = mVelocity.y;
	mVelocity.y = 0;
	// keep camera velocity below top speed and above epsilon
	if (mVelocity.squaredLength() > topSpeed * topSpeed)
	{
		mVelocity.normalise();
		mVelocity *= topSpeed;
	}
	else if (mVelocity.squaredLength() < tooSmall * tooSmall)
	{
		mVelocity = Ogre::Vector3::ZERO;
	}
	mVelocity.y = y_tmp;

	// terrain handling, raycast each unit direction
	PolyVox::RaycastResult resultXH;
	PolyVox::RaycastResult resultXL;
	PolyVox::RaycastResult resultY;
	PolyVox::RaycastResult resultZH;
	PolyVox::RaycastResult resultZL;

	double width = 0.5;
	PolyVox::Vector3DFloat cameraPos( mCamera->getPosition().x, mCamera->getPosition().y,						mCamera->getPosition().z );
	PolyVox::Vector3DFloat cameraPosH( mCamera->getPosition().x, mCamera->getPosition().y + width,				mCamera->getPosition().z );
	PolyVox::Vector3DFloat cameraPosL( mCamera->getPosition().x, mCamera->getPosition().y - charHeight + width,	mCamera->getPosition().z );

	if( mVelocity.x > 0 )
	{
		mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( width, 0, 0), resultXH);
		mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( width, 0, 0), resultXL);
	}
	else if( mVelocity.x < 0 )
	{
		mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat(-width, 0, 0), resultXH);
		mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat(-width, 0, 0), resultXL);
	}
	else
	{
		resultXH.foundIntersection = false;
		resultXL.foundIntersection = false;
	}

	if( mVelocity.y > 0 )
	{
		mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( 0, width, 0), resultY);
	}
	else if( mVelocity.y < 0 )
	{
		mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( 0,-width, 0), resultY);
	}
	else
	{
		resultY.foundIntersection = false;
	}

	if( mVelocity.z > 0 )
	{
		mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( 0, 0, width), resultZH);
		mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( 0, 0, width), resultZL);
	}
	else if( mVelocity.z < 0 )
	{
		mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( 0, 0,-width), resultZH);
		mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( 0, 0,-width), resultZL);
	}
	else
	{
		resultZH.foundIntersection = false;
		resultZL.foundIntersection = false;
	}

	Ogre::Vector3 camPos( mCamera->getPosition() );
	// handle horizontal movement
	if( resultXH.foundIntersection || resultXL.foundIntersection )
	{
		mVelocity.x = 0;
		
		if( resultXH.foundIntersection )
		{
			camPos.x = resultXH.previousVoxel.getX();
		}
		else
		{
			camPos.x = resultXL.previousVoxel.getX();
		}
	}
	if( resultZH.foundIntersection || resultZL.foundIntersection )
	{
		mVelocity.z = 0;

		if( resultZH.foundIntersection )
		{
			camPos.z = resultZH.previousVoxel.getZ();
		}
		else
		{
			camPos.z = resultZL.previousVoxel.getZ();
		}
	}

	// handle ground/ceiling
	if( resultY.foundIntersection )
	{
		camPos.y = resultY.previousVoxel.getY();
		if( mVelocity.y < 0 )
		{
			camPos.y += charHeight - 1.0;
		}

		mVelocity.y = 0;
	}
	else
	{
		if( mVelocity.y < -fallSpeedMax )
		{
			mVelocity.y = -fallSpeedMax;
		}
	}

	// set new position, not in a voxel
	mCamera->setPosition( camPos );

	if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame);

	return true;
}