@@ -66,11 +66,12 @@ struct CellNoise2D:Noise
66
66
// as “near” and “far” points. We call these points the *generating points*.
67
67
// The sample point (example) has been marked with an ‘*’.
68
68
69
- // A ------ far
69
+ // A —————— far
70
70
// | | |
71
71
// |----+----|
72
72
// | * | |
73
- // near ------ A
73
+ // near —————— A ← quadrant
74
+ // ↓
74
75
75
76
// The actual feature points never spawn outside of the unit square surrounding
76
77
// their generating points. Therefore, the boundaries of the generating
@@ -79,48 +80,36 @@ struct CellNoise2D:Noise
79
80
// square since it cannot produce a feature point closer than we have already
80
81
// found.
81
82
82
- let quadrant : ( x : Bool , y : Bool ) = ( offset. x > 0.5 , offset. y > 0.5 ) ,
83
- near : IntV2 = ( bin. a + ( quadrant. x ? 1 : 0 ) , bin. b + ( quadrant. y ? 1 : 0 ) ) ,
84
- far : IntV2 = ( bin . a + ( quadrant. x ? 0 : 1 ) , bin . b + ( quadrant. y ? 0 : 1 ) )
83
+ let quadrant : IntV2 = ( offset. x > 0.5 ? 1 : - 1 , offset. y > 0.5 ? 1 : - 1 ) ,
84
+ near : IntV2 = ( bin. a + ( quadrant. a + 1 ) >> 1 , bin. b + ( quadrant. b + 1 ) >> 1 ) ,
85
+ far : IntV2 = ( near . a - quadrant. a , near . b - quadrant. b )
85
86
86
- let nearpoint_disp : DoubleV2 = ( abs ( offset. x - ( quadrant. x ? 1 : 0 ) ) ,
87
- abs ( offset. y - ( quadrant. y ? 1 : 0 ) ) )
87
+ let nearpoint_disp : DoubleV2 = ( abs ( offset. x - Double ( ( quadrant. a + 1 ) >> 1 ) ) ,
88
+ abs ( offset. y - Double ( ( quadrant. b + 1 ) >> 1 ) ) )
88
89
89
- var r2_min : Double = self . distance ( from: sample, generating_point: near)
90
+ var r2 : Double = self . distance ( from: sample, generating_point: near)
90
91
91
92
@inline ( __always)
92
- func test( generating_point: IntV2 )
93
+ func test( generating_point: IntV2 , dx : Double = 0 , dy : Double = 0 )
93
94
{
94
- let r2 : Double = self . distance ( from: sample, generating_point: generating_point)
95
-
96
- if r2 < r2_min
95
+ if dx*dx + dy*dy < r2
97
96
{
98
- r2_min = r2
97
+ r2 = min ( r2 , self . distance ( from : sample , generating_point : generating_point ) )
99
98
}
100
99
}
101
100
102
101
// A points
103
- if ( 0.5 - nearpoint_disp. y) * ( 0.5 - nearpoint_disp. y) < r2_min
104
- {
105
- test ( generating_point: ( near. a, far. b) )
106
- }
107
-
108
- if ( 0.5 - nearpoint_disp. x) * ( 0.5 - nearpoint_disp. x) < r2_min
109
- {
110
- test ( generating_point: ( far. a, near. b) )
111
- }
102
+ test ( generating_point: ( near. a, far. b) , dy: nearpoint_disp. y - 0.5 )
103
+ test ( generating_point: ( far. a, near. b) , dx: nearpoint_disp. x - 0.5 )
112
104
113
105
// far point
114
- if ( 0.5 - nearpoint_disp. x) * ( 0.5 - nearpoint_disp. x) + ( 0.5 - nearpoint_disp. y) * ( 0.5 - nearpoint_disp. y) < r2_min
115
- {
116
- test ( generating_point: far)
117
- }
106
+ test ( generating_point: far, dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y - 0.5 )
118
107
119
108
// EARLY EXIT: if we have a point within 0.5 units, we don’t have to check
120
109
// the outer kernel
121
- if r2_min < 0.5 * 0.5
110
+ if r2 < 0.25
122
111
{
123
- return self . amplitude * r2_min
112
+ return self . amplitude * r2
124
113
}
125
114
126
115
// This is the part where shit hits the fan. (`inner` and `outer` are never
@@ -139,59 +128,37 @@ struct CellNoise2D:Noise
139
128
// | | | | | | |
140
129
// |----+----|----+----|----+----|
141
130
// | | | | | | |
142
- // inner ----- B ------- C --------+
131
+ // inner ----- B ------- C --------+ ← quadrant
132
+ // ↓
143
133
144
- let inner : IntV2 = ( bin. a + ( quadrant. x ? 2 : - 1 ) , bin. b + ( quadrant. y ? 2 : - 1 ) ) ,
145
- outer : IntV2 = ( bin. a + ( quadrant. x ? - 1 : 2 ) , bin. b + ( quadrant. y ? - 1 : 2 ) )
134
+ let inner : IntV2 = ( near. a + quadrant. a, near. b + quadrant. b)
146
135
147
136
// B points
148
- if ( nearpoint_disp. x + 0.5 ) * ( nearpoint_disp. x + 0.5 ) < r2_min
149
- {
150
- test ( generating_point: ( inner. a, near. b) )
151
- }
152
- if ( nearpoint_disp. y + 0.5 ) * ( nearpoint_disp. y + 0.5 ) < r2_min
153
- {
154
- test ( generating_point: ( near. a, inner. b) )
155
- }
137
+ test ( generating_point: ( inner. a, near. b) , dx: nearpoint_disp. x + 0.5 )
138
+ test ( generating_point: ( near. a, inner. b) , dy: nearpoint_disp. y + 0.5 )
156
139
157
140
// C points
158
- if ( nearpoint_disp. x + 0.5 ) * ( nearpoint_disp. x + 0.5 ) + ( 0.5 - nearpoint_disp. y) * ( 0.5 - nearpoint_disp. y) < r2_min
159
- {
160
- test ( generating_point: ( inner. a, far. b) )
161
- }
162
- if ( nearpoint_disp. y + 0.5 ) * ( nearpoint_disp. y + 0.5 ) + ( 0.5 - nearpoint_disp. x) * ( 0.5 - nearpoint_disp. x) < r2_min
163
- {
164
- test ( generating_point: ( far. a, inner. b) )
165
- }
141
+ test ( generating_point: ( inner. a, far. b) , dx: nearpoint_disp. x + 0.5 , dy: nearpoint_disp. y - 0.5 )
142
+ test ( generating_point: ( far. a, inner. b) , dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y + 0.5 )
166
143
167
144
// EARLY EXIT: if we have a point within 1 unit, we don’t have to check
168
145
// the D points or the E points
169
- if r2_min < 1 * 1
146
+ if r2 < 1
170
147
{
171
- return self . amplitude * r2_min
148
+ return self . amplitude * r2
172
149
}
173
150
151
+ let outer : IntV2 = ( far. a - quadrant. a, far. b - quadrant. b)
152
+
174
153
// D points
175
- if ( 1.5 - nearpoint_disp. y) * ( 1.5 - nearpoint_disp. y) < r2_min
176
- {
177
- test ( generating_point: ( near. a, outer. b) )
178
- }
179
- if ( 1.5 - nearpoint_disp. x) * ( 1.5 - nearpoint_disp. x) < r2_min
180
- {
181
- test ( generating_point: ( outer. a, near. b) )
182
- }
154
+ test ( generating_point: ( near. a, outer. b) , dy: nearpoint_disp. y - 1.5 )
155
+ test ( generating_point: ( outer. a, near. b) , dx: nearpoint_disp. x - 1.5 )
183
156
184
157
// E points
185
- if ( 0.5 - nearpoint_disp. x) * ( 0.5 - nearpoint_disp. x) + ( 1.5 - nearpoint_disp. y) * ( 1.5 - nearpoint_disp. y) < r2_min
186
- {
187
- test ( generating_point: ( far. a, outer. b) )
188
- }
189
- if ( 0.5 - nearpoint_disp. y) * ( 0.5 - nearpoint_disp. y) + ( 1.5 - nearpoint_disp. x) * ( 1.5 - nearpoint_disp. x) < r2_min
190
- {
191
- test ( generating_point: ( outer. a, far. b) )
192
- }
158
+ test ( generating_point: ( far. a, outer. b) , dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y - 1.5 )
159
+ test ( generating_point: ( outer. a, far. b) , dx: nearpoint_disp. x - 1.5 , dy: nearpoint_disp. y - 0.5 )
193
160
194
- return self . amplitude * r2_min
161
+ return self . amplitude * r2
195
162
}
196
163
197
164
public
@@ -323,20 +290,20 @@ struct CellNoise3D:Noise
323
290
cell_distance2 = 0
324
291
}
325
292
else
326
- { // move by 0.5 towards zero
327
- let dx : Double = Double ( cell_offset. a) + ( cell_offset. a > 0 ? - 0.5 : 0.5 ) + nearpoint_disp . x
293
+ { // move by 0.5 towards zero
294
+ let dx : Double = nearpoint_disp . x + Double( cell_offset. a) + ( cell_offset. a > 0 ? - 0.5 : 0.5 )
328
295
cell_distance2 = dx*dx
329
296
}
330
297
331
298
if cell_offset. b != 0
332
- { // move by 0.5 towards zero
333
- let dy : Double = Double ( cell_offset. b) + ( cell_offset. b > 0 ? - 0.5 : 0.5 ) + nearpoint_disp . y
299
+ { // move by 0.5 towards zero
300
+ let dy : Double = nearpoint_disp . y + Double( cell_offset. b) + ( cell_offset. b > 0 ? - 0.5 : 0.5 )
334
301
cell_distance2 += dy*dy
335
302
}
336
303
337
304
if cell_offset. c != 0
338
- { // move by 0.5 towards zero
339
- let dz : Double = Double ( cell_offset. c) + ( cell_offset. c > 0 ? - 0.5 : 0.5 ) + nearpoint_disp . z
305
+ { // move by 0.5 towards zero
306
+ let dz : Double = nearpoint_disp . z + Double( cell_offset. c) + ( cell_offset. c > 0 ? - 0.5 : 0.5 )
340
307
cell_distance2 += dz*dz
341
308
}
342
309
0 commit comments