|
38 | 38 |
|
39 | 39 | import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; |
40 | 40 |
|
| 41 | + import { RapierPhysics } from 'three/addons/physics/RapierPhysics.js'; |
| 42 | + import { RapierHelper } from 'three/addons/helpers/RapierHelper.js'; |
| 43 | + |
41 | 44 | import { Inspector } from 'three/addons/inspector/Inspector.js'; |
42 | 45 |
|
43 | 46 | let camera, scene, renderer, postProcessing, controls; |
44 | 47 |
|
| 48 | + let physics, position; |
| 49 | + |
| 50 | + let boxes, spheres; |
| 51 | + |
45 | 52 | init(); |
46 | 53 |
|
47 | 54 | async function init() { |
48 | 55 |
|
| 56 | + physics = await RapierPhysics(); |
| 57 | + position = new THREE.Vector3(); |
| 58 | + |
49 | 59 | camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 100 ); |
50 | 60 | camera.position.set( 0, 10, 30 ); |
51 | 61 |
|
|
125 | 135 | const traaPass = traa( compositePass, scenePassDepth, scenePassVelocity, camera ); |
126 | 136 | postProcessing.outputNode = traaPass; |
127 | 137 |
|
| 138 | + // |
| 139 | + |
| 140 | + const material = new THREE.MeshStandardMaterial(); |
| 141 | + |
| 142 | + const matrix = new THREE.Matrix4(); |
| 143 | + const color = new THREE.Color(); |
| 144 | + |
| 145 | + // Boxes |
| 146 | + |
| 147 | + const geometryBox = new THREE.BoxGeometry( 0.75, 0.75, 0.75 ); |
| 148 | + boxes = new THREE.InstancedMesh( geometryBox, material, 100 ); |
| 149 | + boxes.instanceMatrix.setUsage( THREE.DynamicDrawUsage ); // will be updated every frame |
| 150 | + boxes.castShadow = true; |
| 151 | + boxes.receiveShadow = true; |
| 152 | + boxes.userData.physics = { mass: 1, restitution: 1 }; |
| 153 | + // scene.add( boxes ); |
| 154 | + |
| 155 | + for ( let i = 0; i < boxes.count; i ++ ) { |
| 156 | + |
| 157 | + matrix.setPosition( Math.random() - 0.5, Math.random() * 10, Math.random() - 0.5 ); |
| 158 | + boxes.setMatrixAt( i, matrix ); |
| 159 | + boxes.setColorAt( i, color.setHex( 0xffffff * Math.random() ) ); |
| 160 | + |
| 161 | + } |
| 162 | + |
| 163 | + // Spheres |
| 164 | + |
| 165 | + const geometrySphere = new THREE.IcosahedronGeometry( 0.75, 4 ); |
| 166 | + spheres = new THREE.InstancedMesh( geometrySphere, material, 100 ); |
| 167 | + spheres.instanceMatrix.setUsage( THREE.DynamicDrawUsage ); // will be updated every frame |
| 168 | + spheres.castShadow = true; |
| 169 | + spheres.receiveShadow = true; |
| 170 | + spheres.userData.physics = { mass: 1, restitution: 1 }; |
| 171 | + scene.add( spheres ); |
| 172 | + |
| 173 | + for ( let i = 0; i < spheres.count; i ++ ) { |
| 174 | + |
| 175 | + matrix.setPosition( ( Math.random() - 0.5 ) * 10, Math.random() * 2 + 10, ( Math.random() - 0.5 ) * 10 ); |
| 176 | + spheres.setMatrixAt( i, matrix ); |
| 177 | + spheres.setColorAt( i, color.setHex( 0xffffff * Math.random() ) ); |
| 178 | + |
| 179 | + } |
| 180 | + |
128 | 181 | // Cornell Box inspired scene |
129 | 182 |
|
130 | 183 | // Walls |
|
137 | 190 | leftWall.rotation.y = Math.PI * 0.5; |
138 | 191 | leftWall.position.set( - 10, 7.5, 0 ); |
139 | 192 | leftWall.receiveShadow = true; |
| 193 | + leftWall.userData.physics = { mass: 0 }; |
140 | 194 | scene.add( leftWall ); |
141 | 195 |
|
142 | 196 | // Right wall - green |
|
146 | 200 | rightWall.rotation.y = Math.PI * - 0.5; |
147 | 201 | rightWall.position.set( 10, 7.5, 0 ); |
148 | 202 | rightWall.receiveShadow = true; |
| 203 | + rightWall.userData.physics = { mass: 0 }; |
149 | 204 | scene.add( rightWall ); |
150 | 205 |
|
151 | 206 | // White walls and boxes |
|
156 | 211 | floor.scale.set( 20, 20, 1 ); |
157 | 212 | floor.rotation.x = Math.PI * - .5; |
158 | 213 | floor.receiveShadow = true; |
| 214 | + floor.userData.physics = { mass: 0 }; |
159 | 215 | scene.add( floor ); |
160 | 216 |
|
161 | 217 | // Back wall |
|
164 | 220 | backWall.rotation.z = Math.PI * - 0.5; |
165 | 221 | backWall.position.set( 0, 7.5, - 10 ); |
166 | 222 | backWall.receiveShadow = true; |
| 223 | + backWall.userData.physics = { mass: 0 }; |
167 | 224 | scene.add( backWall ); |
168 | 225 |
|
| 226 | + // Front wall |
| 227 | + const frontWall = new THREE.Mesh( wallGeometry, whiteMaterial ); |
| 228 | + frontWall.scale.set( 15, 20, 1 ); |
| 229 | + frontWall.rotation.z = Math.PI * - 0.5; |
| 230 | + frontWall.position.set( 0, 7.5, 10 ); |
| 231 | + frontWall.visible = false; |
| 232 | + frontWall.userData.physics = { mass: 0 }; |
| 233 | + scene.add( frontWall ); |
| 234 | + |
169 | 235 | // Ceiling |
170 | 236 | const ceiling = new THREE.Mesh( wallGeometry, whiteMaterial ); |
171 | 237 | ceiling.scale.set( 20, 20, 1 ); |
172 | 238 | ceiling.rotation.x = Math.PI * 0.5; |
173 | 239 | ceiling.position.set( 0, 15, 0 ); |
174 | 240 | ceiling.receiveShadow = true; |
| 241 | + ceiling.userData.physics = { mass: 0 }; |
175 | 242 | scene.add( ceiling ); |
176 | 243 |
|
177 | 244 | // Boxes |
|
181 | 248 | tallBox.position.set( - 3, 3.5, - 2 ); |
182 | 249 | tallBox.castShadow = true; |
183 | 250 | tallBox.receiveShadow = true; |
| 251 | + tallBox.userData.physics = { mass: 1 }; |
184 | 252 | scene.add( tallBox ); |
185 | 253 |
|
186 | 254 | const shortBoxGeometry = new THREE.BoxGeometry( 4, 4, 4 ); |
|
189 | 257 | shortBox.position.set( 4, 2, 4 ); |
190 | 258 | shortBox.castShadow = true; |
191 | 259 | shortBox.receiveShadow = true; |
| 260 | + shortBox.userData.physics = { mass: 1 }; |
192 | 261 | scene.add( shortBox ); |
193 | 262 |
|
194 | 263 | // Light source geometry |
195 | 264 | const lightSourceGeometry = new THREE.CylinderGeometry( 2.5, 2.5, 1, 64 ); |
196 | 265 | const lightSourceMaterial = new THREE.MeshBasicMaterial(); |
| 266 | + lightSourceMaterial.color.setScalar( 2 ); |
197 | 267 | const lightSource = new THREE.Mesh( lightSourceGeometry, lightSourceMaterial ); |
198 | 268 | lightSource.position.y = 15; |
199 | 269 | scene.add( lightSource ); |
|
208 | 278 | pointLight.shadow.bias = - 0.0025; |
209 | 279 | scene.add( pointLight ); |
210 | 280 |
|
| 281 | + physics.addScene( scene ); |
| 282 | + |
| 283 | + scene.add( new RapierHelper( physics.world ) ); |
| 284 | + |
| 285 | + /* |
| 286 | + setInterval( () => { |
| 287 | +
|
| 288 | + let index = Math.floor( Math.random() * boxes.count ); |
| 289 | +
|
| 290 | + position.set( 0, Math.random() * 10 + 1, 0 ); |
| 291 | + physics.setMeshPosition( boxes, position, index ); |
| 292 | +
|
| 293 | + // |
| 294 | +
|
| 295 | + index = Math.floor( Math.random() * spheres.count ); |
| 296 | +
|
| 297 | + position.set( 0, Math.random() * 10 + 1, 0 ); |
| 298 | + physics.setMeshPosition( spheres, position, index ); |
| 299 | +
|
| 300 | + }, 1000 / 60 ); |
| 301 | + */ |
| 302 | + |
211 | 303 | // Ambient light |
212 | 304 | const ambientLight = new THREE.AmbientLight( '#0c0c0c' ); |
213 | 305 | scene.add( ambientLight ); |
|
0 commit comments