-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TODO: textures, noise, generators, tests
- Loading branch information
0 parents
commit 15c688a
Showing
22 changed files
with
1,616 additions
and
0 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,9 @@ | ||
build/ | ||
nbproject/ | ||
.project | ||
MANIFEST.MF | ||
master-application.jnlp | ||
lwjgl64.dll | ||
OpenAL64.dll | ||
.classpath | ||
build.xml |
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,50 @@ | ||
package com.jme3.cubed; | ||
|
||
import com.jme3.math.Vector3f; | ||
|
||
public class Block { | ||
|
||
/** | ||
* 0, 0, 0 | ||
*/ | ||
public static final Vector3f FRONT_BOTTOM_LEFT = new Vector3f(0, 0, 0); | ||
/** | ||
* 1, 0, 0 | ||
*/ | ||
public static final Vector3f FRONT_BOTTOM_RIGHT = new Vector3f(1, 0, 0); | ||
/** | ||
* 0, 0, 1 | ||
*/ | ||
public static final Vector3f REAR_BOTTOM_LEFT = new Vector3f(0, 0, 1); | ||
/** | ||
* 1, 0, 1 | ||
*/ | ||
public static final Vector3f REAR_BOTTOM_RIGHT = new Vector3f(1, 0, 1); | ||
/** | ||
* 0, 1, 0 | ||
*/ | ||
public static final Vector3f FRONT_TOP_LEFT = new Vector3f(0, 1, 0); | ||
/** | ||
* 1, 1, 0 | ||
*/ | ||
public static final Vector3f FRONT_TOP_RIGHT = new Vector3f(1, 1, 0); | ||
/** | ||
* 0, 1, 1 | ||
*/ | ||
public static final Vector3f REAR_TOP_LEFT = new Vector3f(0, 1, 1); | ||
/** | ||
* 1, 1, 1 | ||
*/ | ||
public static final Vector3f REAR_TOP_RIGHT = new Vector3f(1, 1, 1); | ||
|
||
private final BlockType type; | ||
|
||
public Block() { | ||
this.type = MaterialManager.getInstance().getType(getClass()); | ||
} | ||
|
||
|
||
public BlockType getType() { | ||
return this.type; | ||
} | ||
} |
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,22 @@ | ||
package com.jme3.cubed; | ||
|
||
import com.jme3.asset.AssetManager; | ||
import com.jme3.material.Material; | ||
import com.jme3.material.RenderState.BlendMode; | ||
import com.jme3.texture.Texture; | ||
|
||
/** | ||
* | ||
* @author Carl | ||
*/ | ||
public class BlockMaterial extends Material { | ||
|
||
public BlockMaterial(AssetManager assetManager, String blockTextureFilePath){ | ||
super(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | ||
Texture texture = assetManager.loadTexture(blockTextureFilePath); | ||
texture.setMagFilter(Texture.MagFilter.Nearest); | ||
texture.setMinFilter(Texture.MinFilter.NearestNoMipMaps); | ||
setTexture("ColorMap", texture); | ||
getAdditionalRenderState().setBlendMode(BlendMode.Alpha); | ||
} | ||
} |
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,32 @@ | ||
package com.jme3.cubed; | ||
|
||
import com.jme3.cubed.math.Vector2i; | ||
|
||
public class BlockSkin { | ||
private Vector2i[] textureLocations; | ||
private boolean isTransparent; | ||
|
||
public BlockSkin(Vector2i textureLocation, boolean isTransparent) { | ||
this(new Vector2i[] { textureLocation }, isTransparent); | ||
} | ||
|
||
public BlockSkin(Vector2i[] textureLocations, boolean isTransparent) { | ||
this.textureLocations = textureLocations; | ||
this.isTransparent = isTransparent; | ||
} | ||
|
||
public Vector2i getTextureLocation(Face face) { | ||
return textureLocations[getTextureLocationIndex(face)]; | ||
} | ||
|
||
protected int getTextureLocationIndex(Face face) { | ||
if(textureLocations.length == 6) { | ||
return face.ordinal(); | ||
} | ||
return 0; | ||
} | ||
|
||
public boolean isTransparent(){ | ||
return isTransparent; | ||
} | ||
} |
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,24 @@ | ||
package com.jme3.cubed; | ||
|
||
/** | ||
* | ||
* @author Carl | ||
*/ | ||
public class BlockType { | ||
|
||
public BlockType(byte type, BlockSkin skin) { | ||
this.type = type; | ||
this.skin = skin; | ||
} | ||
|
||
private byte type; | ||
private BlockSkin skin; | ||
|
||
public byte getType() { | ||
return type; | ||
} | ||
|
||
public BlockSkin getSkin() { | ||
return skin; | ||
} | ||
} |
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,136 @@ | ||
package com.jme3.cubed; | ||
|
||
import com.jme3.cubed.math.Vector3i; | ||
import com.jme3.export.JmeExporter; | ||
import com.jme3.export.JmeImporter; | ||
import com.jme3.scene.Geometry; | ||
import com.jme3.scene.Mesh; | ||
import com.jme3.scene.Node; | ||
import java.io.IOException; | ||
|
||
/** | ||
* | ||
* @author Nicholas Minkler <sleaker@gmail.com> | ||
*/ | ||
public class ChunkTerrain extends Node { | ||
|
||
public static final int C_SIZE = 32; // Length of a chunk | ||
public static final int C_BITS = 5; // Number of Bits allowed per chunk 32 >> 5 == 1; | ||
public static final int X_SHIFT = C_BITS; // Bits offset of the X value when packed into an int. | ||
public static final int Y_SHIFT = 10; // Bit offset of the Y value when packed into an int. | ||
public static final int Z_SHIFT = 0; // Bit offset of the Z value when packed into an int. | ||
public static final int MASK = C_SIZE - 1; // Mask is 1 less than the size. | ||
|
||
/** | ||
* Unpacks an int with 5 bits per value into a vector3. | ||
* @param val | ||
* @return Vector3 | ||
*/ | ||
public static Vector3i vectorFromInt555(int val) { | ||
return new Vector3i((val >> X_SHIFT) & MASK, (val >> Y_SHIFT) & MASK, val & MASK); | ||
} | ||
|
||
/** | ||
* unpacks an int with 5 bits per value and stores it in the given Vector3i | ||
* @param val | ||
* @param to | ||
* @return the Vector3i | ||
*/ | ||
public static Vector3i vectorFromInt555(int val, Vector3i to) { | ||
return to.setX((val >> X_SHIFT) & MASK).setY((val >> Y_SHIFT) & MASK).setZ(val & MASK); | ||
} | ||
|
||
private ChunkTerrainControl chunkControl; | ||
private Vector3i location; | ||
private Vector3i blockLocation; | ||
private Geometry meshData; | ||
private boolean needsMeshUpdate = false; | ||
private byte[] blocks; | ||
|
||
ChunkTerrain(ChunkTerrainControl ct, int x, int y, int z) { | ||
this.chunkControl = ct; | ||
this.location = new Vector3i(x, y, z); | ||
this.blockLocation = location.mult(C_SIZE); | ||
this.blocks = new byte[1 << (C_BITS * 3)]; | ||
this.setLocalTranslation(location.toVector3f().mult(C_SIZE)); | ||
} | ||
|
||
protected void update(float tpf) { | ||
if (needsMeshUpdate) { | ||
if (meshData == null) { | ||
meshData = new Geometry("ChunkMesh: " + location.toString()); | ||
this.attachChild(meshData); | ||
meshData.setMaterial(chunkControl.getMaterial()); | ||
} | ||
Mesh mesh = chunkControl.getMesher().generateMesh(this); | ||
if (mesh != null) { | ||
meshData.setMesh(mesh); | ||
} else { | ||
this.detachChild(meshData); | ||
} | ||
needsMeshUpdate = false; | ||
} | ||
} | ||
|
||
public byte[] getBlocks() { | ||
return blocks; | ||
} | ||
|
||
public void setBlock(Class<? extends Block> blockClass, Vector3i loc) { | ||
int x = loc.getX(); | ||
int y = loc.getY(); | ||
int z = loc.getZ(); | ||
if (x < C_SIZE && y < C_SIZE && z < C_SIZE && x > -1 && y > -1 && z > -1) { | ||
if (blockClass == null) { | ||
blocks[(x << X_SHIFT) + z + ( y << Y_SHIFT)] = 0; | ||
} else { | ||
blocks[(x << X_SHIFT) + z + ( y << Y_SHIFT)] = MaterialManager.getInstance().getType(blockClass).getType(); | ||
} | ||
needsMeshUpdate = true; | ||
} | ||
} | ||
|
||
public byte getBlock(Vector3i loc) { | ||
int x = loc.getX(); | ||
int y = loc.getY(); | ||
int z = loc.getZ(); | ||
if (isInChunk(loc)) { | ||
return blocks[(x << X_SHIFT) + z + (y << Y_SHIFT)]; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
public boolean isFaceVisible(Vector3i loc, Face face) { | ||
Vector3i vec = loc.add(face.getOffsetVector()); | ||
byte type = 0; | ||
if (!isInChunk(vec)) { | ||
type = chunkControl.getBlock(vec.add(blockLocation)); | ||
} else { | ||
type = getBlock(loc.add(face.getOffsetVector())); | ||
} | ||
return type == 0 || MaterialManager.getInstance().getType(type).getSkin().isTransparent(); | ||
} | ||
|
||
private boolean isInChunk(Vector3i vec) { | ||
return vec.getX() < C_SIZE && vec.getY() < C_SIZE && vec.getZ() < C_SIZE && vec.getX() > -1 && vec.getY() > -1 && vec.getZ() > -1; | ||
} | ||
|
||
public Vector3i getLocation() { | ||
return this.location; | ||
} | ||
|
||
public void scheduleMeshUpdate() { | ||
this.needsMeshUpdate = true; | ||
} | ||
|
||
@Override | ||
public void write(JmeExporter e) throws IOException { | ||
super.write(e); | ||
} | ||
|
||
@Override | ||
public void read(JmeImporter e) throws IOException { | ||
super.read(e); | ||
} | ||
} |
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,109 @@ | ||
package com.jme3.cubed; | ||
|
||
import com.jme3.cubed.render.VoxelMesher; | ||
import com.jme3.cubed.math.Vector3i; | ||
import com.jme3.renderer.RenderManager; | ||
import com.jme3.renderer.ViewPort; | ||
import com.jme3.scene.Node; | ||
import com.jme3.scene.control.AbstractControl; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* | ||
* @author Nicholas Minkler <sleaker@gmail.com> | ||
*/ | ||
public class ChunkTerrainControl extends AbstractControl { | ||
private Node chunkRoot; | ||
private BlockMaterial blockMaterial; | ||
private Map<Vector3i, ChunkTerrain> chunks; | ||
private boolean greedy = false; | ||
private VoxelMesher mesher; | ||
|
||
public ChunkTerrainControl(Node terrainNode, BlockMaterial bm, VoxelMesher mesher) { | ||
chunkRoot = terrainNode; | ||
this.blockMaterial = bm; | ||
this.mesher = mesher; | ||
chunks = new HashMap<>(); | ||
} | ||
|
||
/** | ||
* Sends an update call to all <code>ChunkTerrain</code>'s attached to the the ChunkControl | ||
*/ | ||
@Override | ||
protected void controlUpdate(float tpf) { | ||
for (ChunkTerrain terrain : chunks.values()) { | ||
terrain.update(tpf); | ||
} | ||
} | ||
|
||
@Override | ||
protected void controlRender(RenderManager rm, ViewPort vp) { | ||
|
||
} | ||
|
||
public void setBlock(Class<? extends Block> blockClass, Vector3i loc, boolean gen) { | ||
Vector3i pos = worldToChunkVec(loc); | ||
ChunkTerrain terrain = getTerrain(pos); | ||
if (terrain == null) { | ||
if (gen) { | ||
terrain = new ChunkTerrain(this, pos.getX(), pos.getY(), pos.getZ()); | ||
chunkRoot.attachChild(terrain); | ||
chunks.put(pos, terrain); | ||
} else { | ||
return; | ||
} | ||
} | ||
terrain.setBlock(blockClass, new Vector3i(loc.getX() & ChunkTerrain.MASK, loc.getY() & ChunkTerrain.MASK, loc.getZ() & ChunkTerrain.MASK)); | ||
} | ||
|
||
public BlockMaterial getMaterial() { | ||
return blockMaterial; | ||
} | ||
|
||
/** | ||
* Gets a ChunkTerrain from the given chunk vector | ||
* @param vec | ||
* @return | ||
*/ | ||
public ChunkTerrain getTerrain(Vector3i vec) { | ||
return chunks.get(vec); | ||
} | ||
|
||
/** | ||
* Gets a Chunk from the given Block vector | ||
* @param vec | ||
* @return chunk | ||
*/ | ||
public ChunkTerrain getTerrainLocal(Vector3i vec) { | ||
return getTerrain(worldToChunkVec(vec)); | ||
} | ||
|
||
public byte getBlock(Vector3i vec) { | ||
ChunkTerrain terrain = getTerrainLocal(vec); | ||
if (terrain != null) { | ||
return terrain.getBlock(new Vector3i(vec.getX() & ChunkTerrain.MASK, vec.getY() & ChunkTerrain.MASK, vec.getZ() & ChunkTerrain.MASK)); | ||
} else { | ||
return 0; | ||
} | ||
} | ||
private Vector3i worldToChunkVec(Vector3i vec) { | ||
return new Vector3i(vec.getX() >> ChunkTerrain.C_BITS, vec.getY() >> ChunkTerrain.C_BITS, vec.getZ() >> ChunkTerrain.C_BITS); | ||
} | ||
|
||
public void setMesher(VoxelMesher mesher) { | ||
this.mesher = mesher; | ||
switchMesher(); | ||
} | ||
|
||
public VoxelMesher getMesher() { | ||
return this.mesher; | ||
} | ||
|
||
public void switchMesher() { | ||
this.greedy = !greedy; | ||
for (ChunkTerrain terrain : chunks.values()) { | ||
terrain.scheduleMeshUpdate(); | ||
} | ||
} | ||
} |
Oops, something went wrong.