将SCNScene放置在另一个SCNScene上



我试图建立一个应用程序,你可以在桌子上放置设备,自动生成,如果应用程序检测水平面。我将在代码后面解释这个问题:

import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!

var isTableAdded = false

var diceArray = [SCNNode]()

override func viewDidLoad() {
super.viewDidLoad()

// Set the view's delegate
sceneView.delegate = self

self.sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]

sceneView.autoenablesDefaultLighting = true

}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// Create a session configuration
let configuration = ARWorldTrackingConfiguration()

configuration.planeDetection = .horizontal

// Run the view's session
sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

// Pause the view's session
sceneView.session.pause()
}

// MARK: - ADDS DICE
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

print("Tapped")
if let touch = touches.first {
let touchLocation = touch.location(in: sceneView)

let results = sceneView.hitTest(touchLocation, types: .existingPlaneUsingExtent)

if let hitResults = results.first {

// Create a new scene
let diceScene = SCNScene(named: "art.scnassets/diceCollada.scn")!

if let diceNode = diceScene.rootNode.childNode(withName: "Dice", recursively: true) {

diceNode.position = SCNVector3(
x: hitResults.worldTransform.columns.3.x,
y: hitResults.worldTransform.columns.3.y,
z: hitResults.worldTransform.columns.3.z)

diceArray.append(diceNode)

sceneView.scene.rootNode.addChildNode(diceNode)

}
}
}
} 
// MARK: - RENDERS TABLE AT THE HORIZONTAL PLANE
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
print("plane detected")
if isTableAdded == false {
let planeAnchor = anchor
// let planeNode = SCNNode()
let x = planeAnchor.transform.columns.3.x
let y = planeAnchor.transform.columns.3.y
let z = planeAnchor.transform.columns.3.z
//planeNode!.position = SCNVector3(x: x, y: y, z: z)

let idleScene = SCNScene(named: "art.scnassets/Table.scn")!
let node = SCNNode()
for child in idleScene.rootNode.childNodes{
node.addChildNode(child)
}
node.position = SCNVector3(x,y,z)
node.scale = SCNVector3(0.001,0.001,0.001)

sceneView.scene.rootNode.addChildNode(node)

isTableAdded = true
}
print("Model placed")
}

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

print("plane updated")
}
}

问题在这里。(视频来自Imgur)。正如你所看到的桌子被放置,但我不太明白如何将SCNScene直接放置在另一个。我所做的唯一一件事就是在水龙头处创建一个模型,并且它只放置在水平面上。

我如何在另一个模型上生成模型?

您可以使用这个小小的extension来实现您想要的。它基本上是一个辅助函数,允许您从任何场景文件(.scn)中抓取所有几何对象,并且可以将它们放置在您想要的任何地方。我使用这个函数从大量其他场景文件中组合/构建一个场景(默认),这些场景文件包含单独的几何形状。它将返回一个SCNNode而不是一个新的SCNScene。如果你需要更多的信息,或者如果我误解了你的话,请告诉我。

extension SCNNode {
convenience init(named name: String) {
self.init()
guard let scene = SCNScene(named: name) else {return}
for childNode in scene.rootNode.childNodes {addChildNode(childNode)}
}
}

(将此代码片段放在ViewController之外的某个地方)

那么你可以这样使用:

let objectNode = SCNNode(named:"art.scnassets/some_directory/some_scene.scn").flattenedClone()

如果您想将单个SCNNode中的所有几何图形合并到一个对象中,flattenedClone是有用的。如果你不使用flattenedClone,你会发现你的几何图形是objectNode的单独childNodes

请记住,添加静态物理体到表(可能地板)和动态物理体到你的设备,如果你想保持他们在桌子的顶部,防止他们掉下地面(地板)。

相关内容

  • 没有找到相关文章

最新更新