2

我有一个块正在传递数据,我想将其转换为浮点数组 - 例如 [[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 代码(来自 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;
                  }
              }
          }];
4

2 回答 2

2

您实际上可以对键入的内容进行下标,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块内使用。

于 2017-09-10T04:29:38.530 回答
0

基于这个答案,我将粒子系统处理程序函数快速编写为:

    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 代码相比似乎相当麻烦(参见上面的问题)。我当然愿意接受其他解决方案和/或对此解决方案的评论。

于 2017-06-10T22:26:28.283 回答