Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ThermalErosion(val noise: Noise, val talusAngle: Double) extends NoiseOp {
- val DEFAULT_DECAY = 0L
- val cache = TrieMap[(Int, Int), Double]()
- var tDecay = new AtomicLong(DEFAULT_DECAY)
- final def apply(x: Double, y: Double) = {
- val i = x.toInt
- val j = y.toInt
- if (tDecay.get() > 0) {
- tDecay.decrementAndGet()
- noise(i, j) + cache.getOrElse((i, j), 0.0)
- }
- else {
- tDecay.set(DEFAULT_DECAY)
- val mask = Array(
- (-1,-1), (0,-1), (1,-1),
- (-1, 0), (0, 0), (1, 0),
- (-1, 1), (0, 1), (1, 1)
- )
- val data = mask.par.map(t => noise(x + t._1, y + t._2))
- val cachedVal = cache.getOrElse((i, j), 0.0)
- val height = data(4) + cachedVal
- val maxSlope = data.reduce((res, x) => math.max(res, x))
- val minSlope = data.reduce((res, x) => math.min(res, x))
- val minSlopeCoords = (mask zip data).reduce((res, e) => if (math.abs(e._2 - minSlope) <= 1e-13) e else res)._1
- if (maxSlope > talusAngle) {
- val newHeight = (height + maxSlope) * 0.5
- cache.update(minSlopeCoords, cachedVal + newHeight)
- cache.update((i, j), newHeight)
- newHeight
- }
- else {
- height
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement