【问题标题】:How can I create a 3D Grid in scenekit如何在场景包中创建 3D 网格
【发布时间】:2017-05-07 01:07:18
【问题描述】:

如何使用 3d 对象(框)制作网格。我已经知道如何设置场景以及如何创建对象。但我不知道如何进行布局。网格应该看起来像这样,在 3D 空间中有 3d 对象。

这是我尝试过的:

           convenience init(create: Bool) {
        self.init()

        let geometry = SCNBox(width: 0.8 , height: 0.8,
                              length: 0.1, chamferRadius: 0.005)
        geometry.firstMaterial?.diffuse.contents = UIColor.red
        geometry.firstMaterial?.specular.contents = UIColor.white
        geometry.firstMaterial?.emission.contents = UIColor.blue
        let offset: Int = 10

        for xIndex:Int in 0...2 {
            for yIndex:Int in 0...2 {
                // create a geometry copy
                let geoCopy = geometry.copy() as! SCNGeometry

                var images:[UIImage]=[]
                for i in 1...5 {
                    if let img = UIImage(named: "\(i)"){
                        images.append(img)
                        let material = SCNMaterial()
                        material.diffuse.contents = img
                        geoCopy.firstMaterial = material

                    }
                }

                let boxnode = SCNNode(geometry: geoCopy)
                let boxCopy = boxnode.copy() as! SCNNode
                boxCopy.position.x = Float(xIndex - offset)
                boxCopy.position.y = Float(yIndex - offset)
                self.rootNode.addChildNode(boxCopy)
            }
        }
    }

但我只看到一个盒子。

谢谢!

我的图片图片:

【问题讨论】:

    标签: ios swift 3d scenekit scnscene


    【解决方案1】:

    你需要创建一个几何体,一个盒子节点,然后copy那个盒子节点。当您有带子节点的节点时使用克隆,当您想要在节点处合并整个子树的几何/材质时使用 flattenedClone。在您的情况下,副本就足够了。只需更改复制节点的位置即可。

    游戏场景

    import Foundation
    import SceneKit
    
    class GameScene: SCNScene {
    
        override init() {
            super.init()
    
            let geometry = SCNBox(width: 0.6 , height: 0.6,
                                   length: 0.1, chamferRadius: 0.005)
            geometry.firstMaterial?.diffuse.contents = UIColor.red
            geometry.firstMaterial?.specular.contents = UIColor.white
            geometry.firstMaterial?.emission.contents = UIColor.blue
            let boxnode = SCNNode(geometry: geometry)
            let offset: Int = 16
    
            for xIndex:Int in 0...32 {
                for yIndex:Int in 0...32 {
                    let boxCopy = boxnode.copy() as! SCNNode
                    boxCopy.position.x = Float(xIndex - offset)
                    boxCopy.position.y = Float(yIndex - offset)
                    self.rootNode.addChildNode(boxCopy)
                }
            }
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    

    在您的视图控制器中,viewDidLoad:

    override func viewDidLoad() {
            super.viewDidLoad()
    
            // create a new scene
            let scene = GameScene()
    
            // retrieve the SCNView
            let scnView = self.view as! SCNView
    
            // set the scene to the view
            scnView.scene = scene
            scnView.pointOfView?.position = SCNVector3Make(0, 0, 100)
    
            // allows the user to manipulate the camera
            scnView.allowsCameraControl = true
    
            // show statistics such as fps and timing information
            scnView.showsStatistics = true
    
            // configure the view
             scnView.backgroundColor = UIColor.white
    
        }
    

    请注意,我刚刚将相机视点推回到 +Z 轴上,以便更好地查看您的网格。

    网格截图


    编辑:每个几何体的新材质

    如果您想为每个几何图形分配新材质,您需要创建几何图形的副本并将新材质分配给该几何图形副本。请参阅下面的代码,它为每个漫反射属性随机分配一个 UIImage,从一组名为 1.png 到 8.png 的七个图像。

    import Foundation
    import SceneKit
    
    class GameScene: SCNScene {
    
        override init() {
            super.init()
    
            let geometry = SCNBox(width: 6 , height: 6,
                                  length: 6, chamferRadius: 0.5)
    
            for xIndex:Int in stride(from: 0, to: 32, by:8) {
                for yIndex:Int in stride(from: 0, to: 32, by: 8) {
                    // create a geometry copy
                    let geoCopy = geometry.copy() as! SCNGeometry
    
                    // create a random material
                    let r = arc4random_uniform(7) + 1
                    let img = UIImage(named: "\(r).png")
                    let mat = SCNMaterial()
                    mat.diffuse.contents = img
                    geoCopy.firstMaterial = mat
    
                    // create a copy node with new material and geo copy
                    let boxnode = SCNNode(geometry: geoCopy)
                    let boxCopy = boxnode.copy() as! SCNNode
                    boxCopy.position.x = Float(xIndex - offset)
                    boxCopy.position.y = Float(yIndex - offset)
                    self.rootNode.addChildNode(boxCopy)
                }
            }
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    

    截图

    【讨论】:

    • 谢谢!!但我有最后一个问题。我正在尝试在每个几何图形上添加一个 SCNMaterial(),我该怎么做?每个节点的材料都不同,我只有 15 个节点。谢谢。我刚刚更新了我的问题。
    • @John 更新了答案,以便每个节点都有不同的材料。
    • 谢谢,非常感谢。但是我怎么能用图像来做到这一点。刚刚更新了我的答案。
    • 材质属性的内容可以是任何颜色、图像甚至是动画内容。所以设置 `mat.diffuse.contents = UIImage(named:"some.png") 也可以。您可以为每个节点分配一个单独的图像,就像我们对颜色所做的那样。希望这可以帮助。见:developer.apple.com/reference/scenekit/scnmaterialproperty/…
    • 我试过了,但我在每个几何图形上看到了相同的图像。检查我的问题。谢谢
    【解决方案2】:

    您需要将语句 -let boxnode = SCNNode(geometry: self.geometry) - 放入循环中。如果您希望使用相同的材​​料,您可以为所有节点使用相同的几何图形(只需将几何图形存储在变量中并分配它)。否则,如果您希望使用不同的材质,请复制几何体并每次指定不同的材质。

    【讨论】:

    • 谢谢@Karl Sigiscar,我刚刚更新了我的问题。但它不起作用。我仍然只看到一个盒子。你能帮我吗?
    • 您还需要在循环内移动代码的 addChildNode 部分。迭代期间创建的每个新节点都必须添加到您的场景中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 2023-04-09
    • 2015-05-06
    • 1970-01-01
    相关资源
    最近更新 更多