Skip to content

Instantly share code, notes, and snippets.

@algal
Created December 8, 2017 07:25
Show Gist options
  • Save algal/e79c81401d6f72034be085f323526527 to your computer and use it in GitHub Desktop.
Save algal/e79c81401d6f72034be085f323526527 to your computer and use it in GitHub Desktop.
/**
Returns an array of vertex positions.
- precondition: the geoemetry must have vertices which are 3-vectors with floating point component values
*/
fileprivate func vertices(source:SCNGeometrySource) -> [SCNVector3]
{
precondition(source.usesFloatComponents == true, "I can only handle three-vectors whose components are floating-point values, i.e., floats or doubles")
precondition(source.componentsPerVector == 3, "I can only be used for three vectors")
let shouldUseFloatNotDouble:Bool
if source.bytesPerComponent == 4 {
shouldUseFloatNotDouble = true
}
else if source.bytesPerComponent == 8 {
shouldUseFloatNotDouble = false
}
else {
assert(false, "The SCNGeometrySource has reported an unexpected byte size for its vector components, not 4 bytes (float) or 8 bytes (double) but \(source.bytesPerComponent). I am not equipped for this so I am going to use floats and hope for the best. This will probably not work. Sorry.")
shouldUseFloatNotDouble = true
}
let vectors = source.data.withUnsafeBytes {
(p:UnsafePointer<UInt8>) -> [SCNVector3] in
let rawPtr = UnsafeRawPointer(p)
var v:[SCNVector3] = []
v.reserveCapacity(source.vectorCount)
for byteOffset in stride(from: source.dataOffset,
to: source.dataOffset + source.dataStride * source.vectorCount,
by: source.dataStride)
{
if shouldUseFloatNotDouble {
let ff = rawPtr.load(fromByteOffset: byteOffset, as: float3.self)
let val = SCNVector3(ff)
v.append(val)
}
else {
let ff = rawPtr.load(fromByteOffset: byteOffset, as: double3.self)
let val = SCNVector3(ff)
v.append(val)
}
}
return v
}
return vectors
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment