Как повернуть ModelEntity в VisionOS?
При загрузке модели как объекта Model3D вы можете добавить модификатор жеста следующим образом:
Model3D(named: model_name, bundle: realityKitContentBundle){ model in
model
.resizable()
.aspectRatio(contentMode: .fit)
} ...
.gesture(DragGesture()
.onChanged {
...
}
Еще один пример показан в этом посте.
Как добавить к загруженному объекту такой жест, как DragGesture()? Для работы сущности, вероятно, потребуются компоненты InputTarget и Collision:
let loadedEntity = try await ModelEntity(named: modelName, in: RealityKitContent.realityKitContentBundle)
// Add components to entity
loadedEntity.generateCollisionShapes(recursive: true)
loadedEntity.components.set(InputTargetComponent())
2 ответа
Вращение 3D-изображения с помощью жеста перетаскивания
Если 3D-модель находится одна в представлении SwiftUI, вы можете повернуть весь вид с помощью жеста перетаскивания. Однако в сцене может быть несколько моделей. Итак, если вы предпочитаете вращать каждую модель сцены отдельно от остальных, прочтите этот пост .
Когда вы используете RealityView, вы получаете уникальную функциональность, которая недоступна в представлении Model3D (я имею в виду возможность программного изменения структуры сцены или добавления привязок и компонентов). Вот мой код:
import SwiftUI
import RealityKit
struct ContentView: View {
@State var isDragging: Bool = false
@State var rotation: Angle = .zero
var drag: some Gesture {
DragGesture()
.onChanged { _ in
isDragging = true
rotation.degrees += 5.0
}
.onEnded { _ in
isDragging = false
}
}
var body: some View {
RealityView { content in
let cube = ModelEntity(mesh: .generateBox(size: 0.25))
cube.generateCollisionShapes(recursive: false)
cube.components.set(InputTargetComponent())
content.add(cube)
}
.gesture(drag)
.rotation3DEffect(rotation, axis: .xy)
}
}
#Preview {
ContentView()
}
Мне удалось выполнить поворот, прикрепив жест к RealityView и получив доступ к дочернему объекту через его привязку. Однако я считаю, что это не лучшее решение, учитывая, что в одном RealityView имеется несколько объектов.
Должен быть лучший способ прикреплять жесты пообъектно.
RealityView { content in
do {
...
} catch {
print("oopsie")
}
}.gesture(
DragGesture()
.onChanged { value in
// Calculate rotation angle
let angle = sqrt(pow(value.translation.width, 2) + pow(value.translation.height, 2))
rotation = Angle(degrees: Double(angle))
// Calculate rotation axis
let axisX = -value.translation.height / CGFloat(angle)
let axisY = value.translation.width / CGFloat(angle)
rotationAxis = (x: axisX, y: axisY, z: 0)
// Apply rotation to loadedEntity
let quaternion = simd_quatf(
angle: Float(rotation.radians),
axis: SIMD3<Float>(
x: Float(rotationAxis.x),
y: Float(rotationAxis.y),
z: Float(rotationAxis.z)
)
)
anchor.children[0].orientation = quaternion
}
)