mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-04 03:37:59 -04:00
New PerlinNoise
This commit is contained in:
parent
4a79ea0b5a
commit
ea804535d2
@ -81,6 +81,8 @@ public class Chunk {
|
||||
* @param z
|
||||
*/
|
||||
public void addBlock(Block b, int x, int y, int z) {
|
||||
if(y >= World.WORLD_HEIGHT)
|
||||
return;
|
||||
int rx = x - (ox << 4);
|
||||
if (rx < 0) {
|
||||
// Determines if the block is part of another chunk.
|
||||
@ -154,6 +156,8 @@ public class Chunk {
|
||||
for (int py = 0; py < 16; py++) {
|
||||
float value = map[px][py];
|
||||
int y = (int) (value * World.WORLD_HEIGHT);
|
||||
if(y == World.WORLD_HEIGHT)
|
||||
y--;
|
||||
for (int j = y > SEA_LEVEL ? y : SEA_LEVEL; j >= 0; j--) {
|
||||
BlockInstance bi = null;
|
||||
if(j > y) {
|
||||
|
@ -168,9 +168,9 @@ public class LocalWorld extends World {
|
||||
|
||||
public void synchronousGenerate(Chunk ch) {
|
||||
int x = ch.getX() * 16; int y = ch.getZ() * 16;
|
||||
float[][] heightMap = Noise.generateMapFragment(x, y, 16, 16, 300, seed);
|
||||
float[][] vegetationMap = Noise.generateMapFragment(x, y, 16, 16, 300, seed + 3 * (seed + 1 & Integer.MAX_VALUE));
|
||||
float[][] oreMap = Noise.generateMapFragment(x, y, 16, 16, 300, seed - 3 * (seed - 1 & Integer.MAX_VALUE));
|
||||
float[][] heightMap = Noise.generateMapFragment(x, y, 16, 16, 256, seed);
|
||||
float[][] vegetationMap = Noise.generateMapFragment(x, y, 16, 16, 128, seed + 3 * (seed + 1 & Integer.MAX_VALUE));
|
||||
float[][] oreMap = Noise.generateMapFragment(x, y, 16, 16, 128, seed - 3 * (seed - 1 & Integer.MAX_VALUE));
|
||||
ch.generateFrom(heightMap, vegetationMap, oreMap);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
package io.cubyz.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Perlin Noise generator for Worlds
|
||||
* @author zenith391
|
||||
*/
|
||||
public class Noise {
|
||||
private static Random r = new Random();
|
||||
|
||||
static float get2DPerlinNoiseValue(float x, float y, float res, int seed)
|
||||
{
|
||||
@ -75,6 +78,83 @@ public class Noise {
|
||||
|
||||
return 0.5f*(1+Li1 + Cy*(Li2-Li1));
|
||||
}
|
||||
|
||||
private static int seed;
|
||||
private static int resolution;
|
||||
private static int resolution2;
|
||||
// Calculate the gradient instead of storing it.
|
||||
// This is inefficient(since it is called every time), but allows infinite chunk generation.
|
||||
// TODO: Make this faster
|
||||
private static float getGradient(int x, int y, int i) {
|
||||
r.setSeed(seed);
|
||||
r.setSeed(r.nextLong()*x+r.nextLong()*y+r.nextLong()*i);
|
||||
return 2 * r.nextFloat() - 1;
|
||||
}
|
||||
/* Function to linearly interpolate between a0 and a1
|
||||
* Weight w should be in the range [0.0, 1.0]
|
||||
*
|
||||
* as an alternative, this slightly faster equivalent function (macro) can be used:
|
||||
* #define lerp(a0, a1, w) (a0 + w*(a1 - a0))
|
||||
*/
|
||||
private static float lerp(float a0, float a1, float w) {
|
||||
return (1.0f - w)*a0 + w*a1;
|
||||
}
|
||||
|
||||
// Computes the dot product of the distance and gradient vectors.
|
||||
private static float dotGridGradient(int ix, int iy, int x, int y) {
|
||||
|
||||
// Precomputed (or otherwise) gradient vectors at each grid node
|
||||
|
||||
// Compute the distance vector
|
||||
float dx = x/(float)resolution - ix;
|
||||
float dy = y/(float)resolution - iy;
|
||||
|
||||
// Compute the dot-product
|
||||
float gx = getGradient(ix, iy, 0);
|
||||
float gy = getGradient(ix, iy, 1);
|
||||
float gr = (float)Math.sqrt((gx*gx+gy*gy));
|
||||
gx /= gr;
|
||||
gy /= gr;
|
||||
return (dx*gx + dy*gy);
|
||||
}
|
||||
|
||||
// Compute Perlin noise at coordinates x, y
|
||||
private static float perlin(int x, int y) {
|
||||
|
||||
// Determine grid cell coordinates
|
||||
int x0 = x/resolution;
|
||||
if(x < 0) {
|
||||
x0 = (x-resolution2)/resolution;
|
||||
}
|
||||
int x1 = x0 + 1;
|
||||
int y0 = y/resolution;
|
||||
if(y < 0) {
|
||||
y0 = (y-resolution2)/resolution;
|
||||
}
|
||||
int y1 = y0 + 1;
|
||||
|
||||
// Determine interpolation weights
|
||||
// Could also use higher order polynomial/s-curve here
|
||||
float sx = (x&resolution2)/(float)resolution;
|
||||
float sy = (y&resolution2)/(float)resolution;
|
||||
|
||||
// Interpolate between grid point gradients
|
||||
float n0, n1, ix0, ix1, value;
|
||||
|
||||
n0 = dotGridGradient(x0, y0, x, y);
|
||||
n1 = dotGridGradient(x1, y0, x, y);
|
||||
ix0 = lerp(n0, n1, sx);
|
||||
|
||||
n0 = dotGridGradient(x0, y1, x, y);
|
||||
n1 = dotGridGradient(x1, y1, x, y);
|
||||
ix1 = lerp(n0, n1, sx);
|
||||
|
||||
value = lerp(ix0, ix1, sy);
|
||||
value = 0.5F * value + 0.5F;
|
||||
if(value > 1)
|
||||
value = 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float[][] generateMap(int width, int height, int scale, int seed) {
|
||||
return generateMapFragment(0, 0, width, height, scale, seed);
|
||||
@ -82,10 +162,14 @@ public class Noise {
|
||||
|
||||
public static float[][] generateMapFragment(int x, int y, int width, int height, int scale, int seed) {
|
||||
float[][] map = new float[width][height];
|
||||
resolution = scale;
|
||||
resolution2 = resolution-1;
|
||||
Noise.seed = seed;
|
||||
|
||||
for (int x1 = x; x1 < width + x; x1++) {
|
||||
for (int y1 = y; y1 < height + y; y1++) {
|
||||
map[x1 - x][y1 - y] = get2DPerlinNoiseValue(x1, y1, scale, seed);
|
||||
//map[x1 - x][y1 - y] = get2DPerlinNoiseValue(x1, y1, scale, seed);
|
||||
map[x1 - x][y1 - y] = perlin(x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user