How to split out multiple animations from Collada file in SceneKit

前端 未结 3 2009
梦谈多话
梦谈多话 2021-01-03 00:12

I am loading a third-party .dae Collada file as a scene into a SceneKit project.

The .dae file has many different animations in it, set at different times/frames. I

3条回答
  •  孤独总比滥情好
    2021-01-03 00:39

    Here is code that converts frame numbers to times and then plays only that portion of the animation by using a CAAnimationGroup as @Toyos described. This sample code plays an "idle" animation by repeating frames 10 through 160 of fullAnimation:

    func playIdleAnimation() {
        let animation = subAnimation(of:fullAnimation, startFrame: 10, endFrame: 160)
        animation.repeatCount = .greatestFiniteMagnitude
        addAnimation(animation, forKey: "animation")
    }
    
    func subAnimation(of fullAnimation:CAAnimation, startFrame:Int, endFrame:Int) -> CAAnimation {
        let (startTime, duration) = timeRange(startFrame:startFrame, endFrame:endFrame)
        let animation = subAnimation(of: fullAnimation, offset: startTime, duration: duration)
        return animation
    }
    
    func subAnimation(of fullAnimation:CAAnimation, offset timeOffset:CFTimeInterval, duration:CFTimeInterval) -> CAAnimation {
        fullAnimation.timeOffset = timeOffset
        let container = CAAnimationGroup()
        container.animations = [fullAnimation]
        container.duration = duration
        return container
    }
    
    func timeRange(startFrame:Int, endFrame:Int) -> (startTime:CFTimeInterval, duration:CFTimeInterval) {
        let startTime = timeOf(frame:startFrame)
        let endTime = timeOf(frame:endFrame)
        let duration = endTime - startTime
        return (startTime, duration)
    }
    
    func timeOf(frame:Int) -> CFTimeInterval {
        return CFTimeInterval(frame) / framesPerSecond()
    }
    
    func framesPerSecond() -> CFTimeInterval {
        // number of frames per second the model was designed with
        return 30.0
    }
    

提交回复
热议问题