Skip to content

Instantly share code, notes, and snippets.

@Garciat
Last active November 16, 2015 01:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Garciat/f839670517fa8fc263b4 to your computer and use it in GitHub Desktop.
Save Garciat/f839670517fa8fc263b4 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - interactive - voxel painter</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
#oldie { background-color: #ddd !important }
textarea {
position: absolute;
z-index: 100000;
top: 5px; left: 5px;
height: 50px;
}
</style>
</head>
<body>
<script src="http://threejs.org/examples/../build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="http://threejs.org/examples/js/Detector.js"></script>
<textarea id="input"></textarea>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var camera, controls, scene, renderer;
var plane, cube;
var mouse, raycaster, isShiftDown = false;
var rollOverMesh, rollOverMaterial;
var cubeGeo, cubeMaterial;
var objects = [];
init();
loop();
document.getElementById('input').value = '1 2\n2 1';
updateTowers();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 500, 800, 1300 );
camera.lookAt( new THREE.Vector3() );
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 4.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
// roll-over helpers
// cubes
cubeGeo = new THREE.BoxGeometry( 50, 50, 50 );
cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, shading: THREE.FlatShading } );
// grid
var size = 500, step = 50;
var geometry = new THREE.Geometry();
for ( var i = - size; i <= size; i += step ) {
geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
geometry.vertices.push( new THREE.Vector3( i, 0, size ) );
}
var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );
var line = new THREE.LineSegments( geometry, material );
scene.add( line );
//
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
geometry.rotateX( - Math.PI / 2 );
plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
scene.add( plane );
objects.push( plane );
// Lights
var ambientLight = new THREE.AmbientLight( 0x606060 );
scene.add( ambientLight );
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
scene.add( directionalLight );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
document.getElementById('input').addEventListener('keyup', updateTowers);
document.getElementById('input').focus();
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function render() {
renderer.render( scene, camera );
}
function loop() {
controls.update();
render();
requestAnimationFrame(loop);
}
function createVoxel(x, y, z) {
var voxel = new THREE.Mesh( cubeGeo, cubeMaterial );
voxel.name = 'voxel';
voxel.position.set(x * 50, z * 50, y * 50);
voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
scene.add( voxel );
objects.push( voxel );
}
function createTower(x, y, z) {
for (var zi = 0; zi < z; ++zi) {
createVoxel(x, y, zi);
}
}
function parseTowers(input) {
return input.replace(/\n\s*\n/, '\n').split('\n').map(function (line, i) {
return line.trim().split(/\s+/).map(function (token, j) {
return { x: j, y: i, z: parseInt(token.trim()) };
});
}).reduce(function (a, b) { return a.concat(b); }, []);
}
function cleanTowers() {
var voxels = objects.filter(function (o) { return o.name === 'voxel'; });
voxels.forEach(function (voxel) {
scene.remove(voxel);
objects.splice(objects.indexOf(voxel), 1)
});
}
function updateTowers() {
var input = document.getElementById('input').value;
cleanTowers();
parseTowers(input).forEach(function (tower) {
console.log(tower);
createTower(tower.x, tower.y, tower.z);
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment