SceneKit flattenedClone 意外更改节点

问题描述 投票:0回答:1

我有一个包含 3 个几何形状的 3D 模型,如下所示

enter image description here

这是我从 USDZ 文件创建此类 SCNNode 的代码:

  private func readGeo(fn: String) -> SCNNode {
    let bundle = Bundle.main
    let url = bundle.url(forResource: fn, withExtension: nil)!
    let asset = MDLAsset(url: url)
    asset.loadTextures()
    let object = asset.object(at: 0)
    let node = SCNNode(mdlObject: object)
    return node
  }

然后我需要展平节点,因为我想让它只是一个几何体,这样更容易附加物理体。所以我将返回更改为:

return node.flattenedClone()

几何形状的位置似乎不正确,如下所示:(看到盖子伸出来)

enter image description here

您可以在此处下载示例项目:https://drive.google.com/file/d/1ewudz3A2NKeW-72bXRPJJtphyRMae-1e/view?usp=sharing

编辑:

我意识到展平后子节点的位置发生了变化。它们最初位于非零坐标,但在展平后,它们被定位为好像位于零坐标。我不知道为什么

ios swift scenekit
1个回答
0
投票

我相信这是 SceneKit 中的一个错误,如果节点没有几何图形,则变换将被忽略。我能够通过使用 DFS 将变换传递到子节点来修复它:


fileprivate extension SCNNode {
  
  // pre-process it before taking the flattenedClone()
  var preProcessed: SCNNode {
    let clone = self.clone()
    Self.dfs_passDownTransform(node: clone)
    return clone
  }
  
  static func dfs_passDownTransform(node: SCNNode) {
    // If it's an empty node with just transform, we want to pass the transform to its immediate children
    if node.geometry == nil && !SCNMatrix4IsIdentity(node.transform) {
      for child in node.childNodes {
        child.transform = SCNMatrix4Mult(child.transform, node.transform)
      }
      node.transform = SCNMatrix4Identity
    }
    
    for child in node.childNodes {
      dfs_passDownTransform(node: child)
    }
  }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.