2015-10-02 46 views
0

背景OpenTK/OpenGL的 - 旋轉的攝像頭,鼠標

目前,我有我顯示,將永遠是在原點的對象。我有我的遞增x和y的角度,然後計算出新的X,Y的函數,Z爲攝像機座標:

Public Sub update_rotation() 
    If cam.manual_lookat = True Then 
     If camangley >= 360 Then 
      camangley = camangley - 360 
     End If 

     If camanglex >= 360 Then 
      camanglex = camanglex - 360 
     End If 

     If camangley < 0 Then 
      camangley = 360 + camangley 
     End If 

     If camanglex < 0 Then 
      camanglex = 360 + camanglex 
     End If 

     If camangley > 90 And camangley <= 270 Then 
      cam.invert_y = True 
     Else 
      cam.invert_y = False 
     End If 


     camx = distance * -Sin(camanglex * (PI/180)) * Cos((camangley) * (PI/180)) 

     camy = distance * -Sin((camangley) * (PI/180)) 

     camz = distance * Cos((camanglex) * (PI/180)) * Cos((camangley) * (PI/180)) 

     cam.Position.X = camx 
     cam.Position.Y = camy 
     cam.Position.Z = camz 
     cam.lookat.X = 0 
     cam.lookat.Y = 0 
     cam.lookat.Z = 0 

     ' Label2.Text = camanglex & "," & camangley 
    End If 

End Sub 

我有這樣的設置爲使用鍵盤事件.. X按鈕添加到camanglex變量,Y按鈕添加到camangley變量,Z按鈕添加到距離變量。

一切正常,這樣做,使用鍵盤。

問題

我想現在使用鼠標來處理旋轉,而不是鍵盤。我相信這只是一個數學問題,但我該如何計算新的camanglex和camangley變量,或者直接計算新的camx,camy,camz以建立我的相機新位置?

我有一個鼠標功能,它將捕捉鼠標座標,但我有計算部分的麻煩。

+0

這不是一個真正的數學問題,因爲你已經完成了繁重的工作。你需要知道的是鼠標從一幀到另一幀的移動量,並將這些值用作「camanglex」和「camangley」的修飾符,這與您對鍵盤輸入的操作非常相似。 –

回答

0

如果你想圍繞物體轉動,你可以追蹤你的鼠標在假球上的路徑(有時稱爲跟蹤球)。有a working example of orbit controls

這裏是類似的東西的僞草圖:

mouseDownEventFunction(event) { 
    computeDragPoint (event.mouseX, event.mouseY, &oldDragPoint); 
    isMouseDown = true; 
} 
mouseUpEventFunction(event) { 
    isMouseDown = false; 
} 
mouseMoveEventFunction(event) { 
    if (isMouseDown) { 
     computeDragPoint (event.mouseX, event.mouseY, &newDragPoint); 
     rotateCamera (oldDragPoint, newDragPoint); 
     oldDragPoint = newDragPoint; 
    } 
} 

在這裏,我們找到軌跡球點:

/* we want to ray trace a point on face side of fake sphere. 
dragPoint* is our result*/ 

computeDragPoint(int x, int y, Vector3* dragPoint) { 
    /* normalize x and y to [-1, 1] so they match flat circle position on screen. 
    And assign this to dragPoint->x and dragPoint->y. 
    This part depends on what you want to achieve and input units of x, y. 
    Keep in mind aspect ratio */ 
    dragPoint->x = (2*x/screenWidth - 0.5) * (screenHeight/screenWidth); 
    dragPoint->y = 2*y/screenHeight - 0.5; 
    dragPoint->x /= sqrt(dragPoint->x*dragPoint->x + dragPoint->y*dragPoint->y); 
    dragPoint->y /= sqrt(dragPoint->x*dragPoint->x + dragPoint->y*dragPoint->y); 

    /* Then having two values in [-1,1] compute corresponding z */ 
    float tmp = dragPoint->x*dragPoint->x + dragPoint->y*dragPoint->y; 
    if (tmp > 1) { 
     dragPoint.x /= sqrt(tmp); 
     dragPoint.y /= sqrt(tmp); 
    } 

    dragPoint->z = -sqrt (1 - dragPoint->x^2 - dragPoint->y^2) || 0; 
} 

和旋轉的數學可以用四元數來完成(或者從歐拉只是矩陣如果角度你不想使用季銨鹽):

rotateCamera(oldDragPoint, newDragPoint) { 
    Quaternion quat = new Quaternion (Config.AngleX, Config.AngleY, Config.AngleZ); 
    quat.normalize(); 

    Quaternion deltaQuat = new Quaternion(); 
    deltaQuat = deltaQuat.setFromUnitVectors(oldDragPoint, newDragPoint); 

    quat = quat.multiply(deltaQuat); 
    quat.normalize(); 

    Vector3 resultAngles = Vector3(); 
    resultAngles.setFromQuaternion(quat); 

    setCameraPositionFromAngles(resultAngles); 
} 

而且在setCameraPositionFromAngles(resultAngles)通過將three basic rotations應用於初始相機位置來設置最終的X,Y,Z座標。所以你的主要參數是resultAngles。你更新角度,然後設置位置。

也許this working example會解釋得更好。

+0

對不起,延遲到這個,但我與您的計算點功能混淆。當你有浮動tmp = dragPoint-> x^2 + dragPoint-> y^2 - >運算符做什麼?對不起,但我正在寫我的VB .NET,所以我不確定這個?在這個函數中如何使用x和y變量? –

+0

A-> x表示這裏的(* a).x。我可能會弄亂代碼,因爲它只是僞代碼,但我的意思是通過指針傳遞A並訪問它的x成員。這裏的dragpoint是一個帶有x,y和z元素的vector3。 – mlkn

+0

如果我有Private Sub computeDragPoint(x As Integer,y As Integer,dragPoint As Vector3)Dim tmp As Single = dragPoint.X^2 + dragPoint.Y^2 If tmp> 1 Then dragPoint.X/= Sqrt( tmp) dragPoint。Y = Sqrt(tmp) End If dragPoint.Z = -Sqrt(1 - dragPoint.X^2 - dragPoint.Y^2)OrElse 0 End Sub這就是我認爲你的意思,變量x和y被使用的是功能中的輸入? –