buildPolyDetail() 传入的是contours,先对过长的边进行插值,通过”int nn = 1 + (int)floorf(d/sampleDist);“ 进行判断需要划分多少段,这个过程也对点的y轴进行了设置。然后按原来的方向顺序将点的下标放到hull中,形成一个精细化的三维的contours(hull)。
然后进行triangulatehull过程。
再然后,对整个contours进行均匀的网状的划分,找出其中的网的所有交点,这些交点与contours的边的距离(在xz平面上)大于 “-sampleDist/2”
然后循环进行   (每次从采样点中选取  与 上次deluanay划分计算出的mesh 距离最大的点 ,放入到verts中,然后又将所有verts中的点进行deluanay划分)的操作。最后一次的deluanay划分出来的tris就是buildPolyDetail所求。

getHeightData() ,基本上注释说得很明确。

while (head*3 < queue.size())  //在上面先求出满足要求的顶点,再基于这些顶点用广度优先算法一圈一圈的向外扩展,按这样的方式对获取所有有效顶点的高度,并保存到hp.data中

triangulateHull 创建修长的三角形网格,主要代码如下

    tris.push(hull[start]);tris.push(hull[left]);tris.push(hull[right]);tris.push(0);// Triangulate the polygon by moving left or right,// depending on which triangle has shorter perimeter.// This heuristic was chose emprically, since it seems// handle tesselated straight edges well.while (next(left, nhull) != right){// Check to see if se should advance left or right.int nleft = next(left, nhull);int nright = prev(right, nhull);const float* cvleft = &verts[hull[left]*3];const float* nvleft = &verts[hull[nleft]*3];const float* cvright = &verts[hull[right]*3];const float* nvright = &verts[hull[nright]*3];const float dleft = vdist2(cvleft, nvleft) + vdist2(nvleft, cvright);const float dright = vdist2(cvright, nvright) + vdist2(cvleft, nvright);if (dleft < dright){tris.push(hull[left]);tris.push(hull[nleft]);tris.push(hull[right]);tris.push(0);left = nleft;}else{tris.push(hull[left]);tris.push(hull[nright]);tris.push(hull[right]);tris.push(0);right = nright;}}

每次找最左右未取到的相对更短边与上一步新加的边组成新的三角形,根据这个逻辑,结果类似这样:(实际点是三维的,在y轴是不共面的)

        
这里使用triangulateHull而不使用delaunayhull原因如下:
// Tessellate the base mesh.
// We're using the triangulateHull instead of delaunayHull as it tends to
// create a bit better triangulation for long thin triangles when there
// are no internal points.

delaunayHull()//对poly进行德洛内三角划分,得出poly的三角行和顶点,存放到tris和verts中。首先将最外围的一圈点链接起来,再对所有点进行三角划分,将信息存放到edge中。最后再edge中的信息放到tris中
里面主要理解的是edges。 一条边,由四个变量组成,起点,终点,边的左边三角形面id,边的右边三角形面id。默认面id为EV_UNDEF或者EV_HULL(边界的edges)。组装点edge的时候采用逆时针方向进行组装的,所以初始的时候的hull边界的left为EV_HULL。而right正是将要 求取 的,设置为EV_UNDEF。

    int currentEdge = 0;while (currentEdge < nedges){if (edges[currentEdge*4+2] == EV_UNDEF)completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);
//找出一个三角形 ,对nedges会做修改 ,nfaces 会增1,并将face id存放到相关的edge中(edge[2],edge[3])。if (edges[currentEdge*4+3] == EV_UNDEF)completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);currentEdge++;}

completeFacet,采用的方法是 计算该边与所有其他点的最小外接圆。

rcBuildPolyMeshDetail,将上面的rcBuildPolyMesh 计算出来的poly 信息存放到 rcPolyMeshDetail中。逐个poly的进行buildpolydetail计算。
dmesh,meshes存放submesh,实际是存放poly信息。

dmesh.nmeshes = mesh.npolys;  //num sub mesh
dmesh.nverts = 0; //dmesh总的顶点数
dmesh.ntris = 0;//dmesh总的triangle数
dmesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*dmesh.nmeshes*4, RC_ALLOC_PERM);for (int i = 0; i < mesh.npolys; ++i){
。。。。dmesh.meshes[i*4+0] = (unsigned int)dmesh.nverts;//存放poly的vert在dmesh->verts中的存放的起点位置dmesh.meshes[i*4+1] = (unsigned int)nverts;//存放这个poly的verts数量dmesh.meshes[i*4+2] = (unsigned int)dmesh.ntris;//存放poly的triangle在dmesh->tris中存放的起点位置dmesh.meshes[i*4+3] = (unsigned int)ntris;//存放这个poly triangle数量
。。。。

recast 6 rcBuildPolyMeshDetail相关推荐

  1. Recast Detour 寻路引擎的基本流程

    Recast & Detour是一个开源的寻路引擎,其遵循zlib协议,基本上你可以免费且无限制的将它用作个人和商业产品中. 从名字中我们可以看到,这个引擎分成两部分: 第一部分是Recast ...

  2. SAP人工智能服务Recast.AI的一个简单例子

    关于这个例子的完整介绍,请参考公众号 "汪子熙"的两篇文章: SAP C/4HANA与人工智能和增强现实(AR)技术结合的又一个创新案例 和使用Recast.AI创建具有人工智能的 ...

  3. 使用Recast.AI创建具有人工智能的聊天机器人

    很多SAP顾问朋友们对于人工智能/机器学习这个话题非常感兴趣,也在不断思考如何将这种新技术和SAP传统产品相结合.Jerry之前的微信公众号文章C4C和微信集成系列教程曾经介绍了Partner如何利用 ...

  4. 如何将eps/wind数据库里的数据变为stata要求的面板数据以及报错处理\改变数据类型(recast)

    1. wind\eps原始数据如下(只是对原始数据修改了一哈地区名,数据主体和原始数据一样) 2.在你的年份2012.2013等前面都加上统一的标识 比如y,结果如下 3.将其复制到stata中,勾选 ...

  5. A*寻路中第四种烘培寻路方法Recast Mesh方法:

    A*寻路中第四种烘培寻路方法Recast Mesh方法: 全地形烘培

  6. 游戏思考17:寻路引擎recast和detour学习一(跨平台编译库及相关寻路接口解析)

    文章目录 一.windows安装编译recastnavigation1.5.1 二.linux编译recastnavigation1.5.1 三.背景知识 1)分类 2)navmesh定义 3)编译包 ...

  7. recast SoloMesh生成过程详解

    最近游戏中需要使用navmesh,阅读recast过程中顺手把学习记录写下来,方便以后查看. 使用过程主要需要理解每个数据含义,至于生成过程,不做深入研究. 相关资料 recast源码 很好的参考资料 ...

  8. Recast Navigation工具编译生成

    Recast Navigation是一个开源的应用于游戏的网格导航工具.但文档很简陋.这里详细介绍一下该工具在windows下的编译生成. 1.下载recastnavigation的源码. 2.rec ...

  9. Unity寻路初研究—Recast工程编译

    1.准备工具: 从GitHub上下载下来Recast源代码功能(点击跳转) 下载premake用于和Recast工程中的premake5生成对应平台的工程(点击官网首页) 下载SDL库(点击跳转),下 ...

最新文章

  1. ibatis运行流程
  2. jenkins 流水线(pipline)
  3. Python 执行代码的两种方式
  4. 在新的固态硬盘只装ubuntu16.04系统,重启后无启动项解决方案
  5. 算法入门篇八 贪心算法
  6. Java求两个数的最大公约数
  7. c语言abs和fabs的区别,c语言中abs()和fabs()的区别点整理
  8. mapengpeng1999@163.com Web前端之JS
  9. php json encode 参数,PHP json_encode函数的参数说明与用法
  10. pytho_抓取下载音乐歌曲
  11. 计算机动画可分为二维和三维动画,二维动画与三维动画设计的区分
  12. PCL(Point Cloud Library)学习指南资料推荐(2021版)
  13. 股票价格在随机漫步吗?用 Python 来告诉你
  14. 当出现Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this
  15. moviepy音视频剪辑:视频剪辑基类VideoClip的属性及方法详解
  16. ELM饿了么获取COOKIE教程附吃货豆脚本
  17. 杂谈~关于踩shit
  18. Unity AssetBundle学习笔记
  19. 低功耗芯片间串行媒体总线SLIMbus
  20. 移动的黑莓,电信的伤?

热门文章

  1. 收藏 - android
  2. 关于CAN通讯基础知识点
  3. SQL 结构化查询语言 6部分
  4. 正则匹配文件夹及文件路径
  5. 递归函数的写法(以strcpy函数为例)
  6. android:ellipsize的使用
  7. Python爬虫:多线程爬取盗墓笔记
  8. kali精准定位地理位置
  9. 江西省宜春市谷歌高清卫星地图下载
  10. Newcoder和Leetcode5月刷题笔记