3

ノードの変換関連プロパティのシーン キットの使用のセマンティクスの理解に取り組んでいます。特に、ノードのピボット プロパティは単一のポイントではなく、完全な変換マトリックスであり、Collada の仕様やその他のドキュメントで同等のものへの参照が見つかりませんでした。

シーン キットのピボット マトリックス、または同様のセマンティクスを持つプロパティを使用した経験のある人はいますか? 誰かが簡単な説明/これがどのように使用されるかのサンプル、または関連ドキュメントへのポインタを提供できますか? これは潜在的に有用なアプローチのように見えますが、回避できるのであれば、リバース エンジニアリングを行う必要はありません。

編集: OMZ の回答に基づくと、ピボットは変換ツリーの別のレイヤーにすぎないように思われます。しかし、もしそうなら、単に中間ノードを追加するのとどう違うのでしょうか? どの変換をどこに適用するかを決定するための根拠は何でしょうか?

4

3 に答える 3

3

I tried out @omz's idea. but go some conflicting results, so I dug into this some more with some interesting results.

The answer is the inverse of the pivot is applied as a child of the main transformation. This provides quite different semantics than supplying an intermediate parent node.

Specifically, if I start with a parent node with transform P, and a child node with transform C, they combine to make a world transform W = CATransform3DConcat(C, P). The same world transform W is obtained by setting the parent node's pivot to the inverse of C, and not setting a transform on the child.

This approach does appear to provide some additional utility as it cannot be duplicated by interposing an intermediate node, as well as being inverted before being applied. As Hal Mueller pointed out, the documentation does say the pivot influences rotation and scale, as well as position, but is silent on the nature of the influence.

Here are the result of testing this conclusion:

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 }

Here's the code:

    // 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;
}

Comments welcome!

于 2013-04-04T21:44:07.383 に答える
1

Core Animation の資料に関連するサンプルがいくつかあると思います。のpivotSCNNodeとして定義され、CATransform3DMac と iOS の両方の Core Animation 全体で使用されます。

私は、信頼できるほど Scene Kit を深く掘り下げていません。しかし、Brad Larson によるこの投稿を見つけました。

GitHub には、クールな視覚化ツールhttps://github.com/honcheng/CATransform3D-Testもあります。Honcheng のデモは iPad のみですが、それでも役に立つと思います。

于 2013-04-02T01:00:51.953 に答える