如何继承 SCNNode 并使用采用 MDLObject 的 init?

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

我需要对

SCNNode
进行子类化并使用采用
MDLObject
的 init(这不是指定的 init)。


public class MyModelNode: SCNNode {
  public var geo: SCNGeometry!

  private func dfs(node: SCNNode) {
    if let geometry = node.geometry {
      geo = geometry
      return
    }
    for child in node.childNodes {
      dfs(node: child)
    }
  }
  
  public init(model: MDLObject) {
    super.init(mdlObject: model)
    dfs(node: self)
  }
  
  required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

我收到错误消息说我不能这样做,因为 init 不是指定的 init。我如何子类化它但仍然设置模型对象?

ios swift scenekit
1个回答
0
投票

我最终使用 DFS 来搜索几何图形:

import ModelIO
import SceneKit.ModelIO

// Main actor because accessing node.geometry is main isolated
@MainActor
public final class MyModelCache {
  
  public let modelCache: [String: SCNGeometry]
  
  // The model could contain non-geo nodes, such as light and camera.
  // We assume there's only 1 geo per model.
  private static func dfs(node: SCNNode) -> SCNGeometry? {
    if let geometry = node.geometry {
      return geometry
    }
    for child in node.childNodes {
      if let ans = dfs(node: child) {
        return ans
      }
    }
    return nil
  }
  
  public init(bundle: Bundle, models: [String]) {
    modelCache = models.reduce(into: [String:SCNGeometry]()) { result, model in
      let url = bundle.url(forResource: model, withExtension: nil)!
      let asset = MDLAsset(url: url)
      asset.loadTextures()
      let object = asset.object(at: 0)
      let node = SCNNode(mdlObject: object)
      guard let geometry = Self.dfs(node: node) else {
        fatalError("No geometry found in model file")
      }
      result[model] = geometry
    }
  }
  
  public func geometryNamed(_ fn: String) -> SCNGeometry {
    // From Apple's doc: The copy shares the underlying vertex data of the original, but can be assigned materials independently.
    // Since the model cache is shared, we want to keep it unchanged, so we return a copy.
    return modelCache[fn]!.copy() as! SCNGeometry
  }
  
}
© www.soinside.com 2019 - 2024. All rights reserved.