Machineboy空
RealityKit 입문 - Gestures 본문
Tap을 어떻게 감지하는가
import SwiftUI
import RealityKit
struct ContentView : View {
var body: some View {
return ARViewContainer().edgesIgnoringSafeArea(.all)
}
}
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
/// 모든 view는 gesture를 가지고 있음
/// Coordinator = coordinate different kind of delegate functions like in this case and link attempt
/// action = 어떤 행동을 pass할지
arView.addGestureRecognizer(UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap)))
context.coordinator.view = arView
/// events of the view session will be delegated to the coordinator and the coordinator will be responsible
arView.session.delegate = context.coordinator
let anchor = AnchorEntity(plane: .horizontal)
let box = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .blue, isMetallic: true)])
box.generateCollisionShapes(recursive: true)
anchor.addChild(box)
arView.scene.anchors.append(anchor)
return arView
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
import Foundation
import ARKit
import RealityKit
class Coordinator: NSObject, ARSessionDelegate {
/// weak 쓰는 이유: we don't really want it to hold a reference or to retain the actual view which is created in the content view
weak var view: ARView?
/// @objc : when we are registering our handle tap, it uses the selector base registration which is part of the objective-c framework or the objective -c language
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
guard let view = self.view else { return }
let tapLocation = recognizer.location(in: view)
/// wall 이나 carpet을 터치하면 modelEntity를 반환하지 않을것
if let entity = view.entity(at: tapLocation) as? ModelEntity {
let material = SimpleMaterial(color: UIColor.random(), isMetallic: true)
entity.model?.materials = [material]
}
}
}
Raycasting
1)첫번째 방법 - ARAnchor 생성
import Foundation
import ARKit
import RealityKit
class Coordinator: NSObject, ARSessionDelegate {
/// weak 쓰는 이유: we don't really want it to hold a reference or to retain the actual view which is created in the content view
weak var view: ARView?
/// @objc : when we are registering our handle tap, it uses the selector base registration which is part of the objective-c framework or the objective -c language
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
guard let view = self.view else { return }
let tapLocation = recognizer.location(in: view)
/// raycast: going to allow us to cast Ray from the center of screen
/// .estimatedPlane : an estimate of how large the plane is
/// .existingPlaneGeometry: requires a shape and the size
/// .existingPlaneInfinite : it's a conflict claim which just goes on forever
let results = view.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
if let result = results.first {
/// ARAnchor with WorldTransform
/// ARAnchor는 ARKit에 포함되는 거지만 RealityKit에서도 사용할 수 있다.
let anchor = ARAnchor(name: "Plane Anchor", transform: result.worldTransform)
view.session.add(anchor: anchor)
let modelEntity = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .blue, isMetallic: false)])
modelEntity.generateCollisionShapes(recursive: true)
let anchorEntity = AnchorEntity(anchor: anchor)
anchorEntity.addChild(modelEntity)
view.scene.addAnchor(anchorEntity)
}
}
}
2)두번째 방법 -AnchorEntity(raycastResult:) 생성
import SwiftUI
import RealityKit
struct ContentView : View {
var body: some View {
return ARViewContainer().edgesIgnoringSafeArea(.all)
}
}
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
/// 모든 view는 gesture를 가지고 있음
/// Coordinator = coordinate different kind of delegate functions like in this case and link attempt
/// action = 어떤 행동을 pass할지
arView.addGestureRecognizer(UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap)))
context.coordinator.view = arView
return arView
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
import Foundation
import ARKit
import RealityKit
class Coordinator: NSObject {
/// weak 쓰는 이유: we don't really want it to hold a reference or to retain the actual view which is created in the content view
weak var view: ARView?
/// @objc : when we are registering our handle tap, it uses the selector base registration which is part of the objective-c framework or the objective -c language
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
guard let view = self.view else { return }
let tapLocation = recognizer.location(in: view)
/// raycast: going to allow us to cast Ray from the center of screen
/// .estimatedPlane : an estimate of how large the plane is
/// .existingPlaneGeometry: requires a shape and the size
/// .existingPlaneInfinite : it's a conflict claim which just goes on forever
let results = view.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
if let result = results.first {
/// AnchorEntity의 내장 raycastResult를 사용하면 ARSessionDelegate가 없어도 됌
/// ARAnchor을 사용하지 않고 AnchorEntity로 쓰면 됌!
let anchorEntity = AnchorEntity(raycastResult: result)
let modelEntity = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .blue, isMetallic: false)])
modelEntity.generateCollisionShapes(recursive: true)
anchorEntity.addChild(modelEntity)
view.scene.addAnchor(anchorEntity)
}
}
}
Scale, Rotate and Moving Virtual Objects
진작에 강의를 들을 걸 그랬다..
view.installGestures(.all, for: modelEntity) 이거 한줄에 내가 고민했던 것들이 모두 구현이 되는구나
import Foundation
import ARKit
import RealityKit
class Coordinator: NSObject {
/// weak 쓰는 이유: we don't really want it to hold a reference or to retain the actual view which is created in the content view
weak var view: ARView?
/// @objc : when we are registering our handle tap, it uses the selector base registration which is part of the objective-c framework or the objective -c language
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
guard let view = self.view else { return }
let tapLocation = recognizer.location(in: view)
let results = view.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
if let result = results.first {
/// AnchorEntity의 내장 raycastResult를 사용하면 ARSessionDelegate가 없어도 됌
/// ARAnchor을 사용하지 않고 AnchorEntity로 쓰면 됌!
let anchorEntity = AnchorEntity(raycastResult: result)
let modelEntity = ModelEntity(mesh: MeshResource.generateBox(size: 0.3))
modelEntity.generateCollisionShapes(recursive: true)
modelEntity.model?.materials = [SimpleMaterial(color: .blue, isMetallic: true)]
anchorEntity.addChild(modelEntity)
view.scene.addAnchor(anchorEntity)
view.installGestures(.all, for: modelEntity)
}
}
}
'언어 > iOS' 카테고리의 다른 글
RealityKit 입문 - Reality Composer (0) | 2024.10.13 |
---|---|
RealityKit 입문 - Models .usdz (3) | 2024.10.12 |
RealityKit 입문 - Anchor, Entity, MeshResource (1) | 2024.10.11 |
[AR Navigation 개발일지#2] RealityKit의 좌표를 탐구해보자 (상대좌표, 절대좌표) (4) | 2024.10.10 |
[AR Navigation 개발일지#1] ARView의 물체의 위치를 실제 위도, 경도 좌표로 변환해 표시해보자! (1) | 2024.10.09 |