我正在使用场景工具包的SCNParticleSystem构建一个测试应用程序。它有一个回调,允许您修改每个帧上的粒子属性。此回调的签名为
typealias SCNParticleModifierBlock = (UnsafeMutablePointer<UnsafeMutablePointer<Void>>, UnsafeMutablePointer<Int>, Int, Int, Float) -> Void参考资料来自苹果开发者网站- SCNParticleSystem_Class
我不知道如何从Swift访问和修改此引用。如果这是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,这看起来很合理。第二个size值显然是假的,然后它崩溃了,我把它放到调试器中。
indexes 0 0
indexes 0 3
0 0.929816
1 1.51296e-39
(lldb)据我所知,互联网上没有人使用这个功能。我找到的唯一参考资料是苹果的文档,其中只提供了ObjC的例子,而不是Swift。
帮帮我!
发布于 2015-10-29 00:58:48
例如:
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吗?
发布于 2017-06-11 23:03:30
使用非常类似的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
}
}
}在我的问答问题here中有更多细节
https://stackoverflow.com/questions/33249056
复制相似问题