我正在努力理解Scene Kit使用节点的变换相关属性的语义。特别是,节点上的pivot属性不是单个点,而是完整的变换矩阵,我没有找到Collada规范或其他文档中可比较的任何内容。
有没有人有使用Scene Kit中的pivot矩阵或具有类似语义的属性?有人可以提供如何使用的简要说明/样本或相关文档的指针?它看起来像是一种潜在有用的方法,但如果我能避免它,我宁愿不必对它进行逆向工程。
编辑:根据OMZ的回复,看起来枢轴可能只是变换树中的另一个图层。但是,如果是这样,那么与添加中间节点有何不同?什么是确定应用哪个变换的基础?
答案 0 :(得分:3)
我尝试了@ omz的想法。但是会有一些相互矛盾的结果,所以我用一些有趣的结果挖掘了这些结果。
答案是枢轴的反转应用为主变换的子元素。这提供了与提供中间父节点完全不同的语义。
具体来说,如果我从具有变换P的父节点和具有变换C的子节点开始,它们组合起来进行世界变换W = CATransform3DConcat(C,P)。通过将父节点的pivot设置为C的倒数,而不是对子项设置变换,可以获得相同的世界变换W.
这种方法确实提供了一些额外的效用,因为它不能通过插入中间节点来复制,也可以在应用之前被反转。正如哈尔穆勒指出的那样,文献确实说枢轴影响了旋转和规模,以及位置,但对影响的性质没有提及。
以下是测试此结论的结果:
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;
}
欢迎评论!
答案 1 :(得分:2)
我对SceneKit没有多少经验,但在3D建模应用程序中很常见的是枢轴是一个可以旋转的点(有时称为定位器)。这允许您例如使对象更容易围绕其自己的轴旋转(其不一定对应于世界轴)。
对于没有旋转的轴,矩阵只是CATransform3DMakeTranslation(x, y, z)
。
你当然可以将一个数据透视表示为另一个中间节点,并获得相同的结果,但是数据透视是一个更多的语义"表达对象中心的方式,更适合于交互式编辑。当您在建模应用程序中选择一个对象时,定位转换所在的转换工具处理是很常见的,这样您就可以围绕其自然"旋转/缩放对象。无需在节点层次结构中向上导航。
我无法在此找到任何好的参考资料。出现的大多数事情似乎都涉及各种软件包中的具体实现细节。
答案 2 :(得分:1)
我想你会在Core Animation材料中找到一些相关的样本。 pivot
的{{1}}定义为SCNNode
,在Mac和iOS上的整个Core Animation中使用。
我没有充分挖掘Scene Kit以获得权威性。但我发现this post by Brad Larson:“Core Animation提供的用于操作CALayers的CATransform3D结构在结构上与OpenGL中的模型视图矩阵相同”。
GitHub上还有一个很酷的可视化工具,https://github.com/honcheng/CATransform3D-Test。 Honcheng的演示仅限iPad,但我认为仍然有用。