2014-03-04 55 views
3

我的屏幕上有一個對象被旋轉和平移, 但我有2個關於z軸旋轉的問題。這是一個有點棘手解釋,所以我上傳2個視頻描述每個問題。圍繞Z軸的OpenGL ES對象旋轉

1)Reverse rotation:繞x軸旋轉所述對象之後,與z旋轉被反轉,因爲它應該是。

2)Wrong Z axis rotation:再次,圍繞x軸旋轉對象後,我試圖圍繞z軸旋轉對象,旋轉導致不同的軸旋轉。

我相信視頻的描述問題很好。

編輯:UPDATE#1

好,我想我找到了解決辦法,這是僅旋轉相機繞Z軸, 而關於模型本身執行X和Y旋轉。這似乎是不錯的,但當然也導致了(這是在23'd第二,剩下的就是展示它是如何正在做)在這個VIDEO描述了新的問題。

發生這種情況的原因是對象的軸系正在旋轉,並且當我正在執行Z軸旋轉,然後是X或Y軸旋轉時,結果是錯誤的。

我只是不知道如何從軸系統單獨旋轉對象,以便旋轉將正確完成。現在

,對於部分代碼:

呈現函數:

- (void)render:(CADisplayLink*)displayLink { 
    ... 

    CC3GLMatrix *projection = [CC3GLMatrix matrix]; 
    float h = 4.0f * self.frame.size.height/self.frame.size.width; 
    [projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:100]; 
    glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix); 

    [modelView populateFromTranslation:_currentPan]; 
    [modelView rotateBy:_currentRotation]; 
    [modelView rotateByZ:zRotationEnd]; 

    glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix); 
    ...   
} 

X和Y旋轉:

- (void) rotateAroundX:(float) x andY:(float) y newRotate:(BOOL) isNewRotate 
{ 
    if (isNewRotate) { 
     rotationStart = CC3VectorMake(0.0, 0.0, 0.0); 
    } 

    int rotationDirection = ceil(zRotationEnd/90); 
    if (rotationDirection % 4 == 2 || rotationDirection % 4 == 3) { 
     rotationEnd.x = rotationEnd.x - (x-rotationStart.x); 
     rotationEnd.y = rotationEnd.y - (y-rotationStart.y); 
    } else { 
     rotationEnd.x = rotationEnd.x + (x-rotationStart.x); 
     rotationEnd.y = rotationEnd.y + (y-rotationStart.y); 
    } 

    rotationStart.x = x; 
    rotationStart.y = y; 

    _currentRotation = CC3VectorMake(rotationEnd.y, rotationEnd.x, 0); 
    NSLog(@"Current x is: %f y is: %f z is: %f",_currentRotation.x,_currentRotation.y,zRotationEnd); 
} 

及相關調用部分:

if(sender.numberOfTouches == 1) 
    { 
     BOOL started = false; 
     CGPoint rotation = [sender translationInView:sender.view]; 
     float x = rotation.x; 
     float y = rotation.y; 
     if (sender.state == UIGestureRecognizerStateBegan) 
     { 
      started = true; 
     } 
     [self.glView rotateAroundX:x andY:y newRotate:started]; 
    } 

Z rotati在功能:

- (void) rotateAroundZ:(float) z newRotate:(BOOL) isNewRotate 
{ 
    if (isNewRotate) { 
     zRotationStart = 0; 
    } 
    zRotationEnd = zRotationEnd - (z - zRotationStart); 
    zRotationStart = z; 
} 

及相關調用部分:

- (IBAction)rotation:(UIRotationGestureRecognizer *)sender { 
    BOOL started = false; 
    float rotation = RadiansToDegrees([sender rotation]); 
    if (sender.state == UIGestureRecognizerStateBegan) 
    { 
     started = true; 
    } 
    [self.glView rotateAroundZ:rotation newRotate:started]; 
    NSLog(@"Rotation %f", rotation); 
} 

着色器:

attribute vec4 Position; 
attribute vec4 SourceColor; 

varying vec4 DestinationColor; 

uniform mat4 Projection; 
uniform mat4 Modelview; 

attribute vec2 TexCoordIn; 
varying vec2 TexCoordOut; 

void main(void) { 
    DestinationColor = SourceColor; 
    gl_Position = Projection * Modelview * Position; 
    TexCoordOut = TexCoordIn; 
} 

會很感激的任何幫助。

乾杯!

回答

1

它看起來像你試圖實施gimbal

雖然您似乎只使用Cocos3D作爲基本的數據數學結構,但看看this post,它描述了在Cocos3D中創建一個萬向節,這可能會幫助您指出正確的方向。

使用與萬向節結構相匹配的嵌套結構對象(Cocos3D中的CC3Node)更容易實現創建萬向節,而不是試圖將連續旋轉應用於單個矩陣。但是,通過一些算法分析和實驗,您可能能夠提取矩陣數學結果並在單個矩陣上實現。

請記住,一個成功的萬向節要求旋轉以正確的順序執行。

3

簡單的旋轉。

這是基於觸摸移動旋轉對象的最簡單方法。這裏是示例

pseudocode: 

Matrix.setIdentity(modelMatrix); 

... do other translations here ... 

Matrix.rotateX(totalYMovement); 
Matrix.rotateY(totalXMovement); 

這是每幀完成的。要使物體向上或向下旋轉,我們圍繞X軸旋轉物體,並向左或向右旋轉物體,然後圍繞Y軸旋轉物體。如果我們想讓它旋轉,我們也可以圍繞Z軸旋轉一個物體。

Here's a tutorial

1

自己的錯誤來了,因爲你是在X,Y和Z同時旋轉。問題在於當模型矩陣是標識時,您的z軸旋轉圍繞着由對象定義的z軸。

解決此問題的最簡單方法是使用複合矩陣乘法。本質上,通過將矩陣相乘可以指定執行操作的順序。

在你的情況下,你想像你已經做的那樣應用「x-y」動畫。那麼你想要執行你的Z軸旋轉。

所以像下面這樣:(我從來沒有寫過cocos3d代碼,所以這是基於對文檔的快速搜索,可能存在拼寫錯誤)。

CC3GLMatrix* rotationXY = [CC3GLMatrix identity]; 
[rotationXY rotateBy: _currentRotation]; 

CC3GLMatrix* rotationZ = [CC3GLMatrix rotateByZ: zRotationEnd]; 

[rotationXY multiplyByMatrix: rotationZ]; 

這應該會給你正確的模型矩陣。最後,您需要將您的視圖(相機)矩陣乘以:

[rotationXY multiplyByMatrix: view]; 
[CC3GLMatrix copyMatrix: rotationXY into: modelView]; 

您現在應該看到您期望的行爲。