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.
202 lines
4.8 KiB
202 lines
4.8 KiB
|
4 months ago
|
|
||
|
|
// 绕当前视点旋转
|
||
|
|
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;
|
||
|
|
|
||
|
|
};
|