取消引用UnsafeMutablePointer <unsafemutablerawpointer>

时间:2017-06-10 18:40:08

标签: arrays swift3 unsafemutablepointer

我有一个传递数据的块,我想转换为浮点数组的数组 - 例如[[0.1,0.2,0.3,1.0],[0.3,0.4,0.5,1.0],[0.5,0.6,0.7,1.0]]。这些数据以data:UnsafeMutablePointer<UnsafeMutableRawPointer>的形式传递给我(内部数组是RGBA值)

fwiw - 块参数来自SCNParticleEventBlock

如何将数据取消引用到[[Float]]?一旦我有包含内部数组的数组,我可以使用:

引用内部数组(colorArray)数据
let rgba: UnsafeMutablePointer<Float> = UnsafeMutablePointer(mutating: colorArray)
let count = 4
for i in 0..<count {
    print((rgba+i).pointee)
}

fwiw - 这是Apple的示例Objective-C代码,用于引用数据(from SCNParticleSystem handle(_:forProperties:handler:)

[system handleEvent:SCNParticleEventBirth
      forProperties:@[SCNParticlePropertyColor]
          withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) {
              for (NSInteger i = 0; i < count; ++i) {
                  float *color = (float *)((char *)data[0] + dataStride[0] * i);
                  if (rand() & 0x1) { // Switch the green and red color components.
                      color[0] = color[1];
                      color[1] = 0;
                  }
              }
          }];

2 个答案:

答案 0 :(得分:1)

您实际上可以下载已键入的UnsafeMutablePointer,而无需创建UnsafeMutableBufferPointer,如下所示:

let colorsPointer:UnsafeMutableRawPointer = data[0] + dataStride[0] * i
let rgbaBuffer = colorsPointer.bindMemory(to: Float.self, capacity: dataStride[0])
if(arc4random_uniform(2) == 1) {
    rgbaBuffer[0] = rgbaBuffer[1]
    rgbaBuffer[1] = 0
}

您是否能够让您的解决方案发挥作用?看起来只有少数SCNParticleProperties可以在SCNParticleEventBlock块中使用。

答案 1 :(得分:0)

基于this answer,我在swift中编写了粒子系统处理函数:

    ps.handle(SCNParticleEvent.birth, forProperties [SCNParticleSystem.ParticleProperty.color]) {
    (data:UnsafeMutablePointer<UnsafeMutableRawPointer>, dataStride:UnsafeMutablePointer<Int>, indicies:UnsafeMutablePointer<UInt32>?, count:Int) in

    for i in 0..<count {

        // get an UnsafeMutableRawPointer to the i-th rgba element in the data
        let colorsPointer:UnsafeMutableRawPointer = data[0] + dataStride[0] * i

        //  convert the UnsafeMutableRawPointer to a typed pointer by binding it to a type:
        let floatPtr = colorsPointer.bindMemory(to: Float.self, capacity: dataStride[0])
        // convert that to a an  UnsafeMutableBufferPointer
        var rgbaBuffer = UnsafeMutableBufferPointer(start: floatPtr, count: dataStride[0])
        // At this point, I could convert the buffer to an Array, but doing so copies the data into the array and any changes made in the array are not reflected in the original data.  UnsafeMutableBufferPointer are subscriptable, nice.
        //var rgbaArray = Array(rgbaBuffer)

        // about half the time, mess with the red and green components
        if(arc4random_uniform(2) == 1) {
            rgbaBuffer[0] = rgbaBuffer[1]
            rgbaBuffer[1] = 0
        }
    }
 }

我真的不确定这是否是最直接的解决方法,与Objective-C代码相比看起来相当麻烦(参见上面的问题)。我当然对此解决方案的其他解决方案和/或评论持开放态度。