Skip to content

Commit dbaf7d7

Browse files
committed
use batch arithmetic
1 parent d1dd02d commit dbaf7d7

File tree

5 files changed

+269
-320
lines changed

5 files changed

+269
-320
lines changed

sources/noise/cell.swift

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
public
22
struct CellNoise2D:Noise
33
{
4-
private
5-
typealias IntV2 = (a:Int, b:Int)
6-
private
7-
typealias DoubleV2 = (x:Double, y:Double)
8-
94
private
105
let permutation_table:PermutationTable,
116
amplitude:Double,
@@ -20,9 +15,9 @@ struct CellNoise2D:Noise
2015
}
2116

2217
private
23-
func distance(from sample_point:DoubleV2, generating_point:IntV2) -> Double
18+
func distance(from sample_point:Math.DoubleV2, generating_point:Math.IntV2) -> Double
2419
{
25-
let hash:Int = self.permutation_table.hash(generating_point.a, generating_point.b)
20+
let hash:Int = self.permutation_table.hash(generating_point)
2621
// hash is within 0 ... 255, take it to 0 ... 0.5
2722

2823
// Notice that we have 256 possible hashes, and therefore 8 bits of entropy,
@@ -31,20 +26,19 @@ struct CellNoise2D:Noise
3126

3227
// 0b XXXX YYYY
3328

34-
let dpx:Double = (Double(hash >> 4 ) - 15/2) * 1/16,
35-
dpy:Double = (Double(hash & 0b1111) - 15/2) * 1/16
29+
let dp:Math.DoubleV2 = ((Double(hash >> 4 ) - 15/2) * 1/16,
30+
(Double(hash & 0b1111) - 15/2) * 1/16)
3631

37-
let dx:Double = Double(generating_point.a) + dpx - sample_point.x,
38-
dy:Double = Double(generating_point.b) + dpy - sample_point.y
39-
return dx*dx + dy*dy
32+
let dv:Math.DoubleV2 = Math.sub(Math.add(Math.cast_double(generating_point), dp), sample_point)
33+
return Math.dot(dv, dv)
4034
}
4135

4236
public
4337
func evaluate(_ x:Double, _ y:Double) -> Double
4438
{
45-
let sample:DoubleV2 = (x * self.frequency , y * self.frequency),
46-
bin:IntV2 = (Math.ifloor(sample.x) , Math.ifloor(sample.y)),
47-
sample_rel:DoubleV2 = (sample.x - Double(bin.a), sample.y - Double(bin.b))
39+
let sample:Math.DoubleV2 = (x * self.frequency, y * self.frequency)
40+
41+
let (bin, sample_rel):(Math.IntV2, Math.DoubleV2) = Math.fraction(sample)
4842

4943
// determine kernel
5044

@@ -79,17 +73,17 @@ struct CellNoise2D:Noise
7973
// square since it cannot produce a feature point closer than we have already
8074
// found.
8175

82-
let quadrant:IntV2 = (sample_rel.x > 0.5 ? 1 : -1 , sample_rel.y > 0.5 ? 1 : -1),
83-
near:IntV2 = (bin.a + (quadrant.a + 1) >> 1, bin.b + (quadrant.b + 1) >> 1),
84-
far:IntV2 = (near.a - quadrant.a , near.b - quadrant.b)
76+
let quadrant:Math.IntV2 = (sample_rel.x > 0.5 ? 1 : -1 , sample_rel.y > 0.5 ? 1 : -1),
77+
near:Math.IntV2 = (bin.a + (quadrant.a + 1) >> 1, bin.b + (quadrant.b + 1) >> 1),
78+
far:Math.IntV2 = (near.a - quadrant.a , near.b - quadrant.b)
8579

86-
let nearpoint_disp:DoubleV2 = (abs(sample_rel.x - Double((quadrant.a + 1) >> 1)),
87-
abs(sample_rel.y - Double((quadrant.b + 1) >> 1)))
80+
let nearpoint_disp:Math.DoubleV2 = (abs(sample_rel.x - Double((quadrant.a + 1) >> 1)),
81+
abs(sample_rel.y - Double((quadrant.b + 1) >> 1)))
8882

8983
var r2:Double = self.distance(from: sample, generating_point: near)
9084

9185
@inline(__always)
92-
func _inspect(generating_point:IntV2, dx:Double = 0, dy:Double = 0)
86+
func _inspect(generating_point:Math.IntV2, dx:Double = 0, dy:Double = 0)
9387
{
9488
if dx*dx + dy*dy < r2
9589
{
@@ -136,7 +130,7 @@ struct CellNoise2D:Noise
136130
// Cell group II:
137131
// within r^2 = 1.0
138132
// cumulative sample coverage = 99.96%
139-
let inner:IntV2 = (near.a + quadrant.a, near.b + quadrant.b)
133+
let inner:Math.IntV2 = (near.a + quadrant.a, near.b + quadrant.b)
140134

141135
// B points
142136
_inspect(generating_point: (inner.a, near.b), dx: nearpoint_disp.x + 0.5)
@@ -155,7 +149,7 @@ struct CellNoise2D:Noise
155149
// Cell group III:
156150
// within r^2 = 2.0
157151
// cumulative sample coverage = 100%
158-
let outer:IntV2 = (far.a - quadrant.a, far.b - quadrant.b)
152+
let outer:Math.IntV2 = (far.a - quadrant.a, far.b - quadrant.b)
159153

160154
// D points
161155
_inspect(generating_point: (near.a, outer.b), dy: nearpoint_disp.y - 1.5)
@@ -184,11 +178,6 @@ struct CellNoise2D:Noise
184178
public
185179
struct CellNoise3D:Noise
186180
{
187-
private
188-
typealias IntV3 = (a:Int, b:Int, c:Int)
189-
private
190-
typealias DoubleV3 = (x:Double, y:Double, z:Double)
191-
192181
private
193182
let permutation_table:PermutationTable,
194183
amplitude:Double,
@@ -203,9 +192,9 @@ struct CellNoise3D:Noise
203192
}
204193

205194
private
206-
func distance(from sample_point:DoubleV3, generating_point:IntV3) -> Double
195+
func distance(from sample_point:Math.DoubleV3, generating_point:Math.IntV3) -> Double
207196
{
208-
let hash:Int = self.permutation_table.hash(generating_point.a, generating_point.b, generating_point.c)
197+
let hash:Int = self.permutation_table.hash(generating_point)
209198
// hash is within 0 ... 255, take it to 0 ... 0.5
210199

211200
// Notice that we have 256 possible hashes, and therefore 8 bits of entropy,
@@ -216,14 +205,12 @@ struct CellNoise3D:Noise
216205

217206
// 0b XXX YYY ZZ
218207

219-
let dpx:Double = (Double(hash >> 5 ) - 7/2) * 1/8,
220-
dpy:Double = (Double(hash >> 2 & 0b0111 ) - 7/2) * 1/8,
221-
dpz:Double = (Double(hash << 1 & 0b0111 + ((hash >> 5 ^ hash >> 2) & 1)) - 7/2) * 1/8
208+
let dp:Math.DoubleV3 = ((Double(hash >> 5 ) - 7/2) * 1/8,
209+
(Double(hash >> 2 & 0b0111 ) - 7/2) * 1/8,
210+
(Double(hash << 1 & 0b0111 + ((hash >> 5 ^ hash >> 2) & 1)) - 7/2) * 1/8)
222211

223-
let dx:Double = Double(generating_point.a) + dpx - sample_point.x,
224-
dy:Double = Double(generating_point.b) + dpy - sample_point.y,
225-
dz:Double = Double(generating_point.c) + dpz - sample_point.z
226-
return dx*dx + dy*dy + dz*dz
212+
let dv:Math.DoubleV3 = Math.sub(Math.add(Math.cast_double(generating_point), dp), sample_point)
213+
return Math.dot(dv, dv)
227214
}
228215

229216
public
@@ -235,9 +222,9 @@ struct CellNoise3D:Noise
235222
public
236223
func evaluate(_ x:Double, _ y:Double, _ z:Double) -> Double
237224
{
238-
let sample:DoubleV3 = (x * self.frequency , y * self.frequency , z * self.frequency),
239-
bin:IntV3 = (Math.ifloor(sample.x) , Math.ifloor(sample.y) , Math.ifloor(sample.z)),
240-
sample_rel:DoubleV3 = (sample.x - Double(bin.a), sample.y - Double(bin.b), sample.z - Double(bin.c))
225+
let sample:Math.DoubleV3 = (x * self.frequency, y * self.frequency, z * self.frequency)
226+
227+
let (bin, sample_rel):(Math.IntV3, Math.DoubleV3) = Math.fraction(sample)
241228

242229
// determine kernel
243230

@@ -250,17 +237,21 @@ struct CellNoise3D:Noise
250237
// near - quadrant.x ————— near quadrant →
251238
// ↓
252239

253-
let quadrant:IntV3 = (sample_rel.x > 0.5 ? 1 : -1 , sample_rel.y > 0.5 ? 1 : -1 , sample_rel.z > 0.5 ? 1 : -1)
254-
let near:IntV3 = (bin.a + (quadrant.a + 1) >> 1, bin.b + (quadrant.b + 1) >> 1, bin.c + (quadrant.c + 1) >> 1)
240+
let quadrant:Math.IntV3 = (sample_rel.x > 0.5 ? 1 : -1,
241+
sample_rel.y > 0.5 ? 1 : -1,
242+
sample_rel.z > 0.5 ? 1 : -1)
243+
let near:Math.IntV3 = (bin.a + (quadrant.a + 1) >> 1,
244+
bin.b + (quadrant.b + 1) >> 1,
245+
bin.c + (quadrant.c + 1) >> 1)
255246

256-
let nearpoint_disp:DoubleV3 = (abs(sample_rel.x - Double((quadrant.a + 1) >> 1)),
257-
abs(sample_rel.y - Double((quadrant.b + 1) >> 1)),
258-
abs(sample_rel.z - Double((quadrant.c + 1) >> 1)))
247+
let nearpoint_disp:Math.DoubleV3 = (abs(sample_rel.x - Double((quadrant.a + 1) >> 1)),
248+
abs(sample_rel.y - Double((quadrant.b + 1) >> 1)),
249+
abs(sample_rel.z - Double((quadrant.c + 1) >> 1)))
259250

260251
var r2:Double = self.distance(from: sample, generating_point: near)
261252

262253
@inline(__always)
263-
func _inspect_cell(offset:IntV3)
254+
func _inspect_cell(offset:Math.IntV3)
264255
{
265256
// calculate distance from quadrant volume to kernel cell
266257
var cell_distance2:Double
@@ -292,9 +283,9 @@ struct CellNoise3D:Noise
292283
return
293284
}
294285

295-
let generating_point:IntV3 = (near.a + quadrant.a*offset.a,
296-
near.b + quadrant.b*offset.b,
297-
near.c + quadrant.c*offset.c)
286+
let generating_point:Math.IntV3 = (near.a + quadrant.a*offset.a,
287+
near.b + quadrant.b*offset.b,
288+
near.c + quadrant.c*offset.c)
298289
r2 = min(r2, self.distance(from: sample, generating_point: generating_point))
299290
}
300291

0 commit comments

Comments
 (0)