2016-12-21 67 views
3

如何使用3d对象(box)制作网格。我已经知道如何设置scanscene以及如何创建一个对象。但我不知道如何进行布局。网格应该看起来像这样,3D空间中有3d对象。如何在scenekit中创建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

回答

2

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

GameScene

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轴有一个更好地查看您的网格。

网格截图

enter image description here


编辑:对于每个几何

如果你想一个新的材质指定给每个几何图形,您需要创建新材料几何体的副本并将新材料分配给该几何体副本。请参阅下面的代码,从7个名为1.png的图像到8.png的一组图像中为每个diffuse属性随机分配一个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

+0

谢谢!但我有最后一个问题。我试图在每个几何体上添加一个SCNMaterial(),我该怎么做?每个节点的材质都不同,我只有15个节点。谢谢。我刚刚更新了我的问题。 – John

+0

@John更新了答案,以便每个节点具有不同的材质。 –

+0

谢谢,真的很感激。但我怎么能用图像来做到这一点。刚刚更新了我的答案。 – John

0

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

+0

感谢@Karl Sigiscar,我刚刚更新了我的问题。但它不起作用。我仍然只看到一个盒子。你可以帮我吗? – John

+1

您还需要在循环内移动代码的addChildNode部分。迭代期间创建的每个新节点都必须添加到场景中。 –