Created
October 26, 2014 16:16
-
-
Save brianpeiris/e472809e38db8c0c1883 to your computer and use it in GitHub Desktop.
RiftSketch - Birds and Blossoms
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 seed = '1', rands; | |
Math.seedrandom(seed); | |
if ( | |
window.seed && window.seed !== seed || | |
!window.rands | |
) { | |
rands = window.rands = []; | |
for (var i = 0; i < 50000; i++) { | |
rands.push(Math.random()); | |
} | |
} | |
else { | |
rands = window.rands; | |
} | |
window.seed = seed; | |
var randi = 0; | |
Math.random = function () { | |
if (randi > rands.length) { randi = 0; } | |
return rands[randi++]; | |
}; | |
var t3 = THREE; | |
var NUM_LEAVES = 1; | |
var TREE_DEPTH = 1; | |
var TWITTER_SEARCH = 'cherry trees'; | |
var light = new t3.PointLight(); | |
light.position.set(0.55, 2.23, -4.11); | |
scene.add(light); | |
var makeTreePart = function () { | |
return new t3.Mesh( | |
new t3.BoxGeometry(0.2, 2.0, 0.2), | |
new t3.MeshLambertMaterial({color: '#210'}) | |
); | |
}; | |
var makeSegment = function () { | |
var seg = makeTreePart(); | |
seg.translateY(0.33); | |
seg.scale.multiplyScalar(0.7); | |
seg.rotateY(Math.random() * Math.PI * 2); | |
seg.rotateX( | |
Math.random() * Math.PI / 10 + Math.PI / 5); | |
seg.translateZ(-0.4); | |
seg.translateY(1.1); | |
for (var i = 0; i < NUM_LEAVES; i++) { | |
seg.add(makeLeaf()); | |
} | |
return seg; | |
}; | |
var perches = []; | |
var makeBranch = function (depth) { | |
var branch = makeSegment(); | |
perches.push(branch); | |
branch.add(makeTree(depth + 1)); | |
return branch; | |
}; | |
var makeTwigs = function () { | |
var base = makeSegment(); | |
var curr = base; | |
for (var i = 0; i < 3; i++) { | |
var seg = makeSegment(); | |
curr.add(seg); | |
curr = seg; | |
} | |
return base; | |
}; | |
var getCanvasContext = function ( | |
width, height, name | |
) { | |
name = 'canvasTexture' + name; | |
var canvas = ( | |
document.getElementById(name) || | |
document.createElement('canvas')); | |
canvas.id = name; | |
canvas.width = width; | |
canvas.height = height; | |
var context = canvas.getContext('2d'); | |
return context; | |
}; | |
var context = getCanvasContext(20, 20); | |
context.fillStyle = 'hsl(321.39, 54.43%, 68.836%)'; | |
context.arc(10, 10, 6.365, 0, Math.PI * 2); | |
context.fill(); | |
var leafTexture = new THREE.Texture(context.canvas) | |
leafTexture.needsUpdate = true; | |
var leafMaterial = new THREE.MeshBasicMaterial( | |
{map: leafTexture, side:THREE.DoubleSide } ); | |
var makeLeaf = function () { | |
var leaf = new t3.Sprite( | |
new t3.SpriteMaterial(leafMaterial)); | |
leaf.scale.multiplyScalar(0.16); | |
leaf.translateY(Math.random() * 2 - 1.01); | |
leaf.rotateY(Math.random() * Math.PI * 2); | |
leaf.rotateX(Math.random() * Math.PI); | |
leaf.translateY(0.5); | |
return leaf; | |
}; | |
var makeTree = function (depth) { | |
var base = makeTreePart(); | |
if (depth < TREE_DEPTH) { | |
base.add(makeBranch(depth)); | |
base.add(makeBranch(depth)); | |
base.add(makeBranch(depth)); | |
} | |
else { | |
base.add(makeTwigs()); | |
} | |
return base; | |
}; | |
var sphere = function (radius, color) { | |
radius = radius || 1; | |
color = color || 'red'; | |
return new t3.Mesh( | |
new t3.SphereGeometry(radius), | |
new t3.MeshLambertMaterial({color: color}) | |
); | |
}; | |
var cylinder = function ( | |
radiusTop, radiusBottom, height, color | |
) { | |
radiusTop = radiusTop || 1; | |
radiusBottom = radiusBottom || radiusTop; | |
height = height || 1; | |
color = color || 'red'; | |
return new t3.Mesh( | |
new t3.CylinderGeometry( | |
radiusTop, radiusBottom, height), | |
new t3.MeshLambertMaterial({color: color}) | |
); | |
}; | |
var cube = function (width, height, depth, color) { | |
width = width || 1; | |
height = height || 1; | |
depth = depth || 1; | |
return new t3.Mesh( | |
new t3.BoxGeometry(width, height, depth), | |
new t3.MeshLambertMaterial({color: color})) | |
}; | |
var Bird = function (perchIndex, tweet) { | |
this.perchIndex = perchIndex; | |
this.tweet = tweet; | |
scene.updateMatrixWorld(); | |
this.perchPosition = new t3.Vector3(); | |
this.perchPosition.setFromMatrixPosition( | |
perches[perchIndex].matrixWorld); | |
this.perchPosition.y += 0.1; | |
this._wingAngle = this._i = 0; | |
this.mesh = this._makeBirdMesh(); | |
this.mesh.position.set(0.0, 5, -2); | |
}; | |
Bird.prototype.animate = function () { | |
this._i += this.isPerched ? 0 : 0.8; | |
if (this._i >= Math.PI * 2) { | |
this._i = 0; | |
} | |
this._wingAngle = ( | |
Math.sin(this._i) * Math.PI / 10); | |
if (this.mesh.position.distanceTo( | |
this.perchPosition) > 0.1 | |
) { | |
this.mesh.translateZ(0.1); | |
} | |
else { | |
this.isPerched = true; | |
this._wingAngle = Math.random() > 0.9 ? | |
(Math.random() - 0.5) * Math.PI / 10 : | |
this._wingAngle; | |
} | |
this._leftWingPivot.rotation.y = ( | |
this._wingAngle + Math.PI * -0.40); | |
this._rightWingPivot.rotation.y = ( | |
-this._wingAngle + Math.PI * 0.40); | |
if (Math.random() > 0.97) { | |
this.mesh.rotateY( | |
(Math.random() - 0.5) * Math.PI / 4); | |
} | |
if (Math.random() > 0.995) { | |
this.mesh.lookAt(this.perchPosition); | |
} | |
}; | |
var wrapTextOnCanvas = function (text, context) { | |
var words = text.split(' '); | |
var lineHeight = 40; | |
context.font = 'Bold ' + lineHeight + 'px Arial'; | |
context.fillStyle = 'hsla(200, 37%, 50%, 0.95)'; | |
var line = '', y = lineHeight; | |
for (var i = 0; i < words.length; i++) { | |
if ( | |
context.measureText( | |
line + ' ' + words[i]).width > | |
context.canvas.width | |
) { | |
context.fillText(line, 0, y); | |
line = ''; | |
y += lineHeight | |
} | |
line += ' ' + words[i]; | |
} | |
context.fillText(line, 0, y); | |
} | |
Bird.prototype._makeBirdMesh = function () { | |
var color = new t3.Color(); | |
color.setHSL( | |
0.57 + (Math.random() - 0.5) * 0.06, | |
0.84, 0.48); | |
var body = sphere(0.19, color); | |
body.scale.setZ(2.33); | |
body.scale.setY(0.83); | |
var head = sphere(0.16, color); | |
head.position.set(-0.0, 0.07, 0.14); | |
head.scale.set(1.01, 1.11, 0.51); | |
var r = 0.02; | |
body.add(head); | |
var beak = cylinder(0.04, 0.001, 0.08, color); | |
beak.rotateX(4.27) | |
beak.translateY(-0.18); | |
head.add(beak); | |
var r = 0.18; | |
var wing = cylinder(r, r, 0.01, color); | |
wing.scale.setX(0.60); | |
wing.translateZ(-0.16); | |
wing.rotateZ(1.31); | |
this._leftWingPivot = new t3.Object3D(); | |
this._leftWingPivot.position.set( | |
0.16, 0.084, 0.03); | |
this._leftWingPivot.rotation.set( | |
-0.053, 0, 0.44); | |
this._leftWingPivot.add(wing); | |
body.add(this._leftWingPivot); | |
wing = cylinder(r, r, 0.01, color); | |
wing.scale.setX(0.60); | |
wing.translateZ(-0.18); | |
wing.rotateZ(1.14); | |
this._rightWingPivot = new t3.Object3D(); | |
this._rightWingPivot.position.set( | |
-0.13, 0.084, 0.04); | |
this._rightWingPivot.rotation.set(0, 0, 0.11); | |
this._rightWingPivot.add(wing); | |
body.add(this._rightWingPivot); | |
var tail = cube(0.10, 0.032, 0.11, color) | |
tail.position.set(0, 0.09, -0.23); | |
tail.rotation.set(0.64, Math.PI / 4, 0); | |
tail.scale.multiplyScalar(1.81) | |
body.add(tail); | |
body.scale.multiplyScalar(0.38); | |
var context = getCanvasContext( | |
600, 600, this.roostIndex); | |
var text = ( | |
this.tweet.text + ' - @' + | |
this.tweet.user.screen_name); | |
wrapTextOnCanvas(text, context); | |
var tweetTexture = ( | |
new THREE.Texture(context.canvas)); | |
tweetTexture.needsUpdate = true; | |
var tweetMaterial = new THREE.MeshBasicMaterial( | |
{map: tweetTexture, side: THREE.DoubleSide}); | |
tweetMaterial.transparent = true; | |
this.tweet = new t3.Sprite( | |
new t3.SpriteMaterial(tweetMaterial)); | |
body.add(this.tweet); | |
return body; | |
}; | |
var tree = makeTree(0); | |
tree.position.set(4.96, 0.55, -1); | |
//scene.add(tree); | |
var birds = []; | |
/* | |
var bird = new Bird(0, {text:'hi', user:{screen_name: 'brian'}}); | |
bird.mesh.position.set(-0.71, 1.00, -1.12) | |
bird.mesh.rotation.set(0, 2.28, 0) | |
bird.tweet.visible = false; | |
scene.add(bird.mesh); | |
//birds.push(bird) ; | |
//*/ | |
var makeBirds = function (tweets) { | |
for (var i = 0; i < birds.length; i++) { | |
scene.remove(bird.mesh); | |
} | |
birds = []; | |
for ( | |
var i = 0; | |
i < Math.min(perches.length, tweets.length); | |
i++ | |
) { | |
var bird = new Bird(i, tweets[i]); | |
scene.add(bird.mesh); | |
birds.push(bird); | |
} | |
}; | |
api( | |
'twitter', | |
'https://api.twitter.com/1.1/search/tweets.json', | |
{q: TWITTER_SEARCH}, | |
function (data) { | |
var tweets = data.statuses; | |
//makeBirds(tweets); | |
} | |
); | |
var caster = new t3.Raycaster(); | |
return function () { | |
var direction = new t3.Vector3(0, 0, -1); | |
direction.applyQuaternion(camera.quaternion) | |
caster.set(camera.position, direction); | |
var targets = caster.intersectObjects( | |
_.map(birds, function (x) { return x.mesh; }), | |
true); | |
for (var i = 0; i < birds.length; i++) { | |
var bird = birds[i]; | |
bird.tweet.visible = false; | |
if (targets.length) { | |
var target = targets[0].object; | |
if ( | |
bird.mesh === target || | |
bird.mesh.getObjectById(target.id) | |
) { | |
bird.tweet.visible = true; | |
if (bird.isPerched) { | |
bird.mesh.lookAt(camera.position); | |
} | |
} | |
} | |
birds[i].animate(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment