zoukankan      html  css  js  c++  java
  • UE4物理模块(二)---建立物体碰撞

    在前文中介绍了什么是物理以及如何在UE4和PhysX中进行可视化调试:

    Jerry:UE4物理模块(一)---概述与可视化调试​zhuanlan.zhihu.com图标

    这里调试只谈到了碰撞盒(后续还会有场景查询等调试介绍),那么如何创建物体的碰撞盒呢?

    碰撞既可以在3D Max中创建成.fbx文件然后导入UE4,也可以用UE4内建的模型工具进行生成。我们以示例场景中摆在桌上的雕塑为例,选中后,双击右侧Static Mesh图片就可以打开模型编辑器了,如下图:

    在上面工具栏里面有一个Collision,单击后可以看到可选显示简单碰撞与复杂碰撞:

    按照PhysX中的定义,物体的碰撞分为简单碰撞与复杂碰撞,复杂碰撞就是拿物体模型面片作为碰撞盒,除此之外的都是简单碰撞。

    钩选简单碰撞后,可以看到类似于下图(不一定一样,因为我改过了),是比较粗糙的模型轮廓包围盒:

    去掉简单碰撞,钩选复杂碰撞,会看下密密麻麻的三角面片,如下图:

    这是物体的精确碰撞,也就是PhyX定义的复杂碰撞。复杂碰撞一般就是物体的模型面片本身,除非模型改变,否则碰撞就是这样;简单碰撞的花样则比较多,在上面的菜单栏里面有一个“collision”,单击后可见下拉列表如下:

    包含有从Add Sphere Simplified Collision到Add 26DOP Simplified Collision共8种预设碰撞,以及可调参数的第9种自动凸包工具(Auto Convex Collision)。我们可以分成三大类,第一类是基本几何体碰撞,包括球碰撞,胶囊碰撞和盒形碰撞;第二类是k-DOP碰撞,在盒形简单碰撞基础上添加更多的轴逼近物体;第三类是自动凸包生成工具,可以调的参数包括生成最多凸包个数(最小是2个),以及每个凸包顶点的最大数量(最小是6个)。下面先来看下基本几何体碰撞。在看之前要将视图切成简单碰撞:

    并把之前生成的简单碰撞去掉,选择Remove Collision就可以清掉所有简单碰撞了,也可以先选中某一个碰撞盒,然单击这里的Delete Selected Collision:

    球简单碰撞如下:

    胶囊体简单碰撞如下:

    盒形简单碰撞如下:

    其中盒形碰撞又可称之为6-DOP碰撞,那么如何理解k-DOP碰撞模型呢?DOP全称是

    Discrete Oriented Polytope,即离散有向多面体,k是它的轴数量。以一张2D图像为例:

    以轴对齐方式建立包围盒,只需要绿色与橙色四个对齐轴即可(可以将绿轴理解为X轴,将橙轴理解为Y轴),如下图:

    这就是4-DOP,想要成3D图片,对齐轴要换成平面,这样就需要多出前后两个面来限制厚度,所以是6-DOP(恰好对应于盒子的六个面)。我们把这种与XYZ轴对齐的划分包围盒称为AABB盒。

    回到2D图片上,如果想要更精确呢,可以再加四条线,但这四条线不再与XY轴对齐了,如下图所示:

    蓝色与紫色是新加的轴,这样截出来的包围盒就更精确了,如下图红色框所示:

    总共有8个轴来切出这个包围盒,因此称之为8-DOP,扩展到3D,就是18-DOP(怎么数?可以非平行轴数量,然后乘以2:对于方盒前面和后面来说,是XY两个轴+左斜边一个轴+右斜边一个轴,就是四个轴;对于方盒左面和右面来说,左斜边一个轴+右斜边一个轴,就是两个轴;对于方盒顶面和底面来说,左斜边一个轴+右斜边一个轴,也是两个轴;最后再补上厚度Z轴,就是2(前后斜边)+2(左右斜边)+2(顶底斜边)+3(XYZ)=9,再乘以2考虑到平行轴,就是18个轴了)。

    如果分别只考虑某一面的斜边,即2(某一面斜边)+3(XYZ)=5,乘以2得10,就是编辑器里面说的10-DOP的缘由了:

    下面截图示意下,10DOP-X情况,我把坐标也标出来了,注意区分:

    是垂直于X切的左斜和右斜边,下面是10DOP-Y:

    以及10DOP-Z:

    为了方便理解,我再把左右斜边也标注下(其实是斜平面):

    至于18-DOP(每面都有斜边)与26-DOP(除了边还有角也细分),也贴出来示例下:

    18-DOP26-DOP

    一般来说,做到18-DOP就已经差不多了。

    自动凸包工具如下:

    可以改目标凸包个数,以及每个凸包最大顶点数。HullCount表示最多凸包个数,最少是2,MaxHullVerts表示每个凸包最多的顶点个数,最少是6。我们按2和6来自动生成凸包,可见:

    注意到底座几乎没有覆盖到碰撞(貌似与凸包算法有关,将凸包数量调大也不能覆盖),上半身覆盖的不完整,这是因为凸包个数不够的原因。我们采用默认的4个凸包和16个顶点数量生成,如下:

    可以看到碰撞的精细度立刻就上来了,生成的凸包是可以用手拖动的,我们将之分离:

    可以看到这个自动凸包工具是生成了三个凸包(数字4表示生成凸包个数的上限,不一定会正好生成4个凸包),并且每个凸包的顶点数量不会超过16。

    既然可以手拖碰撞,那我们也可以在UE里面使用第十种生成碰撞的方法:人工生成。还是以这个雕塑模型为例,我们添加两个盒形碰撞和一个球形碰撞,并适当绽放和移动位置,就可以得到近似的碰撞如下:

    保存一下,回到编辑器里Play In Editor,然后在控制台show collision可见碰撞已经被修改:

    用pvd connect可视化样子上差不多,但有些模型重合的样子,这是因为叠加了mesh复杂碰撞:

    选中这个模型,可以在左侧面板上看到详细的碰撞信息,此时碰撞PxShape个数是四个,分别是球,盒形柱身与盒形底座这三个简单碰撞,再加上mesh自身的复杂碰撞(旁边未修改过的椅子只有两个PxShape,对应一个简单碰撞和一个复杂碰撞)。

    虽然UE4的show collision没有看到复杂碰撞,但PhysX建立的物理世界里却保留了这个复杂碰撞,后面在谈到物理Query时会说及啥时启用复杂碰撞,不过有一些基本概念还是要明确的,那就是碰撞复杂度越高,检测结果越精确,但性能越差。网上有Unity引擎下的一个大概检测结果视频,链接如下(需翻墙):

    https://www.youtube.com/watch?v=u_fVE-IcPZ8​www.youtube.com

    我这里截几帧图(版权归Three Eyed Games):

    对于球形碰撞:

    两万只模型同时掉落后某种运算时间是29.7ms:

    对于复杂碰撞(mesh作碰撞)运算时间是71.8ms:

    对于18-DOP碰撞而言,运算时间是44.5ms:

    所以与预想的一样,性能消耗是复杂mesh碰撞>k-DOP>球碰撞。

    那么如果想在任何时候都不想启用复杂碰撞的话该如何做?在模型编辑器里,UE提供了配置方法如下:

    默认是ProjectDefault,这个在ProjectSetting里面默认配置成了Simple And Complex:

    这样带入PhysX的既有简单碰撞,也有复杂碰撞了。如果我们选择第三个:Use Simple Collision As Complex,那么复杂mesh碰撞就不会带入PhysX了,选中后我们在PVD里面看下:

    果然复杂mesh碰撞已经没有了,PxShape简化成了三个拼接的简单碰撞。如果选择了Use Complex Collision As Simple,那么简单碰撞就不会带入PhysX,如下:

    顺道提一下UE模型编辑器里面的CollisionPresets:

    如果下面所有通道都是Ignore的话,PhysX就不会创建这个模型的碰撞信息,具体放到下一章节来说:

    Jerry:UE4物理模块(三)---碰撞查询​zhuanlan.zhihu.com图标

  • 相关阅读:
    LeetCode 326. Power of Three
    LeetCode 324. Wiggle Sort II
    LeetCode 322. Coin Change
    LeetCode 321. Create Maximum Number
    LeetCode 319. Bulb Switcher
    LeetCode 318. Maximum Product of Word Lengths
    LeetCode 310. Minimum Height Trees (DFS)
    个人站点大开发!--起始篇
    LeetCode 313. Super Ugly Number
    LeetCode 309. Best Time to Buy and Sell Stock with Cooldown (DP)
  • 原文地址:https://www.cnblogs.com/y114113/p/10913089.html
Copyright © 2011-2022 走看看