python绘制三维地形_基于WebGL的三维地形渲染

/**

* @author Eberhard Graether / http://egraether.com/*/THREE.TrackballControls= function( object, domElement ) {var _this = this;var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM: 4, TOUCH_PAN: 5};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 = newTHREE.Vector3();var lastPosition = newTHREE.Vector3();var _state =STATE.NONE,

_prevState=STATE.NONE,

_eye= newTHREE.Vector3(),

_rotateStart= newTHREE.Vector3(),

_rotateEnd= newTHREE.Vector3(),

_zoomStart= newTHREE.Vector2(),

_zoomEnd= newTHREE.Vector2(),

_touchZoomDistanceStart= 0,

_touchZoomDistanceEnd= 0,

_panStart= newTHREE.Vector2(),

_panEnd= newTHREE.Vector2();//for reset

this.target0 = this.target.clone();this.position0 = this.object.position.clone();this.up0 = this.object.up.clone();//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 newTHREE.Vector2(

( clientX- _this.screen.offsetLeft ) / _this.radius * 0.5,

( clientY- _this.screen.offsetTop ) / _this.radius * 0.5);

};this.getMouseProjectionOnBall = function( clientX, clientY ) {var mouseOnBall = newTHREE.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 ).sub( _this.target );var projection =_this.object.up.clone().setLength( mouseOnBall.y );

projection.add( _this.object.up.clone().cross( _eye ).setLength( mouseOnBall.x ) );

projection.add( _eye.setLength( mouseOnBall.z ) );returnprojection;

};this.rotateCamera = function() {var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() /_rotateEnd.length() );if( angle ) {var axis = ( newTHREE.Vector3() ).crossVectors( _rotateStart, _rotateEnd ).normalize();

quaternion= newTHREE.Quaternion();

angle*=_this.rotateSpeed;

quaternion.setFromAxisAngle( axis,-angle );

_eye.applyQuaternion( quaternion );

_this.object.up.applyQuaternion( quaternion );

_rotateEnd.applyQuaternion( quaternion );if( _this.staticMoving ) {

_rotateStart.copy( _rotateEnd );

}else{

quaternion.setFromAxisAngle( axis, angle* ( _this.dynamicDampingFactor - 1.0) );

_rotateStart.applyQuaternion( quaternion );

}

}

};this.zoomCamera = function() {if ( _state ===STATE.TOUCH_ZOOM ) {var factor = _touchZoomDistanceStart /_touchZoomDistanceEnd;

_touchZoomDistanceStart=_touchZoomDistanceEnd;

_eye.multiplyScalar( factor );

}else{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().sub( _panStart );if( mouseChange.lengthSq() ) {

mouseChange.multiplyScalar( _eye.length()*_this.panSpeed );var pan =_eye.clone().cross( _this.object.up ).setLength( mouseChange.x );

pan.add( _this.object.up.clone().setLength( mouseChange.y ) );

_this.object.position.add( pan );

_this.target.add( pan );if( _this.staticMoving ) {

_panStart=_panEnd;

}else{

_panStart.add( mouseChange.subVectors( _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.addVectors( _this.target, _eye.setLength( _this.minDistance ) );

}

}

};this.update = function() {

_eye.subVectors( _this.object.position, _this.target );if ( !_this.noRotate ) {

_this.rotateCamera();

}if ( !_this.noZoom ) {

_this.zoomCamera();

}if ( !_this.noPan ) {

_this.panCamera();

}

_this.object.position.addVectors( _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 );

}

};this.reset = function() {

_state=STATE.NONE;

_prevState=STATE.NONE;

_this.target.copy( _this.target0 );

_this.object.position.copy( _this.position0 );

_this.object.up.copy( _this.up0 );

_eye.subVectors( _this.object.position, _this.target );

_this.object.lookAt( _this.target );

_this.dispatchEvent( changeEvent );

lastPosition.copy( _this.object.position );

};//listeners

functionkeydown( event ) {if ( _this.enabled === false ) return;

window.removeEventListener(‘keydown‘, keydown );

_prevState=_state;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;

}

}functionkeyup( event ) {if ( _this.enabled === false ) return;

_state=_prevState;

window.addEventListener(‘keydown‘, keydown, false);

}functionmousedown( event ) {if ( _this.enabled === false ) 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 ( _state === STATE.PAN && !_this.noPan ) {

_panStart= _panEnd =_this.getMouseOnScreen( event.clientX, event.clientY );

}

document.addEventListener(‘mousemove‘, mousemove, false);

document.addEventListener(‘mouseup‘, mouseup, false);

}functionmousemove( event ) {if ( _this.enabled === false ) return;

event.preventDefault();

event.stopPropagation();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 );

}

}functionmouseup( event ) {if ( _this.enabled === false ) return;

event.preventDefault();

event.stopPropagation();

_state=STATE.NONE;

document.removeEventListener(‘mousemove‘, mousemove );

document.removeEventListener(‘mouseup‘, mouseup );

}functionmousewheel( event ) {if ( _this.enabled === false ) 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+= delta * 0.01;

}functiontouchstart( event ) {if ( _this.enabled === false ) return;switch( event.touches.length ) {case 1:

_state=STATE.TOUCH_ROTATE;

_rotateStart= _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0].pageY );break;case 2:

_state=STATE.TOUCH_ZOOM;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 );break;case 3:

_state=STATE.TOUCH_PAN;

_panStart= _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0].pageY );break;default:

_state=STATE.NONE;

}

}functiontouchmove( event ) {if ( _this.enabled === false ) return;

event.preventDefault();

event.stopPropagation();switch( event.touches.length ) {case 1:

_rotateEnd= _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0].pageY );break;case 2: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 )break;case 3:

_panEnd= _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0].pageY );break;default:

_state=STATE.NONE;

}

}functiontouchend( event ) {if ( _this.enabled === false ) return;switch( event.touches.length ) {case 1:

_rotateStart= _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0].pageY );break;case 2:

_touchZoomDistanceStart= _touchZoomDistanceEnd = 0;break;case 3:

_panStart= _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0].pageY );break;

}

_state=STATE.NONE;

}this.domElement.addEventListener( ‘contextmenu‘, function ( event ) { event.preventDefault(); }, false);this.domElement.addEventListener( ‘mousedown‘, mousedown, false);this.domElement.addEventListener( ‘mousewheel‘, mousewheel, false);this.domElement.addEventListener( ‘DOMMouseScroll‘, mousewheel, false ); //firefox

this.domElement.addEventListener( ‘touchstart‘, touchstart, false);this.domElement.addEventListener( ‘touchend‘, touchend, false);this.domElement.addEventListener( ‘touchmove‘, touchmove, false);

window.addEventListener(‘keydown‘, keydown, false);

window.addEventListener(‘keyup‘, keyup, false);this.handleResize();

};

THREE.TrackballControls.prototype= Object.create( THREE.EventDispatcher.prototype );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值