swift - SceneKit - 如何获取 .dae 模型的动画?

标签 swift augmented-reality scenekit arkit maya

好的,我在这里使用 ARKit 和 SceneKit,我无法查看其他仅处理 SceneKit 试图在 .dae 中创建模型的问题格式化并加载各种动画以运行该模型 - 现在我们在 iOS11 中似乎有些解决方案不起作用。
这是我获取模型的方法 - 从基础 .dae没有应用动画的场景。我正在使用 Maya 导入这些 -

var modelScene = SCNScene(named: "art.scnassets/ryderFinal3.dae")!

if let d = modelScene.rootNode.childNodes.first {
    theDude.node = d
    theDude.setupNode()
}
然后在 Dude 课上:
func setupNode() {
    node.scale = SCNVector3(x: modifier, y: modifier, z: modifier)
    center(node: node)
}
需要轴的缩放和居中,因为我的模型不在原点。那行得通。然后现在使用另一个名为“Idle.dae”的场景,我尝试加载动画以便稍后在模型上运行:
func animationFromSceneNamed(path: String) -> CAAnimation? {
    let scene  = SCNScene(named: path)
    var animation:CAAnimation?
    scene?.rootNode.enumerateChildNodes({ child, stop in
        if let animKey = child.animationKeys.first {
            animation = child.animation(forKey: animKey)
            stop.pointee = true
        }
    })
    return animation
}
我打算对我导入到 Xcode 中的所有动画场景执行此操作,并将所有动画存储在
var animations = [CAAnimation]()
第一个 Xcode 说 animation(forKey:已弃用并且这似乎不起作用(据我所知)我的模型离中心并缩小到原来的巨大尺寸。它搞砸了它的位置,因为我希望让模型在动画中移动,例如,会使我的游戏中的实例化模型捕捉到相同的位置。
和其他尝试会导致崩溃。我对场景工具包非常陌生,并试图掌握如何正确地为 .dae 设置动画。我在场景中的任何地方实例化的模型 -
  • 在 iOS11 中如何加载一系列动画以应用于他们的 SCNNode?
  • 你是如何做到的,所以这些动画在模型上运行,无论模型在哪里(而不是将它捕捉到其他位置)?
  • 最佳答案

    首先我应该确认CoreAnimation框架及其一些方法,如 animation(forKey:)实例方法在 iOS 和 macOS 中真的被弃用了。但是 CoreAnimation 的某些部分框架现在实现到 SceneKit和其他模块。在 iOS 11+ 和 macOS 10.13+ 中,您可以使用 SCNAnimation类(class):

    let animation = CAAnimation(scnAnimation: SCNAnimation)
    
    在这里SCNAnimation类具有三个有用的初始化器:
    SCNAnimation(caAnimation: CAAnimation)
    SCNAnimation(contentsOf: URL)
    SCNAnimation(named: String)
    
    另外我要补充一点,您不仅可以使用 .dae 中烘焙的动画。文件格式,也可以是 .abc , .scn.usdz .
    此外,您可以使用 SCNSceneSource类(iOS 8+ 和 macOS 10.8+)来检查 SCNScene 的内容文件或选择性地提取场景的某些元素,而不保留整个场景及其包含的所有 Assets .
    下面是如何实现 SCNSceneSource 的代码可能看起来像:
    @IBOutlet var sceneView: ARSCNView!
    var animations = [String: CAAnimation]()
    var idle: Bool = true
    
    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self
    
        let scene = SCNScene()
        sceneView.scene = scene
        
        loadMultipleAnimations()
    }
    
    func loadMultipleAnimations() {
    
        let idleScene = SCNScene(named: "art.scnassets/model.dae")!
        
        let node = SCNNode()
        
        for child in idleScene.rootNode.childNodes {
            node.addChildNode(child)
        }       
        node.position = SCNVector3(0, 0, -5)
        node.scale = SCNVector3(0.45, 0.45, 0.45)
        
        sceneView.scene.rootNode.addChildNode(node)
        
        loadAnimation(withKey: "walking", 
                    sceneName: "art.scnassets/walk_straight", 
          animationIdentifier: "walk_version02")
    }
    
    ...
    func loadAnimation(withKey: String, sceneName: String, animationIdentifier: String) {
    
        let sceneURL = Bundle.main.url(forResource: sceneName, withExtension: "dae")
        let sceneSource = SCNSceneSource(url: sceneURL!, options: nil)
    
        if let animationObj = sceneSource?.entryWithIdentifier(animationIdentifier, 
                                                     withClass: CAAnimation.self) {
            animationObj.repeatCount = 1
            animationObj.fadeInDuration = CGFloat(1)
            animationObj.fadeOutDuration = CGFloat(0.5)
    
            animations[withKey] = animationObj
        }
    }
    
    ...
    func playAnimation(key: String) {
    
        sceneView.scene.rootNode.addAnimation(animations[key]!, forKey: key)
    }
    

    关于swift - SceneKit - 如何获取 .dae 模型的动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46209555/

    相关文章:

    flutter - 如何使用增强现实在 flutter 中创建人脸应用程序

    android - 通过特定位置和经度获取屏幕坐标(android)

    ios - 为 3D 模型的某些部分添加纹理

    swift - 将 Google Admob 横幅固定到 iPhone X 的底部

    ios - swift/用户界面开关 : how to implement a delegate/listener

    ios - 如何将系统项目添加到按钮和操作表

    swift - 不一致的 SceneKit 帧率

    ios - Swift NSString 函数语法用法

    android - 为什么 ARCore 不支持 Nexus 9?

    swift - 生成带有折痕支持的 MDLMesh?