Babylonjs-physics-engine

提供:Dev Guides
移動先:案内検索

BabylonJS-物理エンジン

Babylon.jsには、シーンにインタラクションを追加するのに役立つ物理エンジン用のプラグインシステムがあり、2つのオブジェクト間の衝突と跳ね返りを実生活のインタラクションのように表示します。ビリヤードなどのゲームでも同じ動作が見られ、プレーヤーはスティックでボールを打ったり、ボールが他のボールと衝突したりします。ここで、物理エンジンはボールのリアルな表示を試みます。地面にぶつかると衝突して跳ね返ります。 エンジンには、インパルス、フォース、ベロシティの変更、コールバック関数を適用するのに役立つクラスとAPIがあり、必要に応じて、またメッシュが他のメッシュと衝突した場合に特定のアクションを実行する必要があるときに呼び出されます。

使用できる3つの物理プラグインがあります-

  • Cannon.js
  • Oimo.js *Energy.js

Demo

<!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

GR1

説明

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のパラメーター

物理効果のために次のパラメータを考慮してください-

対象

ここで、オブジェクトは、インタラクションを適用する対象です。 たとえば、球体、箱など。

Type

タイプは次のいずれかです-

  • BABYLON.PhysicsImpostor.SphereImpostor;
  • BABYLON.PhysicsImpostor.BoxImpostor;
  • BABYLON.PhysicsImpostor.PlaneImpostor;
  • BABYLON.PhysicsImpostor.MeshImpostor;
  • BABYLON.PhysicsImpostor.CylinderImpostor;
  • BABYLON.PhysicsImpostor.ParticleImpostor;
  • BABYLON.PhysicsImpostor.HeightmapImpostor;

Mass

唯一の必須パラメーターは質量であり、これはオブジェクトのkg単位の質量です。 値として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);
      }
   });
})

上記のコードは、地面に落ちた球体を戻します。 落下した球体の地面を更新し続けます。 ブラウザで上記のデモを試して、物理効果を確認してください。