基于转换重新计算SCNNode几何

时间:2017-12-02 11:34:46

标签: scenekit arkit

有没有办法通过重新计算几何图形来固化SCNNode比例和方向?

基本上我正在从scn文件加载SCNNode,该文件是从导出到DAE文件的sketchup文件转换而来的。因为ARKit以米为单位并且具有不同的轴方向,所以我必须设置加载的SCNNode的比例(到0.0254)和eulerangle(x -90deg)才能正确显示它。这一切都很好但是因此缩放和旋转会使一些逻辑变得困难,因为这个逻辑也使用了旋转,从而覆盖了前一个...... :(

我认为如果我能简单地告诉SCNNode根据其当前的比例,方向...(基本上是它的变换矩阵)重新计算其几何形状将会产生很好的结果,这将导致具有变换矩阵的SCNNode为零矩阵。 ..

3 个答案:

答案 0 :(得分:0)

如果您“只是”想要告诉节点永久地缩放其顶点,则必须编写一个函数来执行此操作,因为没有标准选项。

该函数应将节点几何的顶点源读入矢量数组,然后使用GLKMatrix4MultiplyAndProjectVector3将变换应用于每个矢量,然后使用新顶点作为源创建新的SCNGeometry。

GLKMatrix4 scalemat = GLKMatrix4MakeScale(aNode.scale.x, aNode.scale.y, aNode.scale.z);

for (HEVertex* vert in toBeTransformedVerts) {
     vert.pos = SCNVector3FromGLKVector3(GLKMatrix4MultiplyAndProjectVector3(scalemat, SCNVector3ToGLKVector3(vert.pos)) );
}

//reset node scale property.
aNode.scale = SCNVector3Make(1.0, 1.0, 1.0);

HEVertex是我用来存储顶点的类,pos属性是SCNVector3。在您的情况下,您必须将SCNNode的.geometry的顶点源读取到SCNVector3的数组中,然后循环遍历这些。

变换每个顶点的位置后,需要更新节点的几何体。即像这样的东西:

SCNGeometrySource *_vertexSource =
        [SCNGeometrySource geometrySourceWithVertices:_meshVertices count:_vertexCount];

aNode.geometry = [SCNGeometry geometryWithSources:@[_vertexSource, _aNode.geometry.geometrySources[1], _aNode.geometry.geometrySources[2]] elements:@[_aNode.geometry.geometryElements.firstObject]];

这只是一个粗略的例子,它只更新顶点源,并重用普通和颜色几何源以及几何元素,每个模型的差别很大。

非常可行,但并不像重新导出具有适当大小的模型那么简单。

答案 1 :(得分:0)

如果该节点没有任何子节点,则可以简单地将节点作为一个空节点的父节点,在该节点上执行所需的转换,然后在该空父节点上调用flatten。您节点的中心和方向将与空父节点相匹配。如果您的节点具有子节点树,则需要递归执行此操作。

答案 2 :(得分:0)

作为更复杂方法的替代方法,您可以通过一个简单的子节点轻松完成此操作...

  1. 创建一个新节点
  2. 将几何图形(以及所需的任何其他节点属性)从原始节点移动到新节点
  3. 将新节点添加为原始节点的子节点
  4. 将比例转换应用于子节点。

基本上,在执行第3步之后,您应该返回到执行任何操作之前的精确位置,除了现在有一个新的子节点将比例转换应用到该子节点,而使父节点不受影响,以便它可以使用单位矩阵(或其他任何方式)您想要的矩阵。)

一种类似的方法是按原样使用现有节点...

  1. 创建一个新的父节点
  2. 将其添加到与现有节点相同的父节点中
  3. 将现有节点从旧父节点移到新父节点
  4. 将转换从现有的子节点复制到新的父节点
  5. 仅使用比例变换替换子节点上的变换

两者之间的选择实际上取决于您要移动的节点上有多少东西,以及它最初对它进行了哪些转换。 (即,如果缩放节点,则该节点可能相对于模型而言偏离其原始位置。)根据该信息,选择要执行的操作。

也就是说,如果仅是几何图形并就地缩放它,则请选择第一个。如果节点属性很多,请选择第二个。重要的是,您要添加一个专门用于将缩放比例应用于现有节点的新节点,而无需直接修改几何。