2012-12-28 361 views
1

我正在使用GLKit和PowerVR庫,用於我的opengl-es 2.0 3D應用程序。 3D場景加載幾個網格,模擬車庫環境。我在車庫的中心有一輛車。我正在嘗試在應用中添加觸摸處理功能,用戶可以在其中旋轉房間(例如,查看圍繞該車的所有4個牆壁)。我也想允許在x軸上旋轉,但限制在一個小範圍內。基本上他們可以從車頂看到地板高度。沿着x軸和y軸旋轉

我可以在Y上旋轉X或X,但不能同時旋​​轉。只要我在兩個軸上旋轉,汽車就會被拋出軸線。汽車與攝像機不在同一水平。我希望我能更好地解釋這一點,但希望你們能理解。

這是我接觸的實現:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 

    UITouch * touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:self.view];  
    CGPoint lastLoc = [touch previousLocationInView:self.view]; 
    CGPoint diff = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y); 

    float rotX = -1 * GLKMathDegreesToRadians(diff.x/4.0); 
    float rotY = GLKMathDegreesToRadians(diff.y/5.0); 

    PVRTVec3 xAxis = PVRTVec3(1, 0, 0); 
    PVRTVec3 yAxis = PVRTVec3(0,1,0); 

    PVRTMat4 yRotMatrix, xRotMatrix; 

    // create rotation matrices with angle 
    PVRTMatrixRotationXF(yRotMatrix, rotY); 
    PVRTMatrixRotationYF(xRotMatrix, -rotX); 

    _rotationY = _rotationY * yRotMatrix; 
    _rotationX = _rotationX * xRotMatrix; 
} 

這裏是我的更新方法:

- (void)update { 

    // Use the loaded effect 
    m_pEffect->Activate(); 


    PVRTVec3 vFrom, vTo, vUp; 
    VERTTYPE fFOV; 
    vUp.x = 0.0f; 
    vUp.y = 1.0f; 
    vUp.z = 0.0f; 

    // We can get the camera position, target and field of view (fov) with GetCameraPos() 
    fFOV = m_Scene.GetCameraPos(vFrom, vTo, 0); 

    /* 
    We can build the world view matrix from the camera position, target and an up vector. 
    For this we use PVRTMat4LookAtRH(). 
    */ 
    m_mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp); 

    // rotate the camera based on the users swipe in the X direction (THIS WORKS) 
    m_mView = m_mView * _rotationX; 

    // Calculates the projection matrix 
    bool bRotate = false; 
    m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)1024.0/768.0, CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate); 
} 

我第一次嘗試新的X軸旋轉矩陣到當前場景旋轉相乘,再乘以新的Y旋轉矩陣秒。我嘗試了相反的一面,認爲乘法的順序是我的問題。這沒有幫助。然後,我嘗試將新的X和Y旋轉矩陣加到一起,然後再乘以當前的旋轉,但這也不起作用。我覺得我很接近,但在這一點上,我只是沒有想法。

你們能幫忙嗎?謝謝。 -Valerie

更新:爲了解決這個問題,我試圖簡化它。我更新了上面的代碼,刪除了Y旋轉範圍內的任何限制。基本上我根據用戶在屏幕上的滑動來計算X和Y旋轉。

如果我正確理解這一點,我想我想用_rotationX的計算來旋轉視圖矩陣(相機/眼睛)。

我想我需要使用世界矩陣(原點0,0,0)進行_rotationY計算。我會試着獲得一些我正在談論的內容。

回答

0

Wahoo,得到這個工作!我用X旋轉矩陣旋轉了視圖矩陣(由LookAt方法創建)。我用Y旋轉矩陣旋轉了模型視圖矩陣。

下面是修改後的更新方法:

- (void)update { 

    PVRTVec3 vFrom, vTo, vUp; 
    VERTTYPE fFOV; 

    // We can get the camera position, target and field of view (fov) with GetCameraPos() 
    fFOV = m_Scene.GetCameraPos(vFrom, vTo, 0); 

    /* 
    We can build the world view matrix from the camera position, target and an up vector. 
    For this we use PVRTMat4LookAtRH(). 
    */ 
    m_mView = PVRTMat4::LookAtRH(vFrom, vTo, PVRTVec3(0.0f, 1.0f, 0.0f)); 

    // rotate on the X axis (finger swipe Y direction) 
    m_mView = m_mView * _rotationY; 

    // Calculates the projection matrix 
    m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)1024.0/768.0, CAM_NEAR, CAM_FAR, PVRTMat4::OGL, false); 

} 

下面是修改後的觸摸移動方法:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 

    UITouch * touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:self.view];  
    CGPoint lastLoc = [touch previousLocationInView:self.view]; 
    CGPoint diff = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y); 

    float rotX = -1 * GLKMathDegreesToRadians(diff.x/2.5); 
    float rotY = GLKMathDegreesToRadians(diff.y/2.5); 

    PVRTMat4 rotMatrixX, rotMatrixY; 

    // create rotation matrices with angle 
    PVRTMatrixRotationYF(rotMatrixX, -rotX); 
    PVRTMatrixRotationXF(rotMatrixY, rotY); 

    _rotationX = _rotationX * rotMatrixX; 
    _rotationY = _rotationY * rotMatrixY; 

}