簡體   English   中英

場景套件。 將節點放置在一個“表面”中

[英]SceneKit. Place nodes in one "surface"

用戶在圖紙視圖上畫一條線,然后我需要將這些點轉換為 3d 世界,但將這些點放在一個“表面”中。 為此,我將點數組 map 轉換為向量(我使用 hitTest with.featurePoint),然后過濾該數組以獲取下一個

func didEndDrawing(with points: [CGPoint]) {

    guard let transform = sceneView.pointOfView?.transform else { return }
    let cameraVectror = SCNVector3(transform.m31, transform.m32, transform.m33)

    let farthestVector = points
        .reduce((vector: SCNVector3(0, 0, 0), distance: CGFloat.zero)) { result, point in
                    
        guard let vector = getVector(for: point) else { return result }
        let distance: CGFloat = cameraVectror.distance(to: vector)
        return  distance > result.distance ? (vector, distance) : result
    }
        .vector
}
let parentNode = SCNNode()
parentNode.position = farthestVector

如何調整坐標(我猜是 z 位置)以使所有子節點與視點的距離相同? 該應用程序的想法是在 AR 中手繪。

更新

在沃爾坦的幫助下,我能夠解決它


points.forEach { point in
    let scenePoint = sceneView.unprojectPoint(SCNVector3(point.x, point.y, CGFloat(projectedPoint.z)))
    let sphere = SCNSphere(radius: 0.01)
    let material = SCNMaterial()
    material.diffuse.contents = UIColor.green
    sphere.materials = [material]
    let node = SCNNode(geometry: sphere)
    node.position = scenePoint
    sceneView.scene.rootNode.addChildNode(node)
}

如果我理解正確,您需要某種點擊/拖動組合 - 從 2D 世界中獲取點並轉換為 3D 世界。 這是導彈命令類型游戲的一些游戲代碼,也許它會幫助你處理 unprojectPoint 的東西。 有一些計時器不包括在內,但希望您能明白這一點。

@objc func handleTap(recognizer: UITapGestureRecognizer)
    {
        if(data.gameState == .endGame)
        {
            endGameAnimates.stop()
            let _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { _ in self.dismiss(animated: false, completion: nil) })
            
            return
        }
        
        if(gameControl.isWaveComplete == true || gNodes.gameNodes.isPaused == true) { return }
        
        currentLocation = recognizer.location(in: gameScene)
        let projectedPoint = gameScene.projectPoint(SCNVector3(0, 0, 0))
        let scenePoint = gameScene.unprojectPoint(SCNVector3(currentLocation.x, currentLocation.y, CGFloat(projectedPoint.z)))
        
        if(data.gameState == .endGame) // Allow animations to finish, otherwise they will show up next round
        {
            DispatchQueue.main.async { self.endGameAnimates.stop() }
            let _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { _ in self.dismiss(animated: false, completion: nil) })
            return
        }
        
        if(data.missilesAvailable <= 0)
        {
            sound.playSoundType(vSoundType: .defenseFails)
            hudControl.notify()
        }
        else
        {
            gameControl.defenseMissileShoot(vPosition: scenePoint, soundType: 0)
            sound.playSoundType(vSoundType: .defenseFires)
        }
    }
    //**************************************************************************
    @objc func handlePan(recognizer: UIPanGestureRecognizer)
    {
        currentLocation = recognizer.location(in: gameScene)
        let projectedPoint = gameScene.projectPoint(SCNVector3(0, 0, 0))
        let scenePoint = gameScene.unprojectPoint(SCNVector3(currentLocation.x, currentLocation.y, CGFloat(projectedPoint.z)))
        
        if(gameControl.isWaveComplete == true || gNodes.gameNodes.isPaused == true) { return }
        
        switch recognizer.state
        {
        case UIGestureRecognizer.State.began:
            gameControl.defenseMissileShoot(vPosition: scenePoint, soundType: 1)
            SNDdefenseSoundCount = 0
            if(data.missilesAvailable <= 0) { sound.playSoundType(vSoundType: .defenseFails); hudControl.notify() }
            beginLocation.x = currentLocation.x
            break
        case UIGestureRecognizer.State.changed:
            if(currentLocation.x > beginLocation.x + dragDistance) 
            {
                beginLocation.x = currentLocation.x
                if(data.missilesAvailable > 0) { gameControl.defenseMissileShoot(vPosition: scenePoint, soundType: 2) }
                SNDdefenseSoundCount += 1
            }
            if(currentLocation.x < beginLocation.x - dragDistance)
            {
                beginLocation.x = currentLocation.x
                if(data.missilesAvailable > 0) { gameControl.defenseMissileShoot(vPosition: scenePoint, soundType: 2) }
                SNDdefenseSoundCount += 1
            }
            break
        case UIGestureRecognizer.State.ended:
            if(data.missilesAvailable > 0)
            {
                if(SNDdefenseSoundCount < 2) { sound.playSoundType(vSoundType: .defenseFires) }
                else                         { sound.playSoundType(vSoundType: .defensePans)  }
            }
            break
        default:
            break
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM