Swift 3 SceneKit - 自定义网格节点上的正确光源

时间:2017-04-19 10:07:18

标签: opengl swift3 camera scenekit light

我试图让相机上的灯光照射到我创建的自定义网格上。但是,无论我如何定位一个光节点,它似乎总是坚持自定义网格的原始枢轴点(0,0)。

This is how it looks currently

这是我用于创建场景光线相机网格节点的代码,以及然后最后添加一个事件处理程序来在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
    }
}

这是我在这里的第一个问题,我希望我已经提供了所需的信息。请告诉我。

0 个答案:

没有答案