Skip to content

Instantly share code, notes, and snippets.

@tomhoag
Last active June 11, 2017 14:38
Show Gist options
  • Save tomhoag/2c785cefd208acd5a1f8bc7d31d21530 to your computer and use it in GitHub Desktop.
Save tomhoag/2c785cefd208acd5a1f8bc7d31d21530 to your computer and use it in GitHub Desktop.
SceneKit particleSystem.handle Swift3 implementation of Objective-C code @ https://developer.apple.com/documentation/scenekit/scnparticleeventblock
/*
dataStride property notes
16 color color[0] color[1] color[2] color[3] RGBA array of four float values
16 angle angle[0] -- single float value
12 rotationAxis rotationAxis[0], rotationAxis[1], rotationAxis[2] array of three float values
16 angularVelocity angularVeclocity[0] -- single float value
16 velocity velocity[0], velocity[1], velocity[2] -- array of three float values
12 contactNormal contactNormal[0], contactNormal[1], contactNormal[2] -- array of three float values
*/
particleSystem.handle(SCNParticleEvent.collision, forProperties:
[SCNParticleSystem.ParticleProperty.angle, // data[0]
SCNParticleSystem.ParticleProperty.rotationAxis, // data[1]
SCNParticleSystem.ParticleProperty.angularVelocity,// data[2]
SCNParticleSystem.ParticleProperty.velocity, // data[3]
SCNParticleSystem.ParticleProperty.contactNormal] // data[4]
) { (data:UnsafeMutablePointer<UnsafeMutableRawPointer>, dataStride:UnsafeMutablePointer<Int>, indicies:UnsafeMutablePointer<UInt32>?, count:Int) in
for i in 0..<count {
// fix orientation
let anglePointer = data[0] + dataStride[0] * Int(indicies![i])
let floatPtr0 = anglePointer.bindMemory(to: Float.self, capacity: dataStride[0])
let angleBuffer = UnsafeMutableBufferPointer(start: floatPtr0, count: dataStride[0])
let rotationAxisPointer = data[1] + dataStride[1] * Int(indicies![i])
let floatPointer1 = rotationAxisPointer.bindMemory(to: Float.self, capacity: dataStride[1])
let rotationAxisBuffer = UnsafeMutableBufferPointer(start: floatPointer1, count: dataStride[1]);
let contactNormalPointer = data[4] + dataStride[4] * Int(indicies![i])
let floatPointer4 = contactNormalPointer.bindMemory(to: Float.self, capacity: dataStride[4])
let contactNormalBuffer = UnsafeMutableBufferPointer(start: floatPointer4, count: dataStride[4]);
let collisionNormal = SCNVector3Make(contactNormalBuffer[0], contactNormalBuffer[1], contactNormalBuffer[2])
let crossProduct = SCNVector3CrossProduct(left: collisionNormal, right: SCNVector3Make(0,0,1));
let crossProductLength = SCNVector3Length(vector: crossProduct)
angleBuffer[0] = asin(crossProductLength)
rotationAxisBuffer[0] = crossProduct.x / crossProductLength;
rotationAxisBuffer[1] = crossProduct.y / crossProductLength;
rotationAxisBuffer[2] = crossProduct.z / crossProductLength;
// kill the angular rotation
let angularVelocityPointer = data[2] + dataStride[2] * Int(indicies![i])
let floatPointer2 = angularVelocityPointer.bindMemory(to: Float.self, capacity: dataStride[2])
let angularVelocityBuffer = UnsafeMutableBufferPointer(start: floatPointer2, count: dataStride[2]);
angularVelocityBuffer[0] = 0;
if(contactNormalBuffer[1] > 0.4) {
let velocityPointer = data[3] + dataStride[3] * Int(indicies![i])
let floatPointer3 = velocityPointer.bindMemory(to: Float.self, capacity: dataStride[3])
let velocityBuffer = UnsafeMutableBufferPointer(start: floatPointer3, count: dataStride[3]);
velocityBuffer[0] = 0
velocityBuffer[1] = 0
velocityBuffer[2] = 0
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment