公路局项目
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

// 绕当前视点旋转
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;
};