raycast 一小段距离碰撞到的poly
dtNavMeshQuery::raycast(dtPolyRef startRef, const float* startPos, const float* endPos,
const dtQueryFilter* filter, const unsigned int options,
dtRaycastHit* hit, dtPolyRef prevRef):
做2D的检测,忽略y轴
1 先让curRef = startRef;
2 while (curRef)
{
3 在curRef上进行碰撞dtIntersectSegmentPoly2D
hit->hitEdgeIndex = segMax;
把碰撞到的polygon存起来hit->path[n++] = curRef;
segMax == -1的时候说明射线的end在这个poly里面
那就不用往下碰撞了,直接hit->pathCount = n;
4 接下来碰撞nextpoly for循环
对于这个poly的所有link
找到segMax那条边
并且根据其ref找到nextPoly和nextTile
if (nextPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION)//有可能是segMax么?
如果这个link->side == 0xff也就是不是tileboundry,nextRef = link->ref;
if (link->bmin == 0 && link->bmax == 255)也就是link跨越了整个边
下一个polyref就找到了
else
就是只覆盖了部分边的link
float z = startPos[2] + (endPos[2]-startPos[2])*tmax;求交点,
如果是在lmin和lmax之间,则说明相交。
下一个polyref就找到了
竖着的两个格子也是一样的
5 lastPos用来存之前的curPos
curpos移动到碰撞点 dtVmad(curPos, startPos, dir, hit->t);
获得segMax对应的边的两个顶点e1,e2
算出curPos的高度值 curPos[1] = e1[1] + eDir[1] * s;
eDir是e1到e2的向量,s是curpos在线段上的插值
计算curpos移动这一段的cost,也就是lastPos, curPos之间的cost
累加到hit->pathCost
6接下来就是,end不在poly的里面,又没有找到nextref的情况
那就是we hit a wall.
计算碰撞点在xz平面上的法线hit->hitNormal,并且dtVnormalize
7 如果没有碰撞上这个poly,进入nextPoly,因为毕竟还有nextRef