首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将SCNScene放置在另一个SCNScene上

将SCNScene放置在另一个SCNScene上
EN

Stack Overflow用户
提问于 2022-11-30 16:53:24
回答 1查看 28关注 0票数 0

我正在尝试建立一个应用程序,你可以把骰子放在桌子上,如果应用程序检测到了水平平面,就会自动产生。我将在代码之后解释这个问题:

代码语言:javascript
复制
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")
    }
}

问题是这里。(伊姆古尔的视频)。正如您所看到的,表是放置的,但我不太明白如何将SCNScene直接放在另一个表上。我所做的唯一的事情就是在水龙头上建立一个模型,它只放在水平线上。

我怎样才能在另一个模型上产生模型呢?

EN

回答 1

Stack Overflow用户

发布于 2022-12-01 13:35:09

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

代码语言:javascript
复制
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__之外的某个地方)

然后你可以像这样使用它:

代码语言:javascript
复制
let objectNode = SCNNode(named:"art.scnassets/some_directory/some_scene.scn").flattenedClone()

如果要将信号flattenedClone中的所有几何图形合并到一个对象中,则该SCNNode非常有用。如果您不使用flattenedClone,您将发现您的几何形状是objectNode的单个childNodes

记住要将静态physicsBody添加到表(可能是地板)和动态physicsBodies到您的骰子,如果您想将它们保持在桌面上,并防止它们掉进地面(地板)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74631408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档