iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0

在多種 3D 物理引擎裡,決定使用同樣基於 js 所開發,學習成本相對較低且對新手較友善的 Cannon.js 做為開發工具

Github 範例

Github
與之前的函式庫相同需要先在 ejs 處匯入

<script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js"></script>

建立 Cannon World

與 Three.js 需要先建立 scene 相同,Cannon.js 也需要先建立 World

  // 建立Cannon世界
  world = new CANNON.World()
  // 設定重力場為 y 軸 -9.8 m/s²
  world.gravity.set(0, -9.8, 0)

建立球剛體

  var radius = 1
  sphereBody = new CANNON.Body({
    mass: 5,  //質量 kg
    position: new CANNON.Vec3(0, 10, 0), // m
    shape: new CANNON.Sphere(radius),
  })
  world.add(sphereBody)

建立平台

  var groundBody = new CANNON.Body({
    mass: 0, // mass = 0 使物體靜止
  })
  var groundShape = new CANNON.Plane()
  groundBody.addShape(groundShape);
  world.add(groundBody)
  // setFromAxisAngle 地板沿著X軸轉90度
  groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2)

建立球網格,建立完的剛體需要加上網格才能看到實體

  let sphereGeometry = new THREE.SphereGeometry(1, 32, 32)
  let sphereMaterial = new THREE.MeshStandardMaterial({ color: 0x33aaaa })
  sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
  sphere.castShadow = true
  scene.add(sphere)

建立地板網格

  let groundGeometry = new THREE.PlaneGeometry(30, 30, 30)
  let groundMaterial = new THREE.MeshLambertMaterial({
    color:0x505050,
    side: THREE.DoubleSide,
  })
  let ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.receiveShadow = true
  scene.add(ground)

渲染畫面,將 cannon 世界中的剛體位置持續更新,同步至網格位置

function render() {
    world.step(fixedTimeStep)
    // 複製剛體位址到物體位置
    sphere.position.copy(sphereBody.position)
    sphere.quaternion.copy(sphereBody.quaternion)
    console.log("Sphere y position: " + sphereBody.position.y);

    statsUI.update()
    cameraControl.update()
    requestAnimationFrame(render)
    renderer.render(scene, camera)
}

成果

Day14 Demo | Github
就可以看到掉落的球體了
https://ithelp.ithome.com.tw/upload/images/20220916/20142082KP3qbPNfbu.png


上一篇
Day13. 物理引擎
下一篇
Day15 .Dat.gui
系列文
Three.js 反閘之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言