technical debt
parent
606e83e2d6
commit
67d6bf8090
|
@ -0,0 +1,754 @@
|
|||
import {
|
||||
EventDispatcher,
|
||||
MOUSE,
|
||||
Quaternion,
|
||||
Vector2,
|
||||
Vector3
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
var TrackballControls = function ( object, domElement ) {
|
||||
|
||||
if ( domElement === undefined ) console.warn( 'THREE.TrackballControls: The second parameter "domElement" is now mandatory.' );
|
||||
if ( domElement === document ) console.error( 'THREE.TrackballControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' );
|
||||
|
||||
var scope = this;
|
||||
var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
|
||||
|
||||
this.object = object;
|
||||
this.domElement = domElement;
|
||||
|
||||
// API
|
||||
|
||||
this.enabled = true;
|
||||
|
||||
this.screen = { left: 0, top: 0, width: 0, height: 0 };
|
||||
|
||||
this.rotateSpeed = 1.0;
|
||||
this.zoomSpeed = 1.2;
|
||||
this.panSpeed = 0.3;
|
||||
|
||||
this.noRotate = false;
|
||||
this.noZoom = false;
|
||||
this.noPan = false;
|
||||
|
||||
this.staticMoving = false;
|
||||
this.dynamicDampingFactor = 0.2;
|
||||
|
||||
this.minDistance = 0;
|
||||
this.maxDistance = Infinity;
|
||||
|
||||
this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
|
||||
|
||||
this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
|
||||
|
||||
// internals
|
||||
|
||||
this.target = new Vector3();
|
||||
|
||||
var EPS = 0.000001;
|
||||
|
||||
var lastPosition = new Vector3();
|
||||
var lastZoom = 1;
|
||||
|
||||
var _state = STATE.NONE,
|
||||
_keyState = STATE.NONE,
|
||||
|
||||
_eye = new Vector3(),
|
||||
|
||||
_movePrev = new Vector2(),
|
||||
_moveCurr = new Vector2(),
|
||||
|
||||
_lastAxis = new Vector3(),
|
||||
_lastAngle = 0,
|
||||
|
||||
_zoomStart = new Vector2(),
|
||||
_zoomEnd = new Vector2(),
|
||||
|
||||
_touchZoomDistanceStart = 0,
|
||||
_touchZoomDistanceEnd = 0,
|
||||
|
||||
_panStart = new Vector2(),
|
||||
_panEnd = new Vector2();
|
||||
|
||||
// for reset
|
||||
|
||||
this.target0 = this.target.clone();
|
||||
this.position0 = this.object.position.clone();
|
||||
this.up0 = this.object.up.clone();
|
||||
this.zoom0 = this.object.zoom;
|
||||
|
||||
// events
|
||||
|
||||
var changeEvent = { type: 'change' };
|
||||
var startEvent = { type: 'start' };
|
||||
var endEvent = { type: 'end' };
|
||||
|
||||
|
||||
// methods
|
||||
|
||||
this.handleResize = function () {
|
||||
|
||||
var box = scope.domElement.getBoundingClientRect();
|
||||
// adjustments come from similar code in the jquery offset() function
|
||||
var d = scope.domElement.ownerDocument.documentElement;
|
||||
scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
|
||||
scope.screen.top = box.top + window.pageYOffset - d.clientTop;
|
||||
scope.screen.width = box.width;
|
||||
scope.screen.height = box.height;
|
||||
|
||||
};
|
||||
|
||||
var getMouseOnScreen = ( function () {
|
||||
|
||||
var vector = new Vector2();
|
||||
|
||||
return function getMouseOnScreen( pageX, pageY ) {
|
||||
|
||||
vector.set(
|
||||
( pageX - scope.screen.left ) / scope.screen.width,
|
||||
( pageY - scope.screen.top ) / scope.screen.height
|
||||
);
|
||||
|
||||
return vector;
|
||||
|
||||
};
|
||||
|
||||
}() );
|
||||
|
||||
var getMouseOnCircle = ( function () {
|
||||
|
||||
var vector = new Vector2();
|
||||
|
||||
return function getMouseOnCircle( pageX, pageY ) {
|
||||
|
||||
vector.set(
|
||||
( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ) ),
|
||||
( ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width ) // screen.width intentional
|
||||
);
|
||||
|
||||
return vector;
|
||||
|
||||
};
|
||||
|
||||
}() );
|
||||
|
||||
this.rotateCamera = ( function () {
|
||||
|
||||
var axis = new Vector3(),
|
||||
quaternion = new Quaternion(),
|
||||
eyeDirection = new Vector3(),
|
||||
objectUpDirection = new Vector3(),
|
||||
objectSidewaysDirection = new Vector3(),
|
||||
moveDirection = new Vector3(),
|
||||
angle;
|
||||
|
||||
return function rotateCamera() {
|
||||
|
||||
moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
|
||||
angle = moveDirection.length();
|
||||
|
||||
if ( angle ) {
|
||||
|
||||
_eye.copy( scope.object.position ).sub( scope.target );
|
||||
|
||||
eyeDirection.copy( _eye ).normalize();
|
||||
objectUpDirection.copy( scope.object.up ).normalize();
|
||||
objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();
|
||||
|
||||
objectUpDirection.setLength( _moveCurr.y - _movePrev.y );
|
||||
objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x );
|
||||
|
||||
moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) );
|
||||
|
||||
axis.crossVectors( moveDirection, _eye ).normalize();
|
||||
|
||||
angle *= scope.rotateSpeed;
|
||||
quaternion.setFromAxisAngle( axis, angle );
|
||||
|
||||
_eye.applyQuaternion( quaternion );
|
||||
scope.object.up.applyQuaternion( quaternion );
|
||||
|
||||
_lastAxis.copy( axis );
|
||||
_lastAngle = angle;
|
||||
|
||||
} else if ( ! scope.staticMoving && _lastAngle ) {
|
||||
|
||||
_lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );
|
||||
_eye.copy( scope.object.position ).sub( scope.target );
|
||||
quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
|
||||
_eye.applyQuaternion( quaternion );
|
||||
scope.object.up.applyQuaternion( quaternion );
|
||||
|
||||
}
|
||||
|
||||
_movePrev.copy( _moveCurr );
|
||||
|
||||
};
|
||||
|
||||
}() );
|
||||
|
||||
|
||||
this.zoomCamera = function () {
|
||||
|
||||
var factor;
|
||||
|
||||
if ( _state === STATE.TOUCH_ZOOM_PAN ) {
|
||||
|
||||
factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
|
||||
_touchZoomDistanceStart = _touchZoomDistanceEnd;
|
||||
|
||||
if ( scope.object.isPerspectiveCamera ) {
|
||||
|
||||
_eye.multiplyScalar( factor );
|
||||
|
||||
} else if ( scope.object.isOrthographicCamera ) {
|
||||
|
||||
scope.object.zoom *= factor;
|
||||
scope.object.updateProjectionMatrix();
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( 'THREE.TrackballControls: Unsupported camera type' );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;
|
||||
|
||||
if ( factor !== 1.0 && factor > 0.0 ) {
|
||||
|
||||
if ( scope.object.isPerspectiveCamera ) {
|
||||
|
||||
_eye.multiplyScalar( factor );
|
||||
|
||||
} else if ( scope.object.isOrthographicCamera ) {
|
||||
|
||||
scope.object.zoom /= factor;
|
||||
scope.object.updateProjectionMatrix();
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( 'THREE.TrackballControls: Unsupported camera type' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( scope.staticMoving ) {
|
||||
|
||||
_zoomStart.copy( _zoomEnd );
|
||||
|
||||
} else {
|
||||
|
||||
_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.panCamera = ( function () {
|
||||
|
||||
var mouseChange = new Vector2(),
|
||||
objectUp = new Vector3(),
|
||||
pan = new Vector3();
|
||||
|
||||
return function panCamera() {
|
||||
|
||||
mouseChange.copy( _panEnd ).sub( _panStart );
|
||||
|
||||
if ( mouseChange.lengthSq() ) {
|
||||
|
||||
if ( scope.object.isOrthographicCamera ) {
|
||||
|
||||
var scale_x = ( scope.object.right - scope.object.left ) / scope.object.zoom / scope.domElement.clientWidth;
|
||||
var scale_y = ( scope.object.top - scope.object.bottom ) / scope.object.zoom / scope.domElement.clientWidth;
|
||||
|
||||
mouseChange.x *= scale_x;
|
||||
mouseChange.y *= scale_y;
|
||||
|
||||
}
|
||||
|
||||
mouseChange.multiplyScalar( _eye.length() * scope.panSpeed );
|
||||
|
||||
pan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x );
|
||||
pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );
|
||||
|
||||
scope.object.position.add( pan );
|
||||
scope.target.add( pan );
|
||||
|
||||
if ( scope.staticMoving ) {
|
||||
|
||||
_panStart.copy( _panEnd );
|
||||
|
||||
} else {
|
||||
|
||||
_panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( scope.dynamicDampingFactor ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}() );
|
||||
|
||||
this.checkDistances = function () {
|
||||
|
||||
if ( ! scope.noZoom || ! scope.noPan ) {
|
||||
|
||||
if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {
|
||||
|
||||
scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );
|
||||
_zoomStart.copy( _zoomEnd );
|
||||
|
||||
}
|
||||
|
||||
if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {
|
||||
|
||||
scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );
|
||||
_zoomStart.copy( _zoomEnd );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.update = function () {
|
||||
|
||||
_eye.subVectors( scope.object.position, scope.target );
|
||||
|
||||
if ( ! scope.noRotate ) {
|
||||
|
||||
scope.rotateCamera();
|
||||
|
||||
}
|
||||
|
||||
if ( ! scope.noZoom ) {
|
||||
|
||||
scope.zoomCamera();
|
||||
|
||||
}
|
||||
|
||||
if ( ! scope.noPan ) {
|
||||
|
||||
scope.panCamera();
|
||||
|
||||
}
|
||||
|
||||
scope.object.position.addVectors( scope.target, _eye );
|
||||
|
||||
if ( scope.object.isPerspectiveCamera ) {
|
||||
|
||||
scope.checkDistances();
|
||||
|
||||
scope.object.lookAt( scope.target );
|
||||
|
||||
if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {
|
||||
|
||||
scope.dispatchEvent( changeEvent );
|
||||
|
||||
lastPosition.copy( scope.object.position );
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope.object.isOrthographicCamera ) {
|
||||
|
||||
scope.object.lookAt( scope.target );
|
||||
|
||||
if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {
|
||||
|
||||
scope.dispatchEvent( changeEvent );
|
||||
|
||||
lastPosition.copy( scope.object.position );
|
||||
lastZoom = scope.object.zoom;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( 'THREE.TrackballControls: Unsupported camera type' );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.reset = function () {
|
||||
|
||||
_state = STATE.NONE;
|
||||
_keyState = STATE.NONE;
|
||||
|
||||
scope.target.copy( scope.target0 );
|
||||
scope.object.position.copy( scope.position0 );
|
||||
scope.object.up.copy( scope.up0 );
|
||||
scope.object.zoom = scope.zoom0;
|
||||
|
||||
scope.object.updateProjectionMatrix();
|
||||
|
||||
_eye.subVectors( scope.object.position, scope.target );
|
||||
|
||||
scope.object.lookAt( scope.target );
|
||||
|
||||
scope.dispatchEvent( changeEvent );
|
||||
|
||||
lastPosition.copy( scope.object.position );
|
||||
lastZoom = scope.object.zoom;
|
||||
|
||||
};
|
||||
|
||||
// listeners
|
||||
|
||||
function onPointerDown( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
switch ( event.pointerType ) {
|
||||
|
||||
case 'mouse':
|
||||
case 'pen':
|
||||
onMouseDown( event );
|
||||
break;
|
||||
|
||||
// TODO touch
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onPointerMove( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
switch ( event.pointerType ) {
|
||||
|
||||
case 'mouse':
|
||||
case 'pen':
|
||||
onMouseMove( event );
|
||||
break;
|
||||
|
||||
// TODO touch
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onPointerUp( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
switch ( event.pointerType ) {
|
||||
|
||||
case 'mouse':
|
||||
case 'pen':
|
||||
onMouseUp( event );
|
||||
break;
|
||||
|
||||
// TODO touch
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function keydown( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
window.removeEventListener( 'keydown', keydown );
|
||||
|
||||
if ( _keyState !== STATE.NONE ) {
|
||||
|
||||
return;
|
||||
|
||||
} else if ( event.keyCode === scope.keys[ STATE.ROTATE ] && ! scope.noRotate ) {
|
||||
|
||||
_keyState = STATE.ROTATE;
|
||||
|
||||
} else if ( event.keyCode === scope.keys[ STATE.ZOOM ] && ! scope.noZoom ) {
|
||||
|
||||
_keyState = STATE.ZOOM;
|
||||
|
||||
} else if ( event.keyCode === scope.keys[ STATE.PAN ] && ! scope.noPan ) {
|
||||
|
||||
_keyState = STATE.PAN;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function keyup() {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
_keyState = STATE.NONE;
|
||||
|
||||
window.addEventListener( 'keydown', keydown );
|
||||
|
||||
}
|
||||
|
||||
function onMouseDown( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if ( _state === STATE.NONE ) {
|
||||
|
||||
switch ( event.button ) {
|
||||
|
||||
case scope.mouseButtons.LEFT:
|
||||
_state = STATE.ROTATE;
|
||||
break;
|
||||
|
||||
case scope.mouseButtons.MIDDLE:
|
||||
_state = STATE.ZOOM;
|
||||
break;
|
||||
|
||||
case scope.mouseButtons.RIGHT:
|
||||
_state = STATE.PAN;
|
||||
break;
|
||||
|
||||
default:
|
||||
_state = STATE.NONE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
|
||||
|
||||
if ( state === STATE.ROTATE && ! scope.noRotate ) {
|
||||
|
||||
_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
|
||||
_movePrev.copy( _moveCurr );
|
||||
|
||||
} else if ( state === STATE.ZOOM && ! scope.noZoom ) {
|
||||
|
||||
_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
|
||||
_zoomEnd.copy( _zoomStart );
|
||||
|
||||
} else if ( state === STATE.PAN && ! scope.noPan ) {
|
||||
|
||||
_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
|
||||
_panEnd.copy( _panStart );
|
||||
|
||||
}
|
||||
|
||||
scope.domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove );
|
||||
scope.domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp );
|
||||
|
||||
scope.dispatchEvent( startEvent );
|
||||
|
||||
}
|
||||
|
||||
function onMouseMove( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
var state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
|
||||
|
||||
if ( state === STATE.ROTATE && ! scope.noRotate ) {
|
||||
|
||||
_movePrev.copy( _moveCurr );
|
||||
_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
|
||||
|
||||
} else if ( state === STATE.ZOOM && ! scope.noZoom ) {
|
||||
|
||||
_zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
|
||||
|
||||
} else if ( state === STATE.PAN && ! scope.noPan ) {
|
||||
|
||||
_panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onMouseUp( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
_state = STATE.NONE;
|
||||
|
||||
scope.domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove );
|
||||
scope.domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp );
|
||||
|
||||
scope.dispatchEvent( endEvent );
|
||||
|
||||
}
|
||||
|
||||
function mousewheel( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
if ( scope.noZoom === true ) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
switch ( event.deltaMode ) {
|
||||
|
||||
case 2:
|
||||
// Zoom in pages
|
||||
_zoomStart.y -= event.deltaY * 0.025;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Zoom in lines
|
||||
_zoomStart.y -= event.deltaY * 0.01;
|
||||
break;
|
||||
|
||||
default:
|
||||
// undefined, 0, assume pixels
|
||||
_zoomStart.y -= event.deltaY * 0.00025;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
scope.dispatchEvent( startEvent );
|
||||
scope.dispatchEvent( endEvent );
|
||||
|
||||
}
|
||||
|
||||
function touchstart( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
switch ( event.touches.length ) {
|
||||
|
||||
case 1:
|
||||
_state = STATE.TOUCH_ROTATE;
|
||||
_moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
|
||||
_movePrev.copy( _moveCurr );
|
||||
break;
|
||||
|
||||
default: // 2 or more
|
||||
_state = STATE.TOUCH_ZOOM_PAN;
|
||||
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
|
||||
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
|
||||
_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
|
||||
|
||||
var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
|
||||
var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
|
||||
_panStart.copy( getMouseOnScreen( x, y ) );
|
||||
_panEnd.copy( _panStart );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
scope.dispatchEvent( startEvent );
|
||||
|
||||
}
|
||||
|
||||
function touchmove( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
switch ( event.touches.length ) {
|
||||
|
||||
case 1:
|
||||
_movePrev.copy( _moveCurr );
|
||||
_moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
|
||||
break;
|
||||
|
||||
default: // 2 or more
|
||||
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
|
||||
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
|
||||
_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
|
||||
|
||||
var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
|
||||
var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
|
||||
_panEnd.copy( getMouseOnScreen( x, y ) );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function touchend( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
switch ( event.touches.length ) {
|
||||
|
||||
case 0:
|
||||
_state = STATE.NONE;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_state = STATE.TOUCH_ROTATE;
|
||||
_moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
|
||||
_movePrev.copy( _moveCurr );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
scope.dispatchEvent( endEvent );
|
||||
|
||||
}
|
||||
|
||||
function contextmenu( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
this.dispose = function () {
|
||||
|
||||
scope.domElement.removeEventListener( 'contextmenu', contextmenu );
|
||||
|
||||
scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
|
||||
scope.domElement.removeEventListener( 'wheel', mousewheel );
|
||||
|
||||
scope.domElement.removeEventListener( 'touchstart', touchstart );
|
||||
scope.domElement.removeEventListener( 'touchend', touchend );
|
||||
scope.domElement.removeEventListener( 'touchmove', touchmove );
|
||||
|
||||
scope.domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove );
|
||||
scope.domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp );
|
||||
|
||||
window.removeEventListener( 'keydown', keydown );
|
||||
window.removeEventListener( 'keyup', keyup );
|
||||
|
||||
};
|
||||
|
||||
this.domElement.addEventListener( 'contextmenu', contextmenu );
|
||||
|
||||
this.domElement.addEventListener( 'pointerdown', onPointerDown );
|
||||
this.domElement.addEventListener( 'wheel', mousewheel );
|
||||
|
||||
this.domElement.addEventListener( 'touchstart', touchstart );
|
||||
this.domElement.addEventListener( 'touchend', touchend );
|
||||
this.domElement.addEventListener( 'touchmove', touchmove );
|
||||
|
||||
this.domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove );
|
||||
this.domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp );
|
||||
|
||||
window.addEventListener( 'keydown', keydown );
|
||||
window.addEventListener( 'keyup', keyup );
|
||||
|
||||
this.handleResize();
|
||||
|
||||
// force an update at start
|
||||
this.update();
|
||||
|
||||
};
|
||||
|
||||
TrackballControls.prototype = Object.create( EventDispatcher.prototype );
|
||||
TrackballControls.prototype.constructor = TrackballControls;
|
||||
|
||||
export { TrackballControls };
|
104
src/Scene.js
104
src/Scene.js
|
@ -7,7 +7,7 @@ import { Sketch } from './Sketch'
|
|||
import Stats from '../lib/stats.module.js';
|
||||
|
||||
import { extrude } from './extrude'
|
||||
import { onHover, onPick } from './mouseEvents';
|
||||
import { onHover, onPick, setHover } from './mouseEvents';
|
||||
import { _vec2, _vec3, color, awaitSelection, ptObj } from './shared'
|
||||
|
||||
import { AxesHelper } from './axes'
|
||||
|
@ -50,7 +50,6 @@ export class Scene {
|
|||
cameraDist * Math.cos(xzAngle)
|
||||
);
|
||||
|
||||
// const controls = new OrbitControls(camera, view1Elem);
|
||||
const controls = new TrackballControls(this.camera, this.canvas);
|
||||
controls.target.set(0, 0, 0);
|
||||
controls.update();
|
||||
|
@ -126,6 +125,7 @@ export class Scene {
|
|||
this.extrude = extrude.bind(this);
|
||||
this.onHover = onHover.bind(this);
|
||||
this.onPick = onPick.bind(this);
|
||||
this.setHover = setHover.bind(this);
|
||||
this.awaitSelection = awaitSelection.bind(this);
|
||||
|
||||
this.obj3d.addEventListener('change', this.render);
|
||||
|
@ -184,7 +184,7 @@ export class Scene {
|
|||
} else if (k[0] == 'm') {
|
||||
|
||||
entries[k] = loader.parse(state.treeEntries.byId[k])
|
||||
console.log(entries[k])
|
||||
// console.log(entries[k])
|
||||
this.obj3d.add(entries[k])
|
||||
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ export class Scene {
|
|||
this.selected = []
|
||||
|
||||
for (let x = 0; x < this.hovered.length; x++) {
|
||||
const obj = this.selected[x]
|
||||
const obj = this.hovered[x]
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.05
|
||||
|
@ -221,12 +221,84 @@ export class Scene {
|
|||
}
|
||||
|
||||
|
||||
hover(obj) {
|
||||
|
||||
if (typeof obj == 'object' && !this.selected.includes(obj)) {
|
||||
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.02
|
||||
obj.children[0].material.color.set(color['planeBorder'])
|
||||
} else {
|
||||
if (obj.userData.type == 'mesh') {
|
||||
obj.material.emissive.set(color.emissive)
|
||||
}
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (typeof obj == 'object' && !this.selected.includes(obj)) {
|
||||
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.02
|
||||
obj.children[0].material.color.set(color['planeBorder'])
|
||||
} else {
|
||||
if (obj.userData.type == 'mesh') {
|
||||
obj.material.emissive.set(color.emissive)
|
||||
}
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
|
||||
if (obj.userData.type == 'mesh') {
|
||||
obj.material.emissive.set(color.emissive)
|
||||
} else if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.02
|
||||
obj.children[0].material.color.set(color['planeBorder'])
|
||||
}
|
||||
|
||||
if (obj.userData.type == 'selpoint') {
|
||||
obj.visible = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (typeof obj == 'object') {
|
||||
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.06
|
||||
obj.children[0].material.color.set(hoverColor['planeBorder'])
|
||||
} else {
|
||||
if (obj.userData.type == 'mesh') {
|
||||
obj.material.emissive.set(hoverColor.emissive)
|
||||
}
|
||||
obj.material.color.set(hoverColor[obj.userData.type])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
subtract(m1, m2) {
|
||||
let bspA = CSG.fromMesh(m1)
|
||||
let bspB = CSG.fromMesh(m2)
|
||||
m1.traverse(e => e.layers.disableAll())
|
||||
m2.traverse(e => e.layers.disableAll())
|
||||
m1.visible = false
|
||||
m2.visible = false
|
||||
m1.traverse(e => e.layers.disable(1))
|
||||
m2.traverse(e => e.layers.disable(1))
|
||||
|
||||
// // Subtract one bsp from the other via .subtract... other supported modes are .union and .intersect
|
||||
|
||||
|
@ -241,9 +313,8 @@ export class Scene {
|
|||
|
||||
|
||||
|
||||
const vertices = new THREE.Points(mesh.geometry, new THREE.PointsMaterial());
|
||||
const vertices = new THREE.Points(mesh.geometry, new THREE.PointsMaterial({ size: 0 }));
|
||||
vertices.userData.type = 'point'
|
||||
vertices.layers.disable(0)
|
||||
vertices.layers.enable(1)
|
||||
|
||||
// mesh.add(line)
|
||||
|
@ -251,6 +322,15 @@ export class Scene {
|
|||
|
||||
|
||||
sc.obj3d.add(mesh)
|
||||
|
||||
this.store.dispatch({
|
||||
type: 'set-entry-visibility', obj: {
|
||||
[m1.name]: false,
|
||||
[m2.name]: false,
|
||||
[mesh.name]: true,
|
||||
}
|
||||
})
|
||||
|
||||
return mesh
|
||||
}
|
||||
}
|
||||
|
@ -333,18 +413,18 @@ async function addSketch() {
|
|||
|
||||
this.clearSelection()
|
||||
|
||||
sketch.activate()
|
||||
this.activeSketch = sketch
|
||||
|
||||
sketch.obj3d.addEventListener('change', this.render);
|
||||
this.render()
|
||||
console.log('render')
|
||||
this.store.dispatch({ type: 'rx-sketch', obj: sketch })
|
||||
|
||||
sketch.activate()
|
||||
|
||||
this.render()
|
||||
}
|
||||
|
||||
window.sc = new Scene(store)
|
||||
sc.loadState()
|
||||
// sc.loadState()
|
||||
|
||||
// sc.camera.layers.enable(1)
|
||||
// rc.layers.set(1)
|
|
@ -152,9 +152,11 @@ class Sketch {
|
|||
|
||||
this.setDimLines()
|
||||
|
||||
this.obj3d.traverse(e=>e.layers.enable(0))
|
||||
this.obj3d.traverse(e=>e.layers.enable(2))
|
||||
this.obj3d.visible = true
|
||||
this.scene.axes.matrix = this.obj3d.matrix
|
||||
this.scene.axes.visible = true
|
||||
this.scene.activeSketch = this
|
||||
|
||||
window.sketcher = this
|
||||
}
|
||||
|
@ -165,8 +167,10 @@ class Sketch {
|
|||
this.canvas.removeEventListener('pointermove', this.onHover)
|
||||
this.store.dispatch({ type: 'exit-sketch' })
|
||||
this.labelContainer.innerHTML = ""
|
||||
this.obj3d.traverse(e=>e.layers.disable(0))
|
||||
this.obj3d.visible = false
|
||||
this.obj3d.traverse(e=>e.layers.disable(2))
|
||||
this.scene.axes.visible = false
|
||||
this.scene.activeSketch = null
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ export async function drawDimension() {
|
|||
|
||||
line.userData.ids = selection.map(e => e.name)
|
||||
|
||||
|
||||
line.layers.enable(2)
|
||||
point.layers.enable(2)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ export function drawOnClick1(e) {
|
|||
this.toPush = drawPoint.call(this, mouseLoc)
|
||||
}
|
||||
|
||||
this.toPush.forEach(element => {
|
||||
element.layers.enable(2)
|
||||
});
|
||||
|
||||
this.updatePoint = this.obj3d.children.length
|
||||
this.obj3d.add(...this.toPush)
|
||||
this.linkedObjs.set(this.l_id, [this.mode, this.toPush.map(e => e.name)])
|
||||
|
|
|
@ -72,12 +72,10 @@ export function extrude(sketch) {
|
|||
|
||||
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
|
||||
|
||||
|
||||
// const material = new THREE.MeshLambertMaterial({
|
||||
const material = new THREE.MeshPhongMaterial({
|
||||
color: color.mesh,
|
||||
emissive: color.emissive,
|
||||
// flatShading:true,
|
||||
});
|
||||
|
||||
const mesh = new THREE.Mesh(geometry, material)
|
||||
|
@ -95,9 +93,14 @@ export function extrude(sketch) {
|
|||
|
||||
this.obj3d.add(mesh)
|
||||
|
||||
this.render()
|
||||
|
||||
this.store.dispatch({ type: 'rx-extrusion', mesh, sketchId: sketch.obj3d.name })
|
||||
|
||||
if (this.activeSketch == sketch) {
|
||||
this.activeSketch = null
|
||||
sketch.deactivate()
|
||||
}
|
||||
|
||||
this.render()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ export function onHover(e) {
|
|||
raycaster.layers.set(1)
|
||||
hoverPts = raycaster.intersectObjects(this.obj3d.children, true)
|
||||
} else {
|
||||
raycaster.layers.set(0)
|
||||
// raycaster.layers.set(0)
|
||||
raycaster.layers.set(2)
|
||||
hoverPts = raycaster.intersectObjects([...this.obj3d.children[1].children, ...this.obj3d.children])
|
||||
}
|
||||
|
||||
|
@ -58,12 +59,7 @@ export function onHover(e) {
|
|||
for (let x = 0; x < this.hovered.length; x++) { // first clear old hovers that are not selected
|
||||
const obj = this.hovered[x]
|
||||
if (typeof obj == 'object' && !this.selected.includes(obj)) {
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.02
|
||||
obj.children[0].material.color.set(color['planeBorder'])
|
||||
} else {
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
setHover(obj, 0)
|
||||
}
|
||||
}
|
||||
this.hovered = []
|
||||
|
@ -71,23 +67,14 @@ export function onHover(e) {
|
|||
for (let x = 0; x < idx.length; x++) {
|
||||
let obj = hoverPts[idx[x]].object
|
||||
|
||||
if (this.obj3d.userData.type == 'sketch') {
|
||||
obj.material.color.set(hoverColor[obj.userData.type])
|
||||
} else {
|
||||
|
||||
if (obj.userData.type == 'mesh') {
|
||||
obj.material.color.set(color['meshTempHover'])
|
||||
} else if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.06
|
||||
obj.children[0].material.color.set(hoverColor['planeBorder'])
|
||||
} else if (obj.userData.type == 'point') {
|
||||
setHover(obj, 1, false)
|
||||
|
||||
if (this.obj3d.userData.type != 'sketch' && obj.userData.type == 'point') {
|
||||
ptLoc = obj.geometry.attributes.position.array
|
||||
.slice(
|
||||
3 * hoverPts[idx[x]].index,
|
||||
3 * hoverPts[idx[x]].index + 3
|
||||
)
|
||||
|
||||
// const pp = this.obj3d.children[0].children[this.fptIdx % 3]
|
||||
const pp = this.obj3d.children[0].children[0]
|
||||
pp.geometry.attributes.position.array.set(ptLoc)
|
||||
|
@ -96,12 +83,8 @@ export function onHover(e) {
|
|||
pp.visible = true
|
||||
|
||||
obj = hoverPts[idx[x]].index
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.hovered.push(obj)
|
||||
}
|
||||
|
||||
|
@ -114,14 +97,12 @@ export function onHover(e) {
|
|||
|
||||
for (let x = 0; x < this.hovered.length; x++) {
|
||||
const obj = this.hovered[x]
|
||||
|
||||
if (typeof obj == 'object' && !this.selected.includes(obj)) {
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.02
|
||||
obj.children[0].material.color.set(color['planeBorder'])
|
||||
} else {
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
setHover(obj, 0)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
this.hovered = []
|
||||
|
||||
|
@ -145,12 +126,9 @@ export function onPick(e) {
|
|||
this.selected.push(obj)
|
||||
} else {
|
||||
if (typeof obj == 'object') {
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.06
|
||||
obj.children[0].material.color.set(hoverColor['planeBorder'])
|
||||
} else {
|
||||
obj.material.color.set(hoverColor[obj.userData.type])
|
||||
}
|
||||
|
||||
setHover(obj, 1)
|
||||
|
||||
} else {
|
||||
const pp = this.obj3d.children[0].children[this.fptIdx % 3 + 1]
|
||||
const p0 = this.obj3d.children[0].children[0]
|
||||
|
@ -198,16 +176,11 @@ export function onPick(e) {
|
|||
} else {
|
||||
for (let x = 0; x < this.selected.length; x++) {
|
||||
const obj = this.selected[x]
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
|
||||
setHover(obj, 0)
|
||||
|
||||
if (obj.userData.type == 'selpoint') {
|
||||
obj.visible = false
|
||||
} else {
|
||||
if (obj.userData.type == 'plane') {
|
||||
obj.material.opacity = 0.02
|
||||
obj.children[0].material.color.set(color['planeBorder'])
|
||||
} else {
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
}
|
||||
}
|
||||
this.obj3d.dispatchEvent({ type: 'change' })
|
||||
|
@ -237,22 +210,55 @@ export function onDrag(e) {
|
|||
}
|
||||
|
||||
|
||||
export function setHover(obj, state, meshHover = true) {
|
||||
let colObj, visible
|
||||
if (state == 1) {
|
||||
colObj = hoverColor
|
||||
visible = true
|
||||
} else {
|
||||
colObj = color
|
||||
visible = false
|
||||
}
|
||||
|
||||
switch (obj.userData.type) {
|
||||
case 'plane':
|
||||
obj.material.opacity = colObj.opacity
|
||||
obj.children[0].material.color.set(colObj['planeBorder'])
|
||||
break;
|
||||
case 'sketch':
|
||||
obj.visible = visible
|
||||
break;
|
||||
case 'mesh':
|
||||
if (meshHover) {
|
||||
obj.material.emissive.set(colObj.emissive)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
default:
|
||||
obj.material.color.set(colObj[obj.userData.type])
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// if (obj.userData.type == 'plane') {
|
||||
// obj.material.opacity = colObj.opacity
|
||||
// obj.children[0].material.color.set(colObj['planeBorder'])
|
||||
// } else if (obj.userData.type != 'mesh') {
|
||||
// obj.material.color.set(colObj[obj.userData.type])
|
||||
// } else if (meshHover) {
|
||||
// obj.material.emissive.set(colObj.emissive)
|
||||
// obj.material.color.set(colObj[obj.userData.type])
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
export function onRelease() {
|
||||
this.canvas.removeEventListener('pointermove', this.onDrag)
|
||||
this.canvas.removeEventListener('pointermove', this.onDragDim)
|
||||
this.canvas.removeEventListener('pointerup', this.onRelease)
|
||||
|
||||
// for (let x = 3; x < this.obj3d.children.length; x++) {
|
||||
// const obj = this.obj3d.children[x]
|
||||
// obj.geometry.computeBoundingSphere()
|
||||
// }
|
||||
|
||||
// for (let x = 0; x < this.obj3d.children[1].children.length; x++) {
|
||||
// const obj = this.obj3d.children[1].children[x]
|
||||
// obj.geometry.computeBoundingSphere()
|
||||
// }
|
||||
|
||||
this.updateBoundingSpheres()
|
||||
|
||||
if (draggedLabel) {
|
||||
draggedLabel.style.zIndex = 0;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
/* @tailwind base; */
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
* {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
@ -52,19 +49,12 @@ body {
|
|||
hover:bg-gray-500 hover:text-gray-200;
|
||||
}
|
||||
|
||||
.btn-light {
|
||||
cursor: pointer;
|
||||
@apply fill-current
|
||||
bg-transparent text-gray-700
|
||||
hover:bg-gray-300 hover:text-gray-700;
|
||||
}
|
||||
|
||||
|
||||
.btn-green {
|
||||
cursor: pointer;
|
||||
@apply fill-current
|
||||
bg-transparent text-gray-200
|
||||
hover:bg-transparent hover:text-green-200;
|
||||
hover:bg-transparent hover:text-green-400;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ import * as Icon from "./icons";
|
|||
export const NavBar = () => {
|
||||
const dispatch = useDispatch()
|
||||
const treeEntries = useSelector(state => state.treeEntries)
|
||||
const activeSketchId = useSelector(state => state.activeSketchId)
|
||||
|
||||
const activeSketchId = useSelector(state => state.treeEntries.activeSketchId)
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeSketchId) {
|
||||
|
@ -35,6 +34,7 @@ export const NavBar = () => {
|
|||
// dispatch({ type: 'update-descendents', sketch})
|
||||
sc.activeSketch = null
|
||||
sc.render()
|
||||
forceUpdate()
|
||||
// sc.activeDim = this.activeSketch.obj3d.children[1].children
|
||||
}, 'Finish'] :
|
||||
[FaEdit, sc.addSketch, 'Sketch [s]']
|
||||
|
|
|
@ -10,10 +10,9 @@ export const preloadedState = {
|
|||
allIds: [],
|
||||
tree: {},
|
||||
order: {},
|
||||
visible: {},
|
||||
activeSketchId: ""
|
||||
},
|
||||
ui: {
|
||||
toolTipImmediate: false
|
||||
}
|
||||
}
|
||||
|
||||
export function reducer(state = {}, action) {
|
||||
|
@ -24,18 +23,33 @@ export function reducer(state = {}, action) {
|
|||
byId: { [action.obj.obj3d.name]: { $set: action.obj } },
|
||||
allIds: { $push: [action.obj.obj3d.name] },
|
||||
tree: { [action.obj.obj3d.name]: { $set: {} } },
|
||||
order: { [action.obj.obj3d.name]: { $set: state.treeEntries.allIds.length } }
|
||||
order: { [action.obj.obj3d.name]: { $set: state.treeEntries.allIds.length } },
|
||||
visible: { [action.obj.obj3d.name]: { $set: true } },
|
||||
},
|
||||
})
|
||||
|
||||
case 'set-entry-visibility': {
|
||||
return update(state, {
|
||||
treeEntries: {
|
||||
visible: { $merge: action.obj },
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'set-active-sketch':
|
||||
return update(state, {
|
||||
treeEntries: {
|
||||
visible: { [action.sketch]: { $set: true } },
|
||||
activeSketchId: { $set: action.sketch },
|
||||
},
|
||||
})
|
||||
case 'exit-sketch':
|
||||
return {
|
||||
...state, activeSketchId: ''
|
||||
}
|
||||
return update(state, {
|
||||
treeEntries: {
|
||||
activeSketchId: { $set: "" },
|
||||
visible: { [state.treeEntries.activeSketchId]: { $set: false } },
|
||||
},
|
||||
})
|
||||
case 'rx-extrusion':
|
||||
|
||||
return update(state, {
|
||||
|
@ -48,7 +62,10 @@ export function reducer(state = {}, action) {
|
|||
[action.sketchId]: { [action.mesh.name]: { $set: true } },
|
||||
[action.mesh.name]: { $set: {} }
|
||||
},
|
||||
order: { [action.mesh.name]: { $set: state.treeEntries.allIds.length } }
|
||||
order: { [action.mesh.name]: { $set: state.treeEntries.allIds.length } },
|
||||
visible: {
|
||||
[action.mesh.name]: { $set: true }
|
||||
}
|
||||
}
|
||||
})
|
||||
case 'rx-boolean':
|
||||
|
@ -62,6 +79,7 @@ export function reducer(state = {}, action) {
|
|||
tree: {
|
||||
[action.deps[0]]: { [action.mesh.name]: { $set: true } },
|
||||
[action.deps[1]]: { [action.mesh.name]: { $set: true } },
|
||||
[action.mesh.name]: { $set: {} }
|
||||
},
|
||||
order: { [action.mesh.name]: { $set: state.treeEntries.allIds.length } }
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
|
||||
import React, { useReducer } from 'react';
|
||||
import React, { useReducer, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { MdEdit, MdVisibilityOff, MdVisibility, MdDelete } from 'react-icons/md'
|
||||
import { MdVisibilityOff, MdVisibility, MdDelete } from 'react-icons/md'
|
||||
|
||||
import { FaCube, FaEdit } from 'react-icons/fa'
|
||||
|
||||
|
@ -29,89 +29,100 @@ const TreeEntry = ({ entId }) => {
|
|||
const treeEntries = useSelector(state => state.treeEntries.byId)
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const activeSketchId = useSelector(state => state.activeSketchId)
|
||||
const activeSketchId = useSelector(state => state.treeEntries.activeSketchId)
|
||||
// const activeSketchId = treeEntries.activeSketchId
|
||||
|
||||
let obj3d, entry;
|
||||
const visible = useSelector(state => state.treeEntries.visible[entId])
|
||||
|
||||
let obj3d, sketch;
|
||||
|
||||
entry = treeEntries[entId]
|
||||
|
||||
if (treeEntries[entId].obj3d) {
|
||||
obj3d = treeEntries[entId].obj3d
|
||||
sketch = treeEntries[entId]
|
||||
} else {
|
||||
obj3d = treeEntries[entId]
|
||||
}
|
||||
console.log(obj3d.userData.type)
|
||||
let Icon = treeIcons[obj3d.userData.type]
|
||||
|
||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||
|
||||
// const vis = obj3d.visible
|
||||
const vis = obj3d.layers.mask & 1
|
||||
|
||||
// const vis = obj3d.layers.mask & 1
|
||||
|
||||
return <div className='btn select-none flex justify-start w-full h-7 items-center text-sm'
|
||||
|
||||
onDoubleClick={() => {
|
||||
if (entId[0] == 's') {
|
||||
activeSketchId && treeEntries[activeSketchId].deactivate()
|
||||
console.log(entry)
|
||||
entry.activate()
|
||||
sketch.activate()
|
||||
sc.clearSelection()
|
||||
sc.activeSketch = entry;
|
||||
}}
|
||||
>
|
||||
<Icon className='h-full w-auto p-1.5' />
|
||||
<div className="btn pl-1"
|
||||
onPointerEnter={() => {
|
||||
if (entId[0] == 'm') {
|
||||
// entry.material.color.set(color.hover)
|
||||
sc.render()
|
||||
sc.activeSketch = sketch;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
onPointerEnter={() => {
|
||||
sc.setHover(obj3d, 1)
|
||||
sc.render()
|
||||
}}
|
||||
onPointerLeave={() => {
|
||||
const obj = entry
|
||||
if (entId[0] == 'm' && !sc.selected.includes(obj)) {
|
||||
// obj.material.color.set(color.mesh)
|
||||
// console.log('activeid',activeSketchId,'visstate',visState)
|
||||
if (visible & entId[0] == 's') return
|
||||
if (sc.selected.includes(obj3d) || activeSketchId == obj3d.name) return
|
||||
sc.setHover(obj3d, 0)
|
||||
sc.render()
|
||||
}
|
||||
}}
|
||||
onPointerDown={() => {
|
||||
onClick={() => {
|
||||
if (entId[0] == 'm') {
|
||||
sc.selected.push(
|
||||
entry
|
||||
obj3d
|
||||
)
|
||||
sc.render()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon className='h-full w-auto p-1.5' />
|
||||
<div className="btn pl-1">
|
||||
{entId}
|
||||
</div>
|
||||
<div className='flex h-full ml-auto'>
|
||||
|
||||
<MdDelete className='btn-green h-full w-auto p-1.5'
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
dispatch({ type: 'delete-node', id: entId })
|
||||
sc.render()
|
||||
e.stopPropagation()
|
||||
}}
|
||||
/>
|
||||
|
||||
{
|
||||
vis ?
|
||||
visible ?
|
||||
<MdVisibility className='btn-green h-full w-auto p-1.5'
|
||||
onClick={() => {
|
||||
obj3d.traverse((e) => e.layers.disableAll())
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
console.log('hide')
|
||||
dispatch({ type: "set-entry-visibility", obj: {[entId]:false} })
|
||||
obj3d.visible = false;
|
||||
if (obj3d.userData.type == 'mesh') {
|
||||
obj3d.traverse((e) => e.layers.disable(1))
|
||||
}
|
||||
|
||||
sc.render()
|
||||
forceUpdate()
|
||||
}}
|
||||
/>
|
||||
:
|
||||
<MdVisibilityOff className='btn-green h-full w-auto p-1.5'
|
||||
onClick={() => {
|
||||
if (obj3d.userData.type == 'sketch') {
|
||||
obj3d.traverse((e) => e.layers.enable(0))
|
||||
} else {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
console.log('show')
|
||||
obj3d.visible = true;
|
||||
dispatch({ type: "set-entry-visibility", obj: {[entId]:true} })
|
||||
if (obj3d.userData.type == 'mesh') {
|
||||
obj3d.traverse((e) => {
|
||||
e.layers.enable(0)
|
||||
e.layers.enable(1)
|
||||
})
|
||||
|
||||
}
|
||||
sc.render()
|
||||
forceUpdate()
|
||||
|
|
|
@ -22,18 +22,23 @@ const color = {
|
|||
line: 0xffffff,
|
||||
mesh: 0x9DCFED,
|
||||
dimension: 0x0000ff,
|
||||
|
||||
plane: 0xffff00,
|
||||
planeBorder: 0x2e2e00,
|
||||
opacity: 0.02
|
||||
}
|
||||
|
||||
const hoverColor = {
|
||||
emissive: 0x343407,
|
||||
point: 0x00ff00,
|
||||
selpoint: 0xff0000,
|
||||
line: 0x00ff00,
|
||||
mesh: 0xFAB601,
|
||||
dimension: 0x00ff00,
|
||||
|
||||
plane: 0xffff00,
|
||||
planeBorder: 0x919100,
|
||||
opacity: 0.06
|
||||
}
|
||||
|
||||
|
||||
|
|
5
todo.txt
5
todo.txt
|
@ -12,15 +12,16 @@ boolean flesh out refresh / replace mesh
|
|||
- hidden bodies messes up hover highlight \\ fixed
|
||||
- add for union and intersect
|
||||
- consume skeches after extrude // done
|
||||
- selection hover disspates when rehovered //fixed
|
||||
- boolean unable to select click //fixed
|
||||
|
||||
|
||||
vertical // done
|
||||
horizontal // done
|
||||
|
||||
|
||||
|
||||
- hover sync between tree and work area
|
||||
- select sketch for extrusion
|
||||
- boolean unable to select click
|
||||
|
||||
auto update extrude
|
||||
extrude dialogue
|
||||
|
|
Loading…
Reference in New Issue