Как повернуть 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
        }
)
Другие вопросы по тегам