Skip to content

Instantly share code, notes, and snippets.

@brianpeiris
Created October 26, 2014 16:16
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianpeiris/e472809e38db8c0c1883 to your computer and use it in GitHub Desktop.
Save brianpeiris/e472809e38db8c0c1883 to your computer and use it in GitHub Desktop.
RiftSketch - Birds and Blossoms
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