Reputation: 103
I try to rotate Model3D for Apple Vision Pro with a DragGesture. To do it I just add degrees to an Angle object, and it works fine but it only rotate left or right not both.
So I've been able to detect left / right gesture and add or remove degrees to the angle. But since there the rotation isn't working well and direction may change to right while I'm still dragging left.
@State var rotation: Angle = .zero
@State var previousLocation: CGPoint = .zero
var rotateGesture: some Gesture {
DragGesture()
.targetedToAnyEntity()
.onChanged { value in
if (previousLocation == .zero) {
previousLocation = value.location
}
if (previousLocation.x > value.location.x) {
rotation.degrees -= 1.0
} else {
rotation.degrees += 1.0
}
previousLocation = value.location
}
}
Rotation is applied to 3d model like this
.gesture(rotateGesture)
.rotation3DEffect(rotation, axis: .y)
Does anyone knows what's wrong or what I missed ?
Upvotes: 1
Views: 666
Reputation: 58133
It seems your problem is related to gimbal lock. To prevent the behavior you are experiencing, use the model's orientation
property in RealityView rather than .rotation3DEffect()
modifier for Model3D view.
import SwiftUI
import RealityKit
struct ContentView: View {
@State var rotation: Angle = .zero
let cube = ModelEntity(mesh: .generateBox(size: 0.25))
var dragGesture: some Gesture {
DragGesture()
.targetedToAnyEntity()
.onChanged { value in
Task { @MainActor in
if value.translation.width < 0 {
rotation.degrees -= 5.0
}
if value.translation.width > 0 {
rotation.degrees += 5.0
}
}
}
}
var body: some View {
RealityView { rvc in
rvc.add(cube)
} update: { rvc in
if let model = rvc.entities.first as? ModelEntity {
model.generateCollisionShapes(recursive: false)
model.components.set(InputTargetComponent())
model.orientation = .init(angle: -Float(rotation.radians),
axis: [0, 0, 1])
}
}.gesture(dragGesture)
}
}
Upvotes: 1