-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored noise interpolation code into data pipeline
- Loading branch information
Showing
13 changed files
with
184 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package hexacraft.math.noise | ||
|
||
import hexacraft.math.Range2D | ||
|
||
import org.joml.Math.biLerp | ||
|
||
case class Data2D(sizeX: Int, sizeY: Int, values: Array[Double]) { | ||
def apply(x: Int, y: Int): Double = | ||
values(x + y * sizeX) | ||
} | ||
|
||
object Data2D { | ||
def evaluate(indices: Range2D, fn: (Int, Int) => Double): Data2D = | ||
val Range2D(xs, ys) = indices | ||
val values = for (y <- ys; x <- xs) yield fn(x, y) | ||
Data2D(xs.length, ys.length, values.toArray) | ||
|
||
def interpolate(scaleX: Int, scaleY: Int, data: Data2D): Data2D = | ||
val xs = 0 until (data.sizeX - 1) * scaleX | ||
val ys = 0 until (data.sizeY - 1) * scaleY | ||
|
||
Data2D.evaluate( | ||
Range2D(xs, ys), | ||
(x, y) => { | ||
val ii = x / scaleX | ||
val ij = y / scaleY | ||
val fi = (x % scaleX) / scaleX.toDouble | ||
val fj = (y % scaleY) / scaleY.toDouble | ||
|
||
biLerp( | ||
data(ii, ij), | ||
data(ii, ij + 1), | ||
data(ii + 1, ij), | ||
data(ii + 1, ij + 1), | ||
fj, | ||
fi | ||
) | ||
} | ||
) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package hexacraft.math.noise | ||
|
||
import hexacraft.math.Range3D | ||
|
||
import org.joml.Math.triLerp | ||
|
||
case class Data3D(sizeX: Int, sizeY: Int, sizeZ: Int, values: Array[Double]) { | ||
def apply(x: Int, y: Int, z: Int): Double = | ||
values(x + y * sizeX + z * sizeX * sizeY) | ||
} | ||
|
||
object Data3D { | ||
def evaluate(indices: Range3D, fn: (Int, Int, Int) => Double): Data3D = | ||
val Range3D(xs, ys, zs) = indices | ||
val values = for (z <- zs; y <- ys; x <- xs) yield fn(x, y, z) | ||
Data3D(xs.length, ys.length, zs.length, values.toArray) | ||
|
||
def interpolate(scaleX: Int, scaleY: Int, scaleZ: Int, data: Data3D): Data3D = | ||
val xs = 0 until (data.sizeX - 1) * scaleX | ||
val ys = 0 until (data.sizeY - 1) * scaleY | ||
val zs = 0 until (data.sizeZ - 1) * scaleZ | ||
|
||
Data3D.evaluate( | ||
Range3D(xs, ys, zs), | ||
(x, y, z) => { | ||
val ii = x / scaleX | ||
val ij = y / scaleY | ||
val ik = z / scaleZ | ||
val fi = (x % scaleX) / scaleX.toDouble | ||
val fj = (y % scaleY) / scaleY.toDouble | ||
val fk = (z % scaleZ) / scaleZ.toDouble | ||
|
||
triLerp( | ||
data(ii, ij, ik), | ||
data(ii, ij, ik + 1), | ||
data(ii, ij + 1, ik), | ||
data(ii, ij + 1, ik + 1), | ||
data(ii + 1, ij, ik), | ||
data(ii + 1, ij, ik + 1), | ||
data(ii + 1, ij + 1, ik), | ||
data(ii + 1, ij + 1, ik + 1), | ||
fk, | ||
fj, | ||
fi | ||
) | ||
} | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 0 additions & 22 deletions
22
src/main/scala/hexacraft/math/noise/NoiseInterpolator2D.scala
This file was deleted.
Oops, something went wrong.
35 changes: 0 additions & 35 deletions
35
src/main/scala/hexacraft/math/noise/NoiseInterpolator3D.scala
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package hexacraft.math | ||
|
||
extension (xs: Range) { | ||
def offset(dx: Int): Range = | ||
val (start, end, step) = (xs.start + dx, xs.end + dx, xs.step) | ||
if xs.isInclusive then start to end by step else start until end by step | ||
} | ||
|
||
case class Range2D(xs: Range, ys: Range) { | ||
def offset(dx: Int, dy: Int): Range2D = | ||
Range2D(xs.offset(dx), ys.offset(dy)) | ||
} | ||
|
||
case class Range3D(xs: Range, ys: Range, zs: Range) { | ||
def offset(dx: Int, dy: Int, dz: Int): Range3D = | ||
Range3D(xs.offset(dx), ys.offset(dy), zs.offset(dz)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 0 additions & 20 deletions
20
src/test/scala/hexacraft/math/noise/NoiseInterpolator2DTest.scala
This file was deleted.
Oops, something went wrong.
22 changes: 0 additions & 22 deletions
22
src/test/scala/hexacraft/math/noise/NoiseInterpolator3DTest.scala
This file was deleted.
Oops, something went wrong.
30 changes: 30 additions & 0 deletions
30
src/test/scala/hexacraft/world/gen/WorldGeneratorTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package hexacraft.world.gen | ||
|
||
import hexacraft.world.CylinderSize | ||
import hexacraft.world.coord.integer.{ChunkRelWorld, ColumnRelWorld} | ||
|
||
import munit.FunSuite | ||
|
||
class WorldGeneratorTest extends FunSuite { | ||
given CylinderSize = CylinderSize(8) | ||
|
||
test("block interpolator works") { | ||
val fn: (Int, Int, Int) => Double = (x, y, z) => x + 3 * y + 5 * z | ||
val sampler = WorldGenerator.makeBlockInterpolator(ChunkRelWorld(1, 2, 3), fn) | ||
for | ||
x <- 0 until 16 | ||
y <- 0 until 16 | ||
z <- 0 until 16 | ||
do assertEqualsDouble(sampler(x, y, z), fn(16 + x, 32 + y, 48 + z), 1e-6, clue = (x, y, z)) | ||
} | ||
|
||
test("heightmap interpolator works") { | ||
val fn: (Int, Int) => Double = (x, z) => x + 5 * z | ||
val sampler = WorldGenerator.makeHeightmapInterpolator(ColumnRelWorld(1, 3), fn) | ||
for | ||
x <- 0 until 16 | ||
y <- 0 until 16 | ||
z <- 0 until 16 | ||
do assertEqualsDouble(sampler(x, z), fn(16 + x, 48 + z), 1e-6, clue = (x, y, z)) | ||
} | ||
} |