mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
New PerlinNoise
This commit is contained in:
parent
4a79ea0b5a
commit
ea804535d2
@ -81,6 +81,8 @@ public class Chunk {
|
|||||||
* @param z
|
* @param z
|
||||||
*/
|
*/
|
||||||
public void addBlock(Block b, int x, int y, int z) {
|
public void addBlock(Block b, int x, int y, int z) {
|
||||||
|
if(y >= World.WORLD_HEIGHT)
|
||||||
|
return;
|
||||||
int rx = x - (ox << 4);
|
int rx = x - (ox << 4);
|
||||||
if (rx < 0) {
|
if (rx < 0) {
|
||||||
// Determines if the block is part of another chunk.
|
// Determines if the block is part of another chunk.
|
||||||
@ -154,6 +156,8 @@ public class Chunk {
|
|||||||
for (int py = 0; py < 16; py++) {
|
for (int py = 0; py < 16; py++) {
|
||||||
float value = map[px][py];
|
float value = map[px][py];
|
||||||
int y = (int) (value * World.WORLD_HEIGHT);
|
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--) {
|
for (int j = y > SEA_LEVEL ? y : SEA_LEVEL; j >= 0; j--) {
|
||||||
BlockInstance bi = null;
|
BlockInstance bi = null;
|
||||||
if(j > y) {
|
if(j > y) {
|
||||||
|
@ -168,9 +168,9 @@ public class LocalWorld extends World {
|
|||||||
|
|
||||||
public void synchronousGenerate(Chunk ch) {
|
public void synchronousGenerate(Chunk ch) {
|
||||||
int x = ch.getX() * 16; int y = ch.getZ() * 16;
|
int x = ch.getX() * 16; int y = ch.getZ() * 16;
|
||||||
float[][] heightMap = Noise.generateMapFragment(x, y, 16, 16, 300, seed);
|
float[][] heightMap = Noise.generateMapFragment(x, y, 16, 16, 256, seed);
|
||||||
float[][] vegetationMap = Noise.generateMapFragment(x, y, 16, 16, 300, seed + 3 * (seed + 1 & Integer.MAX_VALUE));
|
float[][] vegetationMap = Noise.generateMapFragment(x, y, 16, 16, 128, seed + 3 * (seed + 1 & Integer.MAX_VALUE));
|
||||||
float[][] oreMap = Noise.generateMapFragment(x, y, 16, 16, 300, 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);
|
ch.generateFrom(heightMap, vegetationMap, oreMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package io.cubyz.world;
|
package io.cubyz.world;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perlin Noise generator for Worlds
|
* Perlin Noise generator for Worlds
|
||||||
* @author zenith391
|
* @author zenith391
|
||||||
*/
|
*/
|
||||||
public class Noise {
|
public class Noise {
|
||||||
|
private static Random r = new Random();
|
||||||
|
|
||||||
static float get2DPerlinNoiseValue(float x, float y, float res, int seed)
|
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));
|
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) {
|
public static float[][] generateMap(int width, int height, int scale, int seed) {
|
||||||
return generateMapFragment(0, 0, width, height, scale, 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) {
|
public static float[][] generateMapFragment(int x, int y, int width, int height, int scale, int seed) {
|
||||||
float[][] map = new float[width][height];
|
float[][] map = new float[width][height];
|
||||||
|
resolution = scale;
|
||||||
|
resolution2 = resolution-1;
|
||||||
|
Noise.seed = seed;
|
||||||
|
|
||||||
for (int x1 = x; x1 < width + x; x1++) {
|
for (int x1 = x; x1 < width + x; x1++) {
|
||||||
for (int y1 = y; y1 < height + y; y1++) {
|
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