git.iko.soy/metal-metaballs
on master help sign in
Spring interpolation.
05cd2a3vinivendra
PixelImage.xcodeproj/project.pbxproj+4−4
@@ -147,15 +147,15 @@
147 children = (
147 children = (
148 24FFA84B1C6BA038005ACD60 /* SwiftSugar */,
148 24FFA84B1C6BA038005ACD60 /* SwiftSugar */,
149 242686871C63B72A00D62456 /* AppDelegate.swift */,
149 242686871C63B72A00D62456 /* AppDelegate.swift */,
150− 242686891C63B72A00D62456 /* ViewController.swift */,
151 24FC38351C7F9ABE0085C04A /* Dispatch.swift */,
150 24FC38351C7F9ABE0085C04A /* Dispatch.swift */,
152− 24FC38331C7F931E0085C04A /* Metaball.swift */,
153 24E1E7D61C67C8B200ECF1C4 /* UIKit.swift */,
151 24E1E7D61C67C8B200ECF1C4 /* UIKit.swift */,
154 246B0F821C70635D00A71D05 /* UIColor.swift */,
152 246B0F821C70635D00A71D05 /* UIColor.swift */,
155− 24ED21CC1C6C2397009C40FC /* MetaballDataSource.swift */,
153+ 24FC38331C7F931E0085C04A /* Metaball.swift */,
156− 24E1E7EA1C67D70300ECF1C4 /* MetalMetaballRenderer.swift */,
157 24E1E7EE1C67D74300ECF1C4 /* Metal.swift */,
154 24E1E7EE1C67D74300ECF1C4 /* Metal.swift */,
158 249CF84B1C6D113C008B0C78 /* Matrix.swift */,
155 249CF84B1C6D113C008B0C78 /* Matrix.swift */,
156+ 242686891C63B72A00D62456 /* ViewController.swift */,
157+ 24ED21CC1C6C2397009C40FC /* MetaballDataSource.swift */,
158+ 24E1E7EA1C67D70300ECF1C4 /* MetalMetaballRenderer.swift */,
159 24E1E7EF1C67D74300ECF1C4 /* shaders.metal */,
159 24E1E7EF1C67D74300ECF1C4 /* shaders.metal */,
160 2426868B1C63B72A00D62456 /* Main.storyboard */,
160 2426868B1C63B72A00D62456 /* Main.storyboard */,
161 2426868E1C63B72A00D62456 /* Assets.xcassets */,
161 2426868E1C63B72A00D62456 /* Assets.xcassets */,
PixelImage/Interpolation.swift+61
@@ -1,3 +1,6 @@
1+
2+import Darwin
3+
1func interpolateCubeEaseIn<T: Numeric>(linear: T) -> T {
4func interpolateCubeEaseIn<T: Numeric>(linear: T) -> T {
2 return linear ^ 3
5 return linear ^ 3
3}
6}
@@ -13,3 +16,61 @@ func interpolateSquareEaseOut<T: Numeric>(linear: T) -> T {
13func interpolateSmooth<T: Numeric>(linear: T) -> T {
16func interpolateSmooth<T: Numeric>(linear: T) -> T {
14 return ((linear) * (linear) * (linear) * ((linear) * ((linear) * 6 - 15) + 10))
17 return ((linear) * (linear) * (linear) * ((linear) * ((linear) * 6 - 15) + 10))
15}
18}
19+
20+func createStringKeyframes(bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double) -> [(time: Double, position: Double)] {
21+ // Setup keyframes
22+ var keyFrames: [(time: Double, position: Double)] = [(1, 1)]
23+
24+ let overreach = elasticity - 1
25+
26+ var currentBounceTime: Double = overreach / (bounceSpeed ^ Double(bounces))
27+ var bounceDirection = Double((bounces % 2) * 2 - 1)
28+ var bounceReach = overreach / (2 ^ Double(bounces - 1))
29+ var currentBouncePosition: Double = 1.0 + bounceDirection * bounceReach
30+
31+ print(currentBounceTime)
32+ print(bounceDirection)
33+ print(bounceReach)
34+ print(currentBouncePosition)
35+
36+ keyFrames.append((1.0 - currentBounceTime, currentBouncePosition))
37+
38+ for i in (1..<bounces).reverse() {
39+ currentBounceTime += overreach / (bounceSpeed ^ Double(i + 1))
40+ currentBounceTime += overreach / (bounceSpeed ^ Double(i))
41+ bounceDirection = Double((i % 2) * 2 - 1)
42+ bounceReach = overreach / (2 ^ Double(i - 1))
43+ currentBouncePosition = 1.0 + bounceDirection * bounceReach
44+
45+ keyFrames.append((1.0 - currentBounceTime, currentBouncePosition))
46+
47+ print(currentBounceTime)
48+ print(bounceDirection)
49+ print(bounceReach)
50+ print(currentBouncePosition)
51+ }
52+
53+ keyFrames.append((0, 0))
54+
55+ var reversed = [(time: Double, position: Double)]()
56+ for keyFrame in keyFrames.reverse() {
57+ reversed.append(keyFrame)
58+ }
59+
60+ return reversed
61+}
62+
63+func interpolateSpring<T: Numeric>(linear: T, bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double = 1.0) -> T {
64+ let keyFrames: [(time: Double, position: Double)]
65+ keyFrames = createStringKeyframes(bounces, elasticity: elasticity, bounceSpeed: bounceSpeed)
66+
67+ let x = linear.toDouble
68+
69+ let startFrame = keyFrames.filter { $0.time < x }.last ?? (0, 0)
70+ let endFrame = keyFrames.filter { $0.time > x }.first ?? (1, 1)
71+ let adjustedX = (x - startFrame.time) / (endFrame.time - startFrame.time)
72+ let interpolatedX = interpolateSmooth(adjustedX)
73+ let position = startFrame.position + interpolatedX * (endFrame.position - startFrame.position)
74+
75+ return T.fromDouble(position)
76+}