175 lines
4.1 KiB
C++
175 lines
4.1 KiB
C++
// Heuristic.cpp: implementation of the CHeuristic class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "IAgent.h"
|
|
#include "Heuristic.h"
|
|
#include "Graph.h"
|
|
#include "AIObject.h"
|
|
#include "Cry_Math.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CHeuristic::CHeuristic()
|
|
{
|
|
}
|
|
|
|
CHeuristic::~CHeuristic()
|
|
{
|
|
|
|
}
|
|
|
|
float CHeuristic::Estimate(GraphNode *pNode, CGraph* graph)
|
|
{
|
|
// DEFAULT HEURISTIC LIKES EVERYTHING :)
|
|
|
|
//if (m_BaseValues.bWater != data.bWater) return 0;
|
|
|
|
// float diff;
|
|
// diff = m_BaseValues.fSlope - data.fSlope;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
float CStandardHeuristic::Estimate(GraphNode *pNode, CGraph* graph)
|
|
{
|
|
float estimation = 0.0f;
|
|
GameNodeData data = pNode->data;
|
|
// avoids water
|
|
// if (data.bWater)
|
|
// return estimation;
|
|
|
|
// avoids big slopes
|
|
//estimation = 1 - data.fSlope;
|
|
|
|
|
|
// calculate minimum distance from all tagged neighboors
|
|
float mindist = 1000.f; // an arbitrary large value
|
|
GraphNode *pPrevious = 0;
|
|
VectorOfLinks::iterator vli;
|
|
for (vli=pNode->link.begin();vli!=pNode->link.end();vli++)
|
|
{
|
|
if ((*vli).pLink->tag)
|
|
{
|
|
float dist = ((*vli).pLink->data.m_pos - pNode->data.m_pos).GetLength();
|
|
if (dist < mindist)
|
|
{
|
|
mindist = dist;
|
|
pPrevious = (*vli).pLink;
|
|
}
|
|
}
|
|
}
|
|
if (pPrevious)
|
|
{
|
|
// paths that are very much longer than the straight path should be suppressed
|
|
pNode->fDistance = pPrevious->fDistance + mindist;
|
|
estimation += 1.f - (pNode->fDistance / graph->m_fDistance) * 0.5f;
|
|
}
|
|
return estimation;
|
|
}
|
|
|
|
|
|
float CVehicleHeuristic::Estimate(GraphNode *pNode, CGraph* graph)
|
|
{
|
|
float estimation = 0.0f;
|
|
Vec3d candidateDir;
|
|
Vec3d curDir;
|
|
GraphNode *pPrev = 0;
|
|
float maxheur=pNode->fHeuristic;
|
|
//VectorOfLinks::iterator vi;
|
|
bool firstStep = false;
|
|
|
|
//return 1;
|
|
|
|
if( pNode->nBuildingID<0 ) // outdoors
|
|
{
|
|
CStandardHeuristic outdoorHeur;
|
|
estimation = outdoorHeur.Estimate(pNode, graph);
|
|
// just use it for now - somehove vehicle heuristic seems not to work, blin
|
|
return estimation;
|
|
// return outdoorHeur.Estimate(pNode, graph);
|
|
}
|
|
|
|
//return 5 - estimation;
|
|
|
|
size_t sz = graph->m_lstCurrentHistory.size();
|
|
if(sz>2)
|
|
int tooBig=1;
|
|
|
|
if(graph->m_lstCurrentHistory.size()==2)
|
|
{
|
|
ListNodes::iterator prev = graph->m_lstCurrentHistory.begin();
|
|
ListNodes::iterator prevPrev = prev;
|
|
++prevPrev;
|
|
curDir = (*graph->m_lstCurrentHistory.begin())->data.m_pos - (*(++graph->m_lstCurrentHistory.begin()))->data.m_pos;
|
|
candidateDir = pNode->data.m_pos - (*graph->m_lstCurrentHistory.begin())->data.m_pos;
|
|
}
|
|
else if(graph->m_lstCurrentHistory.size()==1)
|
|
{
|
|
curDir = (*graph->m_lstCurrentHistory.begin())->data.m_pos - graph->GetRequester()->GetPos();
|
|
candidateDir = pNode->data.m_pos - (*graph->m_lstCurrentHistory.begin())->data.m_pos;
|
|
}
|
|
else
|
|
{
|
|
Vec3d vAngles = graph->GetRequester()->GetAngles();
|
|
curDir = Vec3d(0, -1, 0);
|
|
Matrix44 mat;
|
|
mat.SetIdentity();
|
|
mat=Matrix44::CreateRotationZYX(-gf_DEGTORAD*vAngles)*mat; //NOTE: angles in radians and negated
|
|
curDir = mat.TransformPointOLD(curDir);
|
|
candidateDir = pNode->data.m_pos - graph->GetRequester()->GetPos();
|
|
firstStep = true;
|
|
}
|
|
|
|
candidateDir.z = 0.0f;
|
|
curDir.z = 0.0f;
|
|
candidateDir.normalize();
|
|
curDir.normalize();
|
|
|
|
float dotz = candidateDir.x * curDir.x + candidateDir.y * curDir.y;
|
|
|
|
// if( fabs(dotz)<.05f )
|
|
// return estimation;
|
|
|
|
if(firstStep) // first step - use requester direction)
|
|
{
|
|
if( dotz<0.0f ) // it's behind
|
|
dotz = (dotz + 1.0f)*.2f;
|
|
else
|
|
{
|
|
// if(dotz < .8f)
|
|
// dotz = .8f + (dotz-.8f)*.2f;
|
|
dotz = .2f + dotz*dotz*dotz*dotz*5.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( dotz<0.0f ) // it's behind
|
|
dotz = (dotz + 1.0f)*.2f;
|
|
else
|
|
{
|
|
// if(dotz > .8f)
|
|
// dotz = .8f + (dotz-.8f)*.2f;
|
|
dotz = .2f + dotz*dotz*8.37f;
|
|
}
|
|
}
|
|
|
|
// estimation = dotz*.7f + (1 - pNode->data.fSlope)*.3f;
|
|
// estimation = dotz;//*.7f + (1 - data.fSlope)*.3f;
|
|
// estimation += dotz*.3f;//*.7f + (1 - data.fSlope)*.3f;
|
|
estimation += dotz*.3f;//*.7f + (1 - data.fSlope)*.3f;
|
|
|
|
// avoids water
|
|
// if (data.bWater)
|
|
// return 0;
|
|
|
|
// avoids big slopes
|
|
|
|
return estimation;
|
|
}
|