Skip to content

Commit

Permalink
Terraform factory
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrlabs committed Jun 20, 2016
1 parent b008c90 commit c8c5007
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 148 deletions.
142 changes: 0 additions & 142 deletions commons/src/com/mbrlabs/mundus/commons/terrain/Terraform.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016. See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.mbrlabs.mundus.commons.terrain.terraform;

/**
*
* @author Marcus Brummer
* @version 20-06-2016
*/
public interface Generator<T extends Generator> {

T minHeight(float min);
T maxHeight(float max);
void generate();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2016. See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.mbrlabs.mundus.commons.terrain.terraform;

import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.mbrlabs.mundus.commons.terrain.Terrain;

import java.nio.ByteBuffer;

/**
*
* @author Marcus Brummer
* @version 20-06-2016
*/
public class HeightMapGenerator implements Generator<HeightMapGenerator> {

private Terrain terrain;
private float minHeight = 0;
private float maxHeight = 20;
private Pixmap map;

public HeightMapGenerator(Terrain terrain) {
this.terrain = terrain;
}

@Override
public HeightMapGenerator minHeight(float min) {
this.minHeight = min;
return this;
}

@Override
public HeightMapGenerator maxHeight(float max) {
this.maxHeight = max;
return this;
}

public HeightMapGenerator heightMap(Pixmap map) {
this.map = map;
return this;
}

@Override
public void generate() {
if (map.getWidth() != terrain.vertexResolution ||
map.getHeight() != terrain.vertexResolution) {
throw new GdxRuntimeException("Incorrect map size");
}
terrain.heightData = heightColorsToMap(map.getPixels(), map.getFormat(),
terrain.vertexResolution, terrain.vertexResolution, maxHeight);
terrain.update();
}

// Simply creates an array containing only all the red components of the heightData.
private float[] heightColorsToMap (final ByteBuffer data, final Pixmap.Format format, int width, int height, float maxHeight) {
final int bytesPerColor = (format == Pixmap.Format.RGB888 ? 3 : (format == Pixmap.Format.RGBA8888 ? 4 : 0));
if (bytesPerColor == 0) throw new GdxRuntimeException("Unsupported format, should be either RGB8 or RGBA8");
if (data.remaining() < (width * height * bytesPerColor)) throw new GdxRuntimeException("Incorrect map size");

final int startPos = data.position();
byte[] source = null;
int sourceOffset = 0;
if (data.hasArray() && !data.isReadOnly()) {
source = data.array();
sourceOffset = data.arrayOffset() + startPos;
} else {
source = new byte[width * height * bytesPerColor];
data.get(source);
data.position(startPos);
}

float[] dest = new float[width * height];
for (int i = 0; i < dest.length; ++i) {
int v = source[sourceOffset + i * 3];
v = v < 0 ? 256 + v : v;
dest[i] = maxHeight * ((float)v / 255f);
}

return dest;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2016. See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.mbrlabs.mundus.commons.terrain.terraform;

import com.badlogic.gdx.math.Interpolation;
import com.mbrlabs.mundus.commons.terrain.Terrain;

import java.util.Random;

/**
*
* @author Marcus Brummer
* @version 20-06-2016
*/
public class PerlinNoiseGenerator implements Generator<PerlinNoiseGenerator> {

private Random rand = new Random();
private Terrain terrain;

private long seed = 0;
private float minHeight = 0;
private float maxHeight = 50;

public PerlinNoiseGenerator(Terrain terrain) {
this.terrain = terrain;
}

@Override
public PerlinNoiseGenerator minHeight(float min) {
this.minHeight = min;
return this;
}

@Override
public PerlinNoiseGenerator maxHeight(float max) {
this.maxHeight = max;
return this;
}

public PerlinNoiseGenerator seed(long seed) {
this.seed = seed;
return this;
}

@Override
public void generate() {
rand.setSeed(seed);

for(int i = 0; i < terrain.heightData.length; i++) {
int x = i % terrain.vertexResolution;
int z = (int) Math.floor((double)i / terrain.vertexResolution);

float height = getInterpolatedNoise(x / 8f, z / 8f);

terrain.heightData[z * terrain.vertexResolution + x] = height;
}

terrain.update();
}

private float interpolate(float a, float b, float blend) {
double theta = blend * Math.PI;
float f = (float) (1f - Math.cos(theta)) * 0.5f;
return a * (1f - f) + b * f;
}

private float getNoise(int x, int z) {
rand.setSeed(x * 49632 + z * 325176 + seed);
return Interpolation.linear.apply(minHeight, maxHeight, rand.nextFloat());
}

private float getInterpolatedNoise(float x, float z){
int intX = (int) x;
int intZ = (int) z;
float fracX = x - intX;
float fracZ = z - intZ;

float v1 = getSmoothNoise(intX, intZ);
float v2 = getSmoothNoise(intX + 1, intZ);
float v3 = getSmoothNoise(intX, intZ + 1);
float v4 = getSmoothNoise(intX + 1, intZ + 1);
float i1 = interpolate(v1, v2, fracX);
float i2 = interpolate(v3, v4, fracX);
return interpolate(i1, i2, fracZ);
}

private float getSmoothNoise(int x, int z) {
// corner noise
float corners = getNoise(x+1, z-1) + getNoise(x+1, z-1) + getNoise(x-1, z+1) + getNoise(x+1, z+1);
corners /= 16f;
// side noise
float sides = getNoise(x-1, z) + getNoise(x+1, z) + getNoise(x, z-1) + getNoise(x, z+1);
sides /= 8f;
// center noise
float center = getNoise(x, z) / 4f;

return corners + sides + center;
}

}

0 comments on commit c8c5007

Please sign in to comment.