'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();