'use strict';
/* global THREE */
var base = {
y: 0,
length: 2000,
angle: Math.PI,
theta: 0,
width: 200,
color: 'brown',
limbs: [],
generation: 0,
hasLeaves: false
};
var maxGeneration = 3;
var maxLimbs = 2;
var randBetween = function (min, max) {
return Math.random() * (max - min) + min;
};
var createLimb = function () {
return {
y: this.y - this.length * Math.cos(this.angle) / 2,
length: randBetween(this.length / 2, this.length),
angle: randBetween(Math.PI * 0.5, Math.PI * 1.5),
theta: randBetween(Math.PI * 0.5, Math.PI * 1.5),
width: this.width - this.width * 0.3,
color: this.color,
limbs: [],
generation: this.generation + 1,
hasLeaves: true
};
};
var createLimbs = function (limb) {
if (limb.generation < maxGeneration) {
var n = Math.round(Math.random() * maxLimbs) + 1;
for (var i = 0; i < n; i++) limb.limbs.push(createLimb.call(limb));
limb.limbs.forEach(createLimbs);
}
};
var iterateLimbs = function (root, cb) {
cb(root);
root.limbs.forEach(function (limb) {
cb(limb);
iterateLimbs(limb, cb);
});
};
var woodMat = new THREE.MeshLambertMaterial({
color: 0x53231B
});
var darkLeafMat = new THREE.MeshLambertMaterial({
color: 0x556910,
transparent: true,
opacity: 0.8
});
var lightLeafMat = new THREE.MeshLambertMaterial({
color: 0x889F57,
transparent: true,
opacity: 0.8
});
var createLimbMesh = function (limb) {
var cylinder = new THREE.CylinderGeometry(limb.width, limb.width, limb.length);
var mesh = new THREE.Mesh(cylinder, woodMat);
mesh.rotation.x += limb.angle;
var dx = limb.length * Math.sin(limb.angle) / 2;
var dy = limb.length * Math.cos(limb.angle) / 2;
mesh.position.set(0, limb.y - dy, -dx);
var dummy = new THREE.Object3D();
dummy.add(mesh);
dummy.rotation.y += limb.theta;
if (limb.hasLeaves) {
var sphere = new THREE.Mesh(new THREE.SphereGeometry(600, 10, 10),
Math.random() > 0.5 ? darkLeafMat : lightLeafMat);
sphere.position.set(0, limb.y - dy - dy, -dx - dx);
dummy.add(sphere);
}
return dummy;
};
var meshes = [];
createLimbs(base);
iterateLimbs(base, function (limb) {
meshes.push(createLimbMesh(limb));
});
function animate() {
requestAnimationFrame(animate);
scene.rotation.y += 0.01;
renderer.render(scene, camera);
}
var scene = new THREE.Scene();
meshes.forEach(function (mesh) {
scene.add(mesh);
});
var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 10000, 0);
scene.add(pointLight);
var pointLight2 = new THREE.PointLight(0xffffff);
pointLight2.position.set(10000, 0, 0);
scene.add(pointLight2);
var pointLight3 = new THREE.PointLight(0xffffff);
pointLight3.position.set(0, 0, 10000);
scene.add(pointLight3);
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 5000;
camera.position.y = 2000;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
animate();