2016-12-21 4 views
3

Как создать сетку с 3d-объектами (вставка). Я уже знаю, как настроить scnscene и как создать объект. Но я не знаю, как сделать макет. Сетка должна выглядеть как эта, с 3D-объектом в трехмерном пространстве.Как создать 3D-сетку в scenekit

Вот что я пробовал:

  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


Edit: Новый материал для каждой геометрии

Если вы хотите назначить новый материал для каждой геометрии, вам нужно создать копию геометрии и присвоение нового материала этой копии геометрии. См. Приведенный ниже код, который произвольно присваивает UIImage для каждого диффузного свойства из набора из семи изображений с именем 1.png to 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) 
    } 
} 

Скриншот

enter image description here

+0

спасибо !! Но у меня есть последний вопрос. Я пытаюсь добавить SCNMaterial() для каждой геометрии, как я могу это сделать? Материал для каждого узла отличается, у меня всего 15 узлов. Благодарю. Я только что обновил свой вопрос. – John

+0

@John Обновлен ответ, так что каждый узел имеет другой материал. –

+0

Спасибо, очень оценили. Но как я могу сделать это с изображениями. Просто обновил свой ответ. – John

0

Вам нужно положить заявление -Давайте boxnode = SCNNode (геометрия: self.geometry) - внутри цикла. Если вы хотите использовать одни и те же материалы, вы можете использовать одну и ту же геометрию для всех узлов (просто сохраните геометрию в переменной и назначьте ее). В противном случае, если вы хотите иметь разные материалы, копируйте геометрию и каждый раз назначайте разные материалы.

+0

Благодаря @Karl Sigiscar, я просто обновил свой вопрос. Но это не сработает. Я все еще вижу только одну коробку. Вы можете мне помочь? – John

+1

Вам также нужно переместить часть кода addChildNode в цикле. Каждый новый узел, созданный во время итерации, должен быть добавлен в вашу сцену. –

Смежные вопросы