Babylon.js的布料物理模拟

在Babylon.js中对物理引擎体系结构进行更改后,我添加了一种新的冒名顶替者类型,受炮的出色冒名顶替者实现(粒子发射器)影响。 粒子是非常简单的冒名顶替者。 可以将其与空间中的一个点进行比较,从而减少了检查碰撞时对大量计算的需求-这是一种点对身体的碰撞,它的计算要简单得多。

Cannon的布料演示(http://schteppe.github.io/cannon.js/examples/threejs_cloth.html)显示了粒子的力量。 我对它们的实现(以及与巴比伦架构本身的集成)受此实现的影响很大。 非常感谢美妙的Cannon.js的创建者Schteppe-我将在本教程中主要使用的物理引擎。

在本教程/博客文章/ infomercial中,我将使用巴比伦重新创建大炮的布料演示。
首先让我们了解发生了什么!

现在,为什么这么复杂?

物理引擎(至少曾经集成在Babylon.js中)基于对象的一个​​非常重要的特性- 刚性 。 通常,这意味着物理体不是弹性的 。 在整个场景的整个生命中都不会改变。 球体将始终具有相同的半径。 盒子将始终具有相同的尺寸。 如果确实更改了对象的参数(主要是尺寸,但在更改网格冒名者的情况下还设置了顶点),则必须为此对象创建一个新的(Rigid!)实体。 因此,如果我们创建一个地面对象(具有预定义尺寸的平面)并注册其冒名顶替者(从而创建其物理物体),则物理引擎将始终将其视为无法更改的非常狭窄的盒子。 最重要的是, 您不能使用单个冒名顶替者来制造柔软的物体 ,例如布。

从单个网格制作软体

想象一下有四个角的飞机。 每个角的位置都有一个球体。 等等,为什么要想象? 这是一个例子!

角落中的四个球将模拟我们的柔软身体。 理论是这样的:如果我们继续使用这四个角的位置更新正方形的位置顶点,那么如果我们单独移动球体,则可以创建“拉伸”效果。
您可以在这个游乐场中看到我的意思:http://www.babylonjs-playground.com/#1J3WEP。 去看,再回来解释。

背部? 大。 我在那里做什么?

我使用地面的位置顶点数据创建球体:

  //获取位置顶点数据 
var position = ground.getVerticesData(BABYLON.VertexBuffer.PositionKind);
//它们将存储在哪里?
var spheres = [];
对于(var i = 0; i <position.length; i = i + 3){
//获取i球的位置
var v = BABYLON.Vector3.FromArray(positions,i);
//创建一个球体,将其放置在“ v”中
var s = BABYLON.MeshBuilder.CreateSphere(“ s” + i,{直径:0.5},场景);
s.position.copyFrom(v);
//将其推入球体数组以供将来参考
spheres.push(s);
}

请注意,我将原始位置转换为vector3对象。 如果要转换地面,则也必须转换这些向量(使用BABYLON.Vector3.TransformCoordinates(…))。 我不会在这里介绍它,但是我非常乐于解释它是如何工作的。

然后使用以下功能更新(内部几何!)地面的位置:

  ground.registerBeforeRender(function(){ 
var position = [];
//获得每个球体的位置,添加到一个临时数组
spheres.forEach(function(s){
position.push(s.position.x,s.position.y,s.position.z);
});
//将此数组设置为新的位置向量
ground.updateVerticesData(BABYLON.VertexBuffer.PositionKind,positions);
});

为了模拟变化,我更改了每帧中x轴上最后一个球体的位置,这在运动场演示中创建了运动。

精彩! 现在我们可以“拉伸”对象了。 现在,我们了解了刚性世界中软体的基本知识。 您现在可能已经知道了这一点-相同的概念可以应用于具有许多细分的地面对象:

现在,改变每个球体的位置将以多种方式扩展地面。 这是一个游乐场:http://www.babylonjs-playground.com/#1J3WEP#2。 走,回来,我们继续。

整合物理引擎

好的,现在我们知道如何“软化”硬网格了。 我们只是更改其位置顶点数据。 但是,我们如何在物理引擎中使用它呢?

粒子!

我们之前看到的每个领域都将充当独立的冒名顶替者。 粒子冒名顶替者。 这种(刚性的)冒名顶替者将帮助我们获得具有物理作用的柔软物体,例如布料。

让我们以最后一个游乐场为基础。 我们有了球体,有了地面,现在我们需要增加物理学。
让我们一次迈出一步。

首先,创建冒名顶替者

每个球体将获得一个新的PhysicsImpostor,其粒子类型。 最初的冒名顶替者的体重将为“ 0”。 这将模拟一个固定布料的条。 就像窗帘:

  //创建冒名顶替者 
spheres.forEach(function(point,idx){
//什么是冒名顶替者的质量?
var mass = idx <细分? 0:1;
point.physicsImpostor =新的BABYLON.PhysicsImpostor(点,BABYLON.PhysicsImpostor.ParticleImpostor,{
质量:质量
},场景);
});

造假者!

二,连接冒名顶替者

大。 现在我们有了冒名顶替者,但如果运行此场景,所有冒名顶替者(质量为0的那些冒名者除外)将被淘汰。 我们需要连接所有冒名顶替者。 这就是物理关节的目的。

为此,我将使用DistanceJoint,它是连接两个物理对象且它们之间具有预定义距离的关节。 物理引擎将保持这些对象之间的距离。

 函数createJoint(imp1,imp2){ 
var joint = new BABYLON.DistanceJoint({
maxDistance:distanceBetweenPoints
})
imp1.addJoint(imp2,联合);
}
  //创建冒名顶替者 
spheres.forEach(function(point,idx){
如果(idx> =细分){
createJoint(point.physicsImpostor,spheres [idx-subdivisions] .physicsImpostor);
if(idx%细分){
createJoint(point.physicsImpostor,spheres [idx-1] .physicsImpostor);
}
}
});

我在这是要干嘛?

首先,我垂直连接-从第二行开始,并将其与上方的行连接。 然后,我水平连接-除了每行中的第一个冒名顶替者之外,我都将其与冒名顶替者连接起来。
现在我们有了一个冒名顶替者网络。 看起来是这样的:

游乐场的链接— http://www.babylonjs-playground.com/#1J3WEP#3

演示版

现在我们有一块布。 我们可以做很多事情!

布被球体阻塞

首先,让我们在布料的路径上放置一个球体,看看它如何反应:

和游乐场-http://www.babylonjs-playground.com/#1J3WEP#5

粒子冒名顶替者撞到球体上,使帷幕在撞击时停止。 请注意,拥有相对大量的细分非常重要。 如果它太低,冒名顶替者将不会发生碰撞,并且布料只会“穿过”球体。 碰撞到球体的不是网格,而是粒子!

布扔在球上

现在,让我们将布料“扔”在球体顶部,看看发生了什么:

游乐场-http://www.babylonjs-playground.com/#1J3WEP#6

很整洁吧?

赶上滚球

游戏的一个不错的主意是将球网扔向一个正在运转的球,并查看需要多少次尝试才能真正接住球。 这是这种游戏的模拟:

可能性是无止境。

有没有更简单的方法来使用它?

是! Babylon.js很快将有一个名为“ physics body”的新物理扩展,它将保留常见物理体的实现。 布将在那里。 因此,一些汽车实施方案和其他一些很酷的事情。
什么时候可用? 现在,这是一个好问题question

但是等等,Oimo.js呢?

巴比伦的物理体系结构的主要目标是将所有物理引擎统一为一个API。 这意味着在理想环境中,将物理引擎更改为Oimo而不是Cannon应该开箱即用。
继续尝试!

而且,我们发现这不是一个完美的世界。 Oimo的远距关节的工作方式与Cannon的远距关节略有不同,并且连接看起来有些“拉伸”。 Oimo也快得多(比大炮简单得多),因此织物将很快“振动”。

但是不要担心。 一切都有解决方案。
首先,两个关节之间的距离应保持最小。 将距离设置为0.1将防止拉伸。
解决“振动”的方法是减少时间步长。 这意味着“降低”物理引擎的速度。
这是使用Oimo的球形演示— http://www.babylonjs-playground.com/#1J3WEP#8

只是一件事-Oimo没有颗粒冒充者 。 这是使用很小的球体模拟的。 有缺点。

下一步是什么?

现在轮到你了。 可能性是无止境!
试用此实现,尝试一下。 问我任何问题。 一旦巴比伦物理身体库完成,我将发布完整的实现,包括变换调整和其他类型的网格。 但这不应该阻止您进行试验。

建议

☞初学者的Unity 3D和2D游戏开发教程

☞Unity 5专业指南—精通C#编程!

☞使用C#在Unity中制作VR游戏-Cardboard,Gear VR,Oculus