CFVec2 CSteeringAgent::GetAdjustedWhisker(const CFVec2& _krvWhisker) const
{
	CFVec2 vAdjustedWhisker = _krvWhisker;
	vAdjustedWhisker.RotateZ(m_krCat.GetHeadingRadians());

	return vAdjustedWhisker;
}
CFVec2 CSteeringAgent::GetWhiskerBearingEffect() const
{
	CBlackboard& rBlackboard = CBlackboard::GetInstance();
	bool bRotationApplied = false;
	FLOAT32 fTotalRotation = 0.0f;

	FLOAT32 fRotation = Math::PI / 2.0f; // 90 degrees
	for (unsigned int uiIndex = 0 ; uiIndex < SIDE_WHISKER_COUNT; uiIndex++)
	{
		FLOAT32 fWhiskerTime =
			rBlackboard.GetClosestWallIntersectionTime(GetAbsoluteWhiskerStart(m_vWhiskersLeft[uiIndex]),
			GetAdjustedWhisker(m_vWhiskersLeft[uiIndex]));
		if (fWhiskerTime != -1.0f)
		{
			fTotalRotation += fRotation;
			bRotationApplied = true;
		}

		fWhiskerTime =
			rBlackboard.GetClosestWallIntersectionTime(GetAbsoluteWhiskerStart(m_vWhiskersRight[uiIndex]),
			GetAdjustedWhisker(m_vWhiskersRight[uiIndex]));
		if (fWhiskerTime != -1.0f)
		{
			fTotalRotation -= fRotation;
			bRotationApplied = true;
		}

		fRotation /= 5.0f; // TODO MAGIC
	}

	if (bRotationApplied)
	{
		// If the rotation was cancelled out (accounting for rounding errors).
		if (abs(fTotalRotation) < 0.0001f)
		{
			// The whiskers are intersecting on both sides so chances are we're heading straight for something and we
			// need to turn. Clockwise 90 degrees sounds good...
			fTotalRotation += Math::PI / 2.0f;
		}

		CFVec2 vWhiskerBearingEffect = m_krCat.GetHeadingVector();
		vWhiskerBearingEffect.Normalise();
		vWhiskerBearingEffect.RotateZ(fTotalRotation);

		return vWhiskerBearingEffect;
	}

	return fv2EMPTY;
}
Exemple #3
0
void
CMole::ComputeWallForce(CFVec2& _vrRepelForce)
{
	for (unsigned int i = 0; i < MAX_WHISKER; ++ i)
	{
		CFVec2 vLineRepelForce;
		CWall* pClosestWall = 0;
		float fImpactTime = 0;
		bool bIntersected = FindWiskerClosestWall(static_cast<EWhisker>(i), pClosestWall, fImpactTime);


		if (bIntersected)
		{
			// Time radio
			float fTimeRatio = 1.0f - (fImpactTime / 1.0f);
			fTimeRatio *= 1.8f;


			if (fTimeRatio > 1.0f)
			{
				fTimeRatio = 1.0f;
			}


			CFVec2 vPointDisplacement(pClosestWall->GetStartPoint());
			vPointDisplacement -= pClosestWall->GetEndPoint();


			// Line direction
			CFVec2 vLineDirection(vPointDisplacement);
			vLineDirection.Normalise();


			// Get Normal
			CFVec2 vLineNormal(pClosestWall->GetNormal());
			vLineNormal.Normalise();


			CFVec2 vStart = pClosestWall->GetStartPoint();
			CFVec2 vEnd = pClosestWall->GetEndPoint();


			// Which side is the cat on
			float fPerpendicularDot = (vEnd.X() - vStart.X()) * (m_vPosition.Y() - vStart.Y()) - (vEnd.Y() - vStart.Y()) * (m_vPosition.X() - vStart.X());


			bool bOnNormalSide = (fPerpendicularDot > 0);

			
			// Cat going against the normal
			if (bOnNormalSide)
			{
				// Cat has to be on normal side
				vLineRepelForce = vLineNormal;
				vLineRepelForce.RotateZ(fDegsToRad(180.0f));
			}


			// Cat going towards normal
			else
			{
				// Cat has to be not on normal side
				vLineRepelForce = vLineNormal;
			}


			// Scale based on collision time
			//vLineRepelForce *= 1.25f;
			vLineRepelForce *= fTimeRatio;


			_vrRepelForce += vLineRepelForce;
			m_pWhiskers[i].SetColour(0xFFFF0000);
		}
	}
}