寻路库recastnavigation改造

简介: 寻路库recastnavigation改造

本文是介绍对寻路库recastnavigation 改造,使得使用更加友好。

Git仓库:

https://github.com/jiangguilong2000/recastnavigation

首先,我们要做一些前置操作

SDL: 开放源代码的跨平台多媒体开发库

Premake:量跨平台构建系统

环境:

VS 2019以及完整的C++编译环境

Rider For Unreal Engine 2022.2.1(下面简称Rider)

Unity 2019.4.8 lts

.Net Core 2.2

1.首先把git库拉到本地,先将下载的SDL库放到ecastnavigation\RecastDemo\Contrib,需要改名为SDL,应该得到如下目录recastnavigation-master\RecastDemo\Contrib\SDL\lib\x64

2/然后将下载premake5.exe放入

recastnavigation\RecastDemo

3.然后通过命令行控制premake编译recastnavigation为sln工程

PS E:\recastnavigation\RecastDemo> .\premake5.exe vs2019
Building configurations...
Running action 'vs2019'...
Generated Build/vs2019/recastnavigation.sln...
Generated Build/vs2019/DebugUtils.vcxproj...
Generated Build/vs2019/DebugUtils.vcxproj.filters...
Generated Build/vs2019/Detour.vcxproj...
Generated Build/vs2019/Detour.vcxproj.filters...
Generated Build/vs2019/DetourCrowd.vcxproj...
Generated Build/vs2019/DetourCrowd.vcxproj.filters...
Generated Build/vs2019/DetourTileCache.vcxproj...
Generated Build/vs2019/DetourTileCache.vcxproj.filters...
Generated Build/vs2019/Recast.vcxproj...
Generated Build/vs2019/Recast.vcxproj.filters...
Generated Build/vs2019/RecastDemo.vcxproj...
Generated Build/vs2019/RecastDemo.vcxproj.user...
Generated Build/vs2019/RecastDemo.vcxproj.filters...
Generated Build/vs2019/Tests.vcxproj...
Generated Build/vs2019/Tests.vcxproj.user...
Generated Build/vs2019/Tests.vcxproj.filters...
Done (160ms).

然后目录中会生成一个Build文件夹,里面是我们编译出来的sln工程

recastnavigation\RecastDemo\Build\vs2019\recastnavigation.sln

用rider打开,直接运行,我们就能看到编辑器画面了

接下去我们要对源码进行一些改造:

原始的recast是没有开始点和结束点的坐标的,那如何能显示出来呢?

void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* view)
{
  GLdouble x, y, z;
  char buf[64];
  // Draw start and end point labels
  if (m_sposSet && gluProject((GLdouble)m_spos[0], (GLdouble)m_spos[1], (GLdouble)m_spos[2],
    model, proj, view, &x, &y, &z))
  {
    if (m_showCoord)
    {
      snprintf(buf, sizeof(buf), "Start (%.1f, %.1f, %.1f)", m_spos[0], m_spos[1], m_spos[2]);
      imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, buf, imguiRGBA(0, 0, 0, 220));
    }
    else
      imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0, 0, 0, 220));
  }
  if (m_toolMode == TOOLMODE_RAYCAST && m_hitResult && m_showCoord &&
    gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
      model, proj, view, &x, &y, &z))
  {
    snprintf(buf, sizeof(buf), "HitPos (%.1f, %.1f, %.1f)", m_hitPos[0], m_hitPos[1], m_hitPos[2]);
    imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, buf, imguiRGBA(0, 0, 0, 220));
  }
  if (m_eposSet && gluProject((GLdouble)m_epos[0], (GLdouble)m_epos[1], (GLdouble)m_epos[2],
    model, proj, view, &x, &y, &z))
  {
    if (m_showCoord)
    {
      float totalCost = 0.0f;
      for (int i = 0; i + 1 < m_nstraightPath; i++)
        totalCost += dtVdist(&m_straightPath[i * 3], &m_straightPath[(i + 1) * 3]);
      snprintf(buf, sizeof(buf), "End (%.1f, %.1f, %.1f), Cost %.1f", m_epos[0], m_epos[1], m_epos[2], totalCost);
      imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, buf, imguiRGBA(0, 0, 0, 220));
    }
    else
      imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "End", imguiRGBA(0, 0, 0, 220));
  }
}

那么,如何能显示出关键点point list?,首先,路径搜索的模式要改成TOOLMODE_PATHFIND_STRAIGHT模式,代码需要增加如下的打印,

在NavMeshTesterTool.cpp中增加,

void NavMeshTesterTool::recalc(){
....
....
  if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT&& m_nstraightPath>0) 
      {
        stringstream os;
        os << "total point size=" << m_nstraightPath<< ",";
        //m_sample->getContext()->log(RC_LOG_PROGRESS, "total point size=%d", m_nstraightPath);
        for (int i = 0; i < m_nstraightPath; ++i)
        {
          if (i > 0&&i%10==0) {
            m_sample->getContext()->log(RC_LOG_PROGRESS, "%s", os.str().c_str());
            os.str("");
          }
          os << "[" << m_straightPath[i * 3] << "," << m_straightPath[i * 3 + 1] << "," << m_straightPath[i * 3 + 2] << "] ";
        }
        m_sample->getContext()->log(RC_LOG_PROGRESS, "%s", os.str().c_str());
      }
}

在Sample.h中增加

public:
  Sample();
  virtual ~Sample();
  void setContext(BuildContext* ctx) { m_ctx = ctx; }
  BuildContext* getContext() {
    return m_ctx;
  }

最后一个问题,如何把显示日志的地方的文本能鼠标选中?做了个曲线救国,通过按钮复制来搞定!

//拷贝
  if (imguiButton("Copy Log"))
  {
    HGLOBAL hGlobal;
    string allLog = "";
    string prefix = "total point";
    bool flag=false;
    for (int i = 0; i < m_sample->getContext()->getLogCount(); ++i)
    {
      string content = string(m_sample->getContext()->getLogText(i));
      if(flag)
      {
        allLog += content + "\n";
      }else
      {
        size_t index = content.find(prefix);
        if(index < content.length())
        {
          flag=true;
          allLog += content + "\n";
        }
      }
    }
    const char* content = allLog.c_str();
    int bufSize = MultiByteToWideChar(CP_ACP, 0, content, -1, NULL, 0);
    wchar_t* wbuf = new wchar_t[bufSize];
    MultiByteToWideChar(CP_ACP, 0, content, -1, wbuf, bufSize);
    hGlobal = GlobalAlloc(GHND, (lstrlenW(wbuf) + 1) * sizeof(wchar_t)); // lstrlenW sizeof(wchar_t)
    wchar_t* pGlobal = (wchar_t*)GlobalLock(hGlobal); // wchar_t
    lstrcpyW(pGlobal, wbuf); // lstrcpyW
    GlobalUnlock(hGlobal);
    OpenClipboard(NULL);
    EmptyClipboard();
    SetClipboardData(CF_UNICODETEXT, hGlobal); // UnicodeCF_UNICODETEXT
    CloseClipboard();
    recalc();
  }

效果如下:

复制出来的结果:

total point start{-31.7925,0,85.1438} end{-91.9496,0,109.848}  size=6,[-31.7925,0,85.1438] [-55.1,1.6,104.598] [-56.3,2,105.498] [-61.1,2.4,107.298] [-65.6,1.6,107.898] [-91.9496,0,109.848]
目录
相关文章
|
2月前
|
前端开发 JavaScript 开发者
揭秘前端高手的秘密武器:深度解析递归组件与动态组件的奥妙,让你代码效率翻倍!
【10月更文挑战第23天】在Web开发中,组件化已成为主流。本文深入探讨了递归组件与动态组件的概念、应用及实现方式。递归组件通过在组件内部调用自身,适用于处理层级结构数据,如菜单和树形控件。动态组件则根据数据变化动态切换组件显示,适用于不同业务逻辑下的组件展示。通过示例,展示了这两种组件的实现方法及其在实际开发中的应用价值。
50 1
|
5月前
|
安全 数据处理 开发者
Flutter相关痛点解决问题之iBox模块的源码结构的设计如何解决
Flutter相关痛点解决问题之iBox模块的源码结构的设计如何解决
|
8月前
|
设计模式 安全 Java
老系统重构系列--如何用一套流程接入所有业务线
**摘要:** 本文介绍了老系统改造的过程,作者提出,ToB业务的挑战在于需要支持多种差异化的业务需求,而模板模式在处理这种需求时可能会导致继承关系复杂和粒度过粗。为了解决这些问题,文章提出了以下步骤: 1. **梳理流程差异点**:识别不同业务流程的差异,以便确定扩展点。 2. **领域模型梳理**:区分核心域和支撑域,确保核心域的稳定性。 3. **二次抽象隔离层**:创建隔离层,避免核心域因新业务接入而变得不稳定。 4. **基于SPI的扩展体系建设**:选择了COLA-SPI实现扩展点,允许业务域定义接口并实现差异化的流程逻辑。
188 0
|
设计模式 JSON 缓存
如何“好好利用多态”写出又臭又长又难以维护的代码?| Feeds 流重构方案
如何“好好利用多态”写出又臭又长又难以维护的代码?| Feeds 流重构方案
89 0
|
数据可视化 前端开发 算法
动态渲染拓扑图方案探究
拓扑图是数据可视化领域一种比较常见的展示类型,目前业界常见的可视化展现的方案有ECharts、HighCharts、D3、AntV等。当前的项目使用的是基于ECharts的静态关系图渲染,为了后续可能扩展成动态的拓扑图渲染,本文探索了ECharts的原理以及G6的原理,也算是对自研一个可视化库的基本实现方法做了一个梳理。
291 0
|
API 开发工具 开发者
打入高德内部获取到的 — Flutter 高德定位的使用方案
定位是我们开发中常用的功能,为了帮助大家理解,我从&quot;高德总部&quot;搞出来了这一份方案~
打入高德内部获取到的 — Flutter 高德定位的使用方案
|
数据管理 测试技术 C#
一个近乎完美的Unity全平台原生c#热更方案
HybridCLR是一个特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更方案。
655 0
一个近乎完美的Unity全平台原生c#热更方案
|
缓存 API 定位技术
商圈库_功能_思路 | 学习笔记
快速学习商圈库_功能_思路。
商圈库_功能_思路 | 学习笔记
|
前端开发 JavaScript API
渲染性能优化的全局视角,教你做的比别人好
遇到性能优化的问题,大抵都会从两个方向入手:行业标准优化手段、实际性能瓶颈问题。既能够从先进的模式、方法、套路吸收借鉴,又能够结合实际性能情况设计应对方案,已然是高质量工作的路径了,但是,路上还充斥着各种判断和选择,稍有不慎还是会泥足深陷,走上“要你命 3000 ”的道路。
渲染性能优化的全局视角,教你做的比别人好
|
缓存 编解码 自然语言处理
高德渲染网关Go语言重构实践
高德启动Go业务建设已经有段时间了,主要包含Go应用落地,Go中间件建设,云原生三个部分。经过持续的发力,在这些方面取得了不错的进展。高德Go业务落地过程是如何实现的,遇到过哪些问题,如何解决?本文将为大家介绍相关经验,希望对感兴趣的同学有所帮助。
320 0
高德渲染网关Go语言重构实践