5

In my previous question I already found how to put a rotation transform over only one axis on an object, now I want this to be animated.

Is there a way to do this in RealityKit?

Andy Jazz
  • 36,357
  • 13
  • 107
  • 175
Robbe Verhoest
  • 341
  • 2
  • 9

2 Answers2

9

1. Transform Animation

You can move, rotate and scale a model in RealityKit using .move(...) instance method. For a faster compiling I used SwiftUI macOS app – although, you can use this code in iOS app as well.

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

enter image description here


2. Transform Animation using Matrices

For those who prefer to use a matrix math, I recommend reading this post:

Change a rotation of AnchorEntity in RealityKit


3. Transform Animation using Physics

For those who like to use dynamics, I give a link to this post:

How to move a model and generate its collision shape at the same time?


4. Asset Animation

To play an asset animation (whether it's a skeletal character animation or a set of transform animations, including a rotation about mesh's pivot point) made in 3D apps, like Maya or Houdini, use an 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.")
        }
    }
}

enter image description here


5. Transform Animation in Reality Composer

For those who prefer UI, there's a "perpetual" spin behavior in Reality Composer:

Reality Composer - How to rotate an object forever?


6. Transform Animation using Python bindings for USDZ

USDZ schemas become more and more popular in everyday Python scripting for Pixar's format.

Augmented Reality 911 — USDZ Schemas

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


Andy Jazz
  • 36,357
  • 13
  • 107
  • 175
  • 1
    Hello @Andy Can You please answer this: https://stackoverflow.com/questions/70890755/how-to-add-motion-to-a-loaded-modelentity-from-usdz-file-realitykit : You are a great help for the community. – Tanvirgeek Jan 28 '22 at 13:22
  • Hi @Tanvirgeek, I'll try to answer your question as soon as I have free time today. – Andy Jazz Jan 28 '22 at 13:25
8

Rotation with animation:

copy the box's current transform

var rotationTransform = boxAnchor.steelBox?.transform

set the box to rotate 90 degrees over z-axis

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

move the box to the new transform over 10s

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

Translation with animation:

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)

Scale with animation:

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)
Robbe Verhoest
  • 341
  • 2
  • 9