2015-10-21 86 views
11

我在使用SceneKit的SCNParticleSystem构建测试应用程序。它有一个回调,可以让你修改每个帧的粒子属性。这个回调的签名是由苹果开发者网站如何使用Swift中的UnsafeMutablePointer <UnsafeMutablePointer <Void>>引用?

typealias SCNParticleModifierBlock = (UnsafeMutablePointer<UnsafeMutablePointer<Void>>, UnsafeMutablePointer<Int>, Int, Int, Float) -> Void 

参考 - SCNParticleSystem_Class

我不知道如何访问和修改斯威夫特此引用。如果这是C,它将是一个**,我可以像数组一样解引用。

一些把玩之后,我就得到了,因为这:

..... 
      particleSystem?.addModifierForProperties([SCNParticlePropertySize], atStage: SCNParticleModifierStage.PostDynamics, withBlock: doit2) 
} 

struct Foos { 
    var size:float_t 
} 
func doit2(data:UnsafeMutablePointer<UnsafeMutablePointer<Void>>, dataStride: UnsafeMutablePointer<Int>, start:Int, end:Int, deltaTime:Float) -> Void { 
    let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data) 
    print("indexes",start,end) 
    for i in 0 ..< end { 
     print(i,myptr[i].memory.size) 
    } 
}¸ 

这适用于第一粒子,但碰撞在第二。函数第一次被调用时有0个粒子,所以它跳过循环。第二次有三个粒子,所以它试图将它们打印出来。第一个尺寸值为0.9,接缝合理。第二个尺寸值显然是假的,然后它崩溃,我掉进调试器。

indexes 0 0 
indexes 0 3 
0 0.929816 
1 1.51296e-39 
(lldb) 

就在我可以告诉互联网上没有人使用此功能。我发现的唯一参考是苹果的文档,它只提供了ObjC的例子,而不是Swift。

帮帮我!

+1

叫我疯了,但既然这是一个指针指针,你不应该把它的'memory.memory'到达真实的东西吗? – matt

+0

好点。切换到'myptr.memory [i] .size'让我更接近,但它仍然偶尔崩溃。如果我设置了大小,那么我可以看到一些但不是所有的粒子都在变化。那些变化的人会被卡住,他们会停止移动。这表明我正在破坏一些记忆。而且我仍然不确定dataStride的用途。文档说它应该是:“数组标识每个粒子的数据条带中每个属性值的偏移量(以字节为单位)。该数组中的偏移顺序对应于addModifierForProperties中的properties数组的顺序“调用 –

+0

而且我应该提及,在ObjC示例代码中使用了dataStride,但我无法看到如何在Swift中使用它版本 –

回答

1

为examle:

var data = [[0.1, 0.2],[0.3, 0.4],[0.5, 0.6]] 
let pData = UnsafeMutablePointer<UnsafeMutablePointer<Void>>(data) 
// how to reconstruct the original data ?? 

// we need to know how much data we have 
let count = data.count 
// we need to know what type of data we have 
let p2 = UnsafeMutablePointer<Array<Double>>(pData) 
// access the data 
for i in 0..<count { 
    print((p2 + i).memory) 
} 
// [0.1, 0.2] 
// [0.3, 0.4] 
// [0.5, 0.6] 

我想,在你的代码,myptr的声明是错误的

let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data) 

dataStride.count在你的榜样应该是1(属性号)和值其元素的大小应该是float(属性的大小)。

也要小心!你的循环应该像

for i in start..<end { 
... 
} 

你确定开始是0吗?

+0

你想提高你的答案,所以我可以奖励赏金?也许你能解决它:) –

0

与非常相似SCNParticleEventBlock工作,我写的处理程序Swift3作为

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 
     } 
    } 
} 

在我的SO提出和回答问题更详细一点here

和一对夫妇学家herehere

相关问题