SceneKit-如何获取.dae模型的动画? [英] SceneKit -– How to get animations for a .dae model?

查看:457
本文介绍了SceneKit-如何获取.dae模型的动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我在这里使用ARKit和SceneKit,而我在查看其他与SceneKit有关的其他问题时遇到了麻烦,这些问题试图以.dae格式创建模型并加载各种动画以使该模型运行-现在,我们在iOS11中似乎无法使用某些解决方案.

Ok, I am working with ARKit and SceneKit here and I am having trouble looking at the other questions dealing with just SceneKit trying to have a model in .dae format and load in various animations to have that model run - now that we're in iOS11 seems that some solutions don't work.

这是我如何从没有应用动画的基本.dae场景中获取模型的方法.我正在将这些与Maya一起导入-

Here is how I get my model - from a base .dae scene where no animations are applied. I am importing these with 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"的场景进行操作.我尝试加载动画以便以后在模型上运行:

the scaling and centering of axes is needing because my model was just not at the origin. That worked. Then now with a different scene called "Idle.dae" I try to load in an animation to later run on the model:

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并将所有动画存储在其中的所有动画场景执行此操作

I was going to do this for all my animations scenes that I import into Xcode and store all the animations in

var animations = [CAAnimation]()

第一个Xcode说animation(forKey:已过时,这不起作用,这似乎(据我所知)使模型偏离中心并按比例缩小到了原来的大尺寸.之所以会固定位置,是因为我希望使模型在动画中移动,例如,可以使游戏中的实例化模型与该位置对齐.

First Xcode says animation(forKey: is deprecated and This does not work it seems to (from what I can tell) de-center and de-scale my model back to the huge size it was. It screws up its position because I expect making the model move in an animation, for example, would make the instantiated model in my game snap to that same position.

和其他尝试会导致崩溃.我是场景工具包的新手,并试图掌握如何正确创建我在场景中任何地方实例化的.dae模型的动画-

and other attempts cause crashes. I am very new to scene kit and trying to get a grip on how to properly animate a .dae model that I instantiate anywhere in the scene -

  1. 如何在iOS11中将一组动画加载到SCNNode中?

  1. How in iOS11 does one load in an array of animations to apply to their SCNNode?

如何实现这些动画在模型所在的位置运行(而不是将其捕捉到其他位置)?

How do you make it so those animations are run on the model WHEREVER THE MODEL IS (not snapping it to some other position)?

推荐答案

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

At first I should confirm that CoreAnimation framework and some of its methods like animation(forKey:) instance method are really deprecated in iOS and macOS. But some parts of CoreAnimation framework are now implemented into SceneKit and other modules. In iOS 11+ and macOS 10.13+ you can use SCNAnimation class:

let animation = CAAnimation(scnAnimation: SCNAnimation())

,这里的SCNAnimation类具有三个有用的初始化程序:

and here SCNAnimation class has three useful initializers:

SCNAnimation(caAnimation: CAAnimation())
SCNAnimation(contentsOf: URL())
SCNAnimation(named: String())

此外,我还要补充一点,您不仅可以使用以.dae文件格式烘焙的动画,而且还可以使用.abc.scn.usdz的动画.

In addition I should add that you can use not only animations baked in .dae file format, but also in .abc, .scn and .usdz.

此外,您还可以使用 SCNSceneSource 类(iOS 8+和macOS 10.8+)来检查SCNScene文件的内容或有选择地提取场景的某些元素,而不保留整个场景及其包含的所有资产 .

Also, you can use SCNSceneSource class (iOS 8+ and macOS 10.8+) to examine the contents of a SCNScene file or to selectively extract certain elements of a scene without keeping the entire scene and all the assets it contains.

以下是实现了SCNSceneSource的代码的样子:

Here's how a code with implemented SCNSceneSource might look like:

@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)
}

这篇关于SceneKit-如何获取.dae模型的动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆