Trying the 'Discover Ray Tracing' Sample Code in Swift

I have enjoyed looking through the 'Discover Ray Tracing with Metal' video and Sample Code. While trying to recreate the Project in Swift, I have run across an issue with setting up an MTLPrimativeAccelerationStructureDescriptor.

In Renderer.mm ( Objective C ), within the createAccelerationStructures function, a loop is created:

Code Block
// Create a primitive acceleration structure for each piece of geometry in the scene
for (NSUInteger i = 0; i < _scene.geometries.count; i++) {
Geometry *mesh = _scene.geometries[i];
MTLAccelerationStructureGeometryDescriptor *geometryDescriptor = [mesh geometryDescriptor];
// Assign each piece of geometry a consecutive slot in the intersection function table
        geometryDescriptor.intersectionFunctionTableOffset = i;
// Create a primitive acceleration structure descriptor to contain the single piece of acceleration structure geometry
MTLPrimitiveAccelerationStructureDescriptor *accelDescriptor = [MTLPrimitiveAccelerationStructureDescriptor descriptor];
accelDescriptor.geometryDescriptors = @[ geometryDescriptor ];
// Build the acceleration structure.
id <MTLAccelerationStructure> accelerationStructure = [self newAccelerationStructureWithDescriptor:accelDescriptor];
// Add the acceleration structure to the array of primitive acceleration structures.
[_primitiveAccelerationStructures addObject:accelerationStructure];
}

In Swift, I am trying:

Code Block
for i in 0..<( scene.nodes.count )
{
let aMesh = scene.nodes[i]
let geometryDescriptor: MTLAccelerationStructureGeometryDescriptor = aMesh.getGeometryDescriptor()
// Assign each piece of geometry a consecutive slot in the intersection function table
            geometryDescriptor.intersectionFunctionTableOffset = i
// Create a primitive acceleration structure descriptor to contain the single piece of acceleration structure geometry
var accelDescriptor: MTLPrimitiveAccelerationStructureDescriptor = MTLPrimitiveAccelerationStructureDescriptor()
accelDescriptor.geometryDescriptors.append( geometryDescriptor )
// Build the acceleration structure.
// To follow...
// Add the acceleration structure to the array of primitive acceleration structures.
// To follow...
}

The compiler flags appending the geometryDescriptor with "Cannot use mutating member on immutable value: 'accelDescriptor is immutable'". I have tried a couple of compiler suggested ideas to unwrap the accelDescriptor.geometryDescriptors, but end up with a nil value in the geometryDescriptors array.

It may be naive to simply append the geometryDescriptor, but I would appreciate any suggestions to fill in the accelDescriptor.

In the larger picture, it would be great to have a Swift Project sample to use as a starting point. The concepts spelled out in the video and Objective C project are very compelling!

Thanks so much - John Lobe

Replies

Hi John.

The geometryDescriptors array in MTLPrimitiveAccelerationStructureDescriptor is immutable so you cannot append to it.

However geometryDescriptors is assignable. So you need create another array with geometryDescriptor and assign the entire array to the geometryDescriptors property. This is what the ObjC code does; it creates an array literal with @[ geometryDescriptor ] and assigns it to accelDescriptor.geometryDescriptors

This should be the equivalent in Swift:

Code Block
// Cannot do this: accelDescriptor.geometryDescriptors.append(geometryDescriptor)
// Instead do this:
accelDescriptor.geometryDescriptors = [ geometryDescriptor ]

Very good, this worked. Thanks very much!
And it would seem that I need to do further reading about Swift, immutable and assignable.
Cheers, thanks again