I've put together this marching cube object.
if anyone has any advice on how i can optimise the load time i would be grateful
package Main.Map;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.TriMesh;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.geom.BufferUtils;
import java.net.URL;
import java.util.LinkedList;
/**
*
* @author Dean Kinns
*
* This creates a 10x10x10 area of marching cubes at location
* locin from an 11x11x11 input array
*/
public class BoxMap extends Node {
private int[] loc;
private float[][][] map;
private String[][][] tex;
/**
*
* creates new box map
*
* locin = int[3] location of area
*
* map = float[11][11][11] density of area map
*
* tex = String[11][11][11] URL to texture for nodes
* */
public BoxMap(int[] locin, float[][][] mapinput, String[][][] textures) {
loc = locin;
this.setName("area" + loc[0] + "," + loc[1] + "," + loc[2]);
map = mapinput;
tex = textures;
makeArea();
}
public void makeArea() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
float[] val = {map[i][j][k], map[i + 1][j][k],
map[i + 1][j][k + 1], map[i][j][k + 1],
map[i][j + 1][k], map[i + 1][j + 1][k],
map[i + 1][j + 1][k + 1], map[i][j + 1][k + 1]
};
Vector3f[] loc1 = {
new Vector3f(loc[0] + i + 0, loc[1] + j + 0, loc[2] + k + 0), new Vector3f(loc[0] + i + 1, loc[1] + j + 0, loc[2] + k + 0),
new Vector3f(loc[0] + i + 1, loc[1] + j + 0, loc[2] + k + 1), new Vector3f(loc[0] + i + 0, loc[1] + j + 0, loc[2] + k + 1),
new Vector3f(loc[0] + i + 0, loc[1] + j + 1, loc[2] + k + 0), new Vector3f(loc[0] + i + 1, loc[1] + j + 1, loc[2] + k + 0),
new Vector3f(loc[0] + i + 1, loc[1] + j + 1, loc[2] + k + 1), new Vector3f(loc[0] + i + 0, loc[1] + j + 1, loc[2] + k + 1)
};
GridCell cell = new GridCell(val, loc1);
GTri[] output = Polygonise(cell, .5f);
if (output != null) {
Node n = new Node("Node " + loc[0] + i + "," + loc[1] + j + "," + loc[2] + k);
for (int trinum = 0; trinum < output.length; trinum++) {
TriMesh t = new TriMesh("loc" + output[trinum].p[0].x + "," + output[trinum].p[1].y + "," + output[trinum].p[2].z,
BufferUtils.createFloatBuffer(output[trinum].p), BufferUtils.createFloatBuffer(normals), null,
BufferUtils.createFloatBuffer(texCoords), BufferUtils.createIntBuffer(indexes));
n.attachChild(t);
}
URL monkeyLoc = BoxMap.class.getClassLoader().getResource(tex[i][j][k]);
TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
Texture t = TextureManager.loadTexture(monkeyLoc, Texture.MM_LINEAR, Texture.FM_LINEAR);
ts.setTexture(t);
n.setRenderState(ts);
this.attachChild(n);
}
}
}
}
this.setModelBound(new BoundingBox());
this.updateModelBound();
}
private class GridCell {
public float[] val;
public Vector3f[] p;
public GridCell(float[] valIn, Vector3f[] locIn) {
val = valIn;
p = locIn;
}
}
private class GTri {
public Vector3f[] p;
public GTri(Vector3f[] locIn) {
p = locIn;
}
}
/*
Given a grid cell and an isolevel, calculate the triangular
facets required to represent the isosurface through the cell.
Return the array "triangles". null will be returned if the grid
cell is either totally above of totally below the isolevel.
*/
GTri[] Polygonise(GridCell grid, float isolevel) {
int i, ntriang;
int cubeindex;
Vector3f[] vertlist = new Vector3f[12];
/*
Determine the index into the edge table which
tells us which vertices are inside of the surface
*/
cubeindex = 0;
if (grid.val[0] < isolevel) {
cubeindex |= 1;
}
if (grid.val[1] < isolevel) {
cubeindex |= 2;
}
if (grid.val[2] < isolevel) {
cubeindex |= 4;
}
if (grid.val[3] < isolevel) {
cubeindex |= 8;
}
if (grid.val[4] < isolevel) {
cubeindex |= 16;
}
if (grid.val[5] < isolevel) {
cubeindex |= 32;
}
if (grid.val[6] < isolevel) {
cubeindex |= 64;
}
if (grid.val[7] < isolevel) {
cubeindex |= 128;
}
/* Cube is entirely in/out of the surface */
if (edgeTable[cubeindex] == 0) {
return null;
}
/* Find the vertices where the surface intersects the cube */
if ((edgeTable[cubeindex] & 1) == 1) {
vertlist[0] =
VertexInterp(isolevel, grid.p[0], grid.p[1], grid.val[0], grid.val[1]);
}
if ((edgeTable[cubeindex] & 2) == 2) {
vertlist[1] =
VertexInterp(isolevel, grid.p[1], grid.p[2], grid.val[1], grid.val[2]);
}
if ((edgeTable[cubeindex] & 4) == 4) {
vertlist[2] =
VertexInterp(isolevel, grid.p[2], grid.p[3], grid.val[2], grid.val[3]);
}
if ((edgeTable[cubeindex] & 8) == 8) {
vertlist[3] =
VertexInterp(isolevel, grid.p[3], grid.p[0], grid.val[3], grid.val[0]);
}
if ((edgeTable[cubeindex] & 16) == 16) {
vertlist[4] =
VertexInterp(isolevel, grid.p[4], grid.p[5], grid.val[4], grid.val[5]);
}
if ((edgeTable[cubeindex] & 32) == 32) {
vertlist[5] =
VertexInterp(isolevel, grid.p[5], grid.p[6], grid.val[5], grid.val[6]);
}
if ((edgeTable[cubeindex] & 64) == 64) {
vertlist[6] =
VertexInterp(isolevel, grid.p[6], grid.p[7], grid.val[6], grid.val[7]);
}
if ((edgeTable[cubeindex] & 128) == 128) {
vertlist[7] =
VertexInterp(isolevel, grid.p[7], grid.p[4], grid.val[7], grid.val[4]);
}
if ((edgeTable[cubeindex] & 256) == 256) {
vertlist[8] =
VertexInterp(isolevel, grid.p[0], grid.p[4], grid.val[0], grid.val[4]);
}
if ((edgeTable[cubeindex] & 512) == 512) {
vertlist[9] =
VertexInterp(isolevel, grid.p[1], grid.p[5], grid.val[1], grid.val[5]);
}
if ((edgeTable[cubeindex] & 1024) == 1024) {
vertlist[10] =
VertexInterp(isolevel, grid.p[2], grid.p[6], grid.val[2], grid.val[6]);
}
if ((edgeTable[cubeindex] & 2048) == 2048) {
vertlist[11] =
VertexInterp(isolevel, grid.p[3], grid.p[7], grid.val[3], grid.val[7]);
}
/* Create the triangle */
ntriang = 0;
LinkedList<GTri> t = new LinkedList<GTri>();
for (i = 0; triTable[cubeindex][i] != -1; i += 3) {
Vector3f[] points = {vertlist[triTable[cubeindex][i]], vertlist[triTable[cubeindex][i + 1]], vertlist[triTable[cubeindex][i + 2]]};
GTri test = new GTri(points);
t.add(test);
ntriang++;
}
GTri[] triangles = new GTri[ntriang];
for (i = 0; i < t.size(); i++) {
triangles[i] = t.get(i);
}
return triangles;
}
/*
Linearly interpolate the position where an isosurface cuts
an edge between two vertices, each with their own scalar value
*/
private Vector3f VertexInterp(float isolevel, Vector3f p1, Vector3f p2, float valp1, float valp2) {
float mu;
Vector3f p = new Vector3f();
if (Math.abs(isolevel - valp1) < 0.00001) {
return (p1);
}
if (Math.abs(isolevel - valp2) < 0.00001) {
return (p2);
}
if (Math.abs(valp1 - valp2) < 0.00001) {
return (p1);
}
mu = (isolevel - valp1) / (valp2 - valp1);
p.x = p1.x + mu * (p2.x - p1.x);
p.y = p1.y + mu * (p2.y - p1.y);
p.z = p1.z + mu * (p2.z - p1.z);
return (p);
}
}