Example #1
0
   void EffectBillboardChain::updateBoundingBox()
   {
       if (mChainElementList.size() < 2)
          return;

       Ogre::Real width = mChainElementList[0].width;
       Vector3 widthVector = Vector3(width, width, width);
       const Vector3& position = mChainElementList[0].position;
       Vector3 minimum = position - widthVector;
       Vector3 maximum = position + widthVector;

       for (unsigned int i = 1; i < mChainElementList.size(); i++)
       {
         // Update the bounds of the bounding box
          Ogre::Real width = mChainElementList[i].width;
          Vector3 widthVector = Vector3(width, width, width);
          const Vector3& position = mChainElementList[i].position;

          minimum.makeFloor(position - widthVector);
          maximum.makeCeil(position + widthVector);
       }

       // Set the current bounding box
       setBoundingBox(AxisAlignedBox(minimum, maximum));

       // Set the current radius
       mRadius = Math::Sqrt(std::max(minimum.squaredLength(), maximum.squaredLength()));
   }
/** Checks how the box intersects with the sphere.
*/
Intersection intersect( const Sphere &one, const AxisAlignedBox &two )
{
    OctreeSceneManager::intersect_call++;
    // Null box?
    if (two.isNull()) return OUTSIDE;
    if (two.isInfinite()) return INTERSECT;

    float sradius = one.getRadius();

    sradius *= sradius;

    Vector3 scenter = one.getCenter();

    const Vector3& twoMin = two.getMinimum();
    const Vector3& twoMax = two.getMaximum();

    float s, d = 0;

    Vector3 mndistance = ( twoMin - scenter );
    Vector3 mxdistance = ( twoMax - scenter );

    if ( mndistance.squaredLength() < sradius &&
            mxdistance.squaredLength() < sradius )
    {
        return INSIDE;
    }

    //find the square of the distance
    //from the sphere to the box
    for ( int i = 0 ; i < 3 ; i++ )
    {
        if ( scenter[ i ] < twoMin[ i ] )
        {
            s = scenter[ i ] - twoMin[ i ];
            d += s * s;
        }

        else if ( scenter[ i ] > twoMax[ i ] )
        {
            s = scenter[ i ] - twoMax[ i ];
            d += s * s;
        }

    }

    bool partial = ( d <= sradius );

    if ( !partial )
    {
        return OUTSIDE;
    }

    else
    {
        return INTERSECT;
    }


}
Example #3
0
// Move the whirler
void Whirler::move(Real delta) {
	// Rotate
	mNode->roll(Radian(-10 * delta));
	mNode->pitch(Radian(mRotationSpeed * delta));
	mFlareNode->roll(Radian(delta * 0.25f));

	Vector3 pos = getPosition();

	// Try to avoid all moving objects
	ObjectMapType::const_iterator i;
	ObjectSystem *ob = ObjectSystem::getSingletonPtr();
	for(i=ob->getFirst(); i != ob->getLast(); ++i) {
		if((*i).second == this || (*i).second->getType() == OTYPE_MUSHROOM) continue;

		Vector3 d = pos - (*i).second->getPosition();
		d.z = 0;
		if(d.squaredLength() > 60.0f*60.0f) continue;
		Real dist = d.normalise();
		Real effect = 1.0f - (dist / 60.0f);

		mCurrentSpeed += d * effect * mSpeed * 3.0f * delta;
	}

	// ..and player as well
	Vector3 d = pos - mPlayer->getPosition();
	d.z = 0;
	if(d.squaredLength() <= 60.0f*60.0f) {
		Real dist = d.normalise();
		// If distance is very small, player catches it
		if(dist < 3.0f) {
			pickUp();
			setToBeDeleted();
			mPlayer->catchWhirler();
			return;
		}
		Real effect = 1.0f - (dist / 60.0f);
		mCurrentSpeed += d * effect * mSpeed * 10.0f * delta;
	}

	// Cap the speed
	if(mCurrentSpeed.squaredLength() >= 55*55) {
		mCurrentSpeed = mCurrentSpeed.normalisedCopy() * 55.0f;
	}

	// Move
	mNode->translate(mCurrentSpeed * delta);
	mFlareNode->setPosition(mNode->getPosition());
}
Example #4
0
bool AIPerception::viewCheck(Vector3 viewDir, Object* obj)
{
	// Is the object in the view range?
	Vector3 toObject = obj->position - owner->position;
	float distToObjectSq = toObject.squaredLength();
	if (distToObjectSq > viewRangeSq)
		return false;

	// Is the object in the field of view?
	float distToObject = sqrt(distToObjectSq);
	if (distToObject != 0.0f)
		toObject /= distToObject;
	if (viewDir.dotProduct(toObject) < fieldOfView)
		return false;

	// Do a ray test as the final step
	Vector3 hitPos;
	if (!luaRayTestCombined(&owner->position, &toObject, distToObject, &hitPos, owner, RAYTEST_NO_DEBRIS))
		return false;
		
	Object* hitObj = luaGetLastHitObject();
	if ((!hitObj) || (hitObj != obj))
		return false;

	return true;
}
Example #5
0
Real
Polygon3::area() const
{
  array_size_t n = vertices.size();
  if (n < 3)
    return 0;

  if (n == 3)
    return 0.5f * (vertices[2].position - vertices[1].position).cross(vertices[0].position - vertices[1].position).length();

  static Real const EPSILON = 1e-10f;

  Vector3 normal = getNormal();
  if (normal.squaredLength() < EPSILON)
    return 0;

  Real a = 0;
  Vector3 const & last = vertices[n - 1].position;
  Vector3 prev = last;
  for (array_size_t p = 0; p < n; ++p)
  {
    Vector3 const & v = vertices[p].position;
    a += (prev.cross(v)).dot(normal);
    prev = v;
  }

  return std::fabs(0.5f * a);
}
Example #6
0
bool BoundingSphere::intersects(const BoundingSphere& sphere) const
{
	Vector3 dist = center - sphere.center;
	float minDist = radius + sphere.radius;

	return dist.squaredLength() <= minDist * minDist;
}
Example #7
0
Vector3 Cone::randomDirectionInCone(Random& rng) const {
        const float cosThresh = cos(angle);

        float cosAngle;
        float normalizer;
        Vector3 v;
        do {
            float vlenSquared;

            // Sample uniformly on a sphere by rejection sampling and then normalizing
            do {
                v.x = rng.uniform(-1, 1);
                v.y = rng.uniform(-1, 1);
                v.z = rng.uniform(-1, 1);

                // Sample uniformly on a cube
                vlenSquared = v.squaredLength();
            } while (vlenSquared > 1);


            const float temp = v.dot(direction);
        
            // Compute 1 / ||v||, but
            // if the vector is in the wrong hemisphere, flip the sign
            normalizer = rsqrt(vlenSquared) * sign(temp);

            // Cosine of the angle between v and the light's negative-z axis
            cosAngle = temp * normalizer;

        } while (cosAngle < cosThresh);

        // v was within the cone.  Normalize it and maybe flip the hemisphere.
        return v * normalizer;
    }
Example #8
0
    //------------------------------------------------------------------------
    Real TerrainBatch::Rend::getSquaredViewDepth(const Ogre::Camera* cam) const
    {
        Vector3 diff = mCenterPos - cam->getDerivedPosition();

        // NB use squared length rather than real depth to avoid square root
        return diff.squaredLength();
    }
Example #9
0
    //-----------------------------------------------------------------------
    Real Node::getSquaredViewDepth(const Camera* cam) const
    {
        Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();

        // NB use squared length rather than real depth to avoid square root
        return diff.squaredLength();
    }
Example #10
0
Real
raySphereIntersectionTime(Ray3 const & ray, Vector3 const & center, Real radius)
{
  Vector3 pmc = ray.getOrigin() - center;

  double s[3];
  s[2] = ray.getDirection().squaredLength();
  s[1] = 2 * pmc.dot(ray.getDirection());
  s[0] = pmc.squaredLength() - radius * radius;

  double roots[2];
  int num_roots = Math::solveQuadratic(s[0], s[1], s[2], roots);

  double min_root = -1;
  for (int i = 0; i < num_roots; ++i)
    if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root))
      min_root = roots[i];

#if 0
  if (min_root >= 0)
    qDebug() << "min_root =" << min_root;
#endif

  return (Real)min_root;
}
Example #11
0
	//---------------------------------------------------------------------
	void Pose::addVertex(size_t index, const Vector3& offset, const Vector3& normal)
	{
		if (!mVertexOffsetMap.empty() && mNormalsMap.empty())
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
				"Inconsistent calls to addVertex, must include normals always or never",
				"Pose::addVertex");

        if(offset.squaredLength() < 1e-6f && normal.squaredLength() < 1e-6f)
        {
            return;
        }

        mVertexOffsetMap[index] = offset;
		mNormalsMap[index] = normal;
		mBuffer.setNull();
	}
Vector3 SphericalField::Gradient(const Vector3& position) const
{
	//Compute the relative position from the center
	//The gradient is is proportional to 1/r^3 and radial to the sphere
	Vector3 relativePos = m_center - position;
	float lengthSquared = relativePos.squaredLength();
	return (2 * m_radiusSquared / (lengthSquared*lengthSquared)) * relativePos;
}
Example #13
0
bool BoundingSphere::intersects(const Vector3& pt) const
{
	Vector3 v = center - pt;

	if( v.squaredLength() > radius*radius )
		return false;

	return true;
}
	void CEnemyMeleeAttack::onTick(unsigned int msecs)
	{
		//BaseSubsystems::Log::Debug(std::to_string(_count)+" - "+_entity->getName() + " Acumulando tiempo de ataque: "+std::to_string(_timeAcum)+" / "+std::to_string(_timeBetweenAttacks));
		_timeAcum += msecs;
		if(canDoDamage())
		{
			Vector3 dir = _target->getPosition() - _entity->getPosition();

			if( dir.squaredLength() <= _maxDist2)
			{
				Vector3 offsetPos = _entity->getPosition();
				offsetPos.y += _upOffset;
				CEntity* ent;

				Vector3 collisionPoint;

				if (_target->getTag() == "player")
				{
					ent = Physics::CServer::getSingletonPtr()->raycastSimple(offsetPos, dir, _maxDist ,Physics::CollisionGroup::ePlayer,collisionPoint);

					if (ent)
					{
						ApplyDamage(ent);

						//Instanciamos la chispa en el punto de colision
						CEntityFactory::getSingletonPtr()->createEntityByType("ChispaDanhoPlayer", collisionPoint, _entity->getMap());
						damageEnemy(collisionPoint);
					
					}

				}
				else if (_target->getTag() == "enemy")
				{
					std::vector<Vector3> pointsCollision;
					Physics::FilterMask mask = Physics::FilterMask(Physics::FilterMask::eEnemyTMask |Physics::FilterMask::eEnemyVMask);
					std::vector<Logic::CEntity*> vecLEnt = Physics::CServer::getSingletonPtr()->raycastMultiple(offsetPos, dir, _maxDist, 64, mask,pointsCollision);
					
					for (int i = 0; i < vecLEnt.size(); ++i)
					{
						if (vecLEnt.at(i)->getEntityID() == _targetID)
						{
							ApplyDamage(vecLEnt.at(i));

							//Generamos particula de choque
							CEntityFactory::getSingletonPtr()->createEntityByType("ChispaDanhoEnemy", pointsCollision.at(i), _entity->getMap());
							break;
						}
					}
				}
			}
		}

	}//tick
Example #15
0
//-----------------------------------------------------------------------
Real DLight::getSquaredViewDepth(const Camera* cam) const
{
    if(bIgnoreWorld)
    {
        return 0.0f;
    }
    else
    {
        Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition();
        return dist.squaredLength();
    }
}
Vector3 MetaballField::Gradient(const Vector3& position) const
{
	assert(m_radiusSquared!=-1.0f);

	Vector3 gradient = Vector3::ZERO;
	for(size_t i = 0; i < m_spherePositionBufElementSize; ++i)
	{
		Vector3 relativePos = m_spherePosition[i] - position;
		float lengthSquared = relativePos.squaredLength();

		gradient += (2 * m_radiusSquared / (lengthSquared*lengthSquared)) * relativePos;
	}
	return gradient;
}
Example #17
0
/* ------------------------------------------------------- */
bool SphereVolume::intersects(const Vector3& origin, const Vector3& direction) const
{
	Vector3 v = origin - m_center;
	float a = v.squaredLength() - m_radius*m_radius;
	if (a <= 0.0f)
	{
		return true;
	}
	else
	{
		float b = direction.dot(v);
		if (b >= 0.0f)
			return false;
		return (b*b >= a);
	}
}
Example #18
0
			inline
			Real getFieldStrength (const signed int x, const signed int y, const signed int z) const
			{
				Vector3 v = dg->getBoundingBox().getMinimum();
				
				v += Vector3((Real)x, (Real)y, (Real)z) * dg->getGridScale();
				v -= self->_pos;

				Real r2 = Real(v.squaredLength() / (2.0 * self->_sphere.getRadius()*self->_sphere.getRadius()));

				const Real i = r2 - 0.5f;
				
				// Cubic-spline has better fall-off than parabolic polynomial
				// Builds on Metaballs from http://www.geisswerks.com/ryan/BLOBS/blobs.html
				const Real k = -0.4f*i*i*i + 0.8f*i*i - 0.5f*i;	
				return k * self->_fExcavating;
			}
Example #19
0
	ParaEngine::Vector3 Vector3::perpendicular(void) const
	{
		static const float fSquareZero = 1e-06f * 1e-06f;

		Vector3 perp = this->crossProduct(Vector3::UNIT_X);

		// Check length
		if (perp.squaredLength() < fSquareZero)
		{
			/* This vector is the Y axis multiplied by a scalar, so we have
			   to use another axis.
			   */
			perp = this->crossProduct(Vector3::UNIT_Y);
		}
		perp.normalise();

		return perp;
	}
Example #20
0
    //-----------------------------------------------------------------------
    Real Node::getSquaredViewDepth(const Camera* cam) const
    {
        Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();
#if 1
		Matrix4 viewObectMat;
		if (cam)
		{
			Matrix4 viewMat(cam->getViewMatrix(false));
			Matrix4 objMat(_getFullTransform());
			viewObectMat =viewMat *  objMat ;
		}
		
		 viewObectMat.getTrans(diff);
		 diff.x =0;
		 diff.z =0;
#endif
        // NB use squared length rather than real depth to avoid square root
        return diff.squaredLength();
    }
Example #21
0
float CShapeRay::SquareDistance(const Vector3& point, float* t)	const
{
	Vector3 Diff = point - mOrig;
	
	float fT = Diff.dotProduct(mDir);

	if(fT<=0.0f)
	{
		fT = 0.0f;
	}
	else
	{
		fT /= mDir.squaredLength();
		Diff -= fT*mDir;
	}

	if(t) *t = fT;

	return Diff.squaredLength();
}
	void CAltarFeedbackController::onTick(unsigned int msecs)
	{
		//calculamos el speed
		Vector3 speed = _direction * _vel;

		//calculamos la nueva posición
		Vector3 newPos = _entity->getPosition() + speed * msecs;

		//seteamos la nueva posición
		_entity->setPosition(newPos);

		//comprobamos si debemos parar el alma
		Vector3 distance = _pointDestino - _entity->getPosition();
		float sqrdistance = distance.squaredLength();

		if(sqrdistance <= _radio2)
		{
			//matamos la entidad
			CEntityFactory::getSingletonPtr()->deferredDeleteEntity(_entity);
		}
	}
Example #23
0
Vector3
Polygon3::getNormal() const
{
  array_size_t n = vertices.size();
  if (n < 3)
    return Vector3::zero();

  static Real const EPSILON = 1e-10f;

  for (array_size_t i = 0; i < n; ++i)
  {
    array_size_t i1 = (i + 1) % n;
    array_size_t i2 = (i + 2) % n;
    Vector3 normal = (vertices[i2].position - vertices[i1].position).cross(vertices[i].position - vertices[i1].position);

    if (normal.squaredLength() >= EPSILON)
      return normal.unit();
  }

  return Vector3::zero();
}
//-----------------------------------------------------------------------------
// Name: TestCollisionRay()
/// Desc: Check the ray intersection with the object  
/// input:vPickRayOrig,vPickRayDir: mouse ray params
/// output: fDistance: the distance between the eye and the intersection point.
///      this is only set when it's intersection in the first place
/// return: true if they collide.
/// note: TODO: currently the caller should always be the biped class
//-----------------------------------------------------------------------------
bool IViewClippingObject::TestCollisionRay(const Vector3& vPickRayOrig, const Vector3& vPickRayDir_, FLOAT* fDistance)
{
	bool bCollided = false;

	Vector3 vPickRayDir = vPickRayDir_.normalisedCopy();
	
	// center of this object
	Vector3 vCenter = GetPosition();
	float radius = GetRadius();
	vCenter.y += radius;

	Vector3 tmpDiff = vPickRayOrig - vCenter;
	/**
	Let:a = Dx2 + Dy2 + Dz2; (for normalized rays, a=1)
		b = 2[ Dx(x0 每cx) + Dy(y0 每cy) + Dz(z0 每cz)]
		c = (x0 每cx)2 +(y0 每cy)2 +(z0 每cz)2-r2
	Then: t = (-b ㊣ sqrt(b2 每 4ac))/2a
		if (b2 每 4ac) < 0, the ray does not intersect the sphere;
		if (b2 每 4ac) = 0, the ray grazes the sphere;
		if (b2 每 4ac) > 0, the ray enters and passes through the sphere, exiting on the other side.
	Use the smallest positive t to find the closest visible ray/sphere intersection point x(t), y(t), z(t),
	*/
	float a, b, c;
	a = 1.0f;
	b = 2*(vPickRayDir.x*tmpDiff.x + 
		   vPickRayDir.y*tmpDiff.y + 
		   vPickRayDir.z*tmpDiff.z);
	c = tmpDiff.squaredLength() - radius*radius;

	float delta = b*b-4*a*c;
	if(delta>=0)
	{
		// collided
		bCollided = true;
		
		delta = sqrt(delta);
		*fDistance = min(abs((-b+delta)/2*a), abs((-b-delta)/2*a));
	}
	return bCollided;
}
Example #25
0
	Vector3 Sphere::Sample(const Vector3& p_point, float p_u1, float p_u2, Vector3& p_normal) const
	{
		Vector3 wc;
		Vector3::Normalize(centre - p_point, wc);

		float distance_squared = wc.squaredLength();

		OrthonormalBasis basis;

		basis.InitFromW(wc);
		float radius_squared = radius*radius;

		/* Check if inside the sphere*/
		if (distance_squared - radius_squared < 1e-4f) {
			return Sample(p_u1, p_u2, p_normal);
		}

		float sin_theta_max_squared = radius_squared / distance_squared;

		float cos_theta_max = sqrt(std::max(0.0f, 1.0f - sin_theta_max_squared));

		/* The new random direction uses a uniform cone sampling depending on the solid angle. */
		Vector3 direction = MonteCarlo::UniformSampleCone(p_u1, p_u2, cos_theta_max, basis);
		Ray ray(p_point, direction, 1e-3f);
		float t = 0.0f;

		/*test intersection*/
		DifferentialSurface record;
		if (!Intersect(ray, record)) {
			Vector3::Normalize(ray.direction, ray.direction);
			record.t = Vector3::Dot(p_point, ray.direction);
		}
		Vector3 surface_point = ray.PointAlongRay(record.t);

		Vector3::Normalize(surface_point - centre, p_normal);

		return surface_point;

	}
Example #26
0
 Vector3 PerspectiveCamera::sampleDirection(const Sample& sample,
     const Vector3& pCamera, float* We, float* pdfW) const {
     float invXRes = mFilm->getInvXResolution();
     float invYRes = mFilm->getInvYResolution();
     float xNDC = +2.0f * sample.imageX * invXRes - 1.0f;
     float yNDC = -2.0f * sample.imageY * invYRes + 1.0f;
     // from NDC space to view space
     // xView = xNDC * zView * tan(fov / 2) * aspectRatio
     // yView = yNDC * zView * tan(fov / 2)
     // in projection matrix pro,
     // pro[0][0] = 1 / (tan(fov / 2) * aspectRatio)
     // pro[1][1] = 1 / (tan(fov / 2))
     float zView = 1.0f;
     float xView = xNDC / mProj[0][0];
     float yView = yNDC / mProj[1][1];
     Vector3 viewDir = Vector3(xView, yView, zView);
     Vector3 pFocusView = mFocalDistance * viewDir;
     Vector3 pFocusWorld = mOrientation * pFocusView + mPosition;
     Vector3 sampleDir = pFocusWorld - pCamera;
     float lensToFilmDistance2 = sampleDir.squaredLength();
     sampleDir.normalize();
     // let w be soilid angle start on a a point in lens and extend by film
     // Power = integrate(integrate(L *cosTheta) over w) over lensArea
     // the estimator for the above integration is:
     // L * cosTheta / (pdf(leansArea) * pdf(w)) =
     // L * cosTheta * lensArea * filmArea * cosTheta / (lensToFilm^2) =
     // L * filmArea * lensArea * G where G is the geometry term
     // expectationValue(L) = expectationValue(Power * We)
     // We = 1 / (filmArea * lensArea * G)
     float cosTheta = absdot(mOrientation * Vector3::UnitZ, sampleDir);
     float G = cosTheta * cosTheta / lensToFilmDistance2;
     float lensArea = mLensRadius * mLensRadius * PI;
     *We = mLensRadius > 0.0f ?
         1.0f / (mFilmArea * lensArea * G) : 1.0f / (mFilmArea * G);
     if (pdfW) {
         *pdfW = lensToFilmDistance2 / (mFilmArea * cosTheta);
     }
     return sampleDir;
 }
Example #27
0
// Move the ball worm
void BallWorm::move(Real delta) {
	// Rotate
	mNode->rotate(mRotationAxis, Radian(mRotationSpeed * delta));

	// Move
	mNode->translate(mCurrentSpeed * delta);

	// Check collisions versus the player
	if(mPlayer->isDead() || mPlayer->isOnBase() || mPlayer->isGoingToSpecialLevel() || gameApp->getState() != STATE_GAME) return;

	Vector3 ppos = mPlayer->getPosition();

	for(int f=0; f<numBalls; f++) {
		if(mBallDestroyed[f]) continue;
		Vector3 d = mBalls[f]->_getDerivedPosition() - ppos;
		d.z = 0;
		Real dist = d.squaredLength();
		if(dist < 9) {
			// Collision
			//mPlayer->die();
			mPlayer->doBallWormGlow();
			mBalls[f]->setVisible(false);
			mBallDestroyed[f] = true;
			SoundSystem::getSingleton().playSound("balls");

			// Create an effect
			try {
				Effect *effect = new Effect(EFFECT_MUSHROOM_CATCH, mBalls[f]->getName() + "Effect", mSceneMgr, "", mBalls[f]->_getDerivedPosition());
				effect->createParticles("WormBallEffect");
				effect->setDuration(1.5f);
			}
			catch(...) {
				// Ignore..
			}
			break;
		}
	}
}
Example #28
0
	void CameraFlyer::update()
	{
		bool goingForward = gVirtualInput().isButtonHeld(mMoveForward);
		bool goingBack = gVirtualInput().isButtonHeld(mMoveBack);
		bool goingLeft = gVirtualInput().isButtonHeld(mMoveLeft);
		bool goingRight = gVirtualInput().isButtonHeld(mMoveRight);
		bool fastMove = gVirtualInput().isButtonHeld(mFastMove);
		bool camRotating = gVirtualInput().isButtonHeld(mRotateCam);

		if (camRotating != mLastButtonState)
		{
			if (camRotating)
				Cursor::instance().hide();
			else
				Cursor::instance().show();

			mLastButtonState = camRotating;
		}

		float frameDelta = gTime().getFrameDelta();
		if (camRotating)
		{
			mYaw += Degree(gVirtualInput().getAxisValue(mHorizontalAxis) * ROTATION_SPEED * frameDelta);
			mPitch += Degree(gVirtualInput().getAxisValue(mVerticalAxis) * ROTATION_SPEED * frameDelta);

			mYaw = wrapAngle(mYaw);
			mPitch = wrapAngle(mPitch);

			Quaternion yRot;
			yRot.fromAxisAngle(Vector3::UNIT_Y, Radian(mYaw));

			Quaternion xRot;
			xRot.fromAxisAngle(Vector3::UNIT_X, Radian(mPitch));

			Quaternion camRot = yRot * xRot;
			camRot.normalize();

			SO()->setRotation(camRot);
		}

		Vector3 direction = Vector3::ZERO;
		if (goingForward) direction += SO()->getForward();
		if (goingBack) direction -= SO()->getForward();
		if (goingRight) direction += SO()->getRight();
		if (goingLeft) direction -= SO()->getRight();

		if (direction.squaredLength() != 0)
		{
			direction.normalize();

			float multiplier = 1.0f;
			if (fastMove)
				multiplier = FAST_MODE_MULTIPLIER;

			mCurrentSpeed = Math::clamp(mCurrentSpeed + ACCELERATION * frameDelta, START_SPEED, TOP_SPEED);
			mCurrentSpeed *= multiplier;
		}
		else
		{
			mCurrentSpeed = 0.0f;
		}

		float tooSmall = std::numeric_limits<float>::epsilon();
		if (mCurrentSpeed > tooSmall)
		{
			Vector3 velocity = direction * mCurrentSpeed;
			SO()->move(velocity * frameDelta);
		}
	}
Vector3 AIRayPathFinderStrategy::RouteToTarget()
{
    Ogre::Vector3 point;
	//if (TargetType == TT_OBJECT) {
	//	//assert(TargetID);
	//	Ogre::Vector3 parent_pos = Parent->GetPosition();

	//	if (TargetID<0)
	//	{
	//		assert(false);
	//		TargetPoint = parent_pos;
	//	}
	//	
	//	if (TargetID==0)
	//	{
	//		if (Owner)
	//		{
	//			TargetID = Owner->SelectTargetID();			
	//		}
	//		if (TargetID<=0)
	//		{
	//			//assert(false);
	//			TargetPoint = parent_pos;
	//		}
	//	}
 //       
	//	IAAObject *obj = CommonDeclarations::GetIDObject(TargetID);
	//	//assert(obj);
	//	if (obj)
	//	{
	//		Ogre::Vector3 target_pos = obj->GetPosition();
	//		if (DistanceToTarget>0)
	//			TargetPoint = target_pos + (parent_pos-target_pos).normalisedCopy()*DistanceToTarget;
	//		else
	//			TargetPoint=target_pos;
	//	} else
	//	{
	//		//if (--WaitTargetTimeout<0)
	//		//	CommonDeclarations::DeleteObjectRequest(Parent);
	//		TargetPoint = parent_pos;
	//		//CommonDeclarations::DeleteObjectRequest(Parent);
	//	}
	//}/* else
	//if (TargetType == TT_OBJECT)
	//{
	//	point = TargetPoint;
	//}*/
    
	point = TargetPoint;
	Vector3 dist = point-Parent->GetPosition();
	if (dist.squaredLength()>10.f*10.f)
		Route(point);
	else
	{
		if (TargetType==TT_POINT)
		{
			TargetType = TT_NONE;	
			State = FST_POINTREACHED;
		}		
		Parent->GetPhysical()->SetThrottle(Vector3(0,0,0));		
		Parent->GetPhysical()->SetForces(Ogre::Vector3::ZERO);
		//Parent->SetVelocityVector(Vector3(0,0,0));
	}
	return point;
}
Example #30
0
	bool Frustum::projectSphere(const Sphere& sphere,
		Real* left, Real* top, Real* right, Real* bottom) const
	{
		// 变换光源位置到相机空间

		updateView();
		Vector3 eyeSpacePos = mViewMatrix.transformAffine(sphere.getCenter()); //将球中心坐标转到观察空间中

		// 初始化
		*left = *bottom = -1.0f;
		*right = *top = 1.0f;

		if (eyeSpacePos.z < 0)
		{
			updateFrustum();
			const Matrix4& projMatrix = getProjectionMatrix();
			Real r = sphere.getRadius();
			Real rsq = r * r;  //半径的平方


			if (eyeSpacePos.squaredLength() <= rsq)
				return false;

			Real Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z);  //设原点O,球心P, 向量Vop在XZ平面上的投影
			Real Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z);  //设原点O,球心P, 向量Vop在YZ平面上的投影

			// 用点法式 找出球体切平面
			// 首先XZ 
			// 计算二次根判别式: b*b - 4ac
			// x = Nx
			// a = Lx^2 + Lz^2
			// b = -2rLx
			// c = r^2 - Lz^2
			Real a = Lxz;
			Real b = -2.0f * r * eyeSpacePos.x;
			Real c = rsq - Math::Sqr(eyeSpacePos.z);
			Real D = b*b - 4.0f*a*c;

			// 两个根
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// 解除二次方获取法线的分量
				Real Nx0 = (-b + sqrootD) / (2 * a);
				Real Nx1 = (-b - sqrootD) / (2 * a);

				// 取得Z
				Real Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z;
				Real Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z;

				// 获取切点
				// 只考虑相机前面的切点
				Real Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x));
				if (Pz0 < 0)
				{
					// 投影在近剪裁平面在世界空间的点
					Real nearx0 = (Nz0 * mNearDist) / Nx0;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist);

					//找出这是左边还是右边
					Real Px0 = -(Pz0 * Nz0) / Nx0;
					if (Px0 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx0.x);
					}
					else
					{
						*left = std::max(*left, relx0.x);
					}
				}
				Real Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x));
				if (Pz1 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real nearx1 = (Nz1 * mNearDist) / Nx1;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist);

					//找出这是左边还是右边
					Real Px1 = -(Pz1 * Nz1) / Nx1;
					if (Px1 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx1.x);
					}
					else
					{
						*left = std::max(*left, relx1.x);
					}
				}
			}


			// 现在是 YZ 平面
			// 计算二次方根判别式: b*b - 4ac
			// x = Ny
			// a = Ly^2 + Lz^2
			// b = -2rLy
			// c = r^2 - Lz^2
			a = Lyz;
			b = -2.0f * r * eyeSpacePos.y;
			c = rsq - Math::Sqr(eyeSpacePos.z);
			D = b*b - 4.0f*a*c;

			//两个根
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// 解除二次根获得法线的分量
				Real Ny0 = (-b + sqrootD) / (2 * a);
				Real Ny1 = (-b - sqrootD) / (2 * a);

				// 从这里取得Z
				Real Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z;
				Real Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z;

				// 获取切点
				// 只考虑相机前面的切点
				Real Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y));
				if (Pz0 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real neary0 = (Nz0 * mNearDist) / Ny0;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist);

					//找出这是左边还是右边
					Real Py0 = -(Pz0 * Nz0) / Ny0;
					if (Py0 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely0.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely0.y);
					}
				}
				Real Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y));
				if (Pz1 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real neary1 = (Nz1 * mNearDist) / Ny1;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist);

					//找出这是左边还是右边
					Real Py1 = -(Pz1 * Nz1) / Ny1;
					if (Py1 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely1.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely1.y);
					}
				}
			}
		}

		return (*left != -1.0f) || (*top != 1.0f) || (*right != 1.0f) || (*bottom != -1.0f);

	}