iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Modern Web

Three.js 反閘之路系列 第 20

Day20. 夾娃娃機 - 建立物件剛體

  • 分享至 

  • xImage
  •  

在之前修改的 cannon 範例裡提過剛體,剛體才是實際互動的物件,網格只是套上去的皮,大多數剛體的形狀不會與網格相同,今日先建立剛體並與網格組合

程式碼

設定物件初始位置

// Usagi初始位置
let usagi_init_x = 0
let usagi_init_y = 0.5
let usagi_init_z = 0

建立物件剛體與網格

function initUsagiCannon(){
  // 建立Usagi A 剛體 Sphere(radius)
    let UsagiAShape = new CANNON.Box(new CANNON.Vec3(0.75, 0.1, 0.5))
    UsagiACM = new CANNON.Material()
    UsagiABody = new CANNON.Body({
      mass: 1,
      shape: UsagiAShape,
      position: new CANNON.Vec3(usagi_init_x,usagi_init_y+0.4,usagi_init_z),
      material: UsagiACM,
    })
    world.add(UsagiABody) 
  
    // Usagi A網格
    const UsagiAGeo = new THREE.BoxGeometry(1.5, 0.2, 1);
    const UsagiAMat = new THREE.MeshPhongMaterial({
      color: 0x4287f5,
    });
    UsagiA = new THREE.Mesh(UsagiAGeo, UsagiAMat);
    UsagiA.castShadow = true
    // 若不需要顯示網格可以註解掉 剛體效果還是會在
    scene.add(UsagiA);
  
    // 建立Usagi B 剛體 Sphere(radius)
    let UsagiBShape = new CANNON.Box(new CANNON.Vec3(0.75, 0.1, 0.5))
    let UsagiBCM = new CANNON.Material()
    UsagiBBody = new CANNON.Body({
      mass: 1,
      shape: UsagiBShape,
      position: new CANNON.Vec3(usagi_init_x, usagi_init_y-0.4, usagi_init_z),
      material: UsagiBCM,
    })
    world.add(UsagiBBody)
  
    // Usagi B網格
    const UsagiBGeo = new THREE.BoxGeometry(1.5, 0.2, 1);
    const UsagiBMat = new THREE.MeshPhongMaterial({
      color: 0x4287f5,
    });
    UsagiB = new THREE.Mesh(UsagiBGeo, UsagiBMat);
    UsagiB.castShadow = true
    scene.add(UsagiB);
  
    // 建立Usagi C 剛體 Sphere(radius)
    let UsagiCShape = new CANNON.Box(new CANNON.Vec3(0.25, 0.3, 0.25))
    let UsagiCCM = new CANNON.Material()
    UsagiCBody = new CANNON.Body({
      mass: 1,
      shape: UsagiCShape,
      position: new CANNON.Vec3(usagi_init_x, usagi_init_y, usagi_init_z),
      material: UsagiCCM,
    })
    world.add(UsagiCBody)
  
    // Usagi C網格
    const UsagiCGeo = new THREE.BoxGeometry(0.5, 0.6, 0.5);
    const UsagiCMat = new THREE.MeshPhongMaterial({
      color: 0x4287f5,
    });
    UsagiC = new THREE.Mesh(UsagiCGeo, UsagiCMat);
    UsagiC.castShadow = true
    scene.add(UsagiC);

將剛體組裝

  // Usagi 組裝
  UsagiBodyJoint1 = new CANNON.LockConstraint(UsagiABody,UsagiBBody)
  world.addConstraint(UsagiBodyJoint1)
  UsagiBodyJoint2 = new CANNON.LockConstraint(UsagiBBody,UsagiCBody)
  world.addConstraint(UsagiBodyJoint2)

組合好的剛體樣子
https://ithelp.ithome.com.tw/upload/images/20220920/20142082xUiUnBj6M3.png
將剛體位置複製到想使用的網格上,可以選擇顯示剛體樣子或是套用之前建立好的網格貼圖

function render() {
    world.step(timeStep)
    // 複製剛體位址到物體位置
    // UsagiA.position.copy(UsagiABody.position)
    // UsagiA.quaternion.copy(UsagiABody.quaternion)

    // UsagiB.position.copy(UsagiBBody.position)
    // UsagiB.quaternion.copy(UsagiBBody.quaternion)

    // UsagiC.position.copy(UsagiCBody.position)
    // UsagiC.quaternion.copy(UsagiCBody.quaternion)

    // 貼圖
    usagiObj.usagi.position.copy(UsagiCBody.position)
    usagiObj.usagi.quaternion.copy(UsagiCBody.quaternion)

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

成果

Day20 Demo | Github
就可以將建立好的貼圖套到剛體的位置上了
https://ithelp.ithome.com.tw/upload/images/20220920/20142082Ec0XBhmf1Z.png


上一篇
Day19. 調用模型動畫
下一篇
Day21. 夾娃娃機 - 建立夾爪剛體
系列文
Three.js 反閘之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言