ios - 如何在 scenekit 中创建 3D 网格

标签 ios swift 3d scenekit scnscene

如何用 3d 对象(框)制作网格。我已经知道如何设置 scnscene 以及如何创建对象。但我不知道如何进行布局。网格应该看起来像这样,在 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)
            }
        }
    }

但我只看到一个盒子。

谢谢!

我的图片:

enter image description here

最佳答案

您需要创建一个几何体、一个框节点,然后是 copy那个盒子节点。当您有带有子节点的节点时使用克隆,当您想要在节点处合并整个子树的几何图形/ Material 时使用 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)
    }
}

在您的 View Controller 中,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 轴上,以便更好地查看您的网格。

网格截图

enter image description here


编辑:每个几何体的新 Material

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

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)
    }
}

截图

enter image description here

关于ios - 如何在 scenekit 中创建 3D 网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41265653/

相关文章:

swift - 有谁知道如何快速解决 BackgroundTask 问题?

3d - 约束景观的程序生成

objective-c - iOS RESTful POST调用在UIWebView中有效,但从线程调用时无效

IOS - 处理大量图像的最佳实践(性能+磁盘大小)

swift - 如何在 Swift 中扩展字符串 NSRange?

javascript - 使用球坐标三个js在球体上移动点

css - 使用 PhantomJS 的 CSS3 的 3D 问题

ios - 如何将 iPhone 应用程序标记为仅限 iOS8?

iphone - 如何通过删除应用程序更新中的旧数据来迁移核心数据

ios - 触发 segue 时出现错误 "fatal error: unexpectedly found nil while unwrapping an Optional value"