git.iko.soy/metal-metaballs
on master help sign in
Code style refactor.
commit6b476b7ecb07db4e8df8a97d31823cb55a288a96 authorvinivendra <vinivendra@gmail.com> dateSat 20 Feb 2016, 01:27 (11 years ago) parentf3707d9
19 files changed+199−131
PixelImage.xcodeproj/project.pbxproj+15 PixelImage.xcworkspace/xcuserdata/vini.xcuserdatad/UserInterfaceState.xcuserstate PixelImage/AppDelegate.swift−4 PixelImage/Interpolation.swift−2 PixelImage/Matrix.swift+1−1 PixelImage/MetaballDataSource.swift+2−2 PixelImage/Metal.swift+1−1 PixelImage/MetalMetaballRenderer.swift+25−27 PixelImage/SwiftSugar/Dictionary.swift+1−1 PixelImage/SwiftSugar/Foundation/NSNumber.swift+4−1 PixelImage/SwiftSugar/Numeric.swift+15−4 PixelImage/SwiftSugar/PowerOperator.swift+1−1 PixelImage/SwiftSugar/Sequences/Memoize.swift+51−46 PixelImage/SwiftSugar/SignOperator.swift+8−9 PixelImage/SwiftSugar/String.swift+4−1 PixelImage/SwiftSugar/TestCommons.swift+2−1 PixelImage/UIKit.swift+52−18 PixelImage/ViewController.swift+8−7 PixelImage/shaders.metal+9−5
PixelImage.xcodeproj/project.pbxproj+15
@@ -249,6 +249,7 @@
249249 242686821C63B72A00D62456 /* Resources */,
250250 C7A2DF67265A9D17DEFBD193 /* Embed Pods Frameworks */,
251251 FADC01F75BFAC01F0260D1C9 /* Copy Pods Resources */,
252+ DD0396CE594E3EAC8D18CC6C /* Tailor */,
252253 );
253254 buildRules = (
254255 );
@@ -322,6 +323,20 @@
322323 shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage-frameworks.sh\"\n";
323324 showEnvVarsInLog = 0;
324325 };
326+ DD0396CE594E3EAC8D18CC6C /* Tailor */ = {
327+ isa = PBXShellScriptBuildPhase;
328+ buildActionMask = 2147483647;
329+ files = (
330+ );
331+ inputPaths = (
332+ );
333+ name = Tailor;
334+ outputPaths = (
335+ );
336+ runOnlyForDeploymentPostprocessing = 0;
337+ shellPath = /bin/sh;
338+ shellScript = "if hash tailor 2>/dev/null; then\n tailor --except=function-whitespace,leading-whitespace,constant-k-prefix --max-severity error\nelse\n echo \"warning: Please install Tailor from https://tailor.sh\"\nfi";
339+ };
325340 EF55C7246917A184756D93D8 /* Check Pods Manifest.lock */ = {
326341 isa = PBXShellScriptBuildPhase;
327342 buildActionMask = 2147483647;
PixelImage.xcworkspace/xcuserdata/vini.xcuserdatad/UserInterfaceState.xcuserstate

Binary file not shown.

PixelImage/AppDelegate.swift−4
@@ -13,7 +13,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1313
1414 var window: UIWindow?
1515
16−
1716 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
1817 // Override point for customization after application launch.
1918 return true
@@ -40,7 +39,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
4039 func applicationWillTerminate(application: UIApplication) {
4140 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
4241 }
43−
44−
4542}
46−
PixelImage/Interpolation.swift−2
@@ -1,4 +1,3 @@
1−
21func interpolateCubeEaseIn<T: Numeric>(linear: T) -> T {
32 return linear ^ 3
43}
@@ -14,4 +13,3 @@ func interpolateSquareEaseOut<T: Numeric>(linear: T) -> T {
1413func interpolateSmooth<T: Numeric>(linear: T) -> T {
1514 return ((linear) * (linear) * (linear) * ((linear) * ((linear) * 6 - 15) + 10))
1615}
17−
PixelImage/Matrix.swift+1−1
@@ -1,4 +1,3 @@
1−
21import UIKit
32
43class Graph<T> {
@@ -27,6 +26,7 @@ class Graph<T> {
2726 adjacencyMatrix.reset(i, j)
2827 adjacencyMatrix.reset(j, i)
2928 }
29+
3030}
3131
3232struct Matrix: CustomStringConvertible {
PixelImage/MetaballDataSource.swift+2−2
@@ -1,4 +1,3 @@
1−
21import Metal
32
43protocol MetaballDataSource {
@@ -11,4 +10,5 @@ extension MetaballDataSource {
1110 return metaballGraph.vertices
1211 }
1312 }
14−}
13+
14+}
PixelImage/Metal.swift+1−1
@@ -40,4 +40,4 @@ class MTLComputeContext {
4040 deinit {
4141 free(imageBuffer)
4242 }
43−}
43+}
PixelImage/MetalMetaballRenderer.swift+25−27
@@ -39,8 +39,7 @@ class MetalMetaballRenderer {
3939
4040 let width = Int(frame.width)
4141 let height = Int(frame.height)
42− let textureDescriptor =
43− MTLTextureDescriptor.texture2DDescriptorWithPixelFormat(.BGRA8Unorm, width: width, height: height, mipmapped: false)
42+ let textureDescriptor = MTLTextureDescriptor.texture2DDescriptorWithPixelFormat(.BGRA8Unorm, width: width, height: height, mipmapped: false)
4443
4544 let texture1 = context.device.newTextureWithDescriptor(textureDescriptor)
4645 activeComputeContext = MTLComputeContext(size: targetView.size, texture: texture1)
@@ -55,7 +54,8 @@ class MetalMetaballRenderer {
5554
5655 state = .Ending
5756
58− dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INTERACTIVE.rawValue), 0)) { () -> Void in
57+ let userInteractiveQueue = dispatch_get_global_queue(Int(QOS_CLASS_USER_INTERACTIVE.rawValue), 0)
58+ dispatch_async(userInteractiveQueue) { () -> Void in
5959
6060 let computeContext = self.activeComputeContext
6161 swap(&self.activeComputeContext, &self.idleComputeContext)
@@ -74,10 +74,10 @@ class MetalMetaballRenderer {
7474
7575 dispatch_semaphore_signal(self.semaphore)
7676
77− dispatch_async(dispatch_get_main_queue(), { () -> Void in
77+ dispatch_async(dispatch_get_main_queue()) { () -> Void in
7878 // Send image to view
7979 self.targetView.image = uiimage
80− })
80+ }
8181 }
8282 }
8383
@@ -94,8 +94,7 @@ class MetalMetaballRenderer {
9494
9595 // Configure info for computing
9696 let threadGroupCounts = MTLSizeMake(8, 8, 1)
97− let threadGroups = MTLSizeMake(width / threadGroupCounts.width,
98− height / threadGroupCounts.height, 1)
97+ let threadGroups = MTLSizeMake(width / threadGroupCounts.width, height / threadGroupCounts.height, 1)
9998
10099 // Send commands to metal and render
101100 let commandBuffer = context.commandQueue.commandBuffer()
@@ -113,7 +112,6 @@ class MetalMetaballRenderer {
113112
114113 commandBuffer.commit()
115114 commandBuffer.waitUntilCompleted()
116−
117115 } catch _ {
118116 print("Error!")
119117 }
@@ -123,8 +121,7 @@ class MetalMetaballRenderer {
123121 let texture = computeContext.texture
124122
125123 // Get image info
126− let imageSize = CGSizeMake(CGFloat(texture.width),
127− CGFloat(texture.height))
124+ let imageSize = CGSizeMake(CGFloat(texture.width), CGFloat(texture.height))
128125 let width = Int(imageSize.width)
129126 let height = Int(imageSize.height)
130127 let imageByteCount = width * height * 4
@@ -137,27 +134,20 @@ class MetalMetaballRenderer {
137134 }
138135
139136 // Transfer texture info into image buffer
140− texture.getBytes(computeContext.imageBuffer, bytesPerRow: bytesPerRow,
141− fromRegion: region, mipmapLevel: 0)
137+ texture.getBytes(computeContext.imageBuffer, bytesPerRow: bytesPerRow, fromRegion: region, mipmapLevel: 0)
142138
143139 // Get info for UIImage
144− let provider = CGDataProviderCreateWithData(nil, computeContext.imageBuffer,
145− imageByteCount, nil)
140+ let provider = CGDataProviderCreateWithData(nil, computeContext.imageBuffer, imageByteCount, nil)
146141 let bitsPerComponent = 8
147142 let bitsperPixel = 32
148143 let colorSpaceRef = CGColorSpaceCreateDeviceRGB()
149− let bitmapInfo = CGBitmapInfo(rawValue:
150− CGImageAlphaInfo.PremultipliedLast.rawValue |
151− CGBitmapInfo.ByteOrder32Big.rawValue)
144+ let bitmapInfoRaw = CGImageAlphaInfo.PremultipliedLast.rawValue | CGBitmapInfo.ByteOrder32Big.rawValue
145+ let bitmapInfo = CGBitmapInfo(rawValue: bitmapInfoRaw)
152146 let renderingIntent = CGColorRenderingIntent.RenderingIntentDefault
153147
154148 // Create UIImage from image buffer
155− let imageRef = CGImageCreate(width, height,
156− bitsPerComponent, bitsperPixel, bytesPerRow,
157− colorSpaceRef, bitmapInfo, provider,
158− nil, false, renderingIntent)
159− let image = UIImage(CGImage: imageRef!, scale: 0.0,
160− orientation: UIImageOrientation.Up)
149+ let imageRef = CGImageCreate(width, height, bitsPerComponent, bitsperPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, nil, false, renderingIntent)
150+ let image = UIImage(CGImage: imageRef!, scale: 0.0, orientation: .Up)
161151
162152 return image
163153 }
@@ -165,7 +155,9 @@ class MetalMetaballRenderer {
165155 func metaballEdgesBuffer() -> MTLBuffer {
166156 let floats = dataSource.metaballGraph.adjacencyMatrix.buffer
167157
168− let buffer = context.device.newBufferWithBytes(floats, length: floats.count * sizeof(Float), options: .StorageModeShared)
158+ let bufferLength = floats.count * sizeof(Float)
159+ let device = context.device
160+ let buffer = device.newBufferWithBytes(floats, length: bufferLength, options: .StorageModeShared)
169161
170162 return buffer
171163 }
@@ -175,7 +167,11 @@ class MetalMetaballRenderer {
175167 // Exclude metaballs far from the view's bounds
176168 let border: CGFloat = 100
177169 let metaballs = self.dataSource.metaballs
178− var floats: [Float] = metaballs.reduce([Float](count: 5, repeatedValue: 0)) { (var array, metaball) -> [Float] in
170+
171+ var floats = [Float](count: 5, repeatedValue: 0)
172+ floats = metaballs.reduce(floats) {
173+ (var array, metaball) -> [Float] in
174+
179175 let x = CGFloat(metaball.midX)
180176 let y = CGFloat(metaball.midY)
181177 if -border < x ≤ targetView.width + border &&
@@ -196,8 +192,10 @@ class MetalMetaballRenderer {
196192 floats[0] = Float(floats.count) / 5
197193
198194 // Create buffer
199− let buffer = context.device.newBufferWithBytes(floats, length: floats.count * sizeof(Float), options: .StorageModeShared)
200−
195+ let bufferLength = floats.count * sizeof(Float)
196+ let device = context.device
197+ let buffer = device.newBufferWithBytes(floats, length: bufferLength, options: .StorageModeShared)
198+
201199 return buffer
202200 }
203201}
PixelImage/SwiftSugar/Dictionary.swift+1−1
@@ -1,7 +1,7 @@
11extension Dictionary {
22 subscript(keys: [Key]) -> [Value] {
33 get {
4− return keys.unwrappedMap({ self[$0] })
4+ return keys.unwrappedMap { self[$0] }
55 }
66 set (values) {
77 for (key, value) in zip(keys, values) {
PixelImage/SwiftSugar/Foundation/NSNumber.swift+4−1
@@ -2,10 +2,13 @@ import Foundation
22
33extension NSNumber: DoubleValuable {
44 var toDouble: Double {
5− get { return self.doubleValue }
5+ get {
6+ return self.doubleValue
7+ }
68 }
79
810 static func fromDouble(double: Double) -> Self {
911 return self.init(double: double)
1012 }
13+
1114}
PixelImage/SwiftSugar/Numeric.swift+15−4
@@ -20,43 +20,54 @@ protocol Numeric: DoubleValuable, Incrementable, Comparable,
2020 postfix func ++ (inout _: Self) -> Self
2121}
2222
23−protocol FastNumeric: Numeric { }
23+protocol FastNumeric: Numeric {}
2424
2525extension Double: FastNumeric {
2626 var toDouble: Double {
27− get { return self }
27+ get {
28+ return self
29+ }
2830 }
2931
3032 static func fromDouble(double: Double) -> Double {
3133 return double
3234 }
35+
3336}
3437
3538extension Float: FastNumeric {
3639 var toDouble: Double {
37− get { return Double(self) }
40+ get {
41+ return Double(self)
42+ }
3843 }
3944
4045 static func fromDouble(double: Double) -> Float {
4146 return Float(double)
4247 }
48+
4349}
4450
4551extension Int: FastNumeric {
4652 var toDouble: Double {
47− get { return Double(self) }
53+ get {
54+ return Double(self)
55+ }
4856 }
4957
5058 static func fromDouble(double: Double) -> Int {
5159 return Int(double)
5260 }
61+
5362}
5463
5564//
5665extension Int {
66+
5767 func times(@noescape block: () throws -> ()) rethrows {
5868 for _ in 1...self {
5969 try block()
6070 }
6171 }
72+
6273}
PixelImage/SwiftSugar/PowerOperator.swift+1−1
@@ -2,7 +2,7 @@ import Darwin
22
33infix operator ^ { associativity right precedence 131 }
44
5−func ^<T: DoubleValuable>(left: T, right: T) -> T {
5+func ^ <T: DoubleValuable>(left: T, right: T) -> T {
66 return T.fromDouble(pow(left.toDouble, right.toDouble))
77}
88
PixelImage/SwiftSugar/Sequences/Memoize.swift+51−46
@@ -7,62 +7,66 @@ protocol MemoizedSequence: LazySequenceType {
77 memoizedFunction: (IndexType -> ReturnType))
88}
99
10+struct HashMemoizedSequence<IndexType: Hashable, ReturnType>:
11+ MemoizedSequence {
1012
11−struct HashMemoizedSequence <IndexType: Hashable, ReturnType>:
12−MemoizedSequence {
13+ let memoizedFunction: (IndexType -> ReturnType)
14+ let increment: ((inout IndexType) -> Void)
15+ let firstIndex: IndexType
1316
14− let memoizedFunction: (IndexType -> ReturnType)
15− let increment: ((inout IndexType) -> Void)
16− let firstIndex: IndexType
17+ var index: IndexType
1718
18− var index: IndexType
19+ init(first: IndexType,
20+ incrementer: ((inout IndexType) -> Void),
21+ memoizedFunction: (IndexType -> ReturnType)) {
1922
20− init(first: IndexType,
21− incrementer: ((inout IndexType) -> Void),
22− memoizedFunction: (IndexType -> ReturnType)) {
23+ self.firstIndex = first
2324
24− self.firstIndex = first
25+ self.index = first
26+ self.increment = incrementer
27+ self.memoizedFunction = memoizedFunction
28+ }
2529
26− self.index = first
27− self.increment = incrementer
28− self.memoizedFunction = memoizedFunction
29− }
30+ init(first: IndexType,
31+ incrementer: ((inout IndexType) -> Void),
32+ closure: ((IndexType -> ReturnType, IndexType) -> ReturnType)) {
33+ let memoizedFunction = memoize(closure)
3034
31− init(first: IndexType,
32− incrementer: ((inout IndexType) -> Void),
33− closure: ((IndexType -> ReturnType, IndexType) -> ReturnType)) {
34− let memoizedFunction = memoize(closure)
35−
36− self.init(first: first, incrementer: incrementer,
37− memoizedFunction: memoizedFunction)
38− }
35+ self.init(first: first, incrementer: incrementer,
36+ memoizedFunction: memoizedFunction)
37+ }
3938
40− init(first: IndexType,
41− incrementer: ((inout IndexType) -> Void),
42− function: (IndexType -> ReturnType)) {
39+ init(first: IndexType,
40+ incrementer: ((inout IndexType) -> Void),
41+ function: (IndexType -> ReturnType)) {
4342
44− let memoizedFunction = memoize(function)
43+ let memoizedFunction = memoize(function)
4544
46− self.init(first: first, incrementer: incrementer,
47− memoizedFunction: memoizedFunction)
48− }
45+ self.init(first: first, incrementer: incrementer,
46+ memoizedFunction: memoizedFunction)
47+ }
4948}
5049
5150extension HashMemoizedSequence: GeneratorType {
51+
5252 mutating func next() -> ReturnType? {
5353 let result = memoizedFunction(index)
5454 increment(&index)
5555 return result
5656 }
57+
5758}
5859
5960extension HashMemoizedSequence: LazySequenceType {
61+
6062 func generate() -> HashMemoizedSequence {
6163 return self
6264 }
65+
6366}
6467
6568extension HashMemoizedSequence where ReturnType: Comparable {
69+
6670 @warn_unused_result
6771 func contains(element: ReturnType) -> Bool {
6872 var index = firstIndex
@@ -79,6 +83,7 @@ extension HashMemoizedSequence where ReturnType: Comparable {
7983 increment(&index)
8084 }
8185 }
86+
8287}
8388
8489extension HashMemoizedSequence where IndexType: Incrementable {
@@ -104,29 +109,29 @@ extension HashMemoizedSequence where IndexType: Incrementable {
104109}
105110
106111extension HashMemoizedSequence where IndexType: Incrementable,
107− IndexType: IntegerLiteralConvertible {
112+IndexType: IntegerLiteralConvertible {
108113 init(_ closure: ((IndexType -> ReturnType, IndexType) -> ReturnType)) {
109− self.firstIndex = 1
110− self.index = 1
111− self.increment = { (inout index: IndexType) in
112− index++
113− }
114− self.memoizedFunction = memoize(closure)
114+ self.firstIndex = 1
115+ self.index = 1
116+ self.increment = { (inout index: IndexType) in
117+ index++
118+ }
119+ self.memoizedFunction = memoize(closure)
115120 }
116121
117122 init(_ function: (IndexType -> ReturnType)) {
118− self.firstIndex = 1
119− self.index = 1
120− self.increment = { (inout index: IndexType) in
121− index++
122− }
123− self.memoizedFunction = memoize(function)
123+ self.firstIndex = 1
124+ self.index = 1
125+ self.increment = { (inout index: IndexType) in
126+ index++
127+ }
128+ self.memoizedFunction = memoize(function)
124129 }
125130}
126131
127−func memoize <H: Hashable, R> (closure: ((H -> R, H) -> R) ) -> (H -> R) {
132+func memoize<H: Hashable, R>(closure: ((H -> R, H) -> R)) -> (H -> R) {
128133
129− var table = [H : R]()
134+ var table = [H: R]()
130135
131136 var auxiliaryFunction: (H -> R)!
132137 auxiliaryFunction = { index in
@@ -143,9 +148,9 @@ func memoize <H: Hashable, R> (closure: ((H -> R, H) -> R) ) -> (H -> R) {
143148 return auxiliaryFunction
144149}
145150
146−func memoize <H: Hashable, R> (function: (H -> R) ) -> (H -> R) {
151+func memoize<H: Hashable, R>(function: (H -> R)) -> (H -> R) {
147152
148− var table = [H : R]()
153+ var table = [H: R]()
149154
150155 let result: (H -> R) = { index in
151156 if let result = table[index] {
PixelImage/SwiftSugar/SignOperator.swift+8−9
@@ -1,13 +1,12 @@
1−
21prefix operator ± { }
32
4−prefix func ± <T: Numeric> (number: T) -> T {
3+prefix func ± <T: Numeric>(number: T) -> T {
54
6− if number > 0 {
7− return 1
8− } else if number == 0 {
9− return 0
10− } else {
11− return -1
12− }
5+ if number > 0 {
6+ return 1
7+ } else if number == 0 {
8+ return 0
9+ } else {
10+ return -1
11+ }
1312}
PixelImage/SwiftSugar/String.swift+4−1
@@ -1,9 +1,12 @@
11extension String: DoubleValuable {
22 var toDouble: Double {
3− get { return Double(self) ?? Double(0) }
3+ get {
4+ return Double(self) ?? Double(0)
5+ }
46 }
57
68 static func fromDouble(double: Double) -> String {
79 return "\(double)"
810 }
11+
912}
PixelImage/SwiftSugar/TestCommons.swift+2−1
@@ -8,7 +8,7 @@
88
99import Darwin
1010
11−class Random <T: Numeric> {
11+class Random<T: Numeric> {
1212
1313 let max: Double = Double(INT32_MAX)
1414 let exponent: Double = 7
@@ -92,4 +92,5 @@ class Random <T: Numeric> {
9292 let result = Double((2 * rawRandom) - 1)
9393 return T.fromDouble(result)
9494 }
95+
9596}
PixelImage/UIKit.swift+52−18
@@ -31,6 +31,7 @@ extension CGVector {
3131 dx = dx / norm
3232 dy = dy / norm
3333 }
34+
3435}
3536
3637extension CGFloat: DoubleValuable {
@@ -42,19 +43,28 @@ extension CGFloat: DoubleValuable {
4243 static func fromDouble(double: Double) -> CGFloat {
4344 return CGFloat(double)
4445 }
46+
4547}
4648
4749extension CGFloat: Numeric {}
4850
4951extension CGRect {
5052 var x: CGFloat {
51− get { return origin.x }
52− set { origin.x = newValue }
53+ get {
54+ return origin.x
55+ }
56+ set {
57+ origin.x = newValue
58+ }
5359 }
5460
5561 var y: CGFloat {
56− get { return origin.y }
57− set { origin.y = newValue }
62+ get {
63+ return origin.y
64+ }
65+ set {
66+ origin.y = newValue
67+ }
5868 }
5969}
6070
@@ -66,41 +76,65 @@ extension CGSize {
6676
6777extension UIView {
6878 var origin: CGPoint {
69− get { return frame.origin }
70− set { frame.origin = newValue }
79+ get {
80+ return frame.origin
81+ }
82+ set {
83+ frame.origin = newValue
84+ }
7185 }
7286
7387 var size: CGSize {
74− get { return frame.size }
75− set { frame.size = newValue }
88+ get {
89+ return frame.size
90+ }
91+ set {
92+ frame.size = newValue
93+ }
7694 }
7795
7896 var width: CGFloat {
79− get { return frame.width }
80− set { frame.size = CGSize(width: newValue, height: height) }
97+ get {
98+ return frame.width
99+ }
100+ set {
101+ frame.size = CGSize(width: newValue, height: height)
102+ }
81103 }
82104
83105 var height: CGFloat {
84− get { return frame.height }
85− set { frame.size = CGSize(width: width, height: newValue) }
106+ get {
107+ return frame.height
108+ }
109+ set {
110+ frame.size = CGSize(width: width, height: newValue)
111+ }
86112 }
87113
88114 var middle: CGPoint {
89115 get {
90− return CGPoint(x: origin.x + width/2, y: origin.y + height/2)
116+ return CGPoint(x: origin.x + width / 2, y: origin.y + height / 2)
91117 }
92118 set {
93− origin = CGPoint(x: newValue.x - width/2, y: newValue.y - height/2)
119+ origin = CGPoint(x: newValue.x - width / 2, y: newValue.y - height / 2)
94120 }
95121 }
96122
97123 var midX: CGFloat {
98− get { return middle.x }
99− set { middle = CGPoint(x: newValue, y: midY) }
124+ get {
125+ return middle.x
126+ }
127+ set {
128+ middle = CGPoint(x: newValue, y: midY)
129+ }
100130 }
101131
102132 var midY: CGFloat {
103− get { return middle.y }
104− set { middle = CGPoint(x: midX, y: newValue) }
133+ get {
134+ return middle.y
135+ }
136+ set {
137+ middle = CGPoint(x: midX, y: newValue)
138+ }
105139 }
106140}
PixelImage/ViewController.swift+8−7
@@ -1,4 +1,3 @@
1−
21import UIKit
32
43class ViewController: UIViewController, MetaballDataSource {
@@ -33,7 +32,7 @@ class ViewController: UIViewController, MetaballDataSource {
3332 metaballGraph.addEdge(2, 3)
3433
3534 let border = 20
36− let metaballViewFrame = CGRect(x: border/2, y: border/2, width: width, height: height)
35+ let metaballViewFrame = CGRect(x: border / 2, y: border / 2, width: width, height: height)
3736 renderer = MetalMetaballRenderer(dataSource: self, frame: metaballViewFrame)
3837 metaballView = renderer.targetView
3938
@@ -61,11 +60,12 @@ class ViewController: UIViewController, MetaballDataSource {
6160
6261 func animateEdge(i: Int, _ j: Int, fadeIn: Bool) {
6362 let parameters = EdgeAnimationParameters(startDate: NSDate(), duration: edgeAnimationDuration, fadeIn: fadeIn, i: i, j: j)
64− NSTimer.scheduledTimerWithTimeInterval(1.0/60.0, target: self, selector: "animateEdgeWithTimer:", userInfo: parameters, repeats: true)
63+ NSTimer.scheduledTimerWithTimeInterval(1.0 / 60.0, target: self, selector: "animateEdgeWithTimer:", userInfo: parameters, repeats: true)
6564 }
6665
6766 func animateEdge(withTimer timer: NSTimer) {
68− let (animationStart, duration, fadeIn, i, j) = (timer.userInfo as! EdgeAnimationParameters).unpack()
67+ guard let userInfo = timer.userInfo as? EdgeAnimationParameters else { preconditionFailure() }
68+ let (animationStart, duration, fadeIn, i, j) = (userInfo).unpack()
6969
7070 let now = NSDate()
7171 var timeElapsed = Float(now.timeIntervalSinceDate(animationStart))
@@ -89,9 +89,9 @@ class ViewController: UIViewController, MetaballDataSource {
8989
9090 if selectedMetaball == nil {
9191 for metaball in metaballs where
92− abs(metaball.midX - location.x) < 50 && abs(metaball.midY - location.y) < 50 {
93− selectedMetaball = metaball
94− break
92+ abs(metaball.midX - location.x) < 50 && abs(metaball.midY - location.y) < 50 {
93+ selectedMetaball = metaball
94+ break
9595 }
9696 }
9797
@@ -105,6 +105,7 @@ class ViewController: UIViewController, MetaballDataSource {
105105 selectedMetaball = nil
106106 }
107107 }
108+
108109}
109110
110111class Metaball: UIView {
PixelImage/shaders.metal+9−5
@@ -11,7 +11,11 @@ struct metaballData {
1111 float b;
1212};
1313
14−kernel void drawMetaballs(texture2d<float, access::write> outTexture[[texture(0)]], constant float *edgesBuffer[[buffer(1)]], constant metaballData *metaballBuffer[[buffer(0)]], uint2 gid[[thread_position_in_grid]]) {
14+kernel void
15+ drawMetaballs(texture2d<float, access::write> outTexture[[texture(0)]],
16+ constant float *edgesBuffer[[buffer(1)]],
17+ constant metaballData *metaballBuffer[[buffer(0)]],
18+ uint2 gid[[thread_position_in_grid]]) {
1519
1620 char numberOfMetaballs = metaballBuffer[0].x - 1;
1721
@@ -28,11 +32,12 @@ kernel void drawMetaballs(texture2d<float, access::write> outTexture[[texture(0)
2832 for (x = 1; x <= numberOfMetaballs; x += 1) {
2933 metaballData metaball = metaballBuffer[x];
3034 float2 metaballPosition = float2(metaball.x, metaball.y);
31− float2 vector = float2(metaballPosition.x - gid.x, metaballPosition.y - gid.y);
35+ float2 vector
36+ = float2(metaballPosition.x - gid.x, metaballPosition.y - gid.y);
3237 float squaredDistance = dot(vector, vector);
3338 float realDistance = sqrt(squaredDistance);
3439 metaballDistances[x - 1] = squaredDistance;
35− metaballDirections[x - 1] = vector/realDistance;
40+ metaballDirections[x - 1] = vector / realDistance;
3641 metaballColors[x - 1] = float3(metaball.r, metaball.g, metaball.b);
3742 }
3843
@@ -71,14 +76,13 @@ kernel void drawMetaballs(texture2d<float, access::write> outTexture[[texture(0)
7176
7277 float metaballValue = step(0.5, weightedValue + weightedLink);
7378 sum += metaballValue;
74−
7579 }
7680 }
7781
7882 bendClose = bendClose / bendCloseCount;
7983
8084 if (bendClose != 0.0) {
81− bendClose = (bendClose - 0.4) * (1/(0.6-0.4));
85+ bendClose = (bendClose - 0.4) * (1 / (0.6 - 0.4));
8286 } else {
8387 bendClose = 0.0;
8488 }