BabylonJS - เครื่องยนต์ฟิสิกส์
Babylon.js มีระบบปลั๊กอินสำหรับเอนจิ้นฟิสิกส์ซึ่งช่วยเพิ่มการโต้ตอบให้กับฉากมันแสดงให้เห็นการชนกันและการกระเด้งระหว่างวัตถุ 2 ชิ้นและทำให้มันเหมือนกับการโต้ตอบในชีวิตจริงมากขึ้นการสาธิตจะแสดงให้เห็นลูกบอลที่ชนกันและเคลื่อนที่ไปมาด้วย การปะทะกันและการหยุดพักในภายหลังเราสังเกตเห็นพฤติกรรมเดียวกันกับเกมเช่นบิลเลียดที่ผู้เล่นตีลูกบอลด้วยไม้และลูกบอลชนกับลูกบอลอื่น ๆ ที่นี่ Physics Engine พยายามที่จะให้มุมมองที่เหมือนจริงของลูกบอล การชนกันและการกระเด้งเมื่อกระแทกพื้น เครื่องยนต์มีคลาสและ 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 / 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);
สำหรับการโต้ตอบเครื่องมือฟิสิกส์ใช้ตัวปลอม เมื่อนำไปใช้กับผู้แอบอ้างจะไม่สามารถเปลี่ยนแปลงรูปร่างของวัตถุได้ หากมีการเปลี่ยนแปลงจะต้องสร้างผู้แอบอ้างขึ้นใหม่
สำหรับทรงกลมเราจะตั้งค่า Imposter และเพิ่มแรงกระตุ้นให้กับมันเพื่อให้เกิดผลกระทบดังที่แสดง -
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);
}
});
})
รหัสข้างต้นนำกลับมาที่ทรงกลมที่ตกลงมาบนพื้น มันอัปเดตพื้นดินสำหรับทรงกลมที่ตกลงมา ลองสาธิตด้านบนในเบราว์เซอร์เพื่อดูเอฟเฟกต์ฟิสิกส์