【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的球上來控制。

            

    

 

  

       

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM