我正在尝试使用ARKit制作一个iOS应用程序。到目前为止,我已经使用了Apple的"placing objects“示例,并对其进行了增强,使其具有我自己的几何形状。这部分都工作得很好。
我有几个不同的物体可以放在地上。用简单的术语来解释这些对象,它们是在它们前面有门的盒子。
我遇到的问题是,我现在想要在应用程序中添加手势,这样当门被轻敲时,它就会旋转打开。然后,当它再次被轻敲时,门就会关闭。
我已经寻找了一些关于如何做到这一点的教程,但没有找到任何东西。谁能给我解释一下如何做到这一点,或者告诉我如何实现这种交互性的教程。
谢谢!:)
发布于 2018-01-10 07:58:22
下面是一个基本的快速游乐场,它在装载时创建了一个门。通过轻敲门,您可以旋转打开,再次轻敲将关闭门。我将代码分解成不同的函数,这样您就可以看到门是如何打开和关闭的。
import ARKit
import SceneKit
import PlaygroundSupport
class ViewController: NSObject {
var doorNode: SCNNode!
var doorisOpen: Bool!
var sceneView: ARSCNView
init(sceneView: ARSCNView) {
self.sceneView = sceneView
super.init()
self.setupWorldTracking()
self.sceneView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap(_:))))
// place door
self.sceneView.scene.rootNode.addChildNode(createDoor(position: SCNVector3(0,0,-1)))
}
private func setupWorldTracking() {
if ARWorldTrackingConfiguration.isSupported {
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
configuration.isLightEstimationEnabled = true
self.sceneView.session.run(configuration, options: [])
}
}
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
let results = self.sceneView.hitTest(gesture.location(in: gesture.view), types: ARHitTestResult.ResultType.featurePoint)
guard let result: ARHitTestResult = results.first else {
return
}
let tappedNode = self.sceneView.hitTest(gesture.location(in: gesture.view), options: [:])
if !tappedNode.isEmpty {
let node = tappedNode[0].node
if doorisOpen == true {
// rotate door
closeDoor()
} else {
// rotate door
openDoor()
}
} else {
return
}
}
func createDoor(position: SCNVector3) -> SCNNode {
let door = SCNBox(width: 0.3, height: 0.7, length: 0.025, chamferRadius: 0)
doorNode = SCNNode(geometry: door)
door.firstMaterial?.locksAmbientWithDiffuse = true
door.firstMaterial?.diffuse.contents = UIColor.brown
// place door
doorNode.position = position
// Pivot door from the end
endPivot(for: doorNode)
return doorNode
}
func openDoor() {
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat(degToRadians(degrees: 90)), z: 0, duration: 1)
doorNode.runAction(rotate)
doorisOpen = true
}
func closeDoor() {
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat(degToRadians(degrees: -90)), z: 0, duration: 1)
doorNode.runAction(rotate)
doorisOpen = false
}
func endPivot(for node: SCNNode) {
var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)
node.pivot = SCNMatrix4MakeTranslation(min.x, 0, 0)
}
func degToRadians(degrees:Double) -> Double
{
return degrees * (M_PI / 180);
}
}
let sceneView = ARSCNView()
let viewController = ViewController(sceneView: sceneView)
sceneView.autoenablesDefaultLighting = true
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = viewController.sceneView https://stackoverflow.com/questions/48172003
复制相似问题