BabylonJS-물리 엔진

Babylon.js는 씬에 인터랙션을 추가하는 데 도움이되는 Physics 엔진 용 플러그인 시스템을 가지고 있으며, 두 물체 사이의 충돌과 튀는 모습을 보여주고 실제 상호 작용과 비슷하게 만듭니다. 데모에서는 공이 서로 충돌하고 움직이는 모습을 보여줍니다. 우리는 당구와 같은 게임에서 플레이어가 막대기로 공을 치고 공이 다른 공과 충돌하는 등의 동일한 동작을 발견했습니다. 지면에 부딪히면 충돌하고 튀어 오릅니다. 엔진에는 필요할 때마다 호출되는 임펄스, 힘, 속도 변경, 콜백 함수를 적용하는 데 도움이되는 클래스와 API가 있으며 메시가 다른 메시와 충돌하는 경우 특정 작업을 수행해야 할 때도 있습니다.

사용할 수있는 3 가지 Physics 플러그인이 있습니다.

  • 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());

위 라인은 Physics 플러그인을 활성화합니다. 원하는 플러그인을 사용할 수 있습니다. OimoJsplugin ()을 사용했습니다.

g.physicsImpostor = newBABYLON.PhysicsImpostor(g, BABYLON.PhysicsImpostor.BoxImpostor, { 
   mass: 0, 
   restitution: 0.9 
}, scene);

상호 작용을 위해 Physics Engine은 impostor를 사용합니다. 사기꾼에 적용하면 개체의 모양을 변경할 수 없습니다. 변경된 경우 새 사기꾼을 만들어야합니다.

구의 경우 임 포스터를 설정하고 다음과 같이 바운스 효과를 위해 임펄스를 추가합니다.

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)
);

물리학에 대한 매개 변수

물리 효과에 대한 다음 매개 변수를 고려하십시오.

목적

여기에 상호 작용을 적용 할 개체가 있습니다. 예 : 구, 상자 등

유형

유형은 다음 중 하나 일 수 있습니다.

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

질량

유일한 필수 매개 변수는 물체의 질량 (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);
      }					
   });
})

위의 코드는 땅에 떨어진 구를 다시 가져옵니다. 타락한 구의지면을 계속 업데이트합니다. 물리 효과를 보려면 브라우저에서 위의 데모를 시도하십시오.