checkPathValidity 检查所有agent的corridor的m_path是否有效
Posted icebergliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了checkPathValidity 检查所有agent的corridor的m_path是否有效相关的知识,希望对你有一定的参考价值。
在checkPathValidity(检查所有agent的corridor的m_path是否有效)
如果是无效的要进行重新设置并且设置replan
首先获得第一个polygon,m_path[0]
这里,因为addagent的时候,ag->corridor.reset(ref, nearest);
m_path[0] = ref;
所以就算是没有设定目标,const int npath = ag->corridor.getPathCount();也是1
然后根据FirstPoly的polyref进行检查,isValidPolyRef
检查的条件是,可以获得poly和tile,并且passfilter
如果不是有效的则:
通过findNearestPoly-> queryPolygons找到最近的poly
用其返回的距离poly的最近点覆盖agentPos
如果没有找到NearestPoly,设置agent的state 为 DT_CROWDAGENT_STATE_INVALID
然后ag->corridor.fixPathStart主要是给corridor的m_path[0]设置成找到的这个点
把当前agent的ag->npos设置成我们计算出来的最近点
因为初始点是被设置过了,所以要replan = true;
同样的,对目标点进行isValidPolyRef检查
如果是无效的,用上面的方法,找到一个有效的来
设置到ag->targetPos
如果最终还是找不到targetRef
ag->targetState = DT_CROWDAGENT_TARGET_NONE
然后检查ag->corridor.isValid,其实就是检查这个corridor里面的m_path的所有poly是不是isValidPolyRef,如果有invalid的,则replan = true;
最后 如果需要replan :r
equestMoveTargetReplan 就是设置agent的targetRef, targetPos,以及state设置成DT_CROWDAGENT_TARGET_REQUESTING
=========================
dtNavMeshQuery::queryPolygons(const float* center, const float* halfExtents,
const dtQueryFilter* filter, dtPolyQuery* query):
计算center为中心halfExtents为半径的包围盒所触及的tiles
在所有触及到的tiles中执行queryPolygonsInTile
这个函数的用途就是为了对所有多边形执行process,进而找到最近的poly
如果找到了,我们就覆盖nearestPt
==============
queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax,
const dtQueryFilter* filter, dtPolyQuery* query):
如果使用了bvtree:
{
float minx = dtClamp(qmin[0], tbmin[0], tbmax[0]) - tbmin[0];……
把center为中心halfExtents为半径的包围盒转换为这个相对于这个tile原点的相对位置
Bmax确保比bmin大1
接下来遍历bvtree,从数组中的第一个node开始,计算是否覆盖,
node->i如果大于零说明是叶子,表示其在本tile中的poly序号,否则就表示跨过多少个找其右边的儿子
接下来:
1 如果是叶子并且相交了并且通过了passfilter,记录下来这个node,这个node是一个polygon
如果记录的总数已经到达了batchSize的上限了则process,主要就是找到最近的点和最近的多边形,batchSize是一个批次的量,也就是说是按照批次进行处理的。
2 如果是叶子但是没有相交或者不是叶子但是相交了,那就node++,走下一个树根或者走当前树根的第一个节点
3 如果既不是叶子也没有相交,那就可以跨过去当前这个树根了,直接跨过-node->i个节点。
}
如果没有使用bvtree:
For(这个tile里面的所有polygon)
{
不可以是offmeshconnection并且必须passFilter
求出多边形的AABB
然后跟使用bvtree的情况下一样找到最近的点和最近的多边形
}
最后把没有满一个批次的,调用process进行处理。
=====================
dtFindNearestPolyQuery :: process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count):
For(每一个poly)
{
计算m_center跟这个poly的最近点,dtNavMeshQuery::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly):
通过dtDistancePtPolyEdgesSqr(pos, verts, nv, edged, edget)计算出,pos对于每条边的最近距离,并且存在edged里面,函数返回值表示点是否在多边形内部。
找到距离最小的那条边的两个顶点va,vb
dtVlerp(closest, va, vb, edget[imin]); 根据edget对va,vb进行插值,求得多边形上距离pos最近的点closest
edget里面存的是 http://blog.sina.com.cn/s/blog_5d5c80840101bnhw.html 这里面的r
因为且
所以可以用r来作插值计算closest的坐标。
posOverPoly记录是否在多边形内
接下来计算m_nearestDistanceSqr,存的是点与这些多边形的最短的直线距离。
有一个情况除外,就是在posOverPoly的情况下,计算的是y轴的距离,如果比walkableClimb小的话,直接就选它了,否则就是记录高度距离的平方存在nearestDistanceSqr
然后找到距离最小的点,存在nearestDistanceSqr
}
以上是关于checkPathValidity 检查所有agent的corridor的m_path是否有效的主要内容,如果未能解决你的问题,请参考以下文章