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; }
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); } } }