PhysX 3.2里的布料模拟(4):运动控制

来源:互联网 发布:软件项目简介范本 编辑:程序博客网 时间:2024/04/30 06:45

前面的三节中,我们介绍了PhysX 3.2的布料特性的基础知识、如何创建和更新,这一节中,再给大家介绍一些实际中非常有用的布料的属性和功能,让大家对PhysX 3.2的布料有更加深入的了解,使用起来更加得心应手。

 

首先,看一个简单的,External Acceleration。如果你有过PhysX 2.8.4的使用经历,那么你对这个属性一定不会陌生。这个属性会给布料的每一个顶点加上一个来自我们设定的外部加速度,使用后的效果就是给布料的运动加上了一些扰动。如果我们在实际游戏中每一帧都给布料设置一个合适范围内随机的External Acceleration,那么布料的抖动看起来会更加随机,对布料模拟的效果提升也相当明显。

这个属性最典型的应用就是做旗帜。如果没有这个属性,旗帜经过一段时间的模拟,总会静止下来,缺乏动感。而每一帧都给旗帜加上一些随机的扰动因素,旗帜的飘动看起来会更自然、与场景搭配更和谐。

得到和设置External Acceleration,可以通过下面的API进行:

PxVec3 getExternalAcceleration() const;void setExternalAcceleration(PxVec3 acceleration);


然后,看运动范围控制的一个功能,PhysX 3.2中称为 Motion Contraint。要了解Motion Constraint如何工作,我们先看看PhyX SDK为我们提供了怎样的控制属性:

struct PxClothParticleMotionConstraint{PxVec3 pos;//!< Center of the motion constraint sphere (in cloth local space)PxReal radius;//!< Maximum distance the particle can move away from the sphere center.};

我们可以看到,一个Motion Constraint有两个属性:位置pos和半径radius。其中,pos对应的是布料本地坐标系中的某个的位置,radius则是布料顶点在给定pos周边可以移动的球形空间的范围。在使用的时候,PhysX SDK要求设置的约束的数量跟布料的顶点数一致,这样就可以将设置的约束一一对应到布料的顶点之上。

设置Motion Constraits的API是这样的:

void setMotionConstraints(const PxClothParticleMotionConstraint* motionConstraints);

 

通过调用这个API,我们可以设置布料每一个顶点的活动范围,PhysX SDK会保证模拟的结果在我们设置的范围之内。这就意味着,相比于PhysX 2.8,我们对布料运动范围,有了很大的操作空间,模拟结果也将更加可控,对布料模拟中常见的拉伸等问题的解决有很大的帮助。

与Motion Constraint类似,PhysX 3.2还为我们提供了另一个运动范围控制功能,那就是Separation Constraints。不过与Motion Constraints把布料的顶点限定在模拟范围内相反,Separation Constraints把布料的顶点隔离在它定义的范围之外。我们也先看看Separation Constraints的定义:

struct PxClothParticleSeparationConstraint{PxVec3 pos;//!< Center of the constraint sphere (in cloth local space)PxReal radius;//!< Radius of the constraint sphere such that the particle stay outside of this sphere.};

我们可以看到,pos同样也是布料本地空间中的某个位置,在这个位置,以radius为半径的球体内,PhysX SDK会保证对应的布料顶点的模拟结果在这个球形空间之外。当然了,使用中我们也需要保证Separation Constraint的数量跟布料的顶点数是一致的,可以一一对应到布料的顶点之上。

设置Separation Constraint的API是这样定义的:

void setSeparationConstraints(const PxClothParticleSeparationConstraint* separationConstraints);

这个功能可以帮助我们解决布料模拟中另一类常见的问题,那就是穿透。在我们不希望穿透发生的地方,加上Separation Constraints,保证布料的顶点不会运动到我们设定的的位置去。

通过设置合适的Motion Constraints和Separation Constraints,我们可以基本保证,布料的模拟结果,会在这两种约束定义出来的空间之内,同时可以很大程度上避免穿透和拉伸等问题。

 

最后,我们看PhysX 3.2提供的一个更精细的布料碰撞设置功能,Virtual Particles。Virtual Particles本质来讲是对sphere和capsule碰撞形体的补充,可以模拟出类似于增加了一块Trianglemesh跟布料碰撞一般更精确碰撞效果,比如手腕处的布料模拟。Virtual Particles之所以称之为Virtual,是因为他们不是实际的顶点,而是布料网格中的顶点构成的三角形的质心,所以我们不需要实际创建这些Particles,指定使用到的顶点就可以了。具体我们看设置Virtual Particles的API会更容易理解:

void setVirtualParticles(PxU32 numParticles, const PxU32* triangleVertexAndWeightIndices, PxU32 weightTableSize, const PxVec3* triangleVertexWeightTable);

这个API中:

numParticles是Virtual Particles的个数,也就是第二个参数,triangleVertexAndWeightIndices数组中有多少个虚拟点。

triangleVertexAndWeightIndices则实际定义了虚拟点的情况:每一个虚拟点,需要4个PxU32类型的索引来指定,其中,前三个索引,指定三个实际布料网格顶点,第四个索引,指定这个虚拟点在第四个参数权重表中的索引,这样,就可以通过下面的公式来确定一个虚拟点的位置:

w0 * P0 + w1 * P1 + w2 * P2

其中,P0、P1和P2是前三个索引指定的顶点位置,w0、w1和w2是第四个索引指定的权重表中的PxVex3的三个分量。

weightTableSize很好理解,是第四个参数的数组大小。

triangleVertexWeightTable就是实际指定顶点权重的表格了。这个表格作为一个单独的参数列出,被多个布料设置虚拟点组成的三角网格时共享。

上述这四个功能中,除了第一个非常简单方便之外,剩下的三个都跟具体的模型关系密切,需要在布料模型制作阶段就考虑该如何设置这些属性、控制布料的运动。这需要在编辑工具上下很大的功夫才能做好。不过幸运的是,APEX SDK中的Clothing的实现是依赖这些功能的,并且在工具方面做了很大的努力,为开发人员和美术提供了非常方便使用的Max和Maya插件。因此,如果要制作效果精良的布料模拟,比如人物身上的衣服等,可以优先考虑使用APEX 的Clothing,如果一定要使用PhysX,那么也可以参照APEX Clothing的插件功能,在自己的编辑器中实现类似的功能。

 

到此,这一系列为大家介绍PhysX 3.2的文章就结束了,如果大家有什么问题,也请留言,我会定期查看,及时回复。微笑

原创粉丝点击