/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package net.anzix.fsz.voxelworld.layers;
import com.ardor3d.math.Vector3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import net.anzix.fsz.voxelworld.AbstractBlock;
import net.anzix.fsz.voxelworld.AbstractBlockGenerator;
import net.anzix.fsz.voxelworld.DetailLevel;
import net.anzix.fsz.voxelworld.VoxelBlock;
import net.anzix.fsz.voxelworld.VoxelBlockPool;
import net.anzix.fsz.voxelworld.VoxelWorld;
/**
*
* @author kovacsandras
*/
public class LayerBlockGenerator extends AbstractBlockGenerator{
public enum GeneratorStatus { READY, INITIALIZATION, DENSITY_GENERATION, FINALIZING }
public HeightGenerator heightGenerator = new HeightGenerator();
public HeightGenerator rockDensityGenerator = new HeightGenerator(0.001, 3, 0, 3);
public HeightGenerator plateauDensityGenerator = new HeightGenerator(0.002, 4, 0, 1);
private GeneratorStatus status;
public GeneratorStatus getStatus() {
return status;
}
@Override
public String toString() {
return status.toString();
}
private LayerBlock block;
private LayerBlockPool pool;
public LayerBlockGenerator(LayerBlockPool pool) {
status = GeneratorStatus.READY;
this.pool = pool;
block = null;
}
@Override
public boolean tryToAttachABlock(AbstractBlock block) {
if (this.block == null) {
this.block = (LayerBlock)block;
return true;
} else {
return false; //busy
}
}
@Override
public AbstractBlock getBlock() {
return block;
}
private Vector3 basePosition;
public void init() {
int blockSize = VoxelWorld.BLOCK_SIZE;
for (int x = 0; x < blockSize + 2; x++)
for (int z = 0; z < blockSize + 2; z++) {
block.heightLayer[x][z] = 0.0f;
block.rockDensityLayer[x][z] = 0.0f;
block.plateauDensityLayer[x][z] = 0.0f;
}
block.maxHeight = 0.0f;
block.minHeight = 0.0f;
basePosition = block.getPosition().getAsWorldCoords(pool.getLevel());
}
@Override
public void generate() {
if (block == null || block.getStatus() != VoxelBlock.BlockStatus.UNDER_GENERATION) {
VoxelBlockPool.logInvalidBlockStatus(block, "UNDER_GENERATION");
return;
}
try {
status = GeneratorStatus.INITIALIZATION;
init();
status = GeneratorStatus.DENSITY_GENERATION;
DetailLevel level = pool.getLevel();
Vector3 basePosition = block.getPosition().getAsWorldCoords(level);
double scale = level.getScale();
double baseX = basePosition.getX();
double baseZ = basePosition.getZ();
float h;
double xPos, zPos;
boolean first = true;
int blockSize = VoxelWorld.BLOCK_SIZE;
for (int x = 0; x < blockSize + 2; x++)
for (int z = 0; z < blockSize + 2; z++) {
//h = (x+z) / (blockSize + 2) * 2;
xPos = baseX + (x*scale);
zPos = baseZ + (z*scale);
h = heightGenerator.getHeight_ridged(xPos,zPos );
block.heightLayer[x][z] = h;
if (first) {
block.maxHeight = h;
block.minHeight = h;
first = false;
} else {
if (h>block.maxHeight) block.maxHeight = h;
if (h<block.minHeight) block.minHeight = h;
}
block.rockDensityLayer[x][z] = rockDensityGenerator.getHeight(xPos,zPos);
block.plateauDensityLayer[x][z] = plateauDensityGenerator.getHeight(xPos,zPos);
}
status = GeneratorStatus.FINALIZING;
pool.finalizeBlockGeneration(block, true);
} catch (Exception ex) {
VoxelWorld.logger.log(Level.SEVERE,"Unhandled exception while generating a block.");
status = GeneratorStatus.FINALIZING;
pool.finalizeBlockGeneration(block, false);
} catch (OutOfMemoryError err) {
VoxelWorld.logger.log(Level.SEVERE,"Out of memory errorr while generating a block.");
status = GeneratorStatus.FINALIZING;
pool.finalizeBlockGeneration(block, false);
}
status = GeneratorStatus.READY;
this.block = null; //i am ready to work again
}
}