package de.venjinx.jme3;
import java.util.LinkedList;
import java.util.concurrent.Callable;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer.Type;
import de.venjinx.core.VoxelSurface;
import de.venjinx.core.VoxelChunk;
import de.venjinx.editor.debug.DebugMaterials;
import de.venjinx.jme3.scenegraph.ScenegraphNode;
import de.venjinx.util.Util;
public class VoxelChunkNode extends ScenegraphNode implements Callable<VoxelChunkNode> {
private VoxelChunk voxelChunk;
private Geometry boundGeometry;
private Vector3f min, max;
private LinkedList<Geometry> newGeometries = new LinkedList<>();
private Material material;
private Material lodMat;
private boolean showChunkLODs = false;
private boolean showBound = false;
public VoxelChunkNode(VoxelChunk chunk) {
voxelChunk = chunk;
min = new Vector3f(voxelChunk.getMin().x,
voxelChunk.getMin().y,
voxelChunk.getMin().z);
max = new Vector3f(voxelChunk.getMax().x,
voxelChunk.getMax().y,
voxelChunk.getMax().z);
boundGeometry = Util.createBox(max.subtract(min));
boundGeometry.setLocalTranslation(min);
boundGeometry.setName("Chunk Bound");
boundGeometry.getMesh().setLineWidth(2f);
}
public boolean needsGeneration() {
return voxelChunk.hasNewSurfaces();
}
@Override
public void setMaterial(Material mat) {
material = mat;
switch (voxelChunk.getLOD()) {
case 1:
lodMat = DebugMaterials.lod1Mat;
break;
case 2:
lodMat = DebugMaterials.lod2Mat;
break;
case 3:
lodMat = DebugMaterials.lod3Mat;
break;
case 4:
lodMat = DebugMaterials.lod4Mat;
break;
case 5:
lodMat = DebugMaterials.lod5Mat;
break;
default:
lodMat = DebugMaterials.lod0Mat;
}
for (Spatial s : children)
if (showChunkLODs)
s.setMaterial(lodMat);
// else s.setMaterial(material);
else s.setMaterial(DebugMaterials.getRandomMaterial());
boundGeometry.setMaterial(showChunkLODs == true ? lodMat
: DebugMaterials.boundMat);
}
public Geometry createGeometry(VoxelSurface s) {
Mesh mesh = new Mesh();
mesh.setBuffer(Type.Index, 1, s.getIndexes());
mesh.setBuffer(Type.Position, 3, s.getVertices());
mesh.setBuffer(Type.Normal, 3, s.getNormals());
mesh.setBuffer(Type.Tangent, 4, s.getTangents());
mesh.setBuffer(Type.Binormal, 3, s.getBinormals());
mesh.setBuffer(Type.TexCoord, 2, s.getTexCoords());
mesh.updateBound();
Geometry g = new Geometry("VoxelGeometry", mesh);
return g;
}
public Geometry createGeometry2(VoxelSurface s) {
Mesh mesh = new Mesh();
mesh.setBuffer(Type.Index, 1, s.getIndexes());
mesh.setBuffer(Type.Position, 3, s.getVertices());
mesh.setBuffer(Type.Normal, 3, s.getNormals());
mesh.setBuffer(Type.Tangent, 4, s.getTangents());
mesh.setBuffer(Type.Binormal, 3, s.getBinormals());
mesh.setBuffer(Type.TexCoord, 2, s.getTexCoords());
mesh.updateBound();
Geometry g = new Geometry("VoxelGeometry", mesh);
return g;
}
public void switchGeometries() {
detachAllChildren();
for (Geometry g : newGeometries)
attachChild(g);
if (showBound)
attachChild(boundGeometry);
setMaterial(material);
}
public void showLOD() {
showChunkLODs = !showChunkLODs;
}
public Material getMaterial() {
if (showChunkLODs)
return material;
else return lodMat;
}
public void showBound() {
showBound = !showBound;
if (showBound) {
switch (voxelChunk.getLOD()) {
case 1:
lodMat = DebugMaterials.lod1Mat;
break;
case 2:
lodMat = DebugMaterials.lod2Mat;
break;
case 3:
lodMat = DebugMaterials.lod3Mat;
break;
case 4:
lodMat = DebugMaterials.lod4Mat;
break;
case 5:
lodMat = DebugMaterials.lod5Mat;
break;
default:
lodMat = DebugMaterials.lod0Mat;
}
boundGeometry.setMaterial(lodMat);
attachChild(boundGeometry);
} else detachChild(boundGeometry);
}
public Vector3f getMin() {
return min;
}
public Vector3f getMax() {
return max;
}
@Override
public VoxelChunkNode call() throws Exception {
// LinkedList<VoxelSurface> surfaces = voxelChunk.getSurfaces();
LinkedList<VoxelSurface> surfaces2 = voxelChunk.getSurfaces2();
newGeometries.clear();
// for (VoxelSurface s : surfaces)
// newGeometries.add(createGeometry(s));
for (VoxelSurface s : surfaces2)
newGeometries.add(createGeometry2(s));
return this;
}
}