console
var scene,
camera,
controls,
fieldOfView,
aspectRatio,
nearPlane,
farPlane,
shadowLight,
backLight,
light,
renderer,
container,
raycaster;
var env, floor;
var treeCache = [];
var TREES = true;
var MOUNTAINS = true;
var CLOUDS = true;
var HEIGHT,
WIDTH,
windowHalfX,
windowHalfY,
mousePos = {
x: 0,
y: 0
};
function init() {
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xece9ca, 500, 2000);
raycaster = new THREE.Raycaster();
HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
aspectRatio = WIDTH / HEIGHT;
fieldOfView = 60;
nearPlane = 1;
farPlane = 2000;
camera = new THREE.PerspectiveCamera(
fieldOfView,
aspectRatio,
nearPlane,
farPlane);
camera.position.x = -500;
camera.position.z = 500;
camera.position.y = 300;
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true
});
renderer.setSize(WIDTH, HEIGHT);
renderer.shadowMapEnabled = true;
container = document.getElementById('world');
container.appendChild(renderer.domElement);
windowHalfX = WIDTH / 2;
windowHalfY = HEIGHT / 2;
window.addEventListener('resize', onWindowResize, false);
document.addEventListener('mouseup', handleMouseUp, false);
document.addEventListener('touchend', handleTouchEnd, false);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.minPolarAngle = -Math.PI / 2;
controls.maxPolarAngle = Math.PI / 2 + .1;
controls.noZoom = false;
controls.noPan = true;
}
function onWindowResize() {
HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
windowHalfX = WIDTH / 2;
windowHalfY = HEIGHT / 2;
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
}
function handleMouseUp(event) {
}
function handleTouchEnd(event) {
}
function createLights() {
light = new THREE.HemisphereLight(0xffffff, 0xb3858c, .65);
shadowLight = new THREE.DirectionalLight(0xffe79d, .7);
shadowLight.position.set(80, 120, 50);
shadowLight.castShadow = true;
shadowLight.shadowDarkness = .3;
shadowLight.shadowMapWidth = 2048;
shadowLight.shadowMapHeight = 2048;
backLight = new THREE.DirectionalLight(0xffffff, .4);
backLight.position.set(200, 100, 100);
backLight.shadowDarkness = .1;
scene.add(backLight);
scene.add(light);
scene.add(shadowLight);
}
function makeCube(mat, w, h, d, posX, posY, posZ, rotX, rotY, rotZ) {
var geom = new THREE.BoxGeometry(w, h, d);
var mesh = new THREE.Mesh(geom, mat);
mesh.position.x = posX;
mesh.position.y = posY;
mesh.position.z = posZ;
mesh.rotation.x = rotX;
mesh.rotation.y = rotY;
mesh.rotation.z = rotZ;
return mesh;
}
function createFloor() {
if (env) {
scene.remove(env);
env = null;
}
env = new THREE.Group();
var waterGeo = new THREE.BoxGeometry(1000, 1000, 100, 22, 22);
for (var i = 0; i < waterGeo.vertices.length; i++) {
var vertex = waterGeo.vertices[i];
if (vertex.z > 0)
vertex.z += Math.random() * 2 - 1;
vertex.x += Math.random() * 5 - 2.5;
vertex.y += Math.random() * 5 - 2.5;
vertex.wave = Math.random() * 100;
}
waterGeo.computeFaceNormals();
waterGeo.computeVertexNormals();
floor = new THREE.Mesh(waterGeo, new THREE.MeshLambertMaterial({
color: 0x6092c1,
shading: THREE.FlatShading,
transparent: true,
opacity: 0.9,
side: THREE.DoubleSide,
}));
floor.rotation.x = -Math.PI / 2;
floor.position.y = -105;
floor.receiveShadow = true;
floor.name = "Floor"
env.floor = floor;
env.add(floor);
var islandGeo = new THREE.PlaneGeometry(700, 700, 60, 60);
var zeroVector = new THREE.Vector3();
var mods = [];
var modVector;
var modAmount = Math.floor(Math.random() * 6 + 1)
for (var j = 0; j < modAmount; j++) {
var modVector = new THREE.Vector3(Math.random() * 350, Math.random() * 350, 0);
modVector.radius = Math.random() * 400;
modVector.dir = Math.random() * 1 - .6 + modVector.radius / 5000;
mods.push(modVector)
}
var midY = 0;
for (var i = 0; i < islandGeo.vertices.length; i++) {
var vertex = islandGeo.vertices[i];
vertex.z = -vertex.distanceTo(zeroVector) * .15 + 15 + Math.random() * 3 - 6;
for (var j = 0; j < mods.length; j++) {
var modVector = mods[j];
if (vertex.distanceTo(modVector) < modVector.radius)
vertex.z += vertex.distanceTo(modVector) / 2 * modVector.dir;
}
vertex.y += Math.random() * 20 - 10;
vertex.x += Math.random() * 20 - 10;
midY += vertex.z;
}
midY = midY / islandGeo.vertices.length;
islandGeo.computeFaceNormals();
islandGeo.computeVertexNormals();
var island = new THREE.Mesh(islandGeo, new THREE.MeshLambertMaterial({
color: 0x9bb345,
shading: THREE.FlatShading,
side: THREE.DoubleSide,
wireframe: false
}));
island.rotation.x = -Math.PI / 2;
island.position.y = -14;
island.receiveShadow = true;
island.castShadow = true;
island.name = "island"
env.island = island;
env.add(island);
scene.add(env);
}
Tree1 = function() {
var height = 9 + Math.random() * 8;
var boxGeom = new THREE.BoxGeometry(2, height, 1);
this.root = new THREE.Mesh(boxGeom, this.yellowMat);
this.root.position.y = 0;
var sphereGeometry = new THREE.SphereGeometry(6, 8);
for (var i = 0; i < sphereGeometry.vertices.length; i++) {
var vertex = sphereGeometry.vertices[i];
vertex.y += Math.random() * 3 - 1.5;
vertex.x += Math.random() * 1 - .5;
vertex.z += Math.random() * 1 - .5;
}
sphereGeometry.computeFaceNormals();
sphereGeometry.computeVertexNormals();
this.sphereGeometry = sphereGeometry;
this.sphere = new THREE.Mesh(sphereGeometry, this.greenMat);
this.sphere.position.y = height / 2 + 2;
this.sphere.scale.y = .75 + Math.random() * .5;
}
function getRandomLandPos()
{
var downVector = new THREE.Vector3(0, -1, 0);
var c = {
position: new THREE.Vector3()
};
c.position.y = 100;
var angle = Math.random() * 360;
var r_radius = Math.random() * 200;
c.position.x = r_radius * Math.cos(angle)
c.position.z = r_radius * Math.sin(angle)
scene.updateMatrixWorld();
raycaster.set(c.position, downVector);
var collisions = raycaster.intersectObject(env, true);
if (collisions.length > 0) {
if (collisions[0].object.name == "island") {
c.position.y = collisions[0].point.y + 4;
return c.position;
} else {return null}
} else {
return null;
}
}
var Forest = function(amount, pos, radius) {
if (!treeCache || treeCache.length < 5) {
for (var i = 0; i < 10; i++) {
var t = new Tree1();
treeCache.push(t);
}
}
var yellowMat = new THREE.MeshLambertMaterial({
color: 0xffde79,
shading: THREE.FlatShading
});
var greenMat = new THREE.MeshLambertMaterial({
color: 0xa6d247,
shading: THREE.FlatShading
});
var roots = [];
var crowns = [];
var downVector = new THREE.Vector3(0, -1, 0);
for (var i = 0; i < amount; i++) {
var c = {
position: new THREE.Vector3()
};
c.position.y = 100;
var angle = Math.random() * 360;
var r_radius = Math.random() * radius;
c.position.x = pos.x + r_radius * Math.cos(angle)
c.position.z = pos.z + r_radius * Math.sin(angle)
scene.updateMatrixWorld();
raycaster.set(c.position, downVector);
var collisions = raycaster.intersectObject(env, true);
if (collisions.length > 0) {
if (collisions[0].object.name == "island") {
var rnd = Math.floor(Math.random() * treeCache.length)
c.root = treeCache[rnd].root.clone();
c.sphere = treeCache[rnd].sphere.clone();
c.root.position.y = c.sphere.position.y = collisions[0].point.y + 6;
c.root.position.x = c.sphere.position.x = c.position.x;
c.root.position.z = c.sphere.position.z = c.position.z;
c.sphere.position.y += 4 + Math.random() * 4;
console.log(collisions[0].object.name);
roots.push(c.root);
crowns.push(c.sphere);
}
} else {
console.log("NOT FOUND")
}
}
roots = mergeMeshes(roots);
crowns = mergeMeshes(crowns);
this.threegroup = new THREE.Group();
this.roots = new THREE.Mesh(roots, yellowMat);
this.crowns = new THREE.Mesh(crowns, greenMat);
this.threegroup.add(this.roots);
this.threegroup.add(this.crowns);
this.threegroup.traverse(function(object) {
if (object instanceof THREE.Mesh) {
object.castShadow = true;
object.receiveShadow = true;
}
});
}
Cube = function() {
this.yellowMat = new THREE.MeshLambertMaterial({
color: 0xffde79,
shading: THREE.FlatShading
});
this.whiteMat = new THREE.MeshLambertMaterial({
color: 0xffffff,
shading: THREE.FlatShading,
wireframe: true
});
this.threegroup = new THREE.Group();
var boxGeom = new THREE.BoxGeometry(2, 4, 2);
this.boxMesh = new THREE.Mesh(boxGeom, this.yellowMat);
this.boxMesh.position.y = 0;
this.threegroup.add(this.boxMesh);
this.threegroup.traverse(function(object) {
if (object instanceof THREE.Mesh) {
object.castShadow = true;
object.receiveShadow = true;
}
});
}
Cloud = function() {
this.whiteMat = new THREE.MeshLambertMaterial({
color: 0xfae2c8,
shading: THREE.FlatShading,
wireframe: false
});
var sphereGeom = new THREE.SphereGeometry(6 + Math.floor(Math.random() * 12), 8, 8);
for (var i = 0; i < sphereGeom.vertices.length; i++) {
var vertex = sphereGeom.vertices[i];
vertex.y += Math.random() * 4 - 2;
vertex.x += Math.random() * 3 - 1.5;
vertex.z += Math.random() * 3 - 1.5;
}
sphereGeom.computeFaceNormals();
sphereGeom.computeVertexNormals();
this.threegroup = new THREE.Mesh(sphereGeom, this.whiteMat);
this.threegroup.position.y = 60 + Math.random() * 150;
this.threegroup.castShadow = true;
this.threegroup.scale.x = 1.3 + Math.random() * 2;
this.threegroup.scale.y = this.threegroup.scale.x / 2 + Math.random() * .5 - 0.25;
this.threegroup.scale.z = 0.7 + Math.random() * 0.8;
this.threegroup.rotation.y = Math.random() * 3;
this.threegroup.position.x = Math.random() * 800 - 400;
this.threegroup.position.z = Math.random() * 800 - 400;
var rnd1 = Math.random() * 40 + 30 - (35);
var rnd2 = Math.random() * 10 + 10 - 10;
TweenMax.to(this.threegroup.position, 12 + Math.random() * 10, {
repeat: -1,
yoyo: true,
x: this.threegroup.position.x + rnd1,
ease: Sine.easeInOut
});
TweenMax.to(this.threegroup.position, 4 + Math.random() * 2, {
repeat: -1,
yoyo: true,
overwrite:false,
y: this.threegroup.position.y + rnd2,
ease: Sine.easeInOut
});
}
Mountain = function() {
this.greyMat = new THREE.MeshLambertMaterial({
color: 0xa99a9d,
shading: THREE.FlatShading,
wireframe: false,
side: THREE.DoubleSide
});
this.threegroup = new THREE.Group();
var zeroVector = new THREE.Vector3();
var size = Math.random() * 200 + 100;
var heightScale = Math.random() * .5 + 2;
var boxGeom = new THREE.PlaneGeometry(size, size, 8 + Math.floor(Math.random() * 3), 8 + Math.floor(Math.random() * 3));
for (var i = 0; i < boxGeom.vertices.length; i++) {
var vertex = boxGeom.vertices[i];
vertex.z = (-vertex.distanceTo(zeroVector) * .5) * heightScale + 15 + Math.random() * 3 - 6;
vertex.y += Math.random() * 10 - 5;
vertex.x += Math.random() * 10 - 5;
vertex.z += Math.random() * 20 - 10;
}
boxGeom.computeFaceNormals();
boxGeom.computeVertexNormals();
this.boxMesh = new THREE.Mesh(boxGeom, this.greyMat);
var box = new THREE.Box3().setFromObject(this.boxMesh);
console.log(box);
this.boxMesh.position.y = Math.random() * 15 + 10;
this.boxMesh.rotation.x = -Math.PI / 2;
this.threegroup.add(this.boxMesh);
this.threegroup.traverse(function(object) {
if (object instanceof THREE.Mesh) {
object.castShadow = true;
object.receiveShadow = true;
}
});
}
tick = 0;
function loop() {
render();
tick++;
if (env && env.floor) {
for (var i = 0; i < env.floor.geometry.vertices.length; i++) {
var vertex = env.floor.geometry.vertices[i];
if (vertex.z > 0)
vertex.z += Math.sin(tick * .015 + vertex.wave) * 0.04;
}
env.floor.geometry.verticesNeedUpdate = true;
}
requestAnimationFrame(loop);
}
init();
createLights();
var self = this;
setTimeout(build, 200);
function build() {
TREES = document.getElementById("chkTrees").checked;
MOUNTAINS = document.getElementById("chkMountains").checked;
CLOUDS = document.getElementById("chkClouds").checked;
SHEEP = document.getElementById("chkSheep").checked;
createFloor();
if (MOUNTAINS) {
var mountains = Math.floor(Math.random() * 5 - 2)
for (var i = 0; i < mountains; i++) {
var mountain1 = new Mountain();
env.add(mountain1.threegroup);
mountain1.threegroup.position.x = Math.random() * 700 - 350;
mountain1.threegroup.position.z = Math.random() * 700 - 350;
}
}
if (TREES) {
var forest = new Forest(Math.random() * 20 + 10, new THREE.Vector3(0, 0, 0), 700);
env.add(forest.threegroup);
var extraForests = Math.floor(Math.random() * 15)
for (var i = 0; i < extraForests; i++) {
var forest = new Forest(Math.random() * 100, new THREE.Vector3(Math.random() * 500 - 250, 0, Math.random() * 500 - 250), Math.random() * 300);
env.add(forest.threegroup);
}
}
if (CLOUDS) {
var clouds_num = 1 + Math.random() *5 ;
for (var i = 0; i < clouds_num; i++) {
var c = new Cloud();
env.add(c.threegroup);
}
}
if(SHEEP) {
for(var i= 0; i <80; i++)
{
var pos = getRandomLandPos();
if(pos != null)
{
console.log("FOUND SHEEP")
var s = new Sheep();
env.add(s.group);
s.group.position.x = pos.x;
s.group.position.y = pos.y;
s.group.position.z = pos.z;
s.group.rotation.y = Math.random() * 360;
s.group.scale.x = s.group.scale.y = s.group.scale.z = 2;
console.log(pos.x,pos.y,pos.z)
TweenMax.to(s.group.position,.4,{delay:Math.random()*2,ease:Linear.easeNone,y:(pos.y + 1.5) + Math.random()* 1,repeat:-1,yoyo:true});
}
}
}
}
var cube = new Cube();
scene.add(cube.threegroup);
loop();
function render() {
if (controls) controls.update();
if (cube) {
}
renderer.render(scene, camera);
}
function mergeMeshes(meshes) {
var combined = new THREE.Geometry();
for (var i = 0; i < meshes.length; i++) {
meshes[i].updateMatrix();
combined.merge(meshes[i].geometry, meshes[i].matrix);
}
return combined;
}
function clamp(v, min, max) {
return Math.min(Math.max(v, min), max);
}
function rule3(v, vmin, vmax, tmin, tmax) {
var nv = Math.max(Math.min(v, vmax), vmin);
var dv = vmax - vmin;
var pc = (nv - vmin) / dv;
var dt = tmax - tmin;
var tv = tmin + (pc * dt);
return tv;
}
class Sheep {
constructor() {
this.group = new THREE.Group();
this.group.position.y = 0.4;
this.woolMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff,
roughness: 1,
shading: THREE.FlatShading
});
this.skinMaterial = new THREE.MeshLambertMaterial({
color: 0xffaf8b,
roughness: 1,
shading: THREE.FlatShading
});
this.darkMaterial = new THREE.MeshLambertMaterial({
color: 0x4b4553,
roughness: 1,
shading: THREE.FlatShading
});
this.vAngle = 0;
this.drawBody();
this.drawHead();
this.drawLegs();
}
drawBody() {
const bodyGeometry = new THREE.IcosahedronGeometry(1.7, 0);
const body = new THREE.Mesh(bodyGeometry, this.woolMaterial);
body.castShadow = true;
body.receiveShadow = true;
this.group.add(body);
}
drawHead() {
const head = new THREE.Group();
head.position.set(0, 0.65, 1.6);
head.rotation.x = rad(-20);
this.group.add(head);
const foreheadGeometry = new THREE.BoxGeometry(0.7, 0.6, 0.7);
const forehead = new THREE.Mesh(foreheadGeometry, this.skinMaterial);
forehead.castShadow = true;
forehead.receiveShadow = true;
forehead.position.y = -0.15;
head.add(forehead);
const faceGeometry = new THREE.CylinderGeometry(0.5, 0.15, 0.4, 4, 1);
const face = new THREE.Mesh(faceGeometry, this.skinMaterial);
face.castShadow = true;
face.receiveShadow = true;
face.position.y = -0.65;
face.rotation.y = rad(45);
head.add(face);
const woolGeometry = new THREE.BoxGeometry(0.84, 0.46, 0.9);
const wool = new THREE.Mesh(woolGeometry, this.woolMaterial);
wool.position.set(0, 0.12, 0.07);
wool.rotation.x = rad(20);
head.add(wool);
const rightEyeGeometry = new THREE.CylinderGeometry(0.08, 0.1, 0.06, 6);
const rightEye = new THREE.Mesh(rightEyeGeometry, this.darkMaterial);
rightEye.castShadow = true;
rightEye.receiveShadow = true;
rightEye.position.set(0.35, -0.48, 0.33);
rightEye.rotation.set(rad(130.8), 0, rad(-45));
head.add(rightEye);
const leftEye = rightEye.clone();
leftEye.position.x = -rightEye.position.x;
leftEye.rotation.z = -rightEye.rotation.z;
head.add(leftEye);
const rightEarGeometry = new THREE.BoxGeometry(0.12, 0.5, 0.3);
this.rightEar = new THREE.Mesh(rightEarGeometry, this.skinMaterial);
this.rightEar.castShadow = true;
this.rightEar.receiveShadow = true;
this.rightEar.position.set(0.35, -0.12, -0.07);
this.rightEar.rotation.set(rad(20), 0, rad(50));
head.add(this.rightEar);
this.leftEar = this.rightEar.clone();
this.leftEar.position.x = -this.rightEar.position.x;
this.leftEar.rotation.z = -this.rightEar.rotation.z;
head.add(this.leftEar);
}
drawLegs() {
const legGeometry = new THREE.CylinderGeometry(0.3, 0.15, 1, 4);
this.frontRightLeg = new THREE.Mesh(legGeometry, this.darkMaterial);
this.frontRightLeg.castShadow = true;
this.frontRightLeg.receiveShadow = true;
this.frontRightLeg.position.set(0.7, -0.8, 0.5);
this.frontRightLeg.rotation.x = rad(-12);
this.group.add(this.frontRightLeg);
this.frontLeftLeg = this.frontRightLeg.clone();
this.frontLeftLeg.position.x = -this.frontRightLeg.position.x;
this.frontLeftLeg.rotation.z = -this.frontRightLeg.rotation.z;
this.group.add(this.frontLeftLeg);
this.backRightLeg = this.frontRightLeg.clone();
this.backRightLeg.position.z = -this.frontRightLeg.position.z;
this.backRightLeg.rotation.x = -this.frontRightLeg.rotation.x;
this.group.add(this.backRightLeg);
this.backLeftLeg = this.frontLeftLeg.clone();
this.backLeftLeg.position.z = -this.frontLeftLeg.position.z;
this.backLeftLeg.rotation.x = -this.frontLeftLeg.rotation.x;
this.group.add(this.backLeftLeg);
}
jump(speed) {
this.vAngle += speed;
this.group.position.y = Math.sin(this.vAngle) + 1.38;
const legRotation = Math.sin(this.vAngle) * Math.PI / 6 + 0.4;
this.frontRightLeg.rotation.z = legRotation;
this.backRightLeg.rotation.z = legRotation;
this.frontLeftLeg.rotation.z = -legRotation;
this.backLeftLeg.rotation.z = -legRotation;
const earRotation = Math.sin(this.vAngle) * Math.PI / 3 + 1.5;
this.rightEar.rotation.z = earRotation;
this.leftEar.rotation.z = -earRotation;
}
jumpOnMouseDown() {
if (mouseDown) {
this.jump(0.05);
} else {
if (this.group.position.y <= 0.4) return;
this.jump(0.08);
}
}
}
function rad(degrees) {
return degrees * (Math.PI / 180);
}
<div id="menu">
<div onclick="build()" class='button red center'>Generate new</div>
<input checked type="checkbox" id="chkTrees" />
<label for="chkTrees">Trees</label>
<input checked type="checkbox" id="chkSheep" />
<label for="chkSheep">Sheep</label>
<input checked type="checkbox" id="chkMountains" />
<label for="chkMountains">Mountains</label>
<input checked type="checkbox" id="chkClouds" />
<label class="wskLabel" for="chkClouds">Clouds</label>
</div>
<div id="world"></div>
body{
background-color:#47e4dd;
background: rgba(54,219,214,1);
background: -moz-linear-gradient(top, rgba(54,219,214,1) 0%, rgba(236,231,199,1) 100%);
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(54,219,214,1)), color-stop(100%, rgba(236,231,199,1)));
background: -webkit-linear-gradient(top, rgba(54,219,214,1) 0%, rgba(236,231,199,1) 100%);
background: -o-linear-gradient(top, rgba(54,219,214,1) 0%, rgba(236,231,199,1) 100%);
background: -ms-linear-gradient(top, rgba(54,219,214,1) 0%, rgba(236,231,199,1) 100%);
background: linear-gradient(to bottom, rgba(54,219,214,1) 0%, rgba(236,231,199,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#36dbd6', endColorstr='#ece7c7', GradientType=0 );
overflow:hidden;
margin:0px;
font-family: Arial, sans-serif;
}
button
{
position:absolute;
top:0px;
left:0px;
}
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,700);
h1 {
text-align: center;
text-transform: uppercase;
font-family: "Open Sans", sans-serif;
font-size: 27px;
color: #444444;
font-weight: 700;
}
h1 span {
font-weight: 400;
}
.container {
width: 735px;
margin: 50px auto;
background: whitesmoke;
padding: 25px;
}
.button {
border: 0 none;
border-radius: 2px 2px 2px 2px;
color: #FFFFFF;
cursor: pointer;
display: inline-block;
font-family: Arial,sans-serif;
font-size: 12px;
font-weight: bold;
line-height: 20px;
margin-bottom: 0;
margin-top: 10px;
padding: 7px 10px;
text-transform: none;
transition: all 0.3s ease 0s;
-moz-transition: all 0.3s ease 0s;
-webkit-transition: all 0.3s ease 0s;
width: 16.795%;
text-align: center;
}
.button.red {
background: none repeat scroll 0 0 #E0645C;
color: #FFFFFF;
}
.button.red:hover {
background: none repeat scroll 0 0 #999999;
color: #FFFFFF;
}
menu
{
position:absolute;
left:0px;
top:0px;
}
label
{
font-size:12px;
}