我试图让相机上的灯光照射到我创建的自定义网格上。但是,无论我如何定位一个光节点,它似乎总是坚持自定义网格的原始枢轴点(0,0)。
这是我用于创建场景,光线,相机和网格节点的代码,以及然后最后添加一个事件处理程序来在x轴上旋转网格。
let scene = SCNScene() //Instantiate Scene for 3D object
SceneView.scene = scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = SCNLight.LightType.ambient
ambientLightNode.light!.color = UIColor(white: 0.67, alpha: 1.0)
scene.rootNode.addChildNode(ambientLightNode)
let omniLightNode = SCNNode()
omniLightNode.light = SCNLight()
omniLightNode.light!.castsShadow = true
omniLightNode.light!.type = SCNLight.LightType.omni
omniLightNode.light!.color = UIColor(white: 0.75, alpha: 1.0)
omniLightNode.position = SCNVector3Make(0, 0, 0)
scene.rootNode.addChildNode(omniLightNode)
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3Make(0, 2, 0)
scene.rootNode.addChildNode(cameraNode)
//Create the mesh node.
let environmentMeshNode = SCNNode()
environmentMeshNode.position = SCNVector3Make(0, 0, -8)
scene.rootNode.addChildNode(environmentMeshNode)
//Create the custom mesh, move pivot point and add material.
environmentMesh.geometry = EnvironmentMesh.createEnvironmentMesh(10, 10)
environmentMesh.pivot = SCNMatrix4MakeTranslation(4.5, 0.5, -4.5)
environmentMesh.geometry?.firstMaterial?.diffuse.contents = UIColor.gray
environmentMeshNode.addChildNode(environmentMesh)
//Adding recognisers to manipulate rotation on x axis.
let panXRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.rotateXGesture(_:)))
SceneView.addGestureRecognizer(panXRecognizer)
然后,gestureRecognizer以下列方式旋转网格:
func rotateXGesture (_ sender: UIPanGestureRecognizer) { //X rotation recognizer
let translation = sender.translation(in: sender.view)
var newXAngle = (Float)(translation.x)*(Float)(Double.pi)/180.0
newXAngle += currentXAngle
environmentMesh.transform = SCNMatrix4MakeRotation(newXAngle, 0, 1, 0)
if(sender.state == UIGestureRecognizerState.ended){
currentXAngle = newXAngle
}
}
这是用于创建自定义网格的类,在这种情况下只是一个10x10网格,其中一些顶点略微抬高。
class EnvironmentMesh{
//Custom function for creating the plane mesh. Takes in mesh vertex arguments.
static func createEnvironmentMesh(_ xSize: Int, _ zSize: Int) -> SCNGeometry {
var vertices:[SCNVector3] = []
for x in stride(from:0, to:xSize, by:1){
for z in stride(from:0, to:-zSize, by:-1) { // Creates a X*Y square of vertices.
vertices.append(SCNVector3Make(Float(x), 0, Float(z)))
}
}
vertices[55].y = 5
vertices[27].y = 3
vertices[85].y = 2
vertices[58].y = 1.3
let vertexData = NSData(bytes: vertices, length: vertices.count * MemoryLayout<SCNVector3>.size)
let vertexSource = SCNGeometrySource(data: vertexData as Data, semantic: SCNGeometrySource.Semantic.vertex, vectorCount: vertices.count, usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<SCNVector3>.size)
let normalSource = SCNGeometrySource(data: vertexData as Data, semantic: SCNGeometrySource.Semantic.normal, vectorCount: vertices.count, usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<SCNVector3>.size)
var indices:[Int32] = []
for x in stride(from:0, to:xSize-1, by:1){
for z in stride(from:0, to: zSize-1, by:1){
indices.append(Int32((x * 10) + z)) //0
indices.append(Int32(((x + 1) * 10) + z)) //10
indices.append(Int32((x * 10) + (z + 1))) //1
indices.append(Int32((x * 10) + (z + 1))) //1
indices.append(Int32(((x + 1) * 10) + z)) //10
indices.append(Int32(((x + 1) * 10) + (z + 1))) //11
}
}
let indexData = NSData(bytes: indices, length: MemoryLayout<Int32>.size * indices.count)
let indexElement = SCNGeometryElement(data: indexData as Data, primitiveType: SCNGeometryPrimitiveType.triangles, primitiveCount: indices.count / 3, bytesPerIndex: MemoryLayout<CInt>.size)
let geometry = SCNGeometry(sources: [vertexSource, normalSource], elements: [indexElement])
return geometry
}
}
这是我在这里的第一个问题,我希望我已经提供了所需的信息。请告诉我。