window.delay = (ms, fn)-> setTimeout(fn, ms)
window.timer = (ms, fn)-> setInterval(fn, ms)
window.$options =
startupCows: true
trampolineShader: true
postProcessing: true
t = THREE
scene = new t.Scene
camera = new t.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new t.WebGLRenderer {antialias: true}
renderer.setSize window.innerWidth, window.innerHeight
document.body.appendChild renderer.domElement
cow = new BouncingCows scene, =>
return unless $options.startupCows
cow.addParticle {x: 0.0, y: 1.0, z: 3.0}, {x:0, y:3, z:0}
for x in [1..10]
cow.addParticle {x: Math.random() * 10 - 5, y: Math.random() * 4 + 0.5, z: Math.random() * 10 - 5}, {x: Math.random() * 3 - 1.5, y:Math.random() * 3 - 1.5, z:Math.random() * 3 - 1.5}, false
trampoline = new Trampoline(scene, $options)
cow.trampoline = trampoline
camera.position.z = 5
camera.position.y = 5
camera.rotation.y = -0.2
originalCameraPosition = camera.position
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 10.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', -> render );
ufo = new Ufo(scene, cow, camera)
pointLight = new t.PointLight 0xFFeeee
pointLight.position.x = 0
pointLight.position.y = 0.5
pointLight.position.z = 15
scene.add pointLight
light = new t.AmbientLight 0x444444
scene.add light
# Background
texture = THREE.ImageUtils.loadTexture( 'farm.png' );
backgroundMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2, 2, 0),
new THREE.MeshBasicMaterial({
map: texture
}));
backgroundMesh .material.depthTest = false;
backgroundMesh .material.depthWrite = false;
# Create your background scene
backgroundScene = new THREE.Scene();
backgroundCamera = new THREE.Camera();
backgroundScene.add(backgroundCamera );
backgroundScene.add(backgroundMesh );
window.addEventListener 'resize', ->
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize( window.innerWidth, window.innerHeight )
controls.handleResize()
# postprocessing
width = window.innerWidth || 1;
height = window.innerHeight || 1;
parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
composer = new THREE.EffectComposer( renderer, renderTarget );
composer.addPass( new THREE.RenderPass( backgroundScene, backgroundCamera ) );
composer.addPass( new THREE.RenderPass( scene, camera ) );
effect = new THREE.ShaderPass( THREE.BGCopyShader );
effect.uniforms["background"].value = texture;
composer.addPass( effect );
effect = new THREE.ShaderPass( THREE.VignetteShader );
effect.uniforms[ "offset" ].value = 0.95;
effect.uniforms[ "darkness" ].value = 1.6;
composer.addPass( effect ) if $options.postProcessing
effect = new THREE.ShaderPass( THREE.FXAAShader );
effect.uniforms["resolution"].value = new THREE.Vector2(1.0 / window.innerWidth, 1.0 / window.innerHeight)
composer.addPass(effect) if $options.postProcessing
effect = new THREE.ShaderPass( THREE.CopyShader );
effect.renderToScreen = true;
composer.addPass( effect );
# effect = new THREE.ShaderPass( THREE.RGBShiftShader );
# effect.uniforms[ 'amount' ].value = 0.0015;
# composer.addPass( effect );
lastTime = Date.now()
render = ->
requestAnimationFrame render
timestep = Math.min((Date.now() - lastTime), 50) * 0.001
lastTime = Date.now()
cow.update(timestep)
trampoline.update(timestep)
ufo.update(timestep)
controls.update()
renderer.autoClear = false
renderer.clear()
# renderer.render backgroundScene, backgroundCamera
# renderer.render scene, camera
composer.render scene, camera
render()
document.addEventListener "keydown", (event) ->
ufo.handleKey(event)
document.addEventListener "keyup", (event) ->
switch event.which
when 101 then controls.reset()
else ufo.handleKey(event)
window.$scene = scene
window.$ufo = ufo
window.$cow = cow