文章目录

  • 参考
  • 效果
  • 问题描述
  • 子问题一:使用离散点构造一条Catmull-Rom曲线
  • 子问题二:在曲线上采样点
  • 子问题三:每两个点创建一个长方体Mesh

参考

  • unity-procedural-mesh-bezier-curve:使用Bezier曲线建模。Bezier曲线不能经过每个控制点,所以放弃使用Bezier曲线来拟合离散点。但这个项目的建模方法不错,进行了优化,没有重叠的点或面,相邻的面共享了顶点。我借鉴这个项目改成了使用一条线段建模。
  • Unity-Road-Generator:使用Catmull-Rom曲线建模。这个项目使用线段建模的方法很复杂,且没有进行过优化,有重叠的面,UV也是乱的。所以我只参考了这个项目根据离散度创建Catmull-Rom曲线上的点的代码。

效果

问题描述

输入一些离散的三维点坐标,输出一段Mesh。

  • 输入:蓝色的球代表输入的控制点的三维坐标,一共有5个。这5个点代表了一条道路。控制点数据可以从.Shp文件的Polyline或者PolylineZ的points数组中获取,或者从Unity GameObject的Transform的position获取。
  • 输出:一条道路用一个road游戏物体表示。road包含两个子物体controlPointsObjectmeshObject。前者有5个子物体,用来显示出控制点的位置。后者则添加了MeshFilterMeshRenderer,负责渲染出我们创建出的Mesh。

子问题一:使用离散点构造一条Catmull-Rom曲线

学习了插值技术之Catmull-Rom Spline Interpolating(2)。

已知CatmullRom曲线的参数方程如下,我们需要求出此函数的输入:即start、end、tanPoint1,、tanPoint2。

public static Vector3 Interpolate(Vector3 start, Vector3 end, Vector3 tanPoint1, Vector3 tanPoint2, float t)
{// Catmull-Rom splines are Hermite curves with special tangent values.// Hermite curve formula:// (2t^3 - 3t^2 + 1) * p0 + (t^3 - 2t^2 + t) * m0 + (-2t^3 + 3t^2) * p1 + (t^3 - t^2) * m1// For points p0 and p1 passing through points m0 and m1 interpolated over t = [0, 1]// Tangent M[k] = (P[k+1] - P[k-1]) / 2// With [] indicating subscriptVector3 position = (2.0f * t * t * t - 3.0f * t * t + 1.0f) * start+ (t * t * t - 2.0f * t * t + t) * tanPoint1+ (-2.0f * t * t * t + 3.0f * t * t) * end+ (t * t * t - t * t) * tanPoint2;return position;
}

我们把每两个控制点看做一条曲线,这样就获得了start(p0)和end(p1)点。tanPoint1(m0)需要使用start点的前一个点计算得到,tanPoint2(m1)需要end点的后一个点计算得到。

如果start点前面没有点,或者end点后面没有点怎么办呢?这个时候就简便计算了,tanPoint1=end-start,tanPoint2=end-start。

子问题二:在曲线上采样点

只需要输入t即可得到position。

子问题一、二的代码示例:

public static List<Vector3> CreateSplinePoints(List<Vector3> controlPoints)
{List<Vector3> points = new List<Vector3>(); //All points of the splinepoints.Clear();Vector3[] CurveCoordinates;//采样点的坐标Vector3 p0, p1, m0, m1;int pointsToMake;pointsToMake = (CurveResolution) * (controlPoints.Count - 1);//要在曲线上采样这么多个点if (pointsToMake > 0) //Prevent Number Overflow{CurveCoordinates = new Vector3[pointsToMake];//根据输入的控制点,计算每段曲线需要的4个控制点for (int i = 0; i < controlPoints.Count - 1; i++){p0 = controlPoints[i];p1 = controlPoints[i + 1];// m0if (i == 0)m0 = p1 - p0;else m0 = 0.5f * (p1 - controlPoints[i - 1]);// m1if (i < controlPoints.Count - 2)m1 = 0.5f * (controlPoints[(i + 2) % controlPoints.Count] - p0); else m1 = p1 - p0;Vector3 position;float t;float pointStep = 1.0f / CurveResolution;//0.1if (i == controlPoints.Count - 2){pointStep = 1.0f / (CurveResolution - 1);}for (int j = 0; j < CurveResolution; j++)//遍历10次,确定每个点的位置{t = j * pointStep;//j=0,t=0; j=1,t=0.1;j=2,t=0.2; t从0到0.9position = CatmullRom.Interpolate(p0, p1, m0, m1, t);CurveCoordinates[i * CurveResolution + j] = position;//0-9 10-19 20-29 30-39points.Add(position);}}}return points;
}

子问题三:每两个点创建一个长方体Mesh

  • 先定义一个线段的类LineData。我们将输入的spline points创建为多个线段。
  • 对每个线段,我们要创建6个面(plane)。每个面在建模时需要单独处理,但它们也有共同点,那就是都有4个顶点。我们可以定义一个类LineMeshPlane来保存这个plane,这个类中应该保存plane的类型(如top、bottom等)、四边形(quad)的顶点数组,上个同类型quad的顶点数组(方便复用顶点)。
  • 虽然设计上是创建6个面,但其实只有第一条线段才需要front,最后一条线段才需要back。所以在填充plane的顶点的时候,要注意判断LineData在线段数组中的index。
  • 计算quad的4个顶点时要根据roadWidth(道路宽度,影响top/bottom/front/back)和thickness(道路厚度,影响left/right/front/back)得到。
  • 得到quad的4个顶点后,就按照创建一般面片的方式来创建Mesh即可。
  • 创建完每个plane的Mesh之后,我们可以使用Unity的CombineMeshes函数,把多个Mesh合并成一个Mesh。

合并Mesh的示例代码如下:

//【输入】:需要合并mesh的 GameObjects 列表
public static Mesh Combine(List<GameObject> meshes)
{//【1】获取需要合并的meshCombineInstance[] combine = new CombineInstance[meshes.Count];for (int i = 0; i < meshes.Count; i++){MeshFilter filter = meshes[i].GetComponent<MeshFilter>();combine[i].mesh = filter.sharedMesh;combine[i].transform = filter.transform.localToWorldMatrix;}//【2】合并为一个新的meshMesh newMesh = new Mesh();newMesh.CombineMeshes(combine);return newMesh;
}

Unity:使用Catmull-Rom曲线创建道路模型相关推荐

  1. AutoCAD Civil 3D-创建道路模型(2 道路的挖填方量计算及条件部件)

    上一节中讲了道路创建的三要素:平面路线(Alignment).纵断面(Profile).横断面(Assembly),今天就讲一下条件部件在道路模型中的表现以及道路的挖填方计算. (1)条件部件 首先创 ...

  2. AutoCAD Civil 3D-创建道路模型(1 道路三要素)

    今天给大家讲一下在civil3d中如何创建道路模型,以及在创建道路模型时需要注意的一些事项. 在civil3d中创建道路模型叫做Create Corridor,这里的Corridor泛指一切带状的对象 ...

  3. Unity 3D为策略游戏创建地图学习教程

    MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:30节课(7h 42m) |大小:5 GB 含项目文 ...

  4. android显示3d模型_使用Unity AR Foundation在增强现实中查看模型

    本文将分享麻省理工学院的教程-使用Unity AR Foundation在增强现实中查看模型. 在本教程中,我们将介绍如何把3D模型导入Unity,并使用Android设备或iOS设备在AR中查看模型 ...

  5. 数模【Mathematica(安装、入门方法、基本计算、基本图形、创建互动模型、利用数据、幻灯片演示、完整实例)】

    Mathematica 官方中文入门教程 视频中的".nb"文件[链接:https://pan.baidu.com/s/1mpzhfG5igUFGdB1NrGG3SQ   提取码: ...

  6. 手把手带你 Unity 入门之从零创建一个时钟(GameObjects 与 Scripts)

    目录 写作背景 要点提要 1.创建一个时钟 1.1 创建一个 Game Object 1.2 创建钟盘 1.3 创建时钟的其他部分 1.4 创建指针 2.让时钟动起来 2.1 定义组件类型 2.2 拿 ...

  7. unity 控制点 贝塞尔曲线_在Unity中使用贝塞尔曲线(转)

    鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...

  8. android studio 中配置groovy源码_麻省理工教程:使用Unity AR Foundation在AR中查看模型...

    本文将分享麻省理工学院的教程-使用Unity AR Foundation在增强现实中查看模型. 在本教程中,我们将介绍如何把3D模型导入Unity,并使用Android设备或iOS设备在AR中查看模型 ...

  9. 汽车动力经济性开发工具,发动机最优燃油消耗曲线计算程序 发动机最优燃油消耗曲线matlb计算模型,MATLAB模型,发动机OOL

    汽车动力经济性开发工具,发动机最优燃油消耗曲线计算程序 发动机最优燃油消耗曲线matlb计算模型,MATLAB模型,发动机OOL 1.计算发动机最优燃油消耗曲线是车辆能耗优化,特别是混动汽车策略设计时 ...

最新文章

  1. 关于一对多,多对多的多表查询的控制
  2. android 蓝牙耗电量,外媒测试手机蓝牙耗电情况:近乎毫无影响
  3. 《系统集成项目管理工程师》必背100个知识点-34项目范围基准
  4. charts漏斗图表_ECharts漏斗图属性与实例介绍
  5. shell脚本一键同时推送代码至github和gitee
  6. 天池 在线编程 捡胡萝卜(模拟)
  7. BootstrapTable入门Demo
  8. RT-Thread的线程(任务)处理【RT-Thread学习笔记 2】
  9. HDU 1212 大整数的取模运算
  10. oracle存储过程和视图不存在,Oracle 创建存储过程 提示权限不足或者提示表和视图不存在问题...
  11. 计算机财务基础知识培训,财务部计算机基础知识培训讲议.ppt
  12. 文件截取\裁剪工具软件
  13. VSCode Remote SSH 过程试图写入的管道不存在
  14. LeetCode题解(0695):岛屿的最大面积(Python)
  15. 你还在怕忘记网盘密码?商鼎云助记词登录保障你的安全
  16. 人工智能就业方向及前景,前景如何?好就业吗?
  17. java求三角形周长 面积_用java如何求三角形的周长和面积?
  18. 廖雪峰的GIT教程-读书笔记
  19. Echars安徽地图
  20. 电气工程和计算机软件哪个更好,前景最好的十大专业电气

热门文章

  1. 基于matlab的水准网间接平差程序设计,matlab水准网间接平差
  2. 【C】C语言打开,读取文件
  3. 【CAD】CAD入门知识
  4. 如何在gitlab下载单个文件夹
  5. MATLAB环境下基于包络谱和谱峭度的一维振动信号分析
  6. abb机器人负载配置设定_ABB机器人【 配置设定】大全 , 人手一份,建议永久收藏!...
  7. 迅游科技遭遇瓶颈 购网安资产谋求多元化
  8. win10系统omnipeek无线抓包网卡驱动由于数字签名问题安装失败解决办法
  9. matlab可以画3d图吗,如何用matlab画3d图
  10. BOSSGOO平台免费使用