123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /*
- * @author zz85 / https://github.com/zz85
- * Running this will allow you to drag three.js objects around the screen.
- */
- THREE.DragControls = function( _camera, _objects, _domElement ) {
- var _projector = new THREE.Projector();
- var _raycaster = new THREE.Raycaster();
- var _mouse = new THREE.Vector3(),
- _offset = new THREE.Vector3();
- var _selected, _hovered;
- var p3subp1 = new THREE.Vector3();
- var targetposition = new THREE.Vector3();
- var zerovector = new THREE.Vector3();
- this.enabled = false;
- /* Custom Event Handling */
- var _listeners = {
- };
- var me = this;
- this.on = function( event, handler ) {
-
- if ( ! _listeners[ event ] ) _listeners[ event ] = [];
- _listeners[ event ].push( handler );
- return me;
-
- };
- this.off = function( event, handler ) {
-
- var l = _listeners[ event ];
- if ( ! l ) return me;
- if ( l.indexOf( handler ) > - 1 ) {
-
- l.splice( handler, 1 );
-
- }
- return me;
- };
- var notify = function( event, data, member ) {
-
- var l = _listeners[ event ];
- if ( ! l ) return;
- if ( ! member ) {
-
- for ( var i = 0; i < l.length; i ++ ) {
-
- l[ i ]( data );
-
- }
-
- }
-
- };
- this.setObjects = function( objects ) {
-
- if ( objects instanceof THREE.Scene ) {
-
- _objects = objects.children;
-
- } else {
-
- _objects = objects;
-
- }
-
- };
- this.setObjects( _objects );
- this.activate = function() {
-
- _domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
- _domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
- _domElement.addEventListener( 'mouseup', onDocumentMouseUp, false );
-
- };
- this.deactivate = function() {
-
- _domElement.removeEventListener( 'mousemove', onDocumentMouseMove, false );
- _domElement.removeEventListener( 'mousedown', onDocumentMouseDown, false );
- _domElement.removeEventListener( 'mouseup', onDocumentMouseUp, false );
-
- };
- this.dispose = function() {
- me.deactivate();
- };
- this.activate();
- function onDocumentMouseMove( event ) {
- event.preventDefault();
- _mouse.x = ( event.clientX / _domElement.width ) * 2 - 1;
- _mouse.y = - ( event.clientY / _domElement.height ) * 2 + 1;
- _raycaster.setFromCamera( _mouse, _camera );
- var ray = _raycaster.ray;
- if ( _selected && me.enabled ) {
-
- var normal = _selected.normal;
- // I found this article useful about plane-line intersections
- // http://paulbourke.net/geometry/planeline/
- var denom = normal.dot( ray.direction );
- if ( denom == 0 ) {
- // bail
- console.log( 'no or infinite solutions' );
- return;
-
- }
- var num = normal.dot( p3subp1.copy( _selected.point ).sub( ray.origin ) );
- var u = num / denom;
- targetposition.copy( ray.direction ).multiplyScalar( u ).add( ray.origin ).sub( _offset );
- // _selected.object.position.copy(targetposition);
- var xLock, yLock, zLock = false;
- var moveX, moveY, moveZ;
-
- if ( xLock ) {
-
- moveX = true;
- moveY = false;
- moveZ = false;
-
- } else if ( yLock ) {
-
- moveX = false;
- moveY = true;
- moveZ = false;
-
- } else {
-
- moveX = moveY = moveZ = true;
-
- }
- // Reverse Matrix?
- if ( moveX ) _selected.object.position.x = targetposition.x;
- if ( moveY ) _selected.object.position.y = targetposition.y;
- if ( moveZ ) _selected.object.position.z = targetposition.z;
- notify( 'drag', _selected );
- return;
- }
- _raycaster.setFromCamera( _mouse, _camera );
- var intersects = _raycaster.intersectObjects( _objects );
- if ( intersects.length > 0 ) {
- _domElement.style.cursor = 'pointer';
- _hovered = intersects[ 0 ];
- notify( 'hoveron', _hovered );
- } else {
-
- notify( 'hoveroff', _hovered );
- _hovered = null;
- _domElement.style.cursor = 'auto';
- }
- }
- function onDocumentMouseDown( event ) {
- event.preventDefault();
- _mouse.x = ( event.clientX / _domElement.width ) * 2 - 1;
- _mouse.y = - ( event.clientY / _domElement.height ) * 2 + 1;
- _raycaster.setFromCamera( _mouse, _camera );
- var intersects = _raycaster.intersectObjects( _objects );
- var ray = _raycaster.ray;
- var normal = ray.direction; // normal ray to the camera position
- if ( intersects.length > 0 ) {
-
- _selected = intersects[ 0 ];
- _selected.ray = ray;
- _selected.normal = normal ;
- _offset.copy( _selected.point ).sub( _selected.object.position );
- _domElement.style.cursor = 'move';
- notify( 'dragstart', _selected );
- }
- }
- function onDocumentMouseUp( event ) {
- event.preventDefault();
- if ( _selected ) {
- notify( 'dragend', _selected );
- _selected = null;
-
- }
- _domElement.style.cursor = 'auto';
- }
- }
|