Last active
January 3, 2017 19:22
-
-
Save shshaw/7a4a8d2b0b160c1a90dcc6b8d79788da to your computer and use it in GitHub Desktop.
Toast & Butter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script>console.clear();</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var renderCalls = []; | |
function render () { | |
requestAnimationFrame( render ); | |
renderCalls.forEach((callback)=>{ callback(); }); | |
} | |
render(); | |
/*////////////////////////////////////////*/ | |
const HALFPI = Math.PI / 2; | |
const TWOPI = Math.PI * 2; | |
/*////////////////////////////////////////*/ | |
var world; | |
var dt = 1 / 60; | |
var constraintDown = false; | |
var camera, scene, renderer, gplane=false, clickMarker=false; | |
var geometry, material, mesh; | |
var controls,time = Date.now(); | |
var camera, scene, renderer; | |
initCannon(); | |
init(); | |
function init() { | |
// scene | |
scene = new THREE.Scene(); | |
scene.fog = new THREE.Fog( 0xFFFFFF, 100, 250 ); | |
// camera | |
camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 0.5, 10000 ); | |
camera.position.set(0, 40, 90); | |
camera.quaternion.setFromAxisAngle(new THREE.Vector3(0,1,0), Math.PI/2); | |
scene.add(camera); | |
renderer = new THREE.WebGLRenderer( { antialias: true } ); | |
renderer.setSize( window.innerWidth, window.innerHeight ); | |
renderer.setClearColor( scene.fog.color ); | |
document.body.appendChild( renderer.domElement ); | |
renderer.gammaInput = true; | |
renderer.gammaOutput = true; | |
if ( window.innerWidth > 500 ) { | |
renderer.shadowMap.enabled = true; | |
renderer.shadowMap.type = THREE.PCFSoftShadowMap; | |
console.log(renderer.shadowMap); | |
} | |
renderCalls.push(function(){ renderer.render(scene, camera); }); | |
window.addEventListener( 'resize', onWindowResize, false ); | |
let orbit = new THREE.OrbitControls(camera, renderer.domElement); | |
orbit.zoomSpeed = 0.6; | |
orbit.minDistance = 10; | |
/*////////////////////////////////////////*/ | |
// lights | |
var light, materials; | |
var ambientLight = new THREE.AmbientLight(0x222222); | |
scene.add(ambientLight); | |
/*////////////////////////////////////////*/ | |
light = new THREE.SpotLight( 0xffffff ); | |
light.position.y = 100; | |
light.position.x = 0; | |
light.position.z = 65; //110; | |
light.power = 2; | |
light.angle = Math.PI / 2.5; //Math.PI / 4; | |
light.castShadow = true; | |
light.shadow.mapSize.width = 4096; | |
light.shadow.mapSize.height = 4096; | |
light.shadow.camera.near = 0.1; | |
light.shadow.camera.far = 100; | |
light.shadow.camera.fov = 20; | |
scene.add( light ); | |
let geometry = new THREE.PlaneGeometry( 400, 400, 1, 1 ); | |
let material = new THREE.MeshPhongMaterial({ | |
color: 0xFFFFFF, | |
emissive: 0xFFFFFF, | |
emissiveIntensity: 0.2, | |
shininess: 400, | |
shading: THREE.SmoothShading | |
}); | |
mesh = new THREE.Mesh( geometry, material ); | |
//plane.rotation.x = Math.PI / -2; | |
mesh.castShadow = true; | |
mesh.receiveShadow = true; | |
mesh.quaternion.setFromAxisAngle(new THREE.Vector3(1,0,0), -Math.PI / 2); | |
scene.add(mesh); | |
} | |
function onWindowResize() { | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
renderer.setSize( window.innerWidth, window.innerHeight ); | |
} | |
function initCannon(){ | |
// Setup our world | |
world = new CANNON.World(); | |
world.quatNormalizeSkip = 0; | |
world.quatNormalizeFast = false; | |
world.gravity.set(0,-10,0); | |
world.broadphase = new CANNON.NaiveBroadphase(); | |
// Create a plane | |
var groundShape = new CANNON.Plane(); | |
var groundBody = new CANNON.Body({ mass: 0 }); | |
groundBody.addShape(groundShape); | |
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2); | |
world.add(groundBody); | |
// Joint body | |
var shape = new CANNON.Sphere(0.1); | |
jointBody = new CANNON.Body({ mass: 0 }); | |
jointBody.addShape(shape); | |
jointBody.collisionFilterGroup = 0; | |
jointBody.collisionFilterMask = 0; | |
world.add(jointBody); | |
// // Create a sphere | |
// var mass = 5, radius = 0.3; | |
// sphereShape = new CANNON.Sphere(radius); | |
// sphereBody = new CANNON.Body({ mass: mass }); | |
// sphereBody.addShape(sphereShape); | |
// sphereBody.position.set(0,0,0); | |
// sphereBody.linearDamping = 0.9; | |
// world.add(sphereBody); | |
} | |
function updatePhysics(){ world.step(dt); } | |
renderCalls.push(updatePhysics); | |
/*////////////////////////////////////////*/ | |
function noiseMap(size,intensity){ | |
var canvas = document.createElement('canvas'), | |
ctx = canvas.getContext('2d'), | |
width = canvas.width = size || 512, | |
height = canvas.height = size || 512; | |
intensity = intensity || 120; | |
var imageData = ctx.getImageData(0, 0, width, height), | |
pixels = imageData.data, | |
n = pixels.length, | |
i = 0; | |
while (i < n) { | |
pixels[i++] = pixels[i++] = pixels[i++] = Math.sin( i * i * i + (i/n) * Math.PI) * intensity; | |
pixels[i++] = 255; | |
} | |
ctx.putImageData(imageData, 0, 0); | |
let sprite = new THREE.Texture(canvas); | |
sprite.needsUpdate = true; | |
return sprite; | |
} | |
/*////////////////////////////////////////*/ | |
const toastHeight = 8; | |
const toastWidth = 8; | |
const toastDepth = 1; | |
const toastHeightSegments = 8; | |
const toastWidthSegments = 5; | |
const toastGeo = new THREE.BoxGeometry( toastWidth, toastHeight, toastDepth, toastWidthSegments, toastHeightSegments ); | |
toastGeo.vertices.forEach((vertex,i)=>{ | |
let offsetX = (vertex.y * -0.06); | |
let offsetY = 0; | |
if ( vertex.y === toastHeight / 2 ) { | |
offsetY = -0.4 + 0.5 * Math.cos((vertex.x / (toastWidthSegments-1)) * HALFPI); | |
offsetX = ( Math.abs(vertex.x) > 1 ? -0.5 : -0.25 ); | |
} else if ( vertex.y > (toastHeight / 2) * 0.25 ) {// (toastHeightSegments/2) ) { | |
offsetX = 0.4 * Math.sin((vertex.y / (toastHeightSegments /2)) * Math.PI); | |
} | |
vertex.x += offsetX * ( vertex.x < 0 ? -1 : 1 ); | |
vertex.y += offsetY; | |
}); | |
// Color the outside of the toast | |
let color = 0x630A10; //Math.random() * 0xffffff; | |
for (var i = 0; i < (toastHeightSegments * 4) + ( toastWidthSegments * 4); i++) { | |
toastGeo.faces[i].color.setHex( color ); | |
} | |
var toastMaterial = new THREE.MeshPhongMaterial( { | |
color: 0xFFDD83, //0xFFDD83, | |
vertexColors: THREE.FaceColors, | |
bumpMap: noiseMap(256,10), | |
bumpMapScale: 2, | |
//wireframe: true, | |
shininess: 0 | |
}); | |
function Toast(){ | |
THREE.Mesh.call(this, toastGeo, toastMaterial); | |
}; | |
Toast.prototype = Object.create(THREE.Mesh.prototype); | |
/*////////////////////////////////////////*/ | |
function PhysicalBox(opts) { | |
if (!(this instanceof PhysicalBox)) { return new PhysicalBox(opts); } | |
opts = opts || this.defaultOpts; | |
CANNON.Body.call(this, opts); | |
this.object = new THREE.Object3D(); | |
this.sync = this.sync.bind(this); | |
} | |
PhysicalBox.prototype = Object.assign(Object.create(CANNON.Body.prototype),{ | |
constructor: PhysicalBox, | |
defaultOpts: { mass: 100 }, | |
add: function(obj){ | |
this.object.add(obj); //.apply(this.object, arguments); | |
this.updateShape(); | |
}, | |
updateShape: function(){ | |
let bbox = new THREE.Box3().setFromObject(this.object); | |
this.shapes = []; | |
this.addShape(new CANNON.Box( new CANNON.Vec3( bbox.max.x, bbox.max.y, bbox.max.z) )); | |
}, | |
sync: function(){ | |
if ( this.position && this.object ) { | |
this.object.position.copy( this.position ); | |
this.object.quaternion.copy( this.quaternion ); | |
} | |
} | |
}); | |
/*////////////////////////////////////////*/ | |
function makeToast(){ | |
let c3d = new PhysicalBox({ mass: 100 }); | |
let toast = new Toast(); | |
toast.castShadow = true; | |
toast.receiveShadow = true; | |
c3d.add(toast); | |
world.add(c3d); | |
scene.add(c3d.object); | |
renderCalls.push(c3d.sync); | |
return c3d; | |
} | |
const butterGeometry = new THREE.BoxGeometry( 3, 3, 0.5 ); | |
const butterMaterial = new THREE.MeshPhongMaterial( { color: 0xFBFF64, shininess: 50 } ); | |
function makeButter(){ | |
let c3d = new PhysicalBox({ mass: 20 }); | |
let butter = new THREE.Mesh( butterGeometry, butterMaterial ); | |
butter.castShadow = true; | |
butter.receiveShadow = true; | |
c3d.add(butter); | |
world.add(c3d); | |
scene.add(c3d.object); | |
renderCalls.push(c3d.sync); | |
return c3d; | |
} | |
/*////////////////////////////////////////*/ | |
for (var i = 0, len = 21; i < len; i++){ | |
let c3d = ( i % 2 ? makeButter() : makeToast() ); | |
if ( i === 0 ) { console.log(c3d); } | |
c3d.position.set((Math.random() - 0.5) * 10, 40 + (i * 8), (Math.random() - 0.5 )* 20); | |
c3d.quaternion.setFromEuler(Math.random() * TWOPI, 0, Math.random() * HALFPI); | |
//c3d.velocity.set(19 * Math.sin((i / len) * TWOPI), 8, 5 * (Math.random() - 0.5)); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="http://codepen.io/shshaw/pen/epmrgO"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script> | |
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
canvas { display: block; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment