Created
October 6, 2011 08:12
-
-
Save SomMeri/1266820 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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