cactus source/threejs/cow.js.coffee

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