class BouncingCows
meshes: []
constructor: (@scene, whenReady) ->
loader = new THREE.JSONLoader()
loader.load "cow.json", (@geometry, materials) =>
# @material = new THREE.MeshLambertMaterial { color: 0xaaaaaa }
@material = new THREE.MeshFaceMaterial( materials )
@geometry.computeBoundingBox()
loader.load "eggplant.json", (@dinogeo, materials) =>
@dinogeo.computeBoundingBox()
@dinomat = new THREE.MeshFaceMaterial( materials )
whenReady()
addParticle: (p, v, surprise = true) ->
if Math.random() > 0.1 || !surprise
mesh = new THREE.Mesh @geometry, @material
mesh.mass = 1.0
else
mesh = new THREE.Mesh @dinogeo, @dinomat
mesh.mass = 3.0
mesh.position.set p.x, p.y, p.z
mesh.acceleration = new THREE.Vector3(0.0, -9.8, 0.0)
mesh.velocity = new THREE.Vector3(v.x, v.y, v.z)
mesh.angularVelocity = new THREE.Vector3(0.0, 0.0, 0.0)
@scene.add mesh
@meshes.push mesh
update: (step) ->
v = new THREE.Vector3()
for mesh in @meshes
# Move the particles
v.copy mesh.velocity
v.multiplyScalar step
mesh.position.add v
v.copy mesh.acceleration
v.multiplyScalar step
mesh.velocity.add v
r = mesh.rotation.toVector3()
v.copy mesh.angularVelocity
v.multiplyScalar step
r.add v
mesh.rotation.setFromVector3(r)
# Check collisions
if mesh.position.y + mesh.geometry.boundingBox.min.y < 0.0 and
mesh.position.x < @trampoline.halfsize and mesh.position.x > -@trampoline.halfsize and
mesh.position.z < @trampoline.halfsize and mesh.position.z > -@trampoline.halfsize
@bounce(mesh, step)
bounce: (mesh, step) ->
d = 0.6 + 0.2 * (1.0 - 1.0 / Math.exp(mesh.mass - 1.0))
mesh.position.y += -mesh.velocity.y * step
mesh.velocity.y = - mesh.velocity.y * d
mesh.velocity.x *= d
mesh.velocity.z *= d
mesh.angularVelocity.multiplyScalar d
@trampoline.impact mesh if @trampoline
window.BouncingCows = BouncingCows