|
@@ -20,28 +20,23 @@
|
|
|
<script src="../build/three.min.js"></script>
|
|
|
|
|
|
<script src="js/Detector.js"></script>
|
|
|
- <script src="js/libs/stats.min.js"></script>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
|
|
|
|
|
- var container, stats;
|
|
|
+ var container;
|
|
|
var camera, scene, renderer;
|
|
|
- var projector, plane, cube;
|
|
|
- var mouse2D, mouse3D, raycaster,
|
|
|
- rollOveredFace, isShiftDown = false,
|
|
|
- theta = 45 * 0.5, isCtrlDown = false;
|
|
|
+ var plane, cube;
|
|
|
+ var vector, raycaster, isShiftDown = false;
|
|
|
|
|
|
var rollOverMesh, rollOverMaterial;
|
|
|
- var voxelPosition = new THREE.Vector3(), tmpVec = new THREE.Vector3(), normalMatrix = new THREE.Matrix3();
|
|
|
var cubeGeo, cubeMaterial;
|
|
|
- var i, intersector;
|
|
|
|
|
|
var objects = [];
|
|
|
|
|
|
init();
|
|
|
- animate();
|
|
|
+ render();
|
|
|
|
|
|
function init() {
|
|
|
|
|
@@ -53,11 +48,12 @@
|
|
|
info.style.top = '10px';
|
|
|
info.style.width = '100%';
|
|
|
info.style.textAlign = 'center';
|
|
|
- info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> - voxel painter - webgl<br><strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel, <strong>control</strong>: rotate';
|
|
|
+ info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> - voxel painter - webgl<br><strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel';
|
|
|
container.appendChild( info );
|
|
|
|
|
|
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
|
|
|
- camera.position.y = 800;
|
|
|
+ camera.position.set( 500, 800, 1300 );
|
|
|
+ camera.lookAt( new THREE.Vector3() );
|
|
|
|
|
|
scene = new THREE.Scene();
|
|
|
|
|
@@ -74,10 +70,6 @@
|
|
|
cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, ambient: 0x00ff80, shading: THREE.FlatShading, map: THREE.ImageUtils.loadTexture( "textures/square-outline-textured.png" ) } );
|
|
|
cubeMaterial.ambient = cubeMaterial.color;
|
|
|
|
|
|
- // picking
|
|
|
-
|
|
|
- projector = new THREE.Projector();
|
|
|
-
|
|
|
// grid
|
|
|
|
|
|
var size = 500, step = 50;
|
|
@@ -100,15 +92,20 @@
|
|
|
line.type = THREE.LinePieces;
|
|
|
scene.add( line );
|
|
|
|
|
|
- plane = new THREE.Mesh( new THREE.PlaneGeometry( 1000, 1000 ), new THREE.MeshBasicMaterial() );
|
|
|
- plane.rotation.x = - Math.PI / 2;
|
|
|
+ //
|
|
|
+
|
|
|
+ vector = new THREE.Vector3();
|
|
|
+ raycaster = new THREE.Raycaster();
|
|
|
+
|
|
|
+ var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
|
|
|
+ geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
|
|
|
+
|
|
|
+ plane = new THREE.Mesh( geometry );
|
|
|
plane.visible = false;
|
|
|
scene.add( plane );
|
|
|
|
|
|
objects.push( plane );
|
|
|
|
|
|
- mouse2D = new THREE.Vector3( 0, 10000, 0.5 );
|
|
|
-
|
|
|
// Lights
|
|
|
|
|
|
var ambientLight = new THREE.AmbientLight( 0x606060 );
|
|
@@ -124,11 +121,6 @@
|
|
|
|
|
|
container.appendChild( renderer.domElement );
|
|
|
|
|
|
- stats = new Stats();
|
|
|
- stats.domElement.style.position = 'absolute';
|
|
|
- stats.domElement.style.top = '0px';
|
|
|
- container.appendChild( stats.domElement );
|
|
|
-
|
|
|
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
|
|
|
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
|
|
|
document.addEventListener( 'keydown', onDocumentKeyDown, false );
|
|
@@ -149,70 +141,54 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
- function getRealIntersector( intersects ) {
|
|
|
-
|
|
|
- for( i = 0; i < intersects.length; i++ ) {
|
|
|
-
|
|
|
- intersector = intersects[ i ];
|
|
|
-
|
|
|
- if ( intersector.object != rollOverMesh ) {
|
|
|
-
|
|
|
- return intersector;
|
|
|
+ function onDocumentMouseMove( event ) {
|
|
|
|
|
|
- }
|
|
|
+ event.preventDefault();
|
|
|
|
|
|
- }
|
|
|
+ vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
|
|
|
+ vector.unproject( camera );
|
|
|
|
|
|
- return null;
|
|
|
+ raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );
|
|
|
|
|
|
- }
|
|
|
+ var intersects = raycaster.intersectObjects( objects );
|
|
|
|
|
|
- function setVoxelPosition( intersector ) {
|
|
|
+ if ( intersects.length > 0 ) {
|
|
|
|
|
|
- if ( intersector.face === null ) {
|
|
|
+ var intersect = intersects[ 0 ];
|
|
|
|
|
|
- console.log( intersector )
|
|
|
+ rollOverMesh.position.copy( intersect.point ).add( intersect.face.normal );
|
|
|
+ rollOverMesh.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
|
|
|
|
|
|
}
|
|
|
|
|
|
- normalMatrix.getNormalMatrix( intersector.object.matrixWorld );
|
|
|
-
|
|
|
- tmpVec.copy( intersector.face.normal );
|
|
|
- tmpVec.applyMatrix3( normalMatrix ).normalize();
|
|
|
-
|
|
|
- voxelPosition.addVectors( intersector.point, tmpVec );
|
|
|
- voxelPosition.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
|
|
|
+ render();
|
|
|
|
|
|
}
|
|
|
|
|
|
- function onDocumentMouseMove( event ) {
|
|
|
+ function onDocumentMouseDown( event ) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
- mouse2D.x = ( event.clientX / window.innerWidth ) * 2 - 1;
|
|
|
- mouse2D.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
|
|
|
+ vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
|
|
|
+ vector.unproject( camera );
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- function onDocumentMouseDown( event ) {
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
+ raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );
|
|
|
|
|
|
var intersects = raycaster.intersectObjects( objects );
|
|
|
|
|
|
if ( intersects.length > 0 ) {
|
|
|
|
|
|
- intersector = getRealIntersector( intersects );
|
|
|
+ var intersect = intersects[ 0 ];
|
|
|
|
|
|
// delete cube
|
|
|
|
|
|
if ( isShiftDown ) {
|
|
|
|
|
|
- if ( intersector.object != plane ) {
|
|
|
+ if ( intersect.object != plane ) {
|
|
|
|
|
|
- scene.remove( intersector.object );
|
|
|
+ scene.remove( intersect.object );
|
|
|
|
|
|
- objects.splice( objects.indexOf( intersector.object ), 1 );
|
|
|
+ objects.splice( objects.indexOf( intersect.object ), 1 );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -220,13 +196,9 @@
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- intersector = getRealIntersector( intersects );
|
|
|
- setVoxelPosition( intersector );
|
|
|
-
|
|
|
var voxel = new THREE.Mesh( cubeGeo, cubeMaterial );
|
|
|
- voxel.position.copy( voxelPosition );
|
|
|
- voxel.matrixAutoUpdate = false;
|
|
|
- voxel.updateMatrix();
|
|
|
+ voxel.position.copy( intersect.point ).add( intersect.face.normal );
|
|
|
+ voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
|
|
|
scene.add( voxel );
|
|
|
|
|
|
objects.push( voxel );
|
|
@@ -241,7 +213,6 @@
|
|
|
switch( event.keyCode ) {
|
|
|
|
|
|
case 16: isShiftDown = true; break;
|
|
|
- case 17: isCtrlDown = true; break;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -252,53 +223,13 @@
|
|
|
switch ( event.keyCode ) {
|
|
|
|
|
|
case 16: isShiftDown = false; break;
|
|
|
- case 17: isCtrlDown = false; break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- //
|
|
|
-
|
|
|
- function animate() {
|
|
|
-
|
|
|
- requestAnimationFrame( animate );
|
|
|
-
|
|
|
- render();
|
|
|
- stats.update();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
function render() {
|
|
|
|
|
|
- if ( isCtrlDown ) {
|
|
|
-
|
|
|
- theta += mouse2D.x * 1.5;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- raycaster = projector.pickingRay( mouse2D.clone(), camera );
|
|
|
-
|
|
|
- var intersects = raycaster.intersectObjects( objects );
|
|
|
-
|
|
|
- if ( intersects.length > 0 ) {
|
|
|
-
|
|
|
- intersector = getRealIntersector( intersects );
|
|
|
-
|
|
|
- if ( intersector ) {
|
|
|
-
|
|
|
- setVoxelPosition( intersector );
|
|
|
- rollOverMesh.position.copy( voxelPosition );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- camera.position.x = 1400 * Math.sin( THREE.Math.degToRad( theta ) );
|
|
|
- camera.position.z = 1400 * Math.cos( THREE.Math.degToRad( theta ) );
|
|
|
-
|
|
|
- camera.lookAt( scene.position );
|
|
|
-
|
|
|
renderer.render( scene, camera );
|
|
|
|
|
|
}
|