【Three.js】OrbitControl 旋转

一、摘要

     分析了OrbitControl的基本原理。

二、资源

     源码地址:

三、分析

       最外层框架:OrbitControl 为函数对象,原型处理

THREE.OrbitControls = function ( object , domElement){
    ...
}

THREE.OrbitControls.protorype = Object.create ( THREE.EventDispatcher.prototype);

 

      object : 控制的对象

      domElement : 3D模型控制范围 , 缺省为document 。 

      接下去开始是一些变量定义以及函数定义,看旋转实现即

this.domElement.addEventListener( 'mousedown', onMouseDown, false );

      onMouseDown函数处理:捕捉event.button时间(0|1|2)分别对(left|middle|right),对应事件(rotate|zoom|pan)

if ( event.button === 0 ) {
            if ( scope.noRotate === true ) return;

            state = STATE.ROTATE;

            rotateStart.set( event.clientX, event.clientY );

        } 
else{
.....
}

scope.domElement.addEventListener( 'mousemove', onMouseMove, false );
scope.domElement.addEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( startEvent );

   变量说明:

    scope = this;

    rotateStart , rotateEnd 为Vector2。记录当前二维坐标为初始终止点。

    增加监听mousemove,mouseup。

    mousemove事件onMouseMove:

if ( state === STATE.ROTATE ) {

            if ( scope.noRotate === true ) return;

            rotateEnd.set( event.clientX, event.clientY );
            rotateDelta.subVectors( rotateEnd, rotateStart );

            // rotating across whole screen goes 360 degrees around
            scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );

            // rotating up and down along whole screen attempts to go 360, but limited to 180
            scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );

            rotateStart.copy( rotateEnd );

        } 
else{
    ...
}
scope.update();

       鼠标移动中,记录当前坐标为rotateEnd,计算start与End差为rotateDelta。rotateLeft与rotateUp将二维差值记录到 角度差值 thetaDelta  与 phiDelta中。

       代码中可以看到thetaDelta 与x方向偏移的,phidelta与y偏移成正比。直观得想,x方向移动即让物体沿经度大圆的旋转,过中心绕Y轴。y方向即物体的上下旋转。

       接下来就是theta 和 phi 的问题。高中立体几何基本知识了。theta和phi就是下面2个角度了。

   

            重点在于scope.update.

    update做的主要事情也就几件

    重新计算theta和phi,计算移动后的三维坐标。控制旋转。之后可加上自己对旋转角度的控制。

theta += thetaDelta;
phi += phiDelta;

  加上pan改变target的位置,调整位置。

// move target to panned location
 this.target.add( pan );

 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.target ).add( offset );

 this.object.lookAt( this.target );

四、总结

     OrbitControl处理比较好理解,ThrackballControl.js的方式好像是放在一个半斤为1的球上来控制。

            

    

 

  

       

 

posted on 2014-03-20 20:23  yyjaaa  阅读(7428)  评论(1编辑  收藏  举报