< template>
</ template>
< script setup >
import * as THREE from 'three'
import gsap from 'gsap'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GUI } from 'three/addons/libs/lil-gui.module.min.js' ;
import * as CANNON from 'cannon-es'
const scene = new THREE. Scene ( )
const camera = new THREE. PerspectiveCamera ( 75 , window. innerWidth / window. innerHeight, 0.1 , 30 )
camera. position. set ( 0 , 0 , 20 )
scene. add ( camera)
const sphereGeometry = new THREE. SphereGeometry ( 1 , 20 , 20 )
const sphereMaterial = new THREE. MeshStandardMaterial ( )
const sphere = new THREE. Mesh ( sphereGeometry, sphereMaterial)
sphere. castShadow = true
scene. add ( sphere)
const floor = new THREE. Mesh (
new THREE. PlaneGeometry ( 20 , 20 ) ,
new THREE. MeshStandardMaterial ( )
)
floor. position. set ( 0 , - 5 , 0 )
floor. rotation. x = - Math. PI / 2
floor. receiveShadow = true
scene. add ( floor)
const ambientLight = new THREE. AmbientLight ( 0xffffff , 0.5 )
scene. add ( ambientLight)
const dirLight = new THREE. DirectionalLight ( 0xffffff , 0.5 )
dirLight. castShadow = true
scene. add ( dirLight)
const world = new CANNON. World ( )
world. gravity. set ( 0 , - 9.8 , 0 )
const sphereShape = new CANNON. Sphere ( 1 )
const shperWorldMaterial = new CANNON. Material ( 'default' )
const sphereBody = new CANNON. Body ( {
shape : sphereShape,
position : new CANNON. Vec3 ( 0 , 0 , 0 ) ,
mass : 1 ,
material : shperWorldMaterial
} )
world. addBody ( sphereBody)
const floorShape = new CANNON. Plane ( )
const floorMaterial = new CANNON. Material ( 'name' )
const floorBody = new CANNON. Body ( )
floorBody. material = floorMaterial
floorBody. mass = 0
floorBody. addShape ( floorShape)
floorBody. position. set ( 0 , - 5 , 0 )
floorBody. quaternion. setFromAxisAngle ( new CANNON. Vec3 ( 1 , 0 , 0 ) , - Math. PI / 2 )
world. addBody ( floorBody)
const defaultContactMaterial = new CANNON. ContactMaterial ( shperWorldMaterial, floorMaterial, {
friction : 0.1 ,
restitution : 0.7
} )
world. addContactMaterial ( defaultContactMaterial)
const hitSound = new Audio ( 'matalHit.mp3' )
sphereBody. addEventListener ( 'collide' , ( e ) => {
console. log ( e) ;
const impactStrength = e. contact. getImpactVelocityAlongNormal ( )
console. log ( impactStrength) ;
if ( impactStrength > 2 ) {
hitSound. currentTime = 0
hitSound. play ( )
}
} )
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
const axesHelper = new THREE. AxesHelper ( 5 )
scene. add ( axesHelper)
const clock = new THREE. Clock ( )
function render ( ) {
let deltaTime = clock. getDelta ( )
world. step ( 1 / 120 , deltaTime)
sphere. position. copy ( sphereBody. position)
renderer. render ( scene, camera) ;
requestAnimationFrame ( render)
}
render ( )
window. addEventListener ( "resize" , ( ) => {
camera. aspect = window. innerWidth / window. innerHeight
camera. updateProjectionMatrix ( )
renderer. setSize ( window. innerWidth, window. innerHeight)
renderer. setPixelRatio ( window. devicePixelRatio)
} )
</ script>
< style scoped > </ style>