Modifying SCNParticleSystem colors in an SCNParticleEventBlock doesn't work

422 Views Asked by At

Given the sample code provided for handle(_:forProperties:handler:), the following block should turn green particle red, but doesn't:

[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;
              }
          }
      }];

With the following, I am able to see green particles, but no matter what I do, I can't seem to get various SCNParticlePropertys to do anything.

SCNParticleSystem *system = [SCNParticleSystem particleSystem];
system.particleColor = NSColor.greenColor;
system.birthRate = 1;

An interesting observation is that in the block above, dataStride only appears to have values for certain SCNParticlePropertys. position, angle, velocity, and angularVelocity all yield 16, life and frame yield 4, and all others show nil. I can only assume that either the API allows per-particle adjustment for a few properties, or additional configuration must be done on my SCNParticleSystem instance in order to "unlock" modification via a SCNParticleEventBlock block.

The above produces the same results in Swift, and both Xcode 8 and 9. I've tried assigning values to nearly every property of my SCNParticleSystem with no luck, and do not see any sample code provided by Apple other than what's in the header.

Thanks for any help.

1

There are 1 best solutions below

0
On

For anyone stumbling across this question: check out the particle slide in the WWDC 2014 SceneKit sample project, they provide example for basically everything you can do with SceneKit.

As expected, the property that needed a value for this to work was particleColorVariation on my SCNParticleSystem instance. Setting it to anything besides SCNVector4Zero (eg. SCNVector4Make(0, 0, 0, 1)) results in dataStride in SCNParticleEventBlock having a non-nil value (16) at the index of the particle property.

It's unfortunate that this appears to be an undocumented requirement, so hopefully this post is useful for anyone running into this issue in the future.