objective
:我想要魔方的每张脸(前,后,左,右,上,底部)是构成那张脸的9个cublets的纯色(例如,所有带有z = 1的cublets应该将他们的前脸涂成绿色)。电流行为:颜色是部分或以碎片的模式应用的(例如,顶部的一排绿色,然后在下面的一排绿色,但不是坚固的3x3绿色脸)。所有面孔都会发生这种情况(红色for +x,橙色for -x,白色for +y,黄色,for -y,green for +z,blue for -z)。
被提出的问题:我怀疑Cublets(SCNBox)可能会旋转,导致材料适用于错误的面部或错误的方向,但是我无法确认或修复此材料。
我的代码是我的代码:import SwiftUI
import SceneKit
class CuboScene: SCNScene {
override init() {
super.init()
rootNode.eulerAngles = SCNVector3(0, 0, 0) // Ensure rootNode is not rotated
rootNode.position = SCNVector3(0, 0, 0) // Ensure rootNode is at the origin
rootNode.scale = SCNVector3(1, 1, 1) // Ensure no unexpected scaling
// let light = SCNLight()
// light.type = .omni
// light.intensity = 2000
// let lightNode = SCNNode()
// lightNode.light = light
// lightNode.position = SCNVector3(x: 5, y: 5, z: 5)
// rootNode.addChildNode(lightNode)
configureLights()
createRubikCube()
}
private func createRubikCube() {
let size: CGFloat = 0.8
let spacing: CGFloat = 1.05
for x in -1...1 {
for y in -1...1 {
for z in -1...1 {
let cubelet = SCNBox(width: size, height: size, length: size, chamferRadius: 0.0) // No rounded edges
let cubeletNode = SCNNode(geometry: cubelet)
cubeletNode.position = SCNVector3(Float(x) * Float(spacing),
Float(y) * Float(spacing),
Float(z) * Float(spacing))
cubeletNode.eulerAngles = SCNVector3(0, 0, 0) // Ensure no rotation
print("Cubelet at position: (\(Float(x) * Float(spacing)), \(Float(y) * Float(spacing)), \(Float(z) * Float(spacing)) with materials: \(getFaceMaterial(x: x, y: y, z: z).map { $0.diffuse.contents as? UIColor ?? .gray }) and eulerAngles: \(cubeletNode.eulerAngles), rotation: \(cubeletNode.rotation)")
cubelet.materials = getFaceMaterial(x: x, y: y, z: z)
rootNode.addChildNode(cubeletNode)
}
}
}
}
private func getFaceMaterial(x: Int, y: Int, z: Int) -> [SCNMaterial] {
let colors: [UIColor] = [
// Right face (+X): red if x = 1, gray for x = 0 or -1
(x == 1) ? .red : .gray,
// Left face (-X): orange if x = -1, gray for x = 0 or 1
(x == -1) ? .orange : .gray,
// Top face (+Y): white if y = 1, gray for y = 0 or -1
(y == 1) ? .white : .gray,
// Bottom face (-Y): yellow if y = -1, gray for y = 0 or 1
(y == -1) ? .yellow : .gray,
// Front face (+Z): green if z = 1, gray for z = 0 or -1
(z == 1) ? .green : .gray,
// Back face (-Z): blue if z = -1, gray for z = 0 or 1
(z == -1) ? .blue : .gray
]
// print("Position (\(x), \(y), \(z)): Colors = \(colors)") // Debugging
return colors.map { createMaterial(color: $0) }
}
private func createMaterial(color: UIColor) -> SCNMaterial {
let material = SCNMaterial()
print("Applying material with color: \(color)")
material.diffuse.contents = color.withAlphaComponent(1.0)
material.specular.contents = UIColor.white
material.shininess = 100
material.lightingModel = .phong
return material
}
private func configureLights() {
// Ambient light for base illumination
let ambientLight = SCNLight()
ambientLight.type = .ambient
ambientLight.intensity = 500
let ambientLightNode = SCNNode()
ambientLightNode.light = ambientLight
rootNode.addChildNode(ambientLightNode)
// Array of positions and directions for the 6 lights
let positions: [(SCNVector3, SCNVector3)] = [
(SCNVector3(0, 10, 0), SCNVector3(0, -1, 0)), // Top
(SCNVector3(0, -10, 0), SCNVector3(0, 1, 0)), // Bottom
(SCNVector3(10, 0, 0), SCNVector3(-1, 0, 0)), // Right
(SCNVector3(-10, 0, 0), SCNVector3(1, 0, 0)), // Left
(SCNVector3(0, 0, 10), SCNVector3(0, 0, -1)), // Front
(SCNVector3(0, 0, -10), SCNVector3(0, 0, 1)) // Back
]
for (position, direction) in positions {
let light = SCNLight()
light.type = .directional
light.intensity = 1000
light.color = UIColor.white
let lightNode = SCNNode()
lightNode.light = light
lightNode.position = position
lightNode.eulerAngles = SCNVector3(
atan2(direction.y, direction.z),
atan2(direction.x, direction.z),
0
) // Orient toward the center
rootNode.addChildNode(lightNode)
}
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
ScenekitView:
import SwiftUI
import SceneKit
struct SceneKitView: UIViewRepresentable {
func makeUIView(context: Context) -> SCNView {
let view = SCNView()
view.scene = CuboScene() // Use the created scene
view.allowsCameraControl = true // Allow camera movement with touch
view.autoenablesDefaultLighting = false // Disable default lighting
view.backgroundColor = .clear
// Configure an initial camera
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 5, y: 5, z: 5) // Diagonal position to see all faces
cameraNode.look(at: SCNVector3(0, 0, 0)) // Point to the cubes center
view.pointOfView = cameraNode
return view
}
func updateUIView(_ uiView: SCNView, context: Context) {}
}
#Preview {
SceneKitView()
}
在这里,魔方的颜色是如何产生的:
我尝试了很多不同的事情,但是我不能做对了。
您的材料以错误的顺序固定。它行驶前,右,后,左,顶部,底部。 更新您的材料阵列,例如
let colors: [UIColor] = [
// Front face (+Z): green if z = 1, gray for z = 0 or -1
(z == 1) ? .green : .gray,
// Right face (+X): red if x = 1, gray for x = 0 or -1
(x == 1) ? .red : .gray,
// Back face (-Z): blue if z = -1, gray for z = 0 or 1
(z == -1) ? .blue : .gray,
// Left face (-X): orange if x = -1, gray for x = 0 or 1
(x == -1) ? .orange : .gray,
// Top face (+Y): white if y = 1, gray for y = 0 or -1
(y == 1) ? .white : .gray,
// Bottom face (-Y): yellow if y = -1, gray for y = 0 or 1
(y == -1) ? .yellow : .gray
]