Doodle3D-Slicer/three.js-master/editor_slicer/js/Viewport.js
2015-06-12 21:19:56 +02:00

624 lines
11 KiB
JavaScript
Executable File

/**
* @author mrdoob / http://mrdoob.com/
*/
var Viewport = function ( editor ) {
var signals = editor.signals;
var container = new UI.Panel();
container.setId( 'viewport' );
container.setPosition( 'absolute' );
container.add( new Viewport.Info( editor ) );
var scene = editor.scene;
var sceneHelpers = editor.sceneHelpers;
var objects = [];
// helpers
var grid = new THREE.GridHelper( 500, 25 );
sceneHelpers.add( grid );
//
var camera = editor.camera;
camera.position.fromArray( editor.config.getKey( 'camera/position' ) );
camera.lookAt( new THREE.Vector3().fromArray( editor.config.getKey( 'camera/target' ) ) );
//
var selectionBox = new THREE.BoxHelper();
selectionBox.material.depthTest = false;
selectionBox.material.transparent = true;
selectionBox.visible = false;
sceneHelpers.add( selectionBox );
var transformControls = new THREE.TransformControls( camera, container.dom );
transformControls.addEventListener( 'change', function () {
var object = transformControls.object;
if ( object !== undefined ) {
if ( editor.helpers[ object.id ] !== undefined ) {
editor.helpers[ object.id ].update();
}
}
render();
} );
transformControls.addEventListener( 'mouseDown', function () {
controls.enabled = false;
} );
transformControls.addEventListener( 'mouseUp', function () {
signals.objectChanged.dispatch( transformControls.object );
controls.enabled = true;
} );
sceneHelpers.add( transformControls );
// fog
var oldFogType = "None";
var oldFogColor = 0xaaaaaa;
var oldFogNear = 1;
var oldFogFar = 5000;
var oldFogDensity = 0.00025;
// object picking
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
// events
var getIntersects = function ( point, object ) {
mouse.set( ( point.x * 2 ) - 1, - ( point.y * 2 ) + 1 );
raycaster.setFromCamera( mouse, camera );
if ( object instanceof Array ) {
return raycaster.intersectObjects( object );
}
return raycaster.intersectObject( object );
};
var onDownPosition = new THREE.Vector2();
var onUpPosition = new THREE.Vector2();
var onDoubleClickPosition = new THREE.Vector2();
var getMousePosition = function ( dom, x, y ) {
var rect = dom.getBoundingClientRect();
return [ ( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height ];
};
var handleClick = function () {
if ( onDownPosition.distanceTo( onUpPosition ) == 0 ) {
var intersects = getIntersects( onUpPosition, objects );
if ( intersects.length > 0 ) {
var object = intersects[ 0 ].object;
if ( object.userData.object !== undefined ) {
// helper
editor.select( object.userData.object );
} else {
editor.select( object );
}
} else {
editor.select( null );
}
render();
}
};
var onMouseDown = function ( event ) {
event.preventDefault();
var array = getMousePosition( container.dom, event.clientX, event.clientY );
onDownPosition.fromArray( array );
document.addEventListener( 'mouseup', onMouseUp, false );
};
var onMouseUp = function ( event ) {
var array = getMousePosition( container.dom, event.clientX, event.clientY );
onUpPosition.fromArray( array );
handleClick();
document.removeEventListener( 'mouseup', onMouseUp, false );
};
var onTouchStart = function ( event ) {
var touch = event.changedTouches[ 0 ];
var array = getMousePosition( container.dom, touch.clientX, touch.clientY );
onDownPosition.fromArray( array );
document.addEventListener( 'touchend', onTouchEnd, false );
};
var onTouchEnd = function ( event ) {
var touch = event.changedTouches[ 0 ];
var array = getMousePosition( container.dom, touch.clientX, touch.clientY );
onUpPosition.fromArray( array );
handleClick();
document.removeEventListener( 'touchend', onTouchEnd, false );
};
var onDoubleClick = function ( event ) {
var array = getMousePosition( container.dom, event.clientX, event.clientY );
onDoubleClickPosition.fromArray( array );
var intersects = getIntersects( onDoubleClickPosition, objects );
if ( intersects.length > 0 ) {
var intersect = intersects[ 0 ];
signals.objectFocused.dispatch( intersect.object );
}
};
container.dom.addEventListener( 'mousedown', onMouseDown, false );
container.dom.addEventListener( 'touchstart', onTouchStart, false );
container.dom.addEventListener( 'dblclick', onDoubleClick, false );
// controls need to be added *after* main logic,
// otherwise controls.enabled doesn't work.
var controls = new THREE.EditorControls( camera, container.dom );
controls.center.fromArray( editor.config.getKey( 'camera/target' ) );
controls.addEventListener( 'change', function () {
transformControls.update();
signals.cameraChanged.dispatch( camera );
} );
// signals
signals.editorCleared.add( function () {
controls.center.set( 0, 0, 0 );
render();
} );
signals.themeChanged.add( function ( value ) {
switch ( value ) {
case 'css/light.css':
grid.setColors( 0x444444, 0x888888 );
clearColor = 0xaaaaaa;
break;
case 'css/dark.css':
grid.setColors( 0xbbbbbb, 0x888888 );
clearColor = 0x333333;
break;
}
renderer.setClearColor( clearColor );
render();
} );
signals.transformModeChanged.add( function ( mode ) {
transformControls.setMode( mode );
} );
signals.snapChanged.add( function ( dist ) {
transformControls.setSnap( dist );
} );
signals.spaceChanged.add( function ( space ) {
transformControls.setSpace( space );
} );
signals.rendererChanged.add( function ( type, antialias ) {
container.dom.removeChild( renderer.domElement );
renderer = createRenderer( type, antialias );
renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
container.dom.appendChild( renderer.domElement );
render();
} );
signals.sceneGraphChanged.add( function () {
render();
} );
var saveTimeout;
signals.cameraChanged.add( function () {
if ( saveTimeout !== undefined ) {
clearTimeout( saveTimeout );
}
saveTimeout = setTimeout( function () {
editor.config.setKey(
'camera/position', camera.position.toArray(),
'camera/target', controls.center.toArray()
);
}, 1000 );
render();
} );
signals.objectSelected.add( function ( object ) {
selectionBox.visible = false;
transformControls.detach();
if ( object !== null ) {
if ( object.geometry !== undefined &&
object instanceof THREE.Sprite === false ) {
selectionBox.update( object );
selectionBox.visible = true;
}
transformControls.attach( object );
}
render();
} );
signals.objectFocused.add( function ( object ) {
controls.focus( object );
} );
signals.geometryChanged.add( function ( geometry ) {
selectionBox.update( editor.selected );
render();
} );
signals.objectAdded.add( function ( object ) {
var materialsNeedUpdate = false;
object.traverse( function ( child ) {
if ( child instanceof THREE.Light ) materialsNeedUpdate = true;
objects.push( child );
} );
if ( materialsNeedUpdate === true ) updateMaterials();
} );
signals.objectChanged.add( function ( object ) {
transformControls.update();
if ( object instanceof THREE.PerspectiveCamera ) {
object.updateProjectionMatrix();
}
if ( editor.helpers[ object.id ] !== undefined ) {
editor.helpers[ object.id ].update();
}
render();
} );
signals.objectRemoved.add( function ( object ) {
var materialsNeedUpdate = false;
object.traverse( function ( child ) {
if ( child instanceof THREE.Light ) materialsNeedUpdate = true;
objects.splice( objects.indexOf( child ), 1 );
} );
if ( materialsNeedUpdate === true ) updateMaterials();
} );
signals.helperAdded.add( function ( object ) {
objects.push( object.getObjectByName( 'picker' ) );
} );
signals.helperRemoved.add( function ( object ) {
objects.splice( objects.indexOf( object.getObjectByName( 'picker' ) ), 1 );
} );
signals.materialChanged.add( function ( material ) {
render();
} );
signals.fogTypeChanged.add( function ( fogType ) {
if ( fogType !== oldFogType ) {
if ( fogType === "None" ) {
scene.fog = null;
} else if ( fogType === "Fog" ) {
scene.fog = new THREE.Fog( oldFogColor, oldFogNear, oldFogFar );
} else if ( fogType === "FogExp2" ) {
scene.fog = new THREE.FogExp2( oldFogColor, oldFogDensity );
}
updateMaterials();
oldFogType = fogType;
}
render();
} );
signals.fogColorChanged.add( function ( fogColor ) {
oldFogColor = fogColor;
updateFog( scene );
render();
} );
signals.fogParametersChanged.add( function ( near, far, density ) {
oldFogNear = near;
oldFogFar = far;
oldFogDensity = density;
updateFog( scene );
render();
} );
signals.windowResize.add( function () {
camera.aspect = container.dom.offsetWidth / container.dom.offsetHeight;
camera.updateProjectionMatrix();
renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
render();
} );
signals.showGridChanged.add( function ( showGrid ) {
grid.visible = showGrid;
render();
} );
var animations = [];
signals.playAnimation.add( function ( animation ) {
animations.push( animation );
} );
signals.stopAnimation.add( function ( animation ) {
var index = animations.indexOf( animation );
if ( index !== -1 ) {
animations.splice( index, 1 );
}
} );
//
var createRenderer = function ( type, antialias ) {
if ( type === 'WebGLRenderer' && System.support.webgl === false ) {
type = 'CanvasRenderer';
}
var renderer = new THREE[ type ]( { antialias: antialias } );
renderer.setClearColor( clearColor );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.autoClear = false;
renderer.autoUpdateScene = false;
return renderer;
};
var clearColor;
var renderer = createRenderer( editor.config.getKey( 'project/renderer' ), editor.config.getKey( 'project/renderer/antialias' ) );
container.dom.appendChild( renderer.domElement );
animate();
//
function updateMaterials() {
editor.scene.traverse( function ( node ) {
if ( node.material ) {
node.material.needsUpdate = true;
if ( node.material instanceof THREE.MeshFaceMaterial ) {
for ( var i = 0; i < node.material.materials.length; i ++ ) {
node.material.materials[ i ].needsUpdate = true;
}
}
}
} );
}
function updateFog( root ) {
if ( root.fog ) {
root.fog.color.setHex( oldFogColor );
if ( root.fog.near !== undefined ) root.fog.near = oldFogNear;
if ( root.fog.far !== undefined ) root.fog.far = oldFogFar;
if ( root.fog.density !== undefined ) root.fog.density = oldFogDensity;
}
}
function animate() {
requestAnimationFrame( animate );
// animations
if ( THREE.AnimationHandler.animations.length > 0 ) {
THREE.AnimationHandler.update( 0.016 );
for ( var i = 0, l = sceneHelpers.children.length; i < l; i ++ ) {
var helper = sceneHelpers.children[ i ];
if ( helper instanceof THREE.SkeletonHelper ) {
helper.update();
}
}
render();
}
}
function render() {
sceneHelpers.updateMatrixWorld();
scene.updateMatrixWorld();
renderer.clear();
renderer.render( scene, camera );
if ( renderer instanceof THREE.RaytracingRenderer === false ) {
renderer.render( sceneHelpers, camera );
}
}
return container;
}