主要工作有三:
一、数据组织。根据3D模型得到一个PathMesh,这个PathMesh里记录了三角形与边的邻接信息,边与三角形的邻接信息,边的端点,边的方程(用于求解线段最短距离)。从而间接知道边与边的邻接信息。路径点除了首尾,都通过边来计算。这个数据容易得到。
二、路径搜索算法。一开始使用A*算法,路径不是很好。因为评估函数不好写,评估函数只能描述两个点之间的空间距离,但是无法描述上下楼很难到达这样的信息。所以,A*算法总会先走到目标点的楼下,然后在绕道到目标点。后来改用广度优先搜索,效果很好。考虑到3D空间中寻路,实际的节点数目不是很多,准备采用广度优先搜索。A*对我来说,也很容易。
三、路径美化。这个就是一直以来的心病。因为PathMesh可能是各种各样的样子,导致路径可能会非常难看,怎样优化路径使得看上去美,看上去聪明。至于算法,示意图见图:
(怎么传图片?讯问中。。。)
struct
NodeInfo
... {
V3Vector3 p; //具体坐标
SideInfo * s; //边
FLOAT t; //边上的位置
} ;
void Mesh::FixPath(UINT nTimes)
... {
UINT nCount = (UINT)m_Result.size();
if(nCount < 3)
return ;
nCount -= 2;
for(; nTimes > 0; --nTimes)
...{
for(UINT i=0; i<nCount; ++i)
...{
NodeInfo & s = m_Result[i];
NodeInfo & c = m_Result[i+1];
NodeInfo & e = m_Result[i+2];
SideInfo & si = *c.s;
FLOAT n;
DistanceSquaredLineLine(si.line,V3Line3(s.p,e.p-s.p),&n);
if(n >= 0.0f && n < 1.0f)
...{
c.p = get_side_pos(si,n);
c.t = n;
}
}
}
}
... {
V3Vector3 p; //具体坐标
SideInfo * s; //边
FLOAT t; //边上的位置
} ;
void Mesh::FixPath(UINT nTimes)
... {
UINT nCount = (UINT)m_Result.size();
if(nCount < 3)
return ;
nCount -= 2;
for(; nTimes > 0; --nTimes)
...{
for(UINT i=0; i<nCount; ++i)
...{
NodeInfo & s = m_Result[i];
NodeInfo & c = m_Result[i+1];
NodeInfo & e = m_Result[i+2];
SideInfo & si = *c.s;
FLOAT n;
DistanceSquaredLineLine(si.line,V3Line3(s.p,e.p-s.p),&n);
if(n >= 0.0f && n < 1.0f)
...{
c.p = get_side_pos(si,n);
c.t = n;
}
}
}
}