Как использовать явную сериализацию для получения данных из металлических данных в структуру Swift - PullRequest
1 голос
/ 28 апреля 2019

Я пытаюсь получить данные из массива Metal Mesh Vertex в структуру Swift.

Я знаю, что структуры Swift и структура C могут не совпадать.Я также знаю, что мог бы сделать это с заголовком AC briding, но это вызывает некоторые другие проблемы.

Как мне сделать это с явной сериализацией от металлических данных до массива структур Swift?

Этобыло бы полезно также увидеть десериализацию тех же данных.

import PlaygroundSupport
import MetalKit
import simd

struct Vertex {
    var position: vector_float3
    var normal: vector_float3
    var texture: vector_float2

    init() {
        position = float3(repeating: 0.0)
        normal = float3(repeating: 0.0)
        texture = float2(repeating: 0.0)
    }

    init(pos: vector_float3, nor: vector_float3, text: vector_float2) {
        position = pos
        normal = nor
        texture = text
    }
}

guard let device = MTLCreateSystemDefaultDevice() else {
    fatalError("GPU is not supported")
}

let allocator = MTKMeshBufferAllocator(device: device)

let mesh = MDLMesh.init(boxWithExtent: [0.75, 0.75, 0.75], segments: [1, 1, 1], inwardNormals: false, geometryType: .quads, allocator: allocator)

// Details about the vertex
print("Details about the vertex")
print( mesh.vertexDescriptor )

// Look at the vertex detail
// This doesn't work because, I think, of the way Swift pads the memory in structs.
print("Number of vertex: ", mesh.vertexCount)
let buff = mesh.vertexBuffers[0]

// This gives the wrong result but is nice code
let count = buff.length / MemoryLayout<Vertex>.stride
print("Wrong result!")
print("Space in buffer for vertex: ", count)
let wrongResult = buff.map().bytes.bindMemory(to: Vertex.self, capacity: count)
for i in 0 ..< count {
    print( "Vertex: ", i, wrongResult[i])
}

// This gives the correct result but is really ugly code
print("Correct result!")
let tempResult = buff.map().bytes.bindMemory(to: Float.self, capacity: mesh.vertexCount*8)
var result = Array(repeating: Vertex(), count: mesh.vertexCount)
for i in 0 ..< mesh.vertexCount {
    result[i].position.x = tempResult[i*8 + 0]
    result[i].position.y = tempResult[i*8 + 1]
    result[i].position.z = tempResult[i*8 + 2]
    result[i].normal.x = tempResult[i*8 + 3]
    result[i].normal.y = tempResult[i*8 + 4]
    result[i].normal.z = tempResult[i*8 + 5]
    result[i].texture.x = tempResult[i*8 + 6]
    result[i].texture.y = tempResult[i*8 + 7]
}
for i in 0 ..< mesh.vertexCount {
    print( "Vertex: ", i, result[i])
}
...