Skip to content

Instantly share code, notes, and snippets.

@SomMeri
Created October 6, 2011 08:12
Show Gist options
  • Save SomMeri/1266820 to your computer and use it in GitHub Desktop.
Save SomMeri/1266820 to your computer and use it in GitHub Desktop.
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Voxels</title>
<meta charset="utf-8">
<style type="text/css">
body {
font-family: Monospace;
font-size: 12px;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script type="text/javascript" src="../js-src/Three.js"></script>
<script type="text/javascript">
var Cube = function (width, height, depth) {
THREE.Geometry.call(this);
var scope = this,
width_half = width / 2,
height_half = height / 2,
depth_half = depth / 2;
v( width_half, height_half, -depth_half );
v( width_half, -height_half, -depth_half );
v( -width_half, -height_half, -depth_half );
v( -width_half, height_half, -depth_half );
v( width_half, height_half, depth_half );
v( width_half, -height_half, depth_half );
v( -width_half, -height_half, depth_half );
v( -width_half, height_half, depth_half );
f4( 0, 1, 2, 3 );
f4( 4, 7, 6, 5 );
f4( 0, 4, 5, 1 );
f4( 1, 5, 6, 2 );
f4( 2, 6, 7, 3 );
f4( 4, 0, 3, 7 );
function v(x, y, z) {
scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) );
}
function f4(a, b, c, d) {
scope.faces.push( new THREE.Face4( a, b, c, d ) );
scope.faceVertexUvs[ 0 ].push( [
new THREE.UV( 0, 0 ),
new THREE.UV( 0, 1 ),
new THREE.UV( 1, 1 ),
new THREE.UV( 1, 0 )
] );
}
this.computeCentroids();
this.computeFaceNormals();
this.computeVertexNormals();
};
Cube.prototype = new THREE.Geometry();
Cube.prototype.constructor = Cube;
</script>
<script type="text/javascript">
var container, camera, scene, renderer,
projector, cube, ray, isMouseDown = false,
onMouseDownPosition,
radious = 1600, theta = 45, onMouseDownTheta = 45,
phi = 60, onMouseDownPhi = 60;
init();
render();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '5px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<span style="color: #444; background-color: #fff; border-bottom: 1px solid #ddd; padding: 8px 10px; text-transform: uppercase;"><strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel, <strong>drag</strong>: rotate | <a id="link" href="" target="_blank">share</a> </span>';
container.appendChild( info );
camera = new THREE.Camera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.x = radious * Math.sin( theta * Math.PI / 360 ) * Math.cos( phi * Math.PI / 360 );
camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
camera.position.z = radious * Math.cos( theta * Math.PI / 360 ) * Math.cos( phi * Math.PI / 360 );
camera.target.position.y = 200;
scene = new THREE.Scene();
projector = new THREE.Projector();
ray = new THREE.Ray( camera.position, null );
cube = new Cube( 50, 50, 50 );
onMouseDownPosition = new THREE.Vector2();
// Lights
var ambientLight = new THREE.AmbientLight( 0x404040 );
scene.addLight( ambientLight );
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.x = 1;
directionalLight.position.y = 1;
directionalLight.position.z = 0.75;
directionalLight.position.normalize();
scene.addLight( directionalLight );
var directionalLight = new THREE.DirectionalLight( 0x808080 );
directionalLight.position.x = - 1;
directionalLight.position.y = 1;
directionalLight.position.z = - 0.75;
directionalLight.position.normalize();
scene.addLight( directionalLight );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
//add voxels
var color = new THREE.MeshLambertMaterial( { color: 0xDF1F1F, opacity: 1, shading: THREE.FlatShading } );
addVoxel(-1, -1, color );
addVoxel(-2, -2, color );
addVoxel(-3, -3, color );
addVoxel(-4, -4, color );
//textures
var texture = THREE.ImageUtils.loadTexture("dirt.png");
//add lambert voxels
var lambert = new THREE.MeshLambertMaterial( { map: texture, opacity: 1, shading: THREE.FlatShading } );
addVoxel(1, 1, lambert);
addVoxel(2, 2, lambert);
addVoxel(3, 3, lambert);
addVoxel(4, 4, lambert);
//add basic voxels
var basic = new THREE.MeshBasicMaterial( { map: texture, opacity: 1, shading: THREE.FlatShading } );
addVoxel(1, 0, basic);
addVoxel(2, 0, basic);
addVoxel(3, 0, basic);
addVoxel(4, 0, basic);
container.appendChild(renderer.domElement);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
}
function addVoxel(x, y, material) {
var voxel = new THREE.Mesh( cube, material);
voxel.position.x = x * 50 + 25;
voxel.position.y = 0 * 50 + 25;
voxel.position.z = y * 50 + 25;
voxel.overdraw = true;
scene.addObject( voxel );
return voxel;
}
function onDocumentMouseDown( event ) {
event.preventDefault();
isMouseDown = true;
onMouseDownTheta = theta;
onMouseDownPhi = phi;
onMouseDownPosition.x = event.clientX;
onMouseDownPosition.y = event.clientY;
}
function onDocumentMouseMove( event ) {
event.preventDefault();
if ( isMouseDown ) {
theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 ) + onMouseDownTheta;
phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 ) + onMouseDownPhi;
phi = Math.min( 180, Math.max( 0, phi ) );
var x = radious * Math.sin(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360);
var y = radious * Math.sin(phi * Math.PI / 360);
var z = radious * Math.cos(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360);
if (y <= 0) {
y = 1;
}
camera.position.x = x;
camera.position.y = y;
camera.position.z = z;
camera.updateMatrix();
}
var mouse3D = projector.unprojectVector( new THREE.Vector3( ( event.clientX / renderer.domElement.width ) * 2 - 1, - ( event.clientY / renderer.domElement.height ) * 2 + 1, 0.5 ), camera );
ray.direction = mouse3D.subSelf( camera.position ).normalize();
render();
}
function onDocumentMouseUp( event ) {
event.preventDefault();
isMouseDown = false;
onMouseDownPosition.x = event.clientX - onMouseDownPosition.x;
onMouseDownPosition.y = event.clientY - onMouseDownPosition.y;
if ( onMouseDownPosition.length() > 5 ) {
return;
}
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment