swift 如何在RealityKit中设置模型旋转动画?

t40tm48m  于 2023-08-02  发布在  Swift
关注(0)|答案(2)|浏览(202)

在我的previous question中,我已经找到了如何在对象上只在一个轴上进行旋转变换,现在我想将其设置为动画。
在RealityKit中有没有这样做的方法?

6g8kf2rb

6g8kf2rb1#

1.变换动画

您可以使用.move(...)示例方法在RealityKit中移动,* 旋转 * 和缩放模型。为了更快地编译,我使用了SwiftUI macOS应用程序-尽管,您也可以在iOS应用程序中使用此代码。

import SwiftUI
import RealityKit

struct ContentView: View {
    var body: some View {
        ARInterface().ignoresSafeArea()
    }
}

struct ARInterface: NSViewRepresentable {

    let arView = ARView(frame: .zero)
    
    func makeNSView(context: Context) -> ARView {
        
        let scene = try! Experience.loadBox()
        scene.steelBox?.scale = [10, 10, 10]

        let transform = Transform(pitch: 0, yaw: 0, roll: .pi)
        scene.steelBox?.orientation = transform.rotation

        arView.scene.anchors.append(scene)
            
        scene.steelBox?.move(to: transform,
                     relativeTo: scene.steelBox,
                       duration: 5.0,
                 timingFunction: .linear)
        
        return arView
    }
    
    func updateNSView(_ uiView: ARView, context: Context) { }
}

字符串
阅读这篇文章,了解如何克服 *180度旋转障碍
x1c 0d1x的数据

2.使用矩阵变换动画

对于那些喜欢使用矩阵数学的人,我推荐阅读这篇文章:
在RealityKit中更改AnchorEntity的旋转

3.使用物理变换动画

对于那些喜欢使用动态的人,我给予了这个帖子的链接:
如何移动模型并同时生成其碰撞形状?

4.资产动画

要播放在3D应用程序(如Maya或Houdini)中制作的资源动画(无论是骨骼角色动画还是一组变换动画,包括围绕网格轴点的 * 旋转 *),请使用animationPlaybackController

import Cocoa
import RealityKit

class ViewController: NSViewController {
    
    @IBOutlet var arView: ARView!
    
    override func awakeFromNib() {

        do {
            let robot = try ModelEntity.load(named: "drummer")

            let anchor = AnchorEntity(world: [0, -0.7, 0])

            anchor.transform.rotation = simd_quatf(angle: .pi/4, 
                                                    axis: [0, 1, 0])
            arView.scene.anchors.append(anchor)
            
            robot.scale = [1, 1, 1] * 0.1

            anchor.children.append(robot)
            
            robot.playAnimation(robot.availableAnimations[0].repeat(), 
                                transitionDuration: 0.5, 
                                      startsPaused: false)
        } catch {
            fatalError("Cannot load USDZ asset.")
        }
    }
}


要能够播放多个动画,请尝试此技术或此技术。


5. Reality Composer中的变换动画

对于那些喜欢UI的人来说,在Reality Composer中有一个“永久”的旋转行为:
现实 composer -如何永远旋转一个对象?

6.使用Python绑定USDZ转换动画

USDZ模式在Pixar格式的日常Python脚本中变得越来越流行。
Augmented Reality 911 — USDZ Schemas

float xformOp:rotateY:spin.timeSamples = { 1: 0, 300: 1800 }
uniform token[] xformOpOrder = ["xformOp:rotateY:spin"]

7.三角法永恒轨道

三角函数sin()cos()、Timer和counter对象将允许您围绕任何轴动态观察模型。
将实体悬停在ARCamera前面

8.环绕动画

使用OrbitAnimation结构体,您可以围绕其原点旋转实体。下面是visionOS应用程序的代码片段。

import SwiftUI
import RealityKit

struct ContentView: View {
    var body: some View {
        RealityView { content in
            async let car = ModelEntity(named: "car.usdz")
            
            let entity = Entity()
            entity.position.y = 0.1
            
            if let car = try? await car {
                car.scale /= 5
                entity.addChild(car)
                
                let orbit = OrbitAnimation(duration: 5.0,
                                               axis: [1,0,0],
                                     startTransform: entity.transform,
                                         bindTarget: .transform,
                                         repeatMode: .repeat)
                
                if let animation = try? AnimationResource.generate(with: orbit) {
                    entity.playAnimation(animation)
                }
                content.add(entity)
            }
        }
    }
}
#Preview {
    ContentView()
}


ulmd4ohb

ulmd4ohb2#

带动画旋转:

复制长方体的当前变换

var rotationTransform = boxAnchor.steelBox?.transform

字符串
将长方体设置为沿z轴旋转90度

rotationTransform?.rotation = simd_quatf(angle: .pi/2, axis: [0,0,1])


在10秒内将长方体移动到新变换

boxAnchor.steelBox?.move(to: rotationTransform!, relativeTo: boxAnchor.steelBox?.parent, duration: 10, timingFunction: .easeInOut)

动画翻译:

var translationTransform = boxAnchor.steelBox?.transform

translationTransform?.translation = SIMD3<Float>(x: 5, y: 0, z: 0)

boxAnchor.steelBox?.move(to: translationTransform!, relativeTo: boxAnchor.steelBox?.parent, duration: 10, timingFunction: .easeInOut)

动画缩放:

var scaleTransform = boxAnchor.steelBox?.transform

scaleTransform?.scale = SIMD3<Float>(x: 1, y: 1, z: 1)

boxAnchor.steelBox?.move(to: scaleTransform!, relativeTo: boxAnchor.steelBox?.parent, duration: 10, timingFunction: .easeInOut)

相关问题