-
Notifications
You must be signed in to change notification settings - Fork 97
/
native-three-with-physics.html
136 lines (112 loc) Β· 4.62 KB
/
native-three-with-physics.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Native three.js with Physics</title>
<link rel="stylesheet" href="/css/examples.css?ver=1.0.0" />
<script src="/js/examples.js?ver=1.1.1"></script>
</head>
<body>
<div id="info-text">Using enable3d as Physics Plugin for three.js</div>
<script type="importmap">
{
"imports": {
"three": "/lib/threejs/r171/three.module.min.js",
"orbit-controls": "/lib/threejs/r171/OrbitControls.module.min.js",
"enable3d": "/lib/enable3d/enable3d.ammoPhysics.0.26.0_dev0.module.min.js"
}
}
</script>
<script type="module">
import * as THREE from 'three'
import { AmmoPhysics, PhysicsLoader } from 'enable3d'
import { OrbitControls } from 'orbit-controls'
const MainScene = () => {
// scene
const scene = new THREE.Scene()
scene.background = new THREE.Color(0xf0f0f0)
// camera
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(10, 10, 20)
camera.lookAt(0, 1, 0)
// renderer
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// dpr
const DPR = window.devicePixelRatio
renderer.setPixelRatio(Math.min(2, DPR))
// orbit controls
const controls = new OrbitControls(camera, renderer.domElement)
controls.target.set(0, 1, 0)
controls.update()
// light
scene.add(new THREE.HemisphereLight(0xffffff, 0x000000, 1))
scene.add(new THREE.AmbientLight(0xffffff, 1))
const light = new THREE.DirectionalLight(0xffffff, 1)
light.position.set(50, 200, 100)
light.position.multiplyScalar(1.3)
// physics
const physics = new AmmoPhysics(scene)
physics.debug.enable(true)
// extract the object factory from physics
// the factory will make/add object without physics
const { factory } = physics
// blue box
physics.add.box({ x: 0.05, y: 10 }, { lambert: { color: 0x2194ce } })
// static ground
physics.add.ground({ width: 20, height: 20 })
// add a normal sphere using the object factory
// (NOTE: This will be factory.add.sphere() in the future)
// first parameter is the config for the geometry
// second parameter is for the material
// you could also add a custom material like so { custom: new THREE.MeshLambertMaterial({ color: 0x00ff00 }) }
let greenSphere = factory.addSphere({ y: 2, z: 5 }, { lambert: { color: 'red' } })
// once the object is created, you can add physics to it
physics.add.existing(greenSphere)
// green sphere
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 })
const cube = new THREE.Mesh(geometry, material)
cube.position.set(0, 5, 0)
scene.add(cube)
physics.add.existing(cube)
cube.body.setCollisionFlags(2) // make it kinematic
// merge children to compound shape
const exclamationMark = () => {
const material = new THREE.MeshLambertMaterial({ color: 0xffff00 })
const sphere = new THREE.Mesh(new THREE.SphereGeometry(0.25), material)
sphere.position.set(0, -0.8, 0)
const cube = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.8, 0.4), material)
cube.position.set(5, 2, 5)
cube.add(sphere)
scene.add(cube)
cube.position.set(5, 5, 5)
cube.rotation.set(0, 0.4, 0.2)
physics.add.existing(cube)
}
exclamationMark()
// clock
const clock = new THREE.Clock()
// loop
const animate = () => {
cube.rotation.x += 0.01
cube.rotation.y += 0.01
cube.body.needUpdate = true // this is how you update kinematic bodies
physics.update(clock.getDelta() * 1000)
physics.updateDebugger()
renderer.render(scene, camera)
requestAnimationFrame(animate)
}
requestAnimationFrame(animate)
}
PhysicsLoader('/lib/ammo/kripken', () => MainScene())
console.log(`three.js version "${THREE.REVISION}"`)
</script>
</body>
</html>