user19037628
user19037628

Reputation: 321

RealityKit – Rotating an Entity affects its Scale

I am loading an entity using the USDZ file. I want after loading the entity, I want to rotate is forever. I am using the following code.

cancellable = ModelEntity.loadAsync(named: "toy_drummer").sink { [weak self] completion in
            if case let .failure(error) = completion {
                print("Unable to load model \(error)")
            }
            self?.cancellable?.cancel()
        } receiveValue: { entity in
            anchor.addChild(entity)
            arView.scene.addAnchor(anchor)
            let rotation = Transform(pitch: 0, yaw: .pi, roll: 0)
            entity.move(to: rotation,
                                    relativeTo: nil,
                                      duration: 15.0,
                                timingFunction: .linear)
        }

Instead of rotating correctly, the entity is scaling and getting bigger and bigger. Any ideas?

Upvotes: 2

Views: 1034

Answers (2)

Andy Jazz
Andy Jazz

Reputation: 58153

You need a starting transform "point" and ending transform "point". If a value of referenceEntity (relativeTo) argument equal to nil it means relative to world space. Since the same 4x4 matrix slots are used for rotation values ​​as for scaling, when the model is rotated, its scale also changes at the same time, if there is a difference in scale.

For perpetual transform animation use some of RealityKit 2.0 tricks.

And, of course, there is a Trigonometry that was really conceived for perpetual orbiting.

Here's a correct version of your code:

import UIKit
import RealityKit
import Combine

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!
    var cancellable: Cancellable? = nil
    let anchor = AnchorEntity()

    override func viewDidLoad() {
        super.viewDidLoad()

        cancellable = ModelEntity.loadAsync(named: "drummer.usdz").sink { _ in
                self.cancellable?.cancel()
            } receiveValue: { entity in
                self.anchor.addChild(entity)
                self.arView.scene.addAnchor(self.anchor)
                    
                let rotation = Transform(pitch: 0, yaw: .pi, roll: 0)
                entity.move(to: rotation,
                    relativeTo: entity,
                      duration: 5.0,
                timingFunction: .linear)
            }
    }
}

Upvotes: 1

maxxfrazer
maxxfrazer

Reputation: 1253

I made a swift package a couple of years ago, RealityUI, which does include animations like a continuous rotation:

https://github.com/maxxfrazer/RealityUI/wiki/Animations#spin

enter image description here

You'd just need to include the package, and call:

entity.ruiSpin(by: [0, 1, 0], period: 1)

docs here: https://maxxfrazer.github.io/RealityUI/Extensions/Entity.html#/s:10RealityKit6EntityC0A2UIE7ruiSpin2by6period5times10completionys5SIMD3VySfG_SdSiyycSgtF

Upvotes: 1

Related Questions