Change a rotation of AnchorEntity in RealityKit
Try move(...)
instance method:
import UIKit
import RealityKit
import SceneKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
let box = try! Experience.loadBox()
let entity = box.steelBox!
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
let currentMatrix = entity.transform.matrix
// Nothing prevents you from using even SceneKit's matrix methods
let rotation = simd_float4x4(SCNMatrix4MakeRotation(.pi/2, 0,1,0))
let transform = simd_mul(currentMatrix, rotation)
entity.move(to: transform, relativeTo: nil, duration: 3.0)
}
arView.scene.anchors.append(box)
}
}
RealityKit – Rotating an Entity affects its Scale
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)
}
}
}
How do I rotate an object around only one axis in RealityKit?
In RealityKit there are, at least, three ways to rotate an object around single axis.
In each example we rotate an object counterclockwise (CCW).
First approach
let boxScene = try! Experience.loadBox()
boxScene.steelBox?.orientation = simd_quatf(angle: .pi/4, /* 45 Degrees */
axis: [0,0,1]) /* About Z axis */
Second approach
boxScene.steelBox?.transform = Transform(pitch: 0,
yaw: 0,
roll: .pi/4) /* Around Z axis */
pitch, yaw and roll are rotations about X, Y and Z axis expressed in radians.
Third approach
let a: Float = cos(.pi/4)
let b: Float = sin(.pi/4)
let matrix = float4x4([ a, b, 0, 0 ], /* column 0 */
[-b, a, 0, 0 ], /* column 1 */
[ 0, 0, 1, 0 ], /* column 2 */
[ 0, 0, 0, 1 ]) /* column 3 */
boxAnchor.steelBox?.setTransformMatrix(matrix, relativeTo: nil)
Visual representation of rotation matrix looks like this:
let a: Float = cos(.pi/4)
let b: Float = sin(.pi/4)
// 0 1 2 3
┌ ┐
| a -b 0 0 |
| b a 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
└ ┘
If you wanna know more about Rotation Matrices, read this post.
RealityKit – How to add motion to a loaded ModelEntity from USDZ file?
Add to your code .generateCollisionShapes(recursive:)
instance method for every participant (entity) that not only creates collision's shapes but also allows you to simulate physics.
import SwiftUI
import RealityKit
struct ARViewContainer: UIViewRepresentable {
let boxx = ModelEntity(mesh: .generateBox(size: 0.5))
let ball = ModelEntity(mesh: .generateSphere(radius: 0.25))
let anchor = AnchorEntity()
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
// BALL
ball.physicsBody = .init()
ball.physicsMotion = .init()
ball.physicsMotion?.linearVelocity = [10,0,0]
ball.position.x = -3
ball.generateCollisionShapes(recursive: true)
anchor.addChild(ball)
// BOX
boxx.physicsBody = .init()
boxx.physicsMotion = .init()
boxx.physicsMotion?.linearVelocity = [0,2,0]
boxx.generateCollisionShapes(recursive: true)
anchor.addChild(boxx)
// Anchor
anchor.position.z = -3
arView.scene.addAnchor(anchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) { }
}
...
struct ContentView : View {
var body: some View {
return ARViewContainer().edgesIgnoringSafeArea(.all)
}
}
For more details, read THIS post.
Related Topics
Wkwebview Does Not Load Links to Pdfs
Swift Sphere Combine Star Data
Alamofire Asynchronous Completionhandler For Json Request
Include Swiftui Views in Existing Uikit Application
Generating Random Numbers With Swift
Swift - Custom Setter on Property
Why Is the Shorthand Argument Name $0 Returning a Tuple of All Parameters
Swift: Failing to Copy Files to a Newly Created Folder
Swift: Setting an Optional Property of a Protocol
How to Configure Contextmenu Buttons For Delete and Disabled in Swiftui
Extension May Not Contain Stored Property But Why Is Static Allowed
Can You Override Between Extensions in Swift or Not? (Compiler Seems Confused!)
Swift Spritekit Adding Button Programmatically
Spritekit Physics in Swift - Ball Slides Against Wall Instead of Reflecting