You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
4.8 KiB
201 lines
4.8 KiB
|
|
// 绕当前视点旋转 |
|
RotControl = function ( camera, div) { |
|
|
|
var self = this; |
|
var $div = $(div); |
|
camera.target = new THREE.Vector3( 0, 0, 0 ); |
|
|
|
// 事件,回调函数 |
|
this.onRot = function(event){ |
|
} |
|
|
|
var limit = Math.PI *3/ 4; |
|
|
|
|
|
var first = true; |
|
var drag = false; |
|
var lastX=0; |
|
var lastY=0; |
|
var lastDist=0; |
|
|
|
|
|
|
|
// touch消息里没有offseXY数值,我得想办法从其他数值计算出来 |
|
// 以前我记得做过,好像是要遍历父子链 |
|
function getDivPos(div) |
|
{ |
|
var pos={}; |
|
pos.x = div.offsetLeft; |
|
pos.y = div.offsetTop; |
|
while(div.offsetParent!=null) |
|
{ |
|
div = div.offsetParent; |
|
pos.x += div.offsetLeft; |
|
pos.y += div.offsetTop; |
|
} |
|
return pos; |
|
} |
|
function calcOffset(event) |
|
{ |
|
if (event.offsetX != null) |
|
return; |
|
|
|
var pos = getDivPos(event.target); |
|
event.offsetX = event.clientX - pos.x + document.body.scrollLeft; |
|
event.offsetY = event.clientY - pos.y + document.body.scrollTop; |
|
} |
|
|
|
var onMouseDown = function ( event ) { |
|
drag = true; |
|
first = true; |
|
} |
|
var onMouseUp = function ( event ) { |
|
drag = false; |
|
} |
|
var onMouseMove = function ( event ) { |
|
|
|
/* |
|
var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; |
|
var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; |
|
*/ |
|
|
|
if (event.originalEvent.touches !=null) |
|
{ |
|
if (event.originalEvent.touches.length>=2)//缩放 |
|
{ |
|
var m1 = event.originalEvent.touches[0]; |
|
var m2 = event.originalEvent.touches[1]; |
|
var dx = m1.clientX-m2.clientX; |
|
var dy = m1.clientY-m2.clientY; |
|
|
|
var dist = Math.sqrt(dx*dx+dy*dy); |
|
var delta = dist - lastDist; |
|
lastDist = dist; |
|
if (first) |
|
{ |
|
first = false; |
|
return; |
|
} |
|
|
|
if (delta>0 && camera.fov>5){ |
|
camera.fov*=0.99; |
|
camera.updateProjectionMatrix(); |
|
}else if (delta<0 && camera.fov<90){ |
|
camera.fov*=1.01;; |
|
camera.updateProjectionMatrix(); |
|
} |
|
|
|
|
|
return; |
|
} |
|
else if (event.originalEvent.touches.length>=1)//模仿鼠标 |
|
{ |
|
event = event.originalEvent.touches[0]; |
|
// 重点touch消息里没有offseXY数值,我得想办法从其他数值计算出来 |
|
calcOffset(event); |
|
// |
|
event.buttons = 1; |
|
} |
|
else //说明length=0,应该不可能 |
|
{ |
|
return; |
|
} |
|
} |
|
|
|
var movementX = event.offsetX-lastX; |
|
var movementY = event.offsetY-lastY; |
|
lastX = event.offsetX; |
|
lastY = event.offsetY; |
|
|
|
if (first) |
|
{ |
|
first = false; |
|
return; |
|
} |
|
|
|
|
|
if ( self.enabled == false ) |
|
return; |
|
// event.button\buttons\which和按键有关 |
|
// 但没有按键时,button也等于0,和左键冲突 |
|
// buttons=1、4、2,好像是ie的定义 |
|
// which=1、2、3,比较正常 |
|
//if (event.which == 0)//左中右健按下,意味着开始拖拽,ie下放开按键后,仍然保持状态 |
|
// return; |
|
if (event.buttons == 0)//左中右健按下,意味着开始拖拽 |
|
return; |
|
if (!drag) |
|
return; |
|
|
|
// 对camera施加一个微小的旋转,直接改变matrix |
|
|
|
// 1 更新prs到matrix |
|
//camera.updateMatrix(); |
|
|
|
// |
|
var angleZ = 0.02*camera.fov*movementX/div.clientHeight; |
|
var angleX = 0.02*camera.fov*movementY/div.clientHeight; |
|
|
|
|
|
var dir = camera.getWorldDirection(); |
|
var up = new THREE.Vector3(0,0,1); |
|
var side = new THREE.Vector3(); |
|
side.crossVectors(dir, up); |
|
side.normalize(); |
|
var rotX = new THREE.Quaternion(); rotX.setFromAxisAngle(side, angleX); |
|
var rotZ = new THREE.Quaternion(); rotZ.setFromAxisAngle(up, angleZ); |
|
|
|
// 限制上下不能垂直 |
|
var temp = new THREE.Vector3(); |
|
temp.copy(dir); |
|
temp.applyQuaternion(rotX); |
|
if (Math.abs(temp.z)<0.9) |
|
dir.applyQuaternion(rotX); |
|
dir.applyQuaternion(rotZ); |
|
|
|
var pos = camera.position; |
|
var tar = new THREE.Vector3(); |
|
tar.addVectors(pos, dir); |
|
camera.up.set(0,0,1); |
|
camera.lookAt(tar); |
|
|
|
// 这里一大堆是为了从视线计算出航向角 |
|
var dir = camera.getWorldDirection(); |
|
// 注意,heading的目的地是leaflet的orientedMarker |
|
// 他的起始轴是y轴,但正方向是顺时针 |
|
var heading= Math.atan2(dir.x, dir.y)*180/Math.PI;//[-pi, pi] |
|
var fovy = camera.fov; |
|
var fovx = (Math.atan(Math.tan(fovy/2)*camera.aspect)*2)*180/Math.PI; |
|
var eventEye = {heading:heading, fovx:fovx}; |
|
self.onRot(eventEye); |
|
|
|
}; |
|
|
|
this.dispose = function() { |
|
|
|
$div.unbind( 'mousemove', onMouseMove ); |
|
$div.unbind( 'mousedown', onMouseDown ); |
|
$div.unbind( 'mouseup', onMouseUp ); |
|
// $div.unbind( 'touchmove', onMouseMove ); |
|
// $div.unbind( 'touchstart', onMouseDown ); |
|
// $div.unbind( 'touchend', onMouseUp ); |
|
|
|
}; |
|
|
|
$div.bind( 'mousemove', onMouseMove ); |
|
$div.bind( 'mousedown', onMouseDown ); |
|
$div.bind( 'mouseup', onMouseUp ); |
|
$div.bind( 'touchmove', onMouseMove ); |
|
$div.bind( 'touchstart', onMouseDown ); |
|
$div.bind( 'touchend', onMouseUp ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.enabled = false; |
|
|
|
};
|
|
|