如何在 scenekit 中创建 3D 网格
How can I create a 3D Grid in scenekit
如何用 3d 对象(框)制作网格。我已经知道如何设置 scnscene 以及如何创建对象。但我不知道如何进行布局。网格应该看起来像这样,在 3D space 中有 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)
}
}
}
但是我只看到一个盒子。
谢谢!
我的图片:
您需要将语句 -let boxnode = SCNNode(geometry: self.geometry) - 放在循环内。如果你想使用相同的材料,你可以对所有节点使用相同的几何体(只需将几何体存储在一个变量中并分配它)。否则,如果您希望有不同的材料,请复制几何体并每次分配不同的材料。
您需要创建一个几何图形、一个框节点,然后 copy 该框节点。当您有带有子节点的节点时使用克隆,当您想要合并节点上整个子树的 geometries/materials 时使用 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 轴上,以便更好地查看您的网格。
网格截图
编辑:每个几何体的新 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)
}
}
截图
如何用 3d 对象(框)制作网格。我已经知道如何设置 scnscene 以及如何创建对象。但我不知道如何进行布局。网格应该看起来像这样,在 3D space 中有 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)
}
}
}
但是我只看到一个盒子。
谢谢!
我的图片:
您需要将语句 -let boxnode = SCNNode(geometry: self.geometry) - 放在循环内。如果你想使用相同的材料,你可以对所有节点使用相同的几何体(只需将几何体存储在一个变量中并分配它)。否则,如果您希望有不同的材料,请复制几何体并每次分配不同的材料。
您需要创建一个几何图形、一个框节点,然后 copy 该框节点。当您有带有子节点的节点时使用克隆,当您想要合并节点上整个子树的 geometries/materials 时使用 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 轴上,以便更好地查看您的网格。
网格截图
编辑:每个几何体的新 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)
}
}
截图