- BabylonJS 教程
- BabylonJS - 首页
- BabylonJS - 简介
- BabylonJS - 环境搭建
- BabylonJS - 概述
- BabylonJS - 基本元素
- BabylonJS - 材质
- BabylonJS - 动画
- BabylonJS - 相机
- BabylonJS - 光照
- BabylonJS - 参数化形状
- BabylonJS - 网格
- 矢量位置和旋转
- BabylonJS - 贴花
- BabylonJS - Curve3
- BabylonJS - 动态纹理
- BabylonJS - 视差贴图
- BabylonJS - 镜头光晕
- BabylonJS - 创建屏幕截图
- BabylonJS - 反射探针
- 标准渲染管线
- BabylonJS - ShaderMaterial
- BabylonJS - 骨骼和骨架
- BabylonJS - 物理引擎
- BabylonJS - 播放声音和音乐
- BabylonJS 有用资源
- BabylonJS - 快速指南
- BabylonJS - 有用资源
- BabylonJS - 讨论
BabylonJS - 物理引擎
Babylon.js 有一个物理引擎插件系统,有助于向场景添加交互。它显示了两个物体之间的碰撞和反弹,使其更像真实的交互。演示将显示球体彼此碰撞并围绕碰撞移动,然后静止。我们在台球等游戏中注意到同样的行为,玩家用球杆击球,球与其他球碰撞等等。在这里,物理引擎试图给出一个真实的球体碰撞和反弹(当它们撞击地面时)的视图。该引擎具有类和API,有助于应用冲量、力、改变速度、在需要时调用的回调函数,以及当我们需要在网格与其他网格碰撞时执行某些操作时。
可以使用3个物理插件:
- Cannon.js
- Oimo.js
- Energy.js
演示
<!doctype html> <html> <head> <meta charset = "utf-8"> <title>BabylonJs - Ball/Ground Demo</title> <script type = "text/javascript" src="https://cdn.babylonjs.com/Oimo.js"></script> <script src = "babylon.js"></script> <style> canvas {width: 100%; height: 100%;} </style> </head> <body> <canvas id = "renderCanvas"></canvas> <script type = "text/javascript"> var canvas = document.getElementById("renderCanvas"); var engine = new BABYLON.Engine(canvas, true); var v3 = BABYLON.Vector3; var createScene = function () { // This creates a basic Babylon Scene object (non-mesh) var scene = new BABYLON.Scene(engine); var camera = new BABYLON.ArcRotateCamera("Camera", 0.86, 1.37, 250, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas); camera.maxZ = 5000; camera.lowerRadiusLimit = 120; camera.upperRadiusLimit = 430; camera.lowerBetaLimit =0.75; camera.upperBetaLimit =1.58 ; new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene); var randomNumber = function (min, max) { if (min == max) { return (min); } var random = Math.random(); return ((random * (max - min)) + min); }; var mat = new BABYLON.StandardMaterial("ground", scene); var t = new BABYLON.Texture("images/gr1.jpg", scene); t.uScale = t.vScale = 10; mat.diffuseTexture = t; mat.specularColor = BABYLON.Color3.Black(); var g = BABYLON.Mesh.CreateBox("ground", 200, scene); g.position.y = -20; g.position.x = 0 g.scaling.y = 0.01; g.material = mat; scene.enablePhysics(new BABYLON.Vector3(0, -10, 0), new BABYLON.OimoJSPlugin()); g.physicsImpostor = new BABYLON.PhysicsImpostor(g, BABYLON.PhysicsImpostor.BoxImpostor, { mass: 0, restitution: 0.9 }, scene); var getPosition = function(y) { return new v3(randomNumber(-100, 100), y, randomNumber(-100, 100)); }; var allspheres = []; var y = 50; var max = 50; for (var index = 0; index < max; index++) { var redSphere = BABYLON.Mesh.CreateSphere("s" + index, 32, 8, scene); redSphere.position = getPosition(y); redSphere.physicsImpostor = new BABYLON.PhysicsImpostor(redSphere, BABYLON.PhysicsImpostor.SphereImpostor,{ mass: 1, restitution:0.9 }, scene); redSphere.physicsImpostor.applyImpulse(new BABYLON.Vector3(1, 2, -1), new BABYLON.Vector3(1, 2, 0)); var redMat = new BABYLON.StandardMaterial("ground", scene); redMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4); redMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4); redMat.emissiveColor = BABYLON.Color3.Red(); redSphere.material = redMat; // push all spheres in the allspheres variable allspheres.push(redSphere); y += 10; // increment height } scene.registerBeforeRender(function() { allspheres.forEach(function(obj) { // if the sphers falls down its updated again over here // If object falls if (obj.position.y < -100) { obj.position = getPosition(200); } }); }) return scene; }; var scene = createScene(); engine.runRenderLoop(function() { scene.render(); }); </script> </body> </html>
输出
以上代码生成以下输出:
在这个演示中,我们使用了图像images/gr1.jpg。这些图像存储在本地images/文件夹中,并也在下面粘贴以供参考。您可以下载任何您选择的图像,并在演示链接中使用。
images/gr1.jpg
解释
scene.enablePhysics(new BABYLON.Vector3(0,-10,0), new BABYLON.OimoJSPlugin());
以上代码启用物理插件。您可以使用您选择的插件。我们使用了OimoJsplugin()。
g.physicsImpostor = newBABYLON.PhysicsImpostor(g, BABYLON.PhysicsImpostor.BoxImpostor, { mass: 0, restitution: 0.9 }, scene);
对于交互,物理引擎使用模拟体。当应用于模拟体时,物体的形状不能改变。如果更改,则必须创建一个新的模拟体。
对于球体,我们将设置模拟体并添加冲量以实现反弹效果,如下所示:
redSphere.physicsImpostor = new BABYLON.PhysicsImpostor( redSphere, BABYLON.PhysicsImpostor.SphereImpostor, { mass: 1, restitution:0.9 }, scene ); redSphere.physicsImpostor.applyImpulse( new BABYLON.Vector3(1, 2, -1), new BABYLON.Vector3(1, 2, 0) );
physicsImposter参数
考虑以下物理效果参数:
物体
这里指的是要应用交互的物体。例如,球体、盒子等。
类型
类型可以是以下之一:
- BABYLON.PhysicsImpostor.SphereImpostor;
- BABYLON.PhysicsImpostor.BoxImpostor;
- BABYLON.PhysicsImpostor.PlaneImpostor;
- BABYLON.PhysicsImpostor.MeshImpostor;
- BABYLON.PhysicsImpostor.CylinderImpostor;
- BABYLON.PhysicsImpostor.ParticleImpostor;
- BABYLON.PhysicsImpostor.HeightmapImpostor;
质量
唯一必需的参数是质量,它以千克为单位表示物体的质量。值为0将创建一个静态模拟体——适合地面。
恢复系数
这是物体在碰撞时“回馈”的力的大小。较低的值将不会产生反弹,值为1将产生非常有弹性的交互。
scene.registerBeforeRender(function() { allspheres.forEach(function(obj) { // if the sphers falls down its updated again over here // If object falls if (obj.position.y < -100) { obj.position = getPosition(200); } }); })
以上代码将掉落在地面上的球体带回地面。它不断更新地面上的任何掉落的球体。在浏览器中尝试以上演示以查看物理效果。
广告