Ejemplo n.º 1
0
FMatrix OSVRHMDDescription::GetProjectionMatrix(EEye Eye) const
{
	// @TODO: a proper stereo projection matrix should be calculated

	const float ProjectionCenterOffset = 0.151976421f;
	const float PassProjectionOffset = (Eye == LEFT_EYE) ? ProjectionCenterOffset : -ProjectionCenterOffset;

#if 1
	const float HalfFov = FMath::DegreesToRadians(GetFov(Eye).X) / 2.f;
	const float InWidth = GetDisplaySize(Eye).X;
	const float InHeight = GetDisplaySize(Eye).Y;
	const float XS = 1.0f / tan(HalfFov);
	const float YS = InWidth / tan(HalfFov) / InHeight;
#else
	const float HalfFov = 2.19686294f / 2.f;
	const float InWidth = 640.f;
	const float InHeight = 480.f;
	const float XS = 1.0f / tan(HalfFov);
	const float YS = InWidth / tan(HalfFov) / InHeight;
#endif

	const float InNearZ = GNearClippingPlane;
	return FMatrix(
			   FPlane(XS, 0.0f, 0.0f, 0.0f),
			   FPlane(0.0f, YS, 0.0f, 0.0f),
			   FPlane(0.0f, 0.0f, 0.0f, 1.0f),
			   FPlane(0.0f, 0.0f, InNearZ, 0.0f))

		   *
		   FTranslationMatrix(FVector(PassProjectionOffset, 0, 0));
}
Ejemplo n.º 2
0
	bool Camera::ObjectFrustumCulling( const RenderObject& obj )
	{
		const AABB& aabb = obj.m_worldAABB;

		//物体坐标转换到相机空间进行裁减
		VEC4 pos(aabb.GetCenter(), 1.0f);
		Common::Transform_Vec4_By_Mat44(pos, pos, GetViewMatrix());

		float n = GetNearClip();
		float f = GetFarClip();
		float fov = GetFov();
		float half_w = n * std::tan(fov/2);
		float half_h = half_w / GetAspectRatio();

		//检测前后面
		if(-pos.z+aabb.m_boundingRadius <= n || -pos.z-aabb.m_boundingRadius >= f)
			return true;

		//检测左右面
		float planeX = half_w * pos.z / -n;
		if(pos.x - planeX >= aabb.m_boundingRadius ||
			pos.x + aabb.m_boundingRadius <= -planeX)
			return true;

		//检测上下面
		float planeY = half_h * pos.z / -n;
		if(pos.y - planeY >= aabb.m_boundingRadius ||
			pos.y + aabb.m_boundingRadius <= -planeY)
			return true;

		return false;
	}
Ejemplo n.º 3
0
LUAMTA_FUNCTION(camera, GetFov)
{
	auto self = my->ToCameraPtr(1);

	my->Push(self->GetFov());

	return 1;
}
Ejemplo n.º 4
0
//=========================================================
// FInViewCone - returns true is the passed vector is in
// the caller's forward view cone.
//=========================================================
bool CEntity::FInViewCone(Vector *pOrigin, float fov)
{
    if (fov <= 0)
        fov = GetFov();

    Vector forward;
    GetViewAngles().AngleVectors(&forward);

    Vector vecLOS = (*pOrigin - GetGunPosition()).Normalize();
    float flDot = DotProduct(vecLOS, forward);

    return (flDot >= cos((fov / 2) * (M_PI / 180)));
}
Ejemplo n.º 5
0
	void Camera::_BuildProjMatrix()
	{
		/*	这是第一个版本的透视投影矩阵,即"蛮干"求解法.
			它的缺陷在于为了变换出xy坐标都在[-1, 1]的CVV空间,
			必须满足以下条件:
			1.视距d=1.
			2.fov=90度.
			3.视口AspectRatio=1.
			否则变换不出CVV.

			MatProj = ( 1, 0,	0,	0
						0, 1,	0,	0
						0,  0,	1,	0
						0,  0, 1/d,  0 )

			投影变换加齐次除法后:
			x' = x * d / z, y' = y * d / z	*/

		//普适版投影矩阵.推导见: http://blog.csdn.net/popy007/article/details/1797121
		float r,l,t,b;
		r = m_nearClip*tanf(m_fov/2);
		l = -r;
		t = r/m_aspectRatio;
		b= -t;

		m_matProj.m00 = 2*m_nearClip/(r-l);
		m_matProj.m01 = 0;
		m_matProj.m02 = (r+l)/(r-l);
		m_matProj.m03 = 0;

		m_matProj.m10 = 0;
		m_matProj.m11 = 2*m_nearClip/(t-b);
		m_matProj.m12 = (t+b)/(t-b);
		m_matProj.m13 = 0;

		m_matProj.m20 = 0;
		m_matProj.m21 = 0;
		m_matProj.m22 = -(m_farClip+m_nearClip)/(m_farClip-m_nearClip);
		m_matProj.m23 = -2*m_farClip*m_nearClip/(m_farClip-m_nearClip);

		m_matProj.m30 = 0;
		m_matProj.m31 = 0;
		m_matProj.m32 = -1;
		m_matProj.m33 = 0;

		m_matInvProj = m_matProj.Inverse();

		m_imagePlane_r = GetNearClip() * tanf(GetFov() / 2);
		m_imagePlane_t = m_imagePlane_r / GetAspectRatio();
	}
Ejemplo n.º 6
0
bool CBaseBot::FindEnemy()
{
   // check if the health is decreased
   bool fHealthDecreased = m_iPrevHealth > GetHealth();
   m_iPrevHealth = GetHealth(); // store away the current health value

   float cur_dist;

   if (m_pEnemy && (!m_pEnemy->IsValid() || !m_pEnemy->IsAlive()))
      m_pEnemy = NULL; // null out the enemy pointer as it's no longer valid

   Vector                vecHisPos;
   unsigned char         cHit;

   // see if we can still see the current enemy...
   if (m_pEnemy) {
      if (FBoxVisible(m_pEnemy, &vecHisPos, &cHit)) {
         m_vecEnemy = vecHisPos;
         m_ucVisibility = cHit;
      } else {
         m_pEnemy = NULL; // we can no longer see this enemy
      }
   }

   // if we already have an enemy...
   if (m_pEnemy) {
      // don't discard important enemies (bomb/flag/hostage carrier, VIP, etc)
      if (g_pServer->ClientIsImportant(EnemyClient()))
         return false;
      // calculate the distance to the enemy
      cur_dist = (m_pEnemy->GetOrigin() - GetOrigin()).Length();
   } else {
      cur_dist = FLT_MAX; // just some crazy value
   }

   // loop through all the clients...
   for (int i = 0; i < g_pServer->GetMaxClients(); i++) {
      if (i == entindex() - 1 || (m_pEnemy && i == m_pEnemy->entindex() - 1))
         continue; // skip myself and the current enemy

      CClient *pClient = g_pServer->m_rgpClients[i];
      if (!pClient || !pClient->IsValid() || !pClient->IsAlive())
         continue;

      float dist = (pClient->GetOrigin() - GetOrigin()).Length();

      // if this enemy is further away than the current one...
      if (dist > cur_dist && !g_pServer->ClientIsImportant(pClient))
         continue; // skip it

      if (dist > 900 + 4000 * ((GetDifficulty() - 1) / 4.0))
         continue; // enemy is too far

      if (g_pServer->IsTeamplay() && GetTeam() == g_pServer->GetTeam(pClient))
         continue; // skip our teammates

      float fov;

      // if the bot's health decreased or the enemy is shooting
      if (!m_pEnemy && (fHealthDecreased || pClient->IsShooting()))
         fov = 360;
      else
         fov = GetFov() * 2 - (GetFov() - (dist > GetFov() * 9 ? GetFov() * 9 : dist) / 9);

      // check if enemy is in the view cone
      if (!FInViewCone(pClient, fov))
         continue; // enemy isn't in bot's view cone

      // check if enemy is visible
      if (!FBoxVisible(pClient, &vecHisPos, &cHit)) {
         continue; // skip this enemy
      }

      // if the enemy is quite far away, not shooting and the bot is not damaged
      if (!m_pEnemy && dist > 200 && !fHealthDecreased && !pClient->IsShooting()) {
         // if the bot isn't in the fov of the enemy and the bot doesn't really want to fight
         if (!pClient->FInViewCone(this, 120) /*&& BotWantsToRetreat()*/)
            continue; // skip this enemy
      }

      m_pEnemy = pClient; // found a new enemy
      m_vecEnemy = vecHisPos;
      m_ucVisibility = cHit;

      DebugMsg(DEBUG_BOTCOMBAT, "Found new enemy: %s", m_pEnemy->GetNetName());

      return true;
   }

   return false; // no new enemy is found
}