I have an objective-c function block, that uses (for my understanding) some extra stuff and I would like to make this fully in Swift. Here is the original code, from which I've started. (I was trying to convert this using Swiftify, but with no luck) And this SO article unfortunately did not help: How to reinterpret_cast in Swift?
- (void)updateBuffers
{
id<MTLBuffer> noiseBuffer = _noise[[self frameIndex]];
RandomSample* ptr = reinterpret_cast<RandomSample*>([noiseBuffer contents]);
for (NSUInteger i = 0; i < (NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE); ++i)
{
ptr->pixelSample.x = uniformFloatDistribution(randomGenerator);
ptr->pixelSample.y = uniformFloatDistribution(randomGenerator);
ptr->barycentricSample.x = uniformFloatDistribution(randomGenerator);
ptr->barycentricSample.y = uniformFloatDistribution(randomGenerator);
ptr->emitterBsdfSample.x = uniformFloatDistribution(randomGenerator);
ptr->emitterBsdfSample.y = uniformFloatDistribution(randomGenerator);
ptr->bsdfSample.x = uniformFloatDistribution(randomGenerator);
ptr->bsdfSample.y = uniformFloatDistribution(randomGenerator);
ptr->componentSample = uniformFloatDistribution(randomGenerator);
ptr->emitterSample = uniformFloatDistribution(randomGenerator);
ptr->rrSample = uniformFloatDistribution(randomGenerator);
++ptr;
}
[_noise[[self frameIndex]] didModifyRange:NSMakeRange(0, [noiseBuffer length])];
}
I assume, the objective-c code fills the contents of the Buffer (using the for loop) with the contents from the Struct (RandomSample). NOISE_BLOCK_SIZE is in this case 64
And this is what I have so far:
func updateBuffers() {
let noiseBuffer = noise[Int(frameIndex())] // MTLBuffer
var randomStruct = RandomSample()
// Here I should have this ptr (pointer) that like on objective-c
for i in 0..<(NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE) {
randomStruct.pixelSample.x = Float.random(in: 0..<1)
randomStruct.pixelSample.y = Float.random(in: 0..<1)
randomStruct.barycentricSample.x = Float.random(in: 0..<1)
randomStruct.barycentricSample.y = Float.random(in: 0..<1)
randomStruct.emitterBsdfSample.x = Float.random(in: 0..<1)
randomStruct.emitterBsdfSample.y = Float.random(in: 0..<1)
randomStruct.bsdfSample.x = Float.random(in: 0..<1)
randomStruct.bsdfSample.y = Float.random(in: 0..<1)
randomStruct.componentSample = Float.random(in: 0..<1)
randomStruct.emitterSample = Float.random(in: 0..<1)
randomStruct.rrSample = Float.random(in: 0..<1)
}
// etc... etc...
}
This is the RandomSample struct I want to reference, defined in a .h file (which is my Bridging Header)
struct RandomSample
{
simd_float2 pixelSample;
simd_float2 barycentricSample;
simd_float2 bsdfSample;
simd_float2 emitterBsdfSample;
float componentSample;
float emitterSample;
float rrSample;
};
Instead of the uniformFloatDistribution
I am using (within the Swift code)
Float.random(in: 0..<1)
which should produce more or less the same.
Obviously I can't verify this on my machine, but you should be able to do something like this.
var noiseRaw = noiseBuffer.contents()
let samples = noiseRaw.bindMemory(
to: RandomSample.self,
capacity: NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE
)
for i in 0..<NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE {
let sample = samples + i
sample.pointee.componentSample = Float.random(in: 0..<1)
sample.pointee.emitterSample = Float.random(in: 0..<1)
sample.pointee.rrSample = Float.random(in: 0..<1)
}