2013-02-19 101 views
0

我可以確定用戶在地球上的哪個地方有clicked用鼠標旋轉地球儀

當用戶第一次點擊鼠標按鈕時,我可以存儲他們點擊的位置;我們稱之爲pin

然後,當他們拖動鼠標時,我想將pin放在鼠標光標下。

enter image description here

下面是一些代碼,這似乎大致保持pin鼠標指針下,但不正確維護全球;它隨機閃爍並旋轉。有時候它會完全翻轉軸線,因此地球瞬間反向前進。

function evtPos(evt) { 
    if(!scene.ortho) return null; 
    var x = lerp(scene.ortho[0],scene.ortho[1],evt.clientX/canvas.width), 
     y = lerp(scene.ortho[3],scene.ortho[2],evt.clientY/canvas.height), // flipped 
     sqrd = x*x+y*y; 
    return (sqrd > 1)? 
     null: 
     mat4_vec3_multiply(mat4_inverse(scene.mvMatrix),[x,y,Math.sqrt(1-sqrd)]); 
} 

function onMouseDown(evt) { 
    pin = evtPos(evt); 
} 

function onMouseMove(evt,keys,isMouseDown) { 
    if(!isMouseDown) return; 
    var pt = evtPos(evt); 
    if(pin == null) pin = pt; 
    if(pt == null) return; 
    var d = vec3_sub(pt,pin), 
     rotx = Math.atan2(d[1],d[2]), 
     roty = (d[2] >= 0)? 
      -Math.atan2(d[0] * Math.cos(rotx),d[2]): 
      Math.atan2(d[0] * Math.cos(rotx),-d[2]), 
     rotz = Math.atan2(Math.cos(rotx),Math.sin(rotx)*Math.sin(roty)); 
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotx,[1,0,0])); 
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(roty,[0,1,0])); 
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotz,[0,0,1])); 
} 

function onMouseUp(evt) { 
    pin = null; 
} 

另外,隨着時間的推移,一個錯誤似乎建立和pin從鼠標指針進一步和進一步漂移。我想我應該以某種方式完全計算mvMatrix,而不是每次事件都採用很多小數增量。

我希望用戶能夠拖動地球自然地導航。所有旋轉地球儀的代碼都使用固定的速度,例如箭頭鍵,而不是將鼠標指針固定在地球上。 Unity有一個功能Quaternion.FromToRotation(fromPos,toPos),這看起來很有希望,但是該源不可用。

+3

判斷這個問題,你是[上一個](http://stackoverflow.com/questions/14964257/clicking-on-a-sphere),似乎你想要StackOverflow來爲你實現你的項目。你嘗試了什麼,你卡在哪裏? – 2013-02-19 19:54:28

+0

如果你至少不嘗試你可能會發現尋求幫助是徒勞的。 – Popnoodles 2013-02-19 20:04:42

+1

@popnoodles你只需要先告訴我該先試一下,然後我可以進行調查和嘗試。有時甚至開始解決問題的方式並不明顯。我已經提供了一些代碼,但我知道它是有缺陷的,而不是簡單的可修改的。 – Will 2013-02-19 20:09:11

回答