|
@@ -29181,1886 +29181,6 @@ THREE.CombinedCamera.prototype.toBottomView = function() {
|
|
|
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
- * @author mrdoob / http://mrdoob.com/
|
|
|
- * @author alteredq / http://alteredqualia.com/
|
|
|
- * @author paulirish / http://paulirish.com/
|
|
|
- */
|
|
|
-
|
|
|
-THREE.FirstPersonControls = function ( object, domElement ) {
|
|
|
-
|
|
|
- this.object = object;
|
|
|
- this.target = new THREE.Vector3( 0, 0, 0 );
|
|
|
-
|
|
|
- this.domElement = ( domElement !== undefined ) ? domElement : document;
|
|
|
-
|
|
|
- this.movementSpeed = 1.0;
|
|
|
- this.lookSpeed = 0.005;
|
|
|
-
|
|
|
- this.lookVertical = true;
|
|
|
- this.autoForward = false;
|
|
|
- // this.invertVertical = false;
|
|
|
-
|
|
|
- this.activeLook = true;
|
|
|
-
|
|
|
- this.heightSpeed = false;
|
|
|
- this.heightCoef = 1.0;
|
|
|
- this.heightMin = 0.0;
|
|
|
- this.heightMax = 1.0;
|
|
|
-
|
|
|
- this.constrainVertical = false;
|
|
|
- this.verticalMin = 0;
|
|
|
- this.verticalMax = Math.PI;
|
|
|
-
|
|
|
- this.autoSpeedFactor = 0.0;
|
|
|
-
|
|
|
- this.mouseX = 0;
|
|
|
- this.mouseY = 0;
|
|
|
-
|
|
|
- this.lat = 0;
|
|
|
- this.lon = 0;
|
|
|
- this.phi = 0;
|
|
|
- this.theta = 0;
|
|
|
-
|
|
|
- this.moveForward = false;
|
|
|
- this.moveBackward = false;
|
|
|
- this.moveLeft = false;
|
|
|
- this.moveRight = false;
|
|
|
- this.freeze = false;
|
|
|
-
|
|
|
- this.mouseDragOn = false;
|
|
|
-
|
|
|
- this.viewHalfX = 0;
|
|
|
- this.viewHalfY = 0;
|
|
|
-
|
|
|
- if ( this.domElement !== document ) {
|
|
|
-
|
|
|
- this.domElement.setAttribute( 'tabindex', -1 );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- this.handleResize = function () {
|
|
|
-
|
|
|
- if ( this.domElement === document ) {
|
|
|
-
|
|
|
- this.viewHalfX = window.innerWidth / 2;
|
|
|
- this.viewHalfY = window.innerHeight / 2;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.viewHalfX = this.domElement.offsetWidth / 2;
|
|
|
- this.viewHalfY = this.domElement.offsetHeight / 2;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.onMouseDown = function ( event ) {
|
|
|
-
|
|
|
- if ( this.domElement !== document ) {
|
|
|
-
|
|
|
- this.domElement.focus();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- if ( this.activeLook ) {
|
|
|
-
|
|
|
- switch ( event.button ) {
|
|
|
-
|
|
|
- case 0: this.moveForward = true; break;
|
|
|
- case 2: this.moveBackward = true; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.mouseDragOn = true;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.onMouseUp = function ( event ) {
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- if ( this.activeLook ) {
|
|
|
-
|
|
|
- switch ( event.button ) {
|
|
|
-
|
|
|
- case 0: this.moveForward = false; break;
|
|
|
- case 2: this.moveBackward = false; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.mouseDragOn = false;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.onMouseMove = function ( event ) {
|
|
|
-
|
|
|
- if ( this.domElement === document ) {
|
|
|
-
|
|
|
- this.mouseX = event.pageX - this.viewHalfX;
|
|
|
- this.mouseY = event.pageY - this.viewHalfY;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
|
|
|
- this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.onKeyDown = function ( event ) {
|
|
|
-
|
|
|
- //event.preventDefault();
|
|
|
-
|
|
|
- switch ( event.keyCode ) {
|
|
|
-
|
|
|
- case 38: /*up*/
|
|
|
- case 87: /*W*/ this.moveForward = true; break;
|
|
|
-
|
|
|
- case 37: /*left*/
|
|
|
- case 65: /*A*/ this.moveLeft = true; break;
|
|
|
-
|
|
|
- case 40: /*down*/
|
|
|
- case 83: /*S*/ this.moveBackward = true; break;
|
|
|
-
|
|
|
- case 39: /*right*/
|
|
|
- case 68: /*D*/ this.moveRight = true; break;
|
|
|
-
|
|
|
- case 82: /*R*/ this.moveUp = true; break;
|
|
|
- case 70: /*F*/ this.moveDown = true; break;
|
|
|
-
|
|
|
- case 81: /*Q*/ this.freeze = !this.freeze; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.onKeyUp = function ( event ) {
|
|
|
-
|
|
|
- switch( event.keyCode ) {
|
|
|
-
|
|
|
- case 38: /*up*/
|
|
|
- case 87: /*W*/ this.moveForward = false; break;
|
|
|
-
|
|
|
- case 37: /*left*/
|
|
|
- case 65: /*A*/ this.moveLeft = false; break;
|
|
|
-
|
|
|
- case 40: /*down*/
|
|
|
- case 83: /*S*/ this.moveBackward = false; break;
|
|
|
-
|
|
|
- case 39: /*right*/
|
|
|
- case 68: /*D*/ this.moveRight = false; break;
|
|
|
-
|
|
|
- case 82: /*R*/ this.moveUp = false; break;
|
|
|
- case 70: /*F*/ this.moveDown = false; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.update = function( delta ) {
|
|
|
- var actualMoveSpeed = 0;
|
|
|
-
|
|
|
- if ( this.freeze ) {
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- if ( this.heightSpeed ) {
|
|
|
-
|
|
|
- var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
|
|
|
- var heightDelta = y - this.heightMin;
|
|
|
-
|
|
|
- this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.autoSpeedFactor = 0.0;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- actualMoveSpeed = delta * this.movementSpeed;
|
|
|
-
|
|
|
- if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
|
|
|
- if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );
|
|
|
-
|
|
|
- if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
|
|
|
- if ( this.moveRight ) this.object.translateX( actualMoveSpeed );
|
|
|
-
|
|
|
- if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
|
|
|
- if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
|
|
|
-
|
|
|
- var actualLookSpeed = delta * this.lookSpeed;
|
|
|
-
|
|
|
- if ( !this.activeLook ) {
|
|
|
-
|
|
|
- actualLookSpeed = 0;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.lon += this.mouseX * actualLookSpeed;
|
|
|
- if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed; // * this.invertVertical?-1:1;
|
|
|
-
|
|
|
- this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
|
|
|
- this.phi = ( 90 - this.lat ) * Math.PI / 180;
|
|
|
- this.theta = this.lon * Math.PI / 180;
|
|
|
-
|
|
|
- var targetPosition = this.target,
|
|
|
- position = this.object.position;
|
|
|
-
|
|
|
- targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
|
|
|
- targetPosition.y = position.y + 100 * Math.cos( this.phi );
|
|
|
- targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var verticalLookRatio = 1;
|
|
|
-
|
|
|
- if ( this.constrainVertical ) {
|
|
|
-
|
|
|
- verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.lon += this.mouseX * actualLookSpeed;
|
|
|
- if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
|
|
|
-
|
|
|
- this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
|
|
|
- this.phi = ( 90 - this.lat ) * Math.PI / 180;
|
|
|
-
|
|
|
- this.theta = this.lon * Math.PI / 180;
|
|
|
-
|
|
|
- if ( this.constrainVertical ) {
|
|
|
-
|
|
|
- this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var targetPosition = this.target,
|
|
|
- position = this.object.position;
|
|
|
-
|
|
|
- targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
|
|
|
- targetPosition.y = position.y + 100 * Math.cos( this.phi );
|
|
|
- targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
|
|
|
-
|
|
|
- this.object.lookAt( targetPosition );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
|
|
|
- this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
|
|
|
- this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
|
|
|
- this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
|
|
|
- this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
|
|
|
-
|
|
|
- function bind( scope, fn ) {
|
|
|
-
|
|
|
- return function () {
|
|
|
-
|
|
|
- fn.apply( scope, arguments );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.handleResize();
|
|
|
-
|
|
|
-};
|
|
|
-/**
|
|
|
- * @author alteredq / http://alteredqualia.com/
|
|
|
- */
|
|
|
-
|
|
|
-THREE.PathControls = function ( object, domElement ) {
|
|
|
-
|
|
|
- this.object = object;
|
|
|
- this.domElement = ( domElement !== undefined ) ? domElement : document;
|
|
|
-
|
|
|
- this.id = "PathControls" + THREE.PathControlsIdCounter ++;
|
|
|
-
|
|
|
- // API
|
|
|
-
|
|
|
- this.duration = 10 * 1000; // milliseconds
|
|
|
- this.waypoints = [];
|
|
|
-
|
|
|
- this.useConstantSpeed = true;
|
|
|
- this.resamplingCoef = 50;
|
|
|
-
|
|
|
- this.debugPath = new THREE.Object3D();
|
|
|
- this.debugDummy = new THREE.Object3D();
|
|
|
-
|
|
|
- this.animationParent = new THREE.Object3D();
|
|
|
-
|
|
|
- this.lookSpeed = 0.005;
|
|
|
- this.lookVertical = true;
|
|
|
- this.lookHorizontal = true;
|
|
|
- this.verticalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
|
|
|
- this.horizontalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
|
|
|
-
|
|
|
- // internals
|
|
|
-
|
|
|
- this.target = new THREE.Object3D();
|
|
|
-
|
|
|
- this.mouseX = 0;
|
|
|
- this.mouseY = 0;
|
|
|
-
|
|
|
- this.lat = 0;
|
|
|
- this.lon = 0;
|
|
|
-
|
|
|
- this.phi = 0;
|
|
|
- this.theta = 0;
|
|
|
-
|
|
|
- var PI2 = Math.PI * 2,
|
|
|
- PI180 = Math.PI / 180;
|
|
|
-
|
|
|
- this.viewHalfX = 0;
|
|
|
- this.viewHalfY = 0;
|
|
|
-
|
|
|
- if ( this.domElement !== document ) {
|
|
|
-
|
|
|
- this.domElement.setAttribute( 'tabindex', -1 );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // methods
|
|
|
-
|
|
|
- this.handleResize = function () {
|
|
|
-
|
|
|
- if ( this.domElement === document ) {
|
|
|
-
|
|
|
- this.viewHalfX = window.innerWidth / 2;
|
|
|
- this.viewHalfY = window.innerHeight / 2;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.viewHalfX = this.domElement.offsetWidth / 2;
|
|
|
- this.viewHalfY = this.domElement.offsetHeight / 2;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.update = function ( delta ) {
|
|
|
-
|
|
|
- var srcRange, dstRange;
|
|
|
-
|
|
|
- if( this.lookHorizontal ) this.lon += this.mouseX * this.lookSpeed * delta;
|
|
|
- if( this.lookVertical ) this.lat -= this.mouseY * this.lookSpeed * delta;
|
|
|
-
|
|
|
- this.lon = Math.max( 0, Math.min( 360, this.lon ) );
|
|
|
- this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
|
|
|
-
|
|
|
- this.phi = ( 90 - this.lat ) * PI180;
|
|
|
- this.theta = this.lon * PI180;
|
|
|
-
|
|
|
- this.phi = normalize_angle_rad( this.phi );
|
|
|
-
|
|
|
- // constrain vertical look angle
|
|
|
-
|
|
|
- srcRange = this.verticalAngleMap.srcRange;
|
|
|
- dstRange = this.verticalAngleMap.dstRange;
|
|
|
-
|
|
|
- var tmpPhi = THREE.Math.mapLinear( this.phi, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
|
|
|
- var tmpPhiFullRange = dstRange[ 1 ] - dstRange[ 0 ];
|
|
|
- var tmpPhiNormalized = ( tmpPhi - dstRange[ 0 ] ) / tmpPhiFullRange;
|
|
|
-
|
|
|
- this.phi = QuadraticEaseInOut( tmpPhiNormalized ) * tmpPhiFullRange + dstRange[ 0 ];
|
|
|
-
|
|
|
- // constrain horizontal look angle
|
|
|
-
|
|
|
- srcRange = this.horizontalAngleMap.srcRange;
|
|
|
- dstRange = this.horizontalAngleMap.dstRange;
|
|
|
-
|
|
|
- var tmpTheta = THREE.Math.mapLinear( this.theta, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
|
|
|
- var tmpThetaFullRange = dstRange[ 1 ] - dstRange[ 0 ];
|
|
|
- var tmpThetaNormalized = ( tmpTheta - dstRange[ 0 ] ) / tmpThetaFullRange;
|
|
|
-
|
|
|
- this.theta = QuadraticEaseInOut( tmpThetaNormalized ) * tmpThetaFullRange + dstRange[ 0 ];
|
|
|
-
|
|
|
- var targetPosition = this.target.position,
|
|
|
- position = this.object.position;
|
|
|
-
|
|
|
- targetPosition.x = 100 * Math.sin( this.phi ) * Math.cos( this.theta );
|
|
|
- targetPosition.y = 100 * Math.cos( this.phi );
|
|
|
- targetPosition.z = 100 * Math.sin( this.phi ) * Math.sin( this.theta );
|
|
|
-
|
|
|
- this.object.lookAt( this.target.position );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.onMouseMove = function ( event ) {
|
|
|
-
|
|
|
- if ( this.domElement === document ) {
|
|
|
-
|
|
|
- this.mouseX = event.pageX - this.viewHalfX;
|
|
|
- this.mouseY = event.pageY - this.viewHalfY;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
|
|
|
- this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- // utils
|
|
|
-
|
|
|
- function normalize_angle_rad( a ) {
|
|
|
-
|
|
|
- var b = a % PI2;
|
|
|
- return b >= 0 ? b : b + PI2;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function distance( a, b ) {
|
|
|
-
|
|
|
- var dx = a[ 0 ] - b[ 0 ],
|
|
|
- dy = a[ 1 ] - b[ 1 ],
|
|
|
- dz = a[ 2 ] - b[ 2 ];
|
|
|
-
|
|
|
- return Math.sqrt( dx * dx + dy * dy + dz * dz );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function QuadraticEaseInOut ( k ) {
|
|
|
-
|
|
|
- if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
|
|
|
- return - 0.5 * ( --k * ( k - 2 ) - 1 );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function bind( scope, fn ) {
|
|
|
-
|
|
|
- return function () {
|
|
|
-
|
|
|
- fn.apply( scope, arguments );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function initAnimationPath( parent, spline, name, duration ) {
|
|
|
-
|
|
|
- var animationData = {
|
|
|
-
|
|
|
- name: name,
|
|
|
- fps: 0.6,
|
|
|
- length: duration,
|
|
|
-
|
|
|
- hierarchy: []
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- var i,
|
|
|
- parentAnimation, childAnimation,
|
|
|
- path = spline.getControlPointsArray(),
|
|
|
- sl = spline.getLength(),
|
|
|
- pl = path.length,
|
|
|
- t = 0,
|
|
|
- first = 0,
|
|
|
- last = pl - 1;
|
|
|
-
|
|
|
- parentAnimation = { parent: -1, keys: [] };
|
|
|
- parentAnimation.keys[ first ] = { time: 0, pos: path[ first ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
|
|
|
- parentAnimation.keys[ last ] = { time: duration, pos: path[ last ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
|
|
|
-
|
|
|
- for ( i = 1; i < pl - 1; i++ ) {
|
|
|
-
|
|
|
- // real distance (approximation via linear segments)
|
|
|
-
|
|
|
- t = duration * sl.chunks[ i ] / sl.total;
|
|
|
-
|
|
|
- // equal distance
|
|
|
-
|
|
|
- //t = duration * ( i / pl );
|
|
|
-
|
|
|
- // linear distance
|
|
|
-
|
|
|
- //t += duration * distance( path[ i ], path[ i - 1 ] ) / sl.total;
|
|
|
-
|
|
|
- parentAnimation.keys[ i ] = { time: t, pos: path[ i ] };
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- animationData.hierarchy[ 0 ] = parentAnimation;
|
|
|
-
|
|
|
- THREE.AnimationHandler.add( animationData );
|
|
|
-
|
|
|
- return new THREE.Animation( parent, name, THREE.AnimationHandler.CATMULLROM_FORWARD, false );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- function createSplineGeometry( spline, n_sub ) {
|
|
|
-
|
|
|
- var i, index, position,
|
|
|
- geometry = new THREE.Geometry();
|
|
|
-
|
|
|
- for ( i = 0; i < spline.points.length * n_sub; i ++ ) {
|
|
|
-
|
|
|
- index = i / ( spline.points.length * n_sub );
|
|
|
- position = spline.getPoint( index );
|
|
|
-
|
|
|
- geometry.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return geometry;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function createPath( parent, spline ) {
|
|
|
-
|
|
|
- var lineGeo = createSplineGeometry( spline, 10 ),
|
|
|
- particleGeo = createSplineGeometry( spline, 10 ),
|
|
|
- lineMat = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 3 } ),
|
|
|
- lineObj = new THREE.Line( lineGeo, lineMat ),
|
|
|
- particleObj = new THREE.ParticleSystem( particleGeo, new THREE.ParticleBasicMaterial( { color: 0xffaa00, size: 3 } ) );
|
|
|
-
|
|
|
- lineObj.scale.set( 1, 1, 1 );
|
|
|
- parent.add( lineObj );
|
|
|
-
|
|
|
- particleObj.scale.set( 1, 1, 1 );
|
|
|
- parent.add( particleObj );
|
|
|
-
|
|
|
- var waypoint,
|
|
|
- geo = new THREE.SphereGeometry( 1, 16, 8 ),
|
|
|
- mat = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
|
|
|
-
|
|
|
- for ( var i = 0; i < spline.points.length; i ++ ) {
|
|
|
-
|
|
|
- waypoint = new THREE.Mesh( geo, mat );
|
|
|
- waypoint.position.copy( spline.points[ i ] );
|
|
|
- parent.add( waypoint );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.init = function ( ) {
|
|
|
-
|
|
|
- // constructor
|
|
|
-
|
|
|
- this.spline = new THREE.Spline();
|
|
|
- this.spline.initFromArray( this.waypoints );
|
|
|
-
|
|
|
- if ( this.useConstantSpeed ) {
|
|
|
-
|
|
|
- this.spline.reparametrizeByArcLength( this.resamplingCoef );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.createDebugDummy ) {
|
|
|
-
|
|
|
- var dummyParentMaterial = new THREE.MeshLambertMaterial( { color: 0x0077ff } ),
|
|
|
- dummyChildMaterial = new THREE.MeshLambertMaterial( { color: 0x00ff00 } ),
|
|
|
- dummyParentGeo = new THREE.CubeGeometry( 10, 10, 20 ),
|
|
|
- dummyChildGeo = new THREE.CubeGeometry( 2, 2, 10 );
|
|
|
-
|
|
|
- this.animationParent = new THREE.Mesh( dummyParentGeo, dummyParentMaterial );
|
|
|
-
|
|
|
- var dummyChild = new THREE.Mesh( dummyChildGeo, dummyChildMaterial );
|
|
|
- dummyChild.position.set( 0, 10, 0 );
|
|
|
-
|
|
|
- this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
|
|
|
-
|
|
|
- this.animationParent.add( this.object );
|
|
|
- this.animationParent.add( this.target );
|
|
|
- this.animationParent.add( dummyChild );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
|
|
|
- this.animationParent.add( this.target );
|
|
|
- this.animationParent.add( this.object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.createDebugPath ) {
|
|
|
-
|
|
|
- createPath( this.debugPath, this.spline );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.handleResize();
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.PathControlsIdCounter = 0;
|
|
|
-/**
|
|
|
- * @author James Baicoianu / http://www.baicoianu.com/
|
|
|
- */
|
|
|
-
|
|
|
-THREE.FlyControls = function ( object, domElement ) {
|
|
|
-
|
|
|
- this.object = object;
|
|
|
-
|
|
|
- this.domElement = ( domElement !== undefined ) ? domElement : document;
|
|
|
- if ( domElement ) this.domElement.setAttribute( 'tabindex', -1 );
|
|
|
-
|
|
|
- // API
|
|
|
-
|
|
|
- this.movementSpeed = 1.0;
|
|
|
- this.rollSpeed = 0.005;
|
|
|
-
|
|
|
- this.dragToLook = false;
|
|
|
- this.autoForward = false;
|
|
|
-
|
|
|
- // disable default target object behavior
|
|
|
-
|
|
|
- this.object.useQuaternion = true;
|
|
|
-
|
|
|
- // internals
|
|
|
-
|
|
|
- this.tmpQuaternion = new THREE.Quaternion();
|
|
|
-
|
|
|
- this.mouseStatus = 0;
|
|
|
-
|
|
|
- this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
|
|
|
- this.moveVector = new THREE.Vector3( 0, 0, 0 );
|
|
|
- this.rotationVector = new THREE.Vector3( 0, 0, 0 );
|
|
|
-
|
|
|
- this.handleEvent = function ( event ) {
|
|
|
-
|
|
|
- if ( typeof this[ event.type ] == 'function' ) {
|
|
|
-
|
|
|
- this[ event.type ]( event );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.keydown = function( event ) {
|
|
|
-
|
|
|
- if ( event.altKey ) {
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //event.preventDefault();
|
|
|
-
|
|
|
- switch ( event.keyCode ) {
|
|
|
-
|
|
|
- case 16: /* shift */ this.movementSpeedMultiplier = .1; break;
|
|
|
-
|
|
|
- case 87: /*W*/ this.moveState.forward = 1; break;
|
|
|
- case 83: /*S*/ this.moveState.back = 1; break;
|
|
|
-
|
|
|
- case 65: /*A*/ this.moveState.left = 1; break;
|
|
|
- case 68: /*D*/ this.moveState.right = 1; break;
|
|
|
-
|
|
|
- case 82: /*R*/ this.moveState.up = 1; break;
|
|
|
- case 70: /*F*/ this.moveState.down = 1; break;
|
|
|
-
|
|
|
- case 38: /*up*/ this.moveState.pitchUp = 1; break;
|
|
|
- case 40: /*down*/ this.moveState.pitchDown = 1; break;
|
|
|
-
|
|
|
- case 37: /*left*/ this.moveState.yawLeft = 1; break;
|
|
|
- case 39: /*right*/ this.moveState.yawRight = 1; break;
|
|
|
-
|
|
|
- case 81: /*Q*/ this.moveState.rollLeft = 1; break;
|
|
|
- case 69: /*E*/ this.moveState.rollRight = 1; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.updateMovementVector();
|
|
|
- this.updateRotationVector();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.keyup = function( event ) {
|
|
|
-
|
|
|
- switch( event.keyCode ) {
|
|
|
-
|
|
|
- case 16: /* shift */ this.movementSpeedMultiplier = 1; break;
|
|
|
-
|
|
|
- case 87: /*W*/ this.moveState.forward = 0; break;
|
|
|
- case 83: /*S*/ this.moveState.back = 0; break;
|
|
|
-
|
|
|
- case 65: /*A*/ this.moveState.left = 0; break;
|
|
|
- case 68: /*D*/ this.moveState.right = 0; break;
|
|
|
-
|
|
|
- case 82: /*R*/ this.moveState.up = 0; break;
|
|
|
- case 70: /*F*/ this.moveState.down = 0; break;
|
|
|
-
|
|
|
- case 38: /*up*/ this.moveState.pitchUp = 0; break;
|
|
|
- case 40: /*down*/ this.moveState.pitchDown = 0; break;
|
|
|
-
|
|
|
- case 37: /*left*/ this.moveState.yawLeft = 0; break;
|
|
|
- case 39: /*right*/ this.moveState.yawRight = 0; break;
|
|
|
-
|
|
|
- case 81: /*Q*/ this.moveState.rollLeft = 0; break;
|
|
|
- case 69: /*E*/ this.moveState.rollRight = 0; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.updateMovementVector();
|
|
|
- this.updateRotationVector();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.mousedown = function( event ) {
|
|
|
-
|
|
|
- if ( this.domElement !== document ) {
|
|
|
-
|
|
|
- this.domElement.focus();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- if ( this.dragToLook ) {
|
|
|
-
|
|
|
- this.mouseStatus ++;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- switch ( event.button ) {
|
|
|
-
|
|
|
- case 0: this.object.moveForward = true; break;
|
|
|
- case 2: this.object.moveBackward = true; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.mousemove = function( event ) {
|
|
|
-
|
|
|
- if ( !this.dragToLook || this.mouseStatus > 0 ) {
|
|
|
-
|
|
|
- var container = this.getContainerDimensions();
|
|
|
- var halfWidth = container.size[ 0 ] / 2;
|
|
|
- var halfHeight = container.size[ 1 ] / 2;
|
|
|
-
|
|
|
- this.moveState.yawLeft = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth ) / halfWidth;
|
|
|
- this.moveState.pitchDown = ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
|
|
|
-
|
|
|
- this.updateRotationVector();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.mouseup = function( event ) {
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- if ( this.dragToLook ) {
|
|
|
-
|
|
|
- this.mouseStatus --;
|
|
|
-
|
|
|
- this.moveState.yawLeft = this.moveState.pitchDown = 0;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- switch ( event.button ) {
|
|
|
-
|
|
|
- case 0: this.moveForward = false; break;
|
|
|
- case 2: this.moveBackward = false; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.updateRotationVector();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.update = function( delta ) {
|
|
|
-
|
|
|
- var moveMult = delta * this.movementSpeed;
|
|
|
- var rotMult = delta * this.rollSpeed;
|
|
|
-
|
|
|
- this.object.translateX( this.moveVector.x * moveMult );
|
|
|
- this.object.translateY( this.moveVector.y * moveMult );
|
|
|
- this.object.translateZ( this.moveVector.z * moveMult );
|
|
|
-
|
|
|
- this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize();
|
|
|
- this.object.quaternion.multiplySelf( this.tmpQuaternion );
|
|
|
-
|
|
|
- this.object.matrix.setPosition( this.object.position );
|
|
|
- this.object.matrix.setRotationFromQuaternion( this.object.quaternion );
|
|
|
- this.object.matrixWorldNeedsUpdate = true;
|
|
|
-
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.updateMovementVector = function() {
|
|
|
-
|
|
|
- var forward = ( this.moveState.forward || ( this.autoForward && !this.moveState.back ) ) ? 1 : 0;
|
|
|
-
|
|
|
- this.moveVector.x = ( -this.moveState.left + this.moveState.right );
|
|
|
- this.moveVector.y = ( -this.moveState.down + this.moveState.up );
|
|
|
- this.moveVector.z = ( -forward + this.moveState.back );
|
|
|
-
|
|
|
- //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.updateRotationVector = function() {
|
|
|
-
|
|
|
- this.rotationVector.x = ( -this.moveState.pitchDown + this.moveState.pitchUp );
|
|
|
- this.rotationVector.y = ( -this.moveState.yawRight + this.moveState.yawLeft );
|
|
|
- this.rotationVector.z = ( -this.moveState.rollRight + this.moveState.rollLeft );
|
|
|
-
|
|
|
- //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.getContainerDimensions = function() {
|
|
|
-
|
|
|
- if ( this.domElement != document ) {
|
|
|
-
|
|
|
- return {
|
|
|
- size : [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
|
|
|
- offset : [ this.domElement.offsetLeft, this.domElement.offsetTop ]
|
|
|
- };
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- return {
|
|
|
- size : [ window.innerWidth, window.innerHeight ],
|
|
|
- offset : [ 0, 0 ]
|
|
|
- };
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function bind( scope, fn ) {
|
|
|
-
|
|
|
- return function () {
|
|
|
-
|
|
|
- fn.apply( scope, arguments );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false );
|
|
|
- this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false );
|
|
|
- this.domElement.addEventListener( 'mouseup', bind( this, this.mouseup ), false );
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'keydown', bind( this, this.keydown ), false );
|
|
|
- this.domElement.addEventListener( 'keyup', bind( this, this.keyup ), false );
|
|
|
-
|
|
|
- this.updateMovementVector();
|
|
|
- this.updateRotationVector();
|
|
|
-
|
|
|
-};
|
|
|
-/**
|
|
|
- * @author mikael emtinger / http://gomo.se/
|
|
|
- * @author alteredq / http://alteredqualia.com/
|
|
|
- */
|
|
|
-
|
|
|
-THREE.RollControls = function ( object, domElement ) {
|
|
|
-
|
|
|
- this.object = object;
|
|
|
- this.domElement = ( domElement !== undefined ) ? domElement : document;
|
|
|
-
|
|
|
- // API
|
|
|
-
|
|
|
- this.mouseLook = true;
|
|
|
- this.autoForward = false;
|
|
|
-
|
|
|
- this.lookSpeed = 1;
|
|
|
- this.movementSpeed = 1;
|
|
|
- this.rollSpeed = 1;
|
|
|
-
|
|
|
- this.constrainVertical = [ -0.9, 0.9 ];
|
|
|
-
|
|
|
- // disable default target object behavior
|
|
|
-
|
|
|
- this.object.matrixAutoUpdate = false;
|
|
|
-
|
|
|
- // internals
|
|
|
-
|
|
|
- this.forward = new THREE.Vector3( 0, 0, 1 );
|
|
|
- this.roll = 0;
|
|
|
-
|
|
|
- var xTemp = new THREE.Vector3();
|
|
|
- var yTemp = new THREE.Vector3();
|
|
|
- var zTemp = new THREE.Vector3();
|
|
|
- var rollMatrix = new THREE.Matrix4();
|
|
|
-
|
|
|
- var doRoll = false, rollDirection = 1, forwardSpeed = 0, sideSpeed = 0, upSpeed = 0;
|
|
|
-
|
|
|
- var mouseX = 0, mouseY = 0;
|
|
|
-
|
|
|
- var windowHalfX = 0;
|
|
|
- var windowHalfY = 0;
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- this.handleResize = function () {
|
|
|
-
|
|
|
- windowHalfX = window.innerWidth / 2;
|
|
|
- windowHalfY = window.innerHeight / 2;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- // custom update
|
|
|
-
|
|
|
- this.update = function ( delta ) {
|
|
|
-
|
|
|
- if ( this.mouseLook ) {
|
|
|
-
|
|
|
- var actualLookSpeed = delta * this.lookSpeed;
|
|
|
-
|
|
|
- this.rotateHorizontally( actualLookSpeed * mouseX );
|
|
|
- this.rotateVertically( actualLookSpeed * mouseY );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var actualSpeed = delta * this.movementSpeed;
|
|
|
- var forwardOrAuto = ( forwardSpeed > 0 || ( this.autoForward && ! ( forwardSpeed < 0 ) ) ) ? 1 : forwardSpeed;
|
|
|
-
|
|
|
- this.object.translateZ( -actualSpeed * forwardOrAuto );
|
|
|
- this.object.translateX( actualSpeed * sideSpeed );
|
|
|
- this.object.translateY( actualSpeed * upSpeed );
|
|
|
-
|
|
|
- if( doRoll ) {
|
|
|
-
|
|
|
- this.roll += this.rollSpeed * delta * rollDirection;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // cap forward up / down
|
|
|
-
|
|
|
- if( this.forward.y > this.constrainVertical[ 1 ] ) {
|
|
|
-
|
|
|
- this.forward.y = this.constrainVertical[ 1 ];
|
|
|
- this.forward.normalize();
|
|
|
-
|
|
|
- } else if( this.forward.y < this.constrainVertical[ 0 ] ) {
|
|
|
-
|
|
|
- this.forward.y = this.constrainVertical[ 0 ];
|
|
|
- this.forward.normalize();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // construct unrolled camera matrix
|
|
|
-
|
|
|
- zTemp.copy( this.forward );
|
|
|
- yTemp.set( 0, 1, 0 );
|
|
|
-
|
|
|
- xTemp.cross( yTemp, zTemp ).normalize();
|
|
|
- yTemp.cross( zTemp, xTemp ).normalize();
|
|
|
-
|
|
|
- this.object.matrix.elements[0] = xTemp.x; this.object.matrix.elements[4] = yTemp.x; this.object.matrix.elements[8] = zTemp.x;
|
|
|
- this.object.matrix.elements[1] = xTemp.y; this.object.matrix.elements[5] = yTemp.y; this.object.matrix.elements[9] = zTemp.y;
|
|
|
- this.object.matrix.elements[2] = xTemp.z; this.object.matrix.elements[6] = yTemp.z; this.object.matrix.elements[10] = zTemp.z;
|
|
|
-
|
|
|
- // calculate roll matrix
|
|
|
-
|
|
|
- rollMatrix.identity();
|
|
|
- rollMatrix.elements[0] = Math.cos( this.roll ); rollMatrix.elements[4] = -Math.sin( this.roll );
|
|
|
- rollMatrix.elements[1] = Math.sin( this.roll ); rollMatrix.elements[5] = Math.cos( this.roll );
|
|
|
-
|
|
|
- // multiply camera with roll
|
|
|
-
|
|
|
- this.object.matrix.multiplySelf( rollMatrix );
|
|
|
- this.object.matrixWorldNeedsUpdate = true;
|
|
|
-
|
|
|
- // set position
|
|
|
-
|
|
|
- this.object.matrix.elements[12] = this.object.position.x;
|
|
|
- this.object.matrix.elements[13] = this.object.position.y;
|
|
|
- this.object.matrix.elements[14] = this.object.position.z;
|
|
|
-
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.translateX = function ( distance ) {
|
|
|
-
|
|
|
- this.object.position.x += this.object.matrix.elements[0] * distance;
|
|
|
- this.object.position.y += this.object.matrix.elements[1] * distance;
|
|
|
- this.object.position.z += this.object.matrix.elements[2] * distance;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.translateY = function ( distance ) {
|
|
|
-
|
|
|
- this.object.position.x += this.object.matrix.elements[4] * distance;
|
|
|
- this.object.position.y += this.object.matrix.elements[5] * distance;
|
|
|
- this.object.position.z += this.object.matrix.elements[6] * distance;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.translateZ = function ( distance ) {
|
|
|
-
|
|
|
- this.object.position.x -= this.object.matrix.elements[8] * distance;
|
|
|
- this.object.position.y -= this.object.matrix.elements[9] * distance;
|
|
|
- this.object.position.z -= this.object.matrix.elements[10] * distance;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- this.rotateHorizontally = function ( amount ) {
|
|
|
-
|
|
|
- // please note that the amount is NOT degrees, but a scale value
|
|
|
-
|
|
|
- xTemp.set( this.object.matrix.elements[0], this.object.matrix.elements[1], this.object.matrix.elements[2] );
|
|
|
- xTemp.multiplyScalar( amount );
|
|
|
-
|
|
|
- this.forward.subSelf( xTemp );
|
|
|
- this.forward.normalize();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.rotateVertically = function ( amount ) {
|
|
|
-
|
|
|
- // please note that the amount is NOT degrees, but a scale value
|
|
|
-
|
|
|
- yTemp.set( this.object.matrix.elements[4], this.object.matrix.elements[5], this.object.matrix.elements[6] );
|
|
|
- yTemp.multiplyScalar( amount );
|
|
|
-
|
|
|
- this.forward.addSelf( yTemp );
|
|
|
- this.forward.normalize();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function onKeyDown( event ) {
|
|
|
-
|
|
|
- //event.preventDefault();
|
|
|
-
|
|
|
- switch ( event.keyCode ) {
|
|
|
-
|
|
|
- case 38: /*up*/
|
|
|
- case 87: /*W*/ forwardSpeed = 1; break;
|
|
|
-
|
|
|
- case 37: /*left*/
|
|
|
- case 65: /*A*/ sideSpeed = -1; break;
|
|
|
-
|
|
|
- case 40: /*down*/
|
|
|
- case 83: /*S*/ forwardSpeed = -1; break;
|
|
|
-
|
|
|
- case 39: /*right*/
|
|
|
- case 68: /*D*/ sideSpeed = 1; break;
|
|
|
-
|
|
|
- case 81: /*Q*/ doRoll = true; rollDirection = 1; break;
|
|
|
- case 69: /*E*/ doRoll = true; rollDirection = -1; break;
|
|
|
-
|
|
|
- case 82: /*R*/ upSpeed = 1; break;
|
|
|
- case 70: /*F*/ upSpeed = -1; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function onKeyUp( event ) {
|
|
|
-
|
|
|
- switch( event.keyCode ) {
|
|
|
-
|
|
|
- case 38: /*up*/
|
|
|
- case 87: /*W*/ forwardSpeed = 0; break;
|
|
|
-
|
|
|
- case 37: /*left*/
|
|
|
- case 65: /*A*/ sideSpeed = 0; break;
|
|
|
-
|
|
|
- case 40: /*down*/
|
|
|
- case 83: /*S*/ forwardSpeed = 0; break;
|
|
|
-
|
|
|
- case 39: /*right*/
|
|
|
- case 68: /*D*/ sideSpeed = 0; break;
|
|
|
-
|
|
|
- case 81: /*Q*/ doRoll = false; break;
|
|
|
- case 69: /*E*/ doRoll = false; break;
|
|
|
-
|
|
|
- case 82: /*R*/ upSpeed = 0; break;
|
|
|
- case 70: /*F*/ upSpeed = 0; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function onMouseMove( event ) {
|
|
|
-
|
|
|
- mouseX = ( event.clientX - windowHalfX ) / window.innerWidth;
|
|
|
- mouseY = ( event.clientY - windowHalfY ) / window.innerHeight;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function onMouseDown ( event ) {
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- switch ( event.button ) {
|
|
|
-
|
|
|
- case 0: forwardSpeed = 1; break;
|
|
|
- case 2: forwardSpeed = -1; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function onMouseUp ( event ) {
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- switch ( event.button ) {
|
|
|
-
|
|
|
- case 0: forwardSpeed = 0; break;
|
|
|
- case 2: forwardSpeed = 0; break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'mousemove', onMouseMove, false );
|
|
|
- this.domElement.addEventListener( 'mousedown', onMouseDown, false );
|
|
|
- this.domElement.addEventListener( 'mouseup', onMouseUp, false );
|
|
|
- this.domElement.addEventListener( 'keydown', onKeyDown, false );
|
|
|
- this.domElement.addEventListener( 'keyup', onKeyUp, false );
|
|
|
-
|
|
|
- this.handleResize();
|
|
|
-
|
|
|
-};
|
|
|
-/**
|
|
|
- * @author Eberhard Graether / http://egraether.com/
|
|
|
- */
|
|
|
-
|
|
|
-THREE.TrackballControls = function ( object, domElement ) {
|
|
|
-
|
|
|
- THREE.EventTarget.call( this );
|
|
|
-
|
|
|
- var _this = this,
|
|
|
- STATE = { NONE : -1, ROTATE : 0, ZOOM : 1, PAN : 2 };
|
|
|
-
|
|
|
- this.object = object;
|
|
|
- this.domElement = ( domElement !== undefined ) ? domElement : document;
|
|
|
-
|
|
|
- // API
|
|
|
-
|
|
|
- this.enabled = true;
|
|
|
-
|
|
|
- this.screen = { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 };
|
|
|
- this.radius = ( this.screen.width + this.screen.height ) / 4;
|
|
|
-
|
|
|
- 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*/ ];
|
|
|
-
|
|
|
- // internals
|
|
|
-
|
|
|
- this.target = new THREE.Vector3();
|
|
|
-
|
|
|
- var lastPosition = new THREE.Vector3();
|
|
|
-
|
|
|
- var _keyPressed = false,
|
|
|
- _state = STATE.NONE,
|
|
|
-
|
|
|
- _eye = new THREE.Vector3(),
|
|
|
-
|
|
|
- _rotateStart = new THREE.Vector3(),
|
|
|
- _rotateEnd = new THREE.Vector3(),
|
|
|
-
|
|
|
- _zoomStart = new THREE.Vector2(),
|
|
|
- _zoomEnd = new THREE.Vector2(),
|
|
|
-
|
|
|
- _panStart = new THREE.Vector2(),
|
|
|
- _panEnd = new THREE.Vector2();
|
|
|
-
|
|
|
- // events
|
|
|
-
|
|
|
- var changeEvent = { type: 'change' };
|
|
|
-
|
|
|
-
|
|
|
- // methods
|
|
|
-
|
|
|
- this.handleResize = function () {
|
|
|
-
|
|
|
- this.screen.width = window.innerWidth;
|
|
|
- this.screen.height = window.innerHeight;
|
|
|
-
|
|
|
- this.screen.offsetLeft = 0;
|
|
|
- this.screen.offsetTop = 0;
|
|
|
-
|
|
|
- this.radius = ( this.screen.width + this.screen.height ) / 4;
|
|
|
- };
|
|
|
-
|
|
|
- this.handleEvent = function ( event ) {
|
|
|
-
|
|
|
- if ( typeof this[ event.type ] == 'function' ) {
|
|
|
-
|
|
|
- this[ event.type ]( event );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.getMouseOnScreen = function ( clientX, clientY ) {
|
|
|
-
|
|
|
- return new THREE.Vector2(
|
|
|
- ( clientX - _this.screen.offsetLeft ) / _this.radius * 0.5,
|
|
|
- ( clientY - _this.screen.offsetTop ) / _this.radius * 0.5
|
|
|
- );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.getMouseProjectionOnBall = function ( clientX, clientY ) {
|
|
|
-
|
|
|
- var mouseOnBall = new THREE.Vector3(
|
|
|
- ( clientX - _this.screen.width * 0.5 - _this.screen.offsetLeft ) / _this.radius,
|
|
|
- ( _this.screen.height * 0.5 + _this.screen.offsetTop - clientY ) / _this.radius,
|
|
|
- 0.0
|
|
|
- );
|
|
|
-
|
|
|
- var length = mouseOnBall.length();
|
|
|
-
|
|
|
- if ( length > 1.0 ) {
|
|
|
-
|
|
|
- mouseOnBall.normalize();
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- mouseOnBall.z = Math.sqrt( 1.0 - length * length );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _eye.copy( _this.object.position ).subSelf( _this.target );
|
|
|
-
|
|
|
- var projection = _this.object.up.clone().setLength( mouseOnBall.y );
|
|
|
- projection.addSelf( _this.object.up.clone().crossSelf( _eye ).setLength( mouseOnBall.x ) );
|
|
|
- projection.addSelf( _eye.setLength( mouseOnBall.z ) );
|
|
|
-
|
|
|
- return projection;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.rotateCamera = function () {
|
|
|
-
|
|
|
- var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
|
|
|
-
|
|
|
- if ( angle ) {
|
|
|
-
|
|
|
- var axis = ( new THREE.Vector3() ).cross( _rotateStart, _rotateEnd ).normalize(),
|
|
|
- quaternion = new THREE.Quaternion();
|
|
|
-
|
|
|
- angle *= _this.rotateSpeed;
|
|
|
-
|
|
|
- quaternion.setFromAxisAngle( axis, -angle );
|
|
|
-
|
|
|
- quaternion.multiplyVector3( _eye );
|
|
|
- quaternion.multiplyVector3( _this.object.up );
|
|
|
-
|
|
|
- quaternion.multiplyVector3( _rotateEnd );
|
|
|
-
|
|
|
- if ( _this.staticMoving ) {
|
|
|
-
|
|
|
- _rotateStart.copy( _rotateEnd );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
|
|
|
- quaternion.multiplyVector3( _rotateStart );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.zoomCamera = function () {
|
|
|
-
|
|
|
- var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
|
|
|
-
|
|
|
- if ( factor !== 1.0 && factor > 0.0 ) {
|
|
|
-
|
|
|
- _eye.multiplyScalar( factor );
|
|
|
-
|
|
|
- if ( _this.staticMoving ) {
|
|
|
-
|
|
|
- _zoomStart.copy( _zoomEnd );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.panCamera = function () {
|
|
|
-
|
|
|
- var mouseChange = _panEnd.clone().subSelf( _panStart );
|
|
|
-
|
|
|
- if ( mouseChange.lengthSq() ) {
|
|
|
-
|
|
|
- mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
|
|
|
-
|
|
|
- var pan = _eye.clone().crossSelf( _this.object.up ).setLength( mouseChange.x );
|
|
|
- pan.addSelf( _this.object.up.clone().setLength( mouseChange.y ) );
|
|
|
-
|
|
|
- _this.object.position.addSelf( pan );
|
|
|
- _this.target.addSelf( pan );
|
|
|
-
|
|
|
- if ( _this.staticMoving ) {
|
|
|
-
|
|
|
- _panStart = _panEnd;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _panStart.addSelf( mouseChange.sub( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.checkDistances = function () {
|
|
|
-
|
|
|
- if ( !_this.noZoom || !_this.noPan ) {
|
|
|
-
|
|
|
- if ( _this.object.position.lengthSq() > _this.maxDistance * _this.maxDistance ) {
|
|
|
-
|
|
|
- _this.object.position.setLength( _this.maxDistance );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
|
|
|
-
|
|
|
- _this.object.position.add( _this.target, _eye.setLength( _this.minDistance ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.update = function () {
|
|
|
-
|
|
|
- _eye.copy( _this.object.position ).subSelf( _this.target );
|
|
|
-
|
|
|
- if ( !_this.noRotate ) {
|
|
|
-
|
|
|
- _this.rotateCamera();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( !_this.noZoom ) {
|
|
|
-
|
|
|
- _this.zoomCamera();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( !_this.noPan ) {
|
|
|
-
|
|
|
- _this.panCamera();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _this.object.position.add( _this.target, _eye );
|
|
|
-
|
|
|
- _this.checkDistances();
|
|
|
-
|
|
|
- _this.object.lookAt( _this.target );
|
|
|
-
|
|
|
- if ( lastPosition.distanceToSquared( _this.object.position ) > 0 ) {
|
|
|
-
|
|
|
- _this.dispatchEvent( changeEvent );
|
|
|
-
|
|
|
- lastPosition.copy( _this.object.position );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- // listeners
|
|
|
-
|
|
|
- function keydown( event ) {
|
|
|
-
|
|
|
- if ( ! _this.enabled ) return;
|
|
|
-
|
|
|
- //event.preventDefault();
|
|
|
-
|
|
|
- if ( _state !== STATE.NONE ) {
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
|
|
|
-
|
|
|
- _state = STATE.ROTATE;
|
|
|
-
|
|
|
- } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
|
|
|
-
|
|
|
- _state = STATE.ZOOM;
|
|
|
-
|
|
|
- } else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
|
|
|
-
|
|
|
- _state = STATE.PAN;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( _state !== STATE.NONE ) {
|
|
|
-
|
|
|
- _keyPressed = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function keyup( event ) {
|
|
|
-
|
|
|
- if ( ! _this.enabled ) return;
|
|
|
-
|
|
|
- if ( _state !== STATE.NONE ) {
|
|
|
-
|
|
|
- _state = STATE.NONE;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function mousedown( event ) {
|
|
|
-
|
|
|
- if ( ! _this.enabled ) return;
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- if ( _state === STATE.NONE ) {
|
|
|
-
|
|
|
- _state = event.button;
|
|
|
-
|
|
|
- if ( _state === STATE.ROTATE && !_this.noRotate ) {
|
|
|
-
|
|
|
- _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
|
|
|
-
|
|
|
- } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
|
|
|
-
|
|
|
- _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
-
|
|
|
- } else if ( !this.noPan ) {
|
|
|
-
|
|
|
- _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function mousemove( event ) {
|
|
|
-
|
|
|
- if ( ! _this.enabled ) return;
|
|
|
-
|
|
|
- if ( _keyPressed ) {
|
|
|
-
|
|
|
- _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
|
|
|
- _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
- _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
-
|
|
|
- _keyPressed = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( _state === STATE.NONE ) {
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- } else if ( _state === STATE.ROTATE && !_this.noRotate ) {
|
|
|
-
|
|
|
- _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
|
|
|
-
|
|
|
- } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
|
|
|
-
|
|
|
- _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
-
|
|
|
- } else if ( _state === STATE.PAN && !_this.noPan ) {
|
|
|
-
|
|
|
- _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function mouseup( event ) {
|
|
|
-
|
|
|
- if ( ! _this.enabled ) return;
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- _state = STATE.NONE;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function mousewheel( event ) {
|
|
|
-
|
|
|
- if ( ! _this.enabled ) return;
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
- event.stopPropagation();
|
|
|
-
|
|
|
- var delta = 0;
|
|
|
-
|
|
|
- if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
|
|
|
-
|
|
|
- delta = event.wheelDelta / 40;
|
|
|
-
|
|
|
- } else if ( event.detail ) { // Firefox
|
|
|
-
|
|
|
- delta = - event.detail / 3;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _zoomStart.y += ( 1 / delta ) * 0.05;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'mousemove', mousemove, false );
|
|
|
- this.domElement.addEventListener( 'mousedown', mousedown, false );
|
|
|
- this.domElement.addEventListener( 'mouseup', mouseup, false );
|
|
|
- this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false );
|
|
|
- this.domElement.addEventListener( 'mousewheel', mousewheel, false );
|
|
|
-
|
|
|
- window.addEventListener( 'keydown', keydown, false );
|
|
|
- window.addEventListener( 'keyup', keyup, false );
|
|
|
-
|
|
|
- this.handleResize();
|
|
|
-
|
|
|
-};
|
|
|
-/**
|
|
|
- * @author qiao / https://github.com/qiao
|
|
|
- * @author mrdoob / http://mrdoob.com
|
|
|
- * @author alteredq / http://alteredqualia.com/
|
|
|
- * @author WestLangley / https://github.com/WestLangley
|
|
|
- */
|
|
|
-
|
|
|
-THREE.OrbitControls = function ( object, domElement ) {
|
|
|
-
|
|
|
- THREE.EventTarget.call( this );
|
|
|
-
|
|
|
- this.object = object;
|
|
|
- this.domElement = ( domElement !== undefined ) ? domElement : document;
|
|
|
-
|
|
|
- // API
|
|
|
-
|
|
|
- this.center = new THREE.Vector3();
|
|
|
-
|
|
|
- this.userZoom = true;
|
|
|
- this.userZoomSpeed = 1.0;
|
|
|
-
|
|
|
- this.userRotate = true;
|
|
|
- this.userRotateSpeed = 1.0;
|
|
|
-
|
|
|
- this.autoRotate = false;
|
|
|
- this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
|
|
|
-
|
|
|
- this.minPolarAngle = 0; // radians
|
|
|
- this.maxPolarAngle = Math.PI; // radians
|
|
|
-
|
|
|
- this.minDistance = 0;
|
|
|
- this.maxDistance = Infinity;
|
|
|
-
|
|
|
- // internals
|
|
|
-
|
|
|
- var scope = this;
|
|
|
-
|
|
|
- var EPS = 0.000001;
|
|
|
- var PIXELS_PER_ROUND = 1800;
|
|
|
-
|
|
|
- var rotateStart = new THREE.Vector2();
|
|
|
- var rotateEnd = new THREE.Vector2();
|
|
|
- var rotateDelta = new THREE.Vector2();
|
|
|
-
|
|
|
- var zoomStart = new THREE.Vector2();
|
|
|
- var zoomEnd = new THREE.Vector2();
|
|
|
- var zoomDelta = new THREE.Vector2();
|
|
|
-
|
|
|
- var phiDelta = 0;
|
|
|
- var thetaDelta = 0;
|
|
|
- var scale = 1;
|
|
|
-
|
|
|
- var lastPosition = new THREE.Vector3();
|
|
|
-
|
|
|
- var STATE = { NONE : -1, ROTATE : 0, ZOOM : 1 };
|
|
|
- var state = STATE.NONE;
|
|
|
-
|
|
|
- // events
|
|
|
-
|
|
|
- var changeEvent = { type: 'change' };
|
|
|
-
|
|
|
-
|
|
|
- this.rotateLeft = function ( angle ) {
|
|
|
-
|
|
|
- if ( angle === undefined ) {
|
|
|
-
|
|
|
- angle = getAutoRotationAngle();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- thetaDelta -= angle;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.rotateRight = function ( angle ) {
|
|
|
-
|
|
|
- if ( angle === undefined ) {
|
|
|
-
|
|
|
- angle = getAutoRotationAngle();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- thetaDelta += angle;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.rotateUp = function ( angle ) {
|
|
|
-
|
|
|
- if ( angle === undefined ) {
|
|
|
-
|
|
|
- angle = getAutoRotationAngle();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- phiDelta -= angle;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.rotateDown = function ( angle ) {
|
|
|
-
|
|
|
- if ( angle === undefined ) {
|
|
|
-
|
|
|
- angle = getAutoRotationAngle();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- phiDelta += angle;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.zoomIn = function ( zoomScale ) {
|
|
|
-
|
|
|
- if ( zoomScale === undefined ) {
|
|
|
-
|
|
|
- zoomScale = getZoomScale();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- scale /= zoomScale;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.zoomOut = function ( zoomScale ) {
|
|
|
-
|
|
|
- if ( zoomScale === undefined ) {
|
|
|
-
|
|
|
- zoomScale = getZoomScale();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- scale *= zoomScale;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.update = function () {
|
|
|
-
|
|
|
- var position = this.object.position;
|
|
|
- var offset = position.clone().subSelf( this.center )
|
|
|
-
|
|
|
- // angle from z-axis around y-axis
|
|
|
-
|
|
|
- var theta = Math.atan2( offset.x, offset.z );
|
|
|
-
|
|
|
- // angle from y-axis
|
|
|
-
|
|
|
- var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
|
|
|
-
|
|
|
- if ( this.autoRotate ) {
|
|
|
-
|
|
|
- this.rotateLeft( getAutoRotationAngle() );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- theta += thetaDelta;
|
|
|
- phi += phiDelta;
|
|
|
-
|
|
|
- // restrict phi to be between desired limits
|
|
|
- phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
|
|
|
-
|
|
|
- // restrict phi to be betwee EPS and PI-EPS
|
|
|
- phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
|
|
|
-
|
|
|
- var radius = offset.length() * scale;
|
|
|
-
|
|
|
- // restrict radius to be between desired limits
|
|
|
- radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
|
|
|
-
|
|
|
- offset.x = radius * Math.sin( phi ) * Math.sin( theta );
|
|
|
- offset.y = radius * Math.cos( phi );
|
|
|
- offset.z = radius * Math.sin( phi ) * Math.cos( theta );
|
|
|
-
|
|
|
- position.copy( this.center ).addSelf( offset );
|
|
|
-
|
|
|
- this.object.lookAt( this.center );
|
|
|
-
|
|
|
- thetaDelta = 0;
|
|
|
- phiDelta = 0;
|
|
|
- scale = 1;
|
|
|
-
|
|
|
- if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
|
|
|
-
|
|
|
- this.dispatchEvent( changeEvent );
|
|
|
-
|
|
|
- lastPosition.copy( this.object.position );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- function getAutoRotationAngle() {
|
|
|
-
|
|
|
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function getZoomScale() {
|
|
|
-
|
|
|
- return Math.pow( 0.95, scope.userZoomSpeed );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onMouseDown( event ) {
|
|
|
-
|
|
|
- if ( !scope.userRotate ) return;
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
-
|
|
|
- if ( event.button === 0 || event.button === 2 ) {
|
|
|
-
|
|
|
- state = STATE.ROTATE;
|
|
|
-
|
|
|
- rotateStart.set( event.clientX, event.clientY );
|
|
|
-
|
|
|
- } else if ( event.button === 1 ) {
|
|
|
-
|
|
|
- state = STATE.ZOOM;
|
|
|
-
|
|
|
- zoomStart.set( event.clientX, event.clientY );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- document.addEventListener( 'mousemove', onMouseMove, false );
|
|
|
- document.addEventListener( 'mouseup', onMouseUp, false );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onMouseMove( event ) {
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
-
|
|
|
- if ( state === STATE.ROTATE ) {
|
|
|
-
|
|
|
- rotateEnd.set( event.clientX, event.clientY );
|
|
|
- rotateDelta.sub( rotateEnd, rotateStart );
|
|
|
-
|
|
|
- scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
|
|
|
- scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );
|
|
|
-
|
|
|
- rotateStart.copy( rotateEnd );
|
|
|
-
|
|
|
- } else if ( state === STATE.ZOOM ) {
|
|
|
-
|
|
|
- zoomEnd.set( event.clientX, event.clientY );
|
|
|
- zoomDelta.sub( zoomEnd, zoomStart );
|
|
|
-
|
|
|
- if ( zoomDelta.y > 0 ) {
|
|
|
-
|
|
|
- scope.zoomIn();
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- scope.zoomOut();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- zoomStart.copy( zoomEnd );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onMouseUp( event ) {
|
|
|
-
|
|
|
- if ( ! scope.userRotate ) return;
|
|
|
-
|
|
|
- document.removeEventListener( 'mousemove', onMouseMove, false );
|
|
|
- document.removeEventListener( 'mouseup', onMouseUp, false );
|
|
|
-
|
|
|
- state = STATE.NONE;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onMouseWheel( event ) {
|
|
|
-
|
|
|
- if ( ! scope.userZoom ) return;
|
|
|
-
|
|
|
- if ( event.wheelDelta > 0 ) {
|
|
|
-
|
|
|
- scope.zoomOut();
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- scope.zoomIn();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
|
|
- this.domElement.addEventListener( 'mousedown', onMouseDown, false );
|
|
|
- this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
|
|
|
-
|
|
|
-};
|
|
|
/**
|
|
|
* @author hughes
|
|
|
*/
|