ios - Swift & SceneKit 3D 多色四面体
问题描述
我正在尝试使用 Swift 4 和 Scenekit 制作一个 3D 旋转四面体,它的每一面都有不同的颜色(或图像)。
我设法创建了四面体并使其旋转良好,但是当我尝试使每一面具有不同的颜色或图像时,我发现它以指定的第一种颜色显示每一面。
我以为我已经node.geometry?.materials
正确定义了,但它只使用列表中的第一种颜色。如果我重新排序列表,那么它将使用新的第一种颜色作为唯一颜色。
我做错了什么?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let sceneView = SCNView(frame: self.view.frame)
self.view.addSubview(sceneView)
let myScene = SCNScene()
sceneView.scene = myScene
let mySphere = SCNSphere(radius: 5)
let mySphereNode = SCNNode(geometry: mySphere)
mySphereNode.position = SCNVector3(x: 0, y: 0, z: 0)
let vertices:[SCNVector3] = [
SCNVector3(x:0, y:1, z:1), // b // 0
SCNVector3(x:1, y:0, z:1), // d // 1
SCNVector3(x:0, y:0, z:0), // a // 2
SCNVector3(x:1, y:1, z:0), // c // 3
]
let vertexSource = SCNGeometrySource(vertices: vertices)
let indices: [UInt16] = [
2, 3, 1, // acd
0, 2, 1, // bad
3, 0, 1, // cbd
3, 2, 0 // cab
]
let element = SCNGeometryElement(indices: indices, primitiveType: .triangles)
let geometry = SCNGeometry(sources: [vertexSource], elements: [element])
let blueMaterial = material(withColor: UIColor.blue)
let yellowMaterial = material(withColor: UIColor.yellow)
let purpleMaterial = material(withColor: UIColor.purple)
let magentaMaterial = material(withColor: UIColor.magenta)
let node = SCNNode(geometry: geometry)
node.position = SCNVector3(x: 0, y: 0, z: 0)
node.scale = SCNVector3(x: 3, y: 3, z: 3)
node.geometry?.materials = [blueMaterial, yellowMaterial, purpleMaterial, magentaMaterial]
myScene.rootNode.addChildNode(node)
node.runAction(SCNAction.rotateBy(x: CGFloat(0), y: CGFloat(10), z: CGFloat(0), duration: 30))
let myCamera = SCNCamera()
let myCameraNode = SCNNode()
myCameraNode.camera = myCamera
myCameraNode.position = SCNVector3(x: -25, y: 10, z: 30)
myCameraNode.orientation = SCNQuaternion(x: -0.26, y: -0.32, z: 0, w: 0.91)
myScene.rootNode.addChildNode(myCameraNode)
}
func material(withColor color : UIColor) -> SCNMaterial {
let material = SCNMaterial();
material.diffuse.contents = color
material.locksAmbientWithDiffuse = true
return material
}
解决方案
您的代码非常好。唯一的问题是构建几何时没有足够的几何元素。像下面这样的快速修复,你可以获得四种颜色。
let element0 = SCNGeometryElement(indices: [UInt16](indices[0...2]), primitiveType: .triangles)
let element1 = SCNGeometryElement(indices: [UInt16](indices[3...5]), primitiveType: .triangles)
let element2 = SCNGeometryElement(indices: [UInt16](indices[6...8]), primitiveType: .triangles)
let element3 = SCNGeometryElement(indices: [UInt16](indices[9...11]), primitiveType: .triangles)
let geometry = SCNGeometry(sources: [vertexSource], elements: [element0, element1,element2,element3])
推荐阅读
- c# - 自定义列表框不会完全显示字符串c#
- javascript - 自定义 debounce 函数不会在 React 中传递 e.target.value
- regex - VBA 正则表达式
- angular - 在相同的 *ngIf else 条件下加载两个模板
- java - 哪个更昂贵:在有效负载中发送额外的字段或在后端进行等效的正则表达式测试
- javascript - 尝试设置带有重音符号的标题时,jQuery .dialog 方法失败
- excel - 用于批量替换 Excel 工作簿中的链接的 Powershell 脚本
- java - Google IoT 设备如何接收 WiFi 密码?是否可以通过编程方式获取 WiFi 密码?(无根)
- reactjs - 在 react-axios 中发送发布请求时如何在数据表单中添加 .wav 文件?
- python - 即使语法与官方网站上的相同,这个 playsound 模块的代码中的错误是什么?