2013-04-01 20 views
3

我正在理解Scene Kit使用節點變換相關屬性的語義。特別是,節點上的pivot屬性不是一個單一的點,而是一個完整的變換矩陣,我還沒有發現在Collada規範或其他文檔中可比較的任何參考。Scene Kit的樞軸矩陣的語義是什麼?

有沒有人有使用場景套件中的樞軸矩陣或具有類似語義的屬性?有人可以提供一個關於如何使用它的簡要說明/樣例或指向相關文檔的指針嗎?它看起來像一個潛在的有用的方法,但我寧願不必逆向工程,如果我能避免它。

編輯:基於OMZ的迴應,它看起來像是轉換樹中的另一層。但是,如果這樣,那麼與單獨添加中間節點有何不同呢?決定在哪裏應用哪些轉換的基礎是什麼?

回答

3

我嘗試了@ omz的想法。但出現一些相互矛盾的結果,所以我更深入地挖掘了一些有趣的結果。

答案是主軸的倒數作爲主變換的子元素應用。這提供了與提供中間父節點完全不同的語義。具體來說,如果我從具有變換P的父節點和具有變換C的子節點開始,它們組合起來進行世界變換W = CATransform3DConcat(C,P)。相同的世界變換W通過將父節點的樞軸設置爲C的倒​​數來獲得,而不是在子節點上設置變換。

這種方法似乎提供了一些額外的實用性,因爲它不能通過插入中間節點來複制,也不能在應用之前反轉。正如Hal Mueller指出的那樣,文件確實表明這個關鍵點會影響旋轉和縮放以及位置,但是對影響的性質沒有提及。

下面是測試這個結論的結果:

Set parent rotation and node position. 

Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 1.00, 2.00, 3.00, 1.00 } 

Pivot: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, 0.00, 0.00, 1.00 } 

World Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, -1.00, 0.00, 0.00 } 
{ 1.00, -3.00, 2.00, 1.00 } 
2013-04-04 13:49:55.453 Model Importer[43504:303] 

CATransform3DConcat(node.transform, node.parentNode.transform)] 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, -1.00, 0.00, 0.00 } 
{ 1.00, -3.00, 2.00, 1.00 } 
2013-04-04 13:49:55.454 Model Importer[43504:303] 

Set parent rotation and parent.pivot to inverse position. 

Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, 0.00, 0.00, 1.00 } 

Pivot: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, 0.00, 0.00, 1.00 } 

World Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, -1.00, 0.00, 0.00 } 
{ 1.00, -3.00, 2.00, 1.00 } 

下面的代碼:

// Verification 
    SCNVector3 v3 = {1.0, 2.0, 3.0}; 
    SCNVector4 v4 = {1.0, 0, 0, M_PI/2.0}; 
    node.parentNode.rotation = v4; 
    node.position = v3; 
    NSLog(@"\n\nSet parent rotation and node position.%@", 
      [self transformsForNodeToString:node]); 
    // 
    // Verify match with CATransform3DConcat 
    NSLog(@"\n\nCATransform3DConcat(node.transform, node.parentNode.transform)]%@", 
      [self transformToString:CATransform3DConcat(node.transform, node.parentNode.transform)]); 
    // 
    // Clear the child node transform and put the inverse in the parent's pivot. 
    CATransform3D position = node.transform; 
    CATransform3D inversePosition = CATransform3DInvert(position); 

    node.transform = CATransform3DIdentity; 
    node.parentNode.pivot = inversePosition; 
    NSLog(@"\n\nSet parent rotation and parent.pivot to inverse position.%@", 
      [self transformsForNodeToString:node]); 
    node.parentNode.pivot = CATransform3DIdentity; 
    node.parentNode.transform = CATransform3DIdentity; 


+ (NSString*)transformsForNodeToString: (SCNNode*)node { 
    NSString* result = @"\n"; 
    result = [result stringByAppendingFormat: 
      @"\nTransform:%@\nPivot:%@\nWorld Transform:%@", 
      [self transformToString:node.transform], 
      [self transformToString:node.pivot], 
      [self transformToString:[node worldTransform]]]; 
    return result; 
} 

+ (NSString*)transformToString: (CATransform3D)transform { 
    NSString* result = @"\n"; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m11, transform.m12, transform.m13, transform.m14]; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m21, transform.m22, transform.m23, transform.m24]; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m31, transform.m32, transform.m33, transform.m34]; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m41, transform.m42, transform.m43, transform.m44]; 
    return result; 
} 

歡迎評論!

2

我對SceneKit沒有太多經驗,但在三維建模應用中,樞軸是一個可以旋轉的點(有時稱爲定位器),這是相當常見的。這允許您例如使對象更容易圍繞其自己的軸旋轉(這不一定對應於世界座標軸)。

對於未旋轉的樞軸,矩陣將簡單地爲CATransform3DMakeTranslation(x, y, z)

編輯:我認爲樞軸被指定爲完整矩陣的事實只是因爲它是一個方便的數據結構,並與模型的其餘部分一致。我想不出你想要縮放一個樞軸的情況,但將它表示爲一個矩陣可以很容易地用通常的矩陣處理函數對其進行操作。

您當然可以將樞軸表示爲另一箇中間節點並獲得相同的結果,但樞軸是表達對象中心的更「語義」方式,更適合於交互式編輯。當您在建模應用程序中選擇一個對象時,通常會將轉換工具句柄放置在樞軸所在的位置,以便您可以圍繞「自然」中心旋轉/縮放對象,而不必在節點層次結構中向上導航。

我真的找不到任何好的參考資料。大部分出現的問題似乎都涉及各種軟件包中的具體實施細節。

+0

感謝您的回覆!儘管如此,我仍然對語義感到困惑,因爲pivot指定了一個完整的矩陣。我嘗試在定位器上進行搜索,但與pivot相似,該術語的用法似乎不明確,沒有與您描述的內容匹配,或者我在Scene Kit中看到的內容。你有沒有可能知道任何鏈接或參考? –

+0

我根據你的回覆編輯了我的問題。 –

+0

看到我的編輯,我希望這使事情更清晰。 – omz

1

我想你會在Core Animation材質中找到一些相關的樣本。 SCNNode的定義爲CATransform3D,它在Mac和iOS上的整個Core Animation中都使用。

我還沒有挖到場景套件足夠我自己是權威。但是我發現this post by Brad Larson:「Core Animation提供的用於操作CALayers的CATransform3D結構在結構上與OpenGL中的模型視圖矩陣相同」。

GitHub上還有一個很酷的可視化工具,https://github.com/honcheng/CATransform3D-Test。 Honcheng的演示僅限於iPad,但我認爲仍然有幫助。

+0

感謝您的GitHub演示鏈接。它看起來可能是一個很好的資源。但是,我知道一般情況下如何轉換工作,但我試圖瞭解Scene Kit中節點的這種特定屬性的意圖,特別是因爲我沒有看到它如何映射到Collada規範,因爲Scene中的大多數其他功能套件做。 –