Threejs Boilerplate : Cannon Physics

Threejs Boilerplate : https://github.com/Sean-Bradley/Three.js-TypeScript-Boilerplate Threejs Course : https://sbcode.net/threejs/ Discount Coupons : https://sbcode.net/coupons#threejs

by seanwasere

HTML

<!--
Threejs Boilerplate : https://github.com/Sean-Bradley/Three.js-TypeScript-Boilerplate
Threejs Course : https://sbcode.net/threejs/
Discount Coupons : https://sbcode.net/coupons#threejs
-->

<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>

<script type="importmap">
  {
		"imports": {
			"three": "https://cdn.skypack.dev/[email protected]/build/three.module",
      "three/": "https://cdn.skypack.dev/[email protected]/",      
      "dat.gui": "https://cdn.skypack.dev/dat.gui",
      "cannon-es": "https://cdn.skypack.dev/cannon-es",
      "CannonUtils": "https://cdn.jsdelivr.net/gh/Sean-Bradley/CannonUtils@main/cannonUtils.js",
      "CannonDebugRenderer": "https://cdn.jsdelivr.net/gh/Sean-Bradley/CannonUtils@main/cannonDebugRenderer.js"
		}
	}
</script>

CSS

body {
  overflow: hidden;
  margin: 0px;
}

JavaScript

import * as THREE from 'three'
import {
   OrbitControls
 } from 'three/examples/jsm/controls/OrbitControls'
 import Stats from 'three/examples/jsm/libs/stats.module'
import {
   GUI
 } from 'dat.gui'
 import {
   OBJLoader
 } from 'three/examples/jsm/loaders/OBJLoader'
 import * as CANNON from 'cannon-es'
 import CannonUtils from 'CannonUtils'
 import CannonDebugRenderer from 'CannonDebugRenderer'

 const scene = new THREE.Scene()
 scene.add(new THREE.AxesHelper(5))

 const light1 = new THREE.SpotLight()
 light1.position.set(2.5, 5, 5)
 light1.angle = Math.PI / 4
 light1.penumbra = 0.5
 light1.castShadow = true
 light1.shadow.mapSize.width = 1024
 light1.shadow.mapSize.height = 1024
 light1.shadow.camera.near = 0.5
 light1.shadow.camera.far = 20
 scene.add(light1)

 const light2 = light1.clone()
 light2.position.x = -2.5
 scene.add(light2)

 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
 camera.position.set(0, 3, 6)

 const renderer = new THREE.WebGLRenderer()
 renderer.setSize(window.innerWidth, window.innerHeight)
 renderer.shadowMap.enabled = true
 document.body.appendChild(renderer.domElement)

 const controls = new OrbitControls(camera, renderer.domElement)
 controls.enableDamping = true
 controls.target.y = 0.5

 const world = new CANNON.World()
 world.gravity.set(0, -9.82, 0)
 // world.broadphase = new CANNON.NaiveBroadphase()
 // ;(world.solver as CANNON.GSSolver).iterations = 10
 // world.allowSleep = true

 const normalMaterial = new THREE.MeshNormalMaterial()
 const phongMaterial = new THREE.MeshPhongMaterial()

 const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)
 const cubeMesh = new THREE.Mesh(cubeGeometry, normalMaterial)
 cubeMesh.position.x = -4
 cubeMesh.position.y = 3
 cubeMesh.castShadow = true
 scene.add(cubeMesh)
 const cubeShape = new CANNON.Box(new CANNON.Vec3(0.5, 0.5, 0.5))
 const cubeBody = new CANNON.Body({
   mass: 1
 })
 cubeBody.addShape(cubeShape)
 cubeBody.position.x =...