Marching Tetrahedrons

Hi,

I’m trying to port a JME2 “engine” to JME3, however I get a memory access violation. The engine is for marching tetrahedrons and its original version is here: https://wiki.jmonkeyengine.org/legacy/doku.php/jme2:rendering_scalar_fields?s[]=marching&s[]=cubes



I changed:


TriangleBatch batch = mesh.getBatch(0);
batch.setIndexBuffer(BufferUtils.createIntBuffer(triangles.toNativeArray()));

batch.setVertexBuffer(BufferUtils.createVector3Buffer(vertexList.size()/3));
batch.setNormalBuffer(BufferUtils.createVector3Buffer(vertexList.size()/3));
batch.setVertexCount(vertexList.size()/3);
//batch.getTextureBuffers().set(0, BufferUtils.createVector2Buffer(???));

FloatBuffer vb = batch.getVertexBuffer();
FloatBuffer nb = batch.getNormalBuffer();
for (int i = 0; i < vertexList.size(); i++) {
vb.put(vertexList.get(i));
nb.put(normalList.get(i));
}


to

mesh.setBuffer(Type.Normal, vertexList.size()/3, BufferUtils.createVector3Buffer(vertexList.size()/3));
mesh.setBuffer(Type.Position, vertexList.size()/3, BufferUtils.createVector3Buffer(vertexList.size()/3));

FloatBuffer vb = mesh.getFloatBuffer(Type.Position);
FloatBuffer nb = mesh.getFloatBuffer(Type.Normal);
for (int i = 0; i < vertexList.size(); i++) {
vb.put(vertexList.get(i));
nb.put(normalList.get(i));
}


and the TFloatArrayList to ArrayList etc.

The error
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x062fc11b, pid=4228, tid=4504
#
# JRE version: 6.0_23-b05
# Java VM: Java HotSpot(TM) Client VM (19.0-b09 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [ig4icd32.dll+0x12c11b]
#
# An error report file with more information is saved as:
# C:UsersKajosDocumentsjMonkeyProjectsCitySccapehs_err_pid4228.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

So the crash happens somewhere in the rendering right?

Any help would be great! Or maybe a tip on another voxel based engine?

Greetings,
Kajos

90% sure that this:



[java]mesh.setBuffer(Type.Normal, vertexList.size()/3, BufferUtils.createVector3Buffer(vertexList.size()/3));

mesh.setBuffer(Type.Position, vertexList.size()/3, BufferUtils.createVector3Buffer(vertexList.size()/3));[/java]



Should really be more like this:

[java]mesh.setBuffer(Type.Normal, 3, BufferUtils.createVector3Buffer(vertexList.size()/3));

mesh.setBuffer(Type.Position, 3, BufferUtils.createVector3Buffer(vertexList.size()/3));[/java]

Thanks! That did the trick! However, I still dont get quite the effect that Im after; instead of Tetrahedrons I get triangles or something not quite right.



I’ve never created a mesh without indexes before… so I’m not sure I can help any further. It does look similar to index problems, though.

pspeed said:
I've never created a mesh without indexes before...

Well...is that even possible? Not in jME3 anyway.

@kajos You have to specify the index buffer so the mesh displays correctly
This doc can help
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:custom_meshes

Alternatively, you can use the very same code that I ported to jME3 a while back :stuck_out_tongue:



[java]

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer;

import com.jme3.scene.VertexBuffer.Type;

import com.jme3.util.BufferUtils;

import java.nio.FloatBuffer;

import java.nio.IntBuffer;

import java.util.HashMap;

import java.util.Map;



/**

  • Based on Paul Bourke’s code from “Polygonising a Scalar Field Using Tetrahedrons”
  • http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/

    *
  • @author Daniel Gronau
  • @author Irrisor (replaced array lists by using buffers)
  • @author basixs (replaced creation of objects with global ‘calc’ vectors, for better performance)

    */

    public class ScalarFieldPolygonisator {



    private final ScalarField scalarField;

    private final Vector3f boxSize;

    private final float cubeSize;

    public final float[][][] field;

    private final Vector3f[] cellPoints = new Vector3f[] {

    new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f(),

    new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f()

    };

    private final int[] gridVal = new int[ 8 ];

    private final Map<Edge, Integer> interpol = new HashMap<Edge, Integer>(5000);

    private final Edge tmpEdge = new Edge();

    private final int xSize;

    private final int ySize;

    private final int zSize;

    private FloatBuffer vertexBuffer;

    private FloatBuffer normalBuffer;

    private IntBuffer indexBuffer;

    private FloatBuffer textureBuffer;

    private FloatBuffer colorBuffer;

    //

    // Temporary calc vars

    private final ColorRGBA calcColor = new ColorRGBA();

    private final Vector3f calcVector = new Vector3f();

    private final Vector3f calcVector1 = new Vector3f();

    private final Vector2f calcVector2f = new Vector2f();





    public ScalarFieldPolygonisator(Vector3f boxSize, float cubeSize, final ScalarField field) {

    this.boxSize = boxSize;

    this.cubeSize = cubeSize;

    xSize = (int) FastMath.ceil(2 * boxSize.x / cubeSize);

    ySize = (int) FastMath.ceil(2 * boxSize.y / cubeSize);

    zSize = (int) FastMath.ceil(2 * boxSize.z / cubeSize);

    this.field = new float[xSize + 1][ySize + 1][zSize + 1];

    this.scalarField = field;



    }



    /**
  • Updates all cells with a given iso
  • @param iso

    */

    protected void calculateCells(final float iso) {

    for(int x = 0; x < xSize; x++) {

    for(int y = 0; y < ySize; y++) {

    for(int z = 0; z < zSize; z++) {

    calculateCell(iso, x, y, z);

    }

    }

    }

    }



    /**
  • Updates a given cell with a given iso
  • @param iso cutoff value
  • @param xk
  • @param yk
  • @param zk
  • @return result

    /

    protected int calculateCell(final float iso, final int xk, final int yk, final int zk) {

    int cubeIndex = 0;



    gridVal[0] = field[xk][yk][zk] > iso ? 1 : 0;

    gridVal[1] = field[xk + 1][yk][zk] > iso ? 1 : 0; // go left

    gridVal[2] = field[xk + 1][yk][zk + 1] > iso ? 1 : 0; // go left

    gridVal[3] = field[xk][yk][zk + 1] > iso ? 1 : 0; // go left

    gridVal[4] = field[xk][yk + 1][zk] > iso ? 1 : 0; // go left and up

    gridVal[5] = field[xk + 1][yk + 1][zk] > iso ? 1 : 0; // go left

    gridVal[6] = field[xk + 1][yk + 1][zk + 1] > iso ? 1 : 0; // go left

    gridVal[7] = field[xk][yk + 1][zk + 1] > iso ? 1 : 0; // go left



    for(int i = 0; i < gridVal.length; ++i) {

    cubeIndex |= (gridVal == 1 ? (1 << i) : 0);

    }



    if(cubeIndex == 0 || cubeIndex == 255) {

    return cubeIndex; // 0 = all vertices inside, 255 = all vertices above

    }



    calcVector.x = xk * cubeSize - boxSize.x;

    calcVector.y = yk * cubeSize - boxSize.y;

    calcVector.z = zk * cubeSize - boxSize.z;

    calcVector1.x = calcVector.x + cubeSize;

    calcVector1.y = calcVector.y + cubeSize;

    calcVector1.z = calcVector.z + cubeSize;



    cellPoints[0].set(calcVector.x, calcVector.y, calcVector.z);

    cellPoints[1].set(calcVector1.x, calcVector.y, calcVector.z);

    cellPoints[2].set(calcVector1.x, calcVector.y, calcVector1.z);

    cellPoints[3].set(calcVector.x, calcVector.y, calcVector1.z);

    cellPoints[4].set(calcVector.x, calcVector1.y, calcVector.z);

    cellPoints[5].set(calcVector1.x, calcVector1.y, calcVector.z);

    cellPoints[6].set(calcVector1.x, calcVector1.y, calcVector1.z);

    cellPoints[7].set(calcVector.x, calcVector1.y, calcVector1.z);



    calculateTetra(iso, 0, 4, 7, 6, xk, yk, zk);

    calculateTetra(iso, 0, 4, 6, 5, xk, yk, zk);

    calculateTetra(iso, 0, 2, 6, 3, xk, yk, zk);

    calculateTetra(iso, 0, 1, 6, 2, xk, yk, zk);

    calculateTetra(iso, 0, 3, 6, 7, xk, yk, zk);

    calculateTetra(iso, 0, 1, 5, 6, xk, yk, zk);



    // return the cell triangle bits

    return cubeIndex;

    }



    private void calculateTetra(final float iso, final int v0, final int v1, final int v2, final int v3, final int xk, final int yk, final int zk) {



    final int triindex = gridVal[v0] + (gridVal[v1] * 2) + (gridVal[v2] * 4) + (gridVal[v3] * 8);



    /
    Form the vertices of the triangles for each case */

    switch(triindex) {

    case 0x00: // 0

    case 0x0F: // 255

    break;

    case 0x0E:

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    addIndex(interpolate(iso, v0, v2, xk, yk, zk));

    addIndex(interpolate(iso, v0, v1, xk, yk, zk));

    break;

    case 0x01:

    addIndex(interpolate(iso, v0, v2, xk, yk, zk));

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    addIndex(interpolate(iso, v0, v1, xk, yk, zk));

    break;

    case 0x0D:

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(interpolate(iso, v1, v3, xk, yk, zk));

    addIndex(interpolate(iso, v0, v1, xk, yk, zk));

    break;

    case 0x02:

    addIndex(interpolate(iso, v1, v3, xk, yk, zk));

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(interpolate(iso, v0, v1, xk, yk, zk));

    break;

    case 0x0C: {

    int temp1 = interpolate(iso, v0, v2, xk, yk, zk);

    int temp2 = interpolate(iso, v1, v3, xk, yk, zk);

    addIndex(temp1);

    addIndex(temp2);

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    addIndex(temp1);

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(temp2);

    break;

    }

    case 0x03: {

    int temp1 = interpolate(iso, v0, v2, xk, yk, zk);

    int temp2 = interpolate(iso, v1, v3, xk, yk, zk);

    addIndex(temp2);

    addIndex(temp1);

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(temp1);

    addIndex(temp2);

    break;

    }

    case 0x0B:

    addIndex(interpolate(iso, v2, v3, xk, yk, zk));

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(interpolate(iso, v0, v2, xk, yk, zk));

    break;

    case 0x04:

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(interpolate(iso, v2, v3, xk, yk, zk));

    addIndex(interpolate(iso, v0, v2, xk, yk, zk));

    break;

    case 0x0A: {

    int temp1 = interpolate(iso, v0, v1, xk, yk, zk);

    int temp2 = interpolate(iso, v2, v3, xk, yk, zk);

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    addIndex(temp2);

    addIndex(temp1);

    addIndex(temp2);

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(temp1);

    break;

    }

    case 0x05: {

    int temp1 = interpolate(iso, v0, v1, xk, yk, zk);

    int temp2 = interpolate(iso, v2, v3, xk, yk, zk);

    addIndex(temp2);

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    addIndex(temp1);

    addIndex(interpolate(iso, v1, v2, xk, yk, zk));

    addIndex(temp2);

    addIndex(temp1);

    break;

    }

    case 0x09: {

    int temp1 = interpolate(iso, v0, v1, xk, yk, zk);

    int temp2 = interpolate(iso, v2, v3, xk, yk, zk);

    addIndex(temp2);

    addIndex(interpolate(iso, v1, v3, xk, yk, zk));

    addIndex(temp1);

    addIndex(interpolate(iso, v0, v2, xk, yk, zk));

    addIndex(temp2);

    addIndex(temp1);

    break;

    }

    case 0x06: {

    int temp1 = interpolate(iso, v0, v1, xk, yk, zk);

    int temp2 = interpolate(iso, v2, v3, xk, yk, zk);

    addIndex(interpolate(iso, v1, v3, xk, yk, zk));

    addIndex(temp2);

    addIndex(temp1);

    addIndex(temp2);

    addIndex(interpolate(iso, v0, v2, xk, yk, zk));

    addIndex(temp1);

    break;

    }

    case 0x07:

    addIndex(interpolate(iso, v1, v3, xk, yk, zk));

    addIndex(interpolate(iso, v2, v3, xk, yk, zk));

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    break;

    case 0x08:

    addIndex(interpolate(iso, v2, v3, xk, yk, zk));

    addIndex(interpolate(iso, v1, v3, xk, yk, zk));

    addIndex(interpolate(iso, v0, v3, xk, yk, zk));

    break;

    }

    }



    private int interpolate(float iso, int v1, int v2, int xk, int yk, int zk) {

    if(v1 > v2) {

    final int tmp = v2;

    v2 = v1;

    v1 = tmp;

    }

    switch(v1) {

    default:

    tmpEdge.x1 = xk;

    tmpEdge.y1 = yk;

    tmpEdge.z1 = zk;

    break;

    case 1:

    tmpEdge.x1 = xk + 1;

    tmpEdge.y1 = yk;

    tmpEdge.z1 = zk;

    break;

    case 2:

    tmpEdge.x1 = xk + 1;

    tmpEdge.y1 = yk;

    tmpEdge.z1 = zk + 1;

    break;

    case 3:

    tmpEdge.x1 = xk;

    tmpEdge.y1 = yk;

    tmpEdge.z1 = zk + 1;

    break;

    case 4:

    tmpEdge.x1 = xk;

    tmpEdge.y1 = yk + 1;

    tmpEdge.z1 = zk;

    break;

    case 5:

    tmpEdge.x1 = xk + 1;

    tmpEdge.y1 = yk + 1;

    tmpEdge.z1 = zk;

    break;

    case 6:

    tmpEdge.x1 = xk + 1;

    tmpEdge.y1 = yk + 1;

    tmpEdge.z1 = zk + 1;

    break;

    case 7:

    tmpEdge.x1 = xk;

    tmpEdge.y1 = yk + 1;

    tmpEdge.z1 = zk + 1;

    break;

    }



    switch(v2) {

    default:

    tmpEdge.x2 = xk;

    tmpEdge.y2 = yk;

    tmpEdge.z2 = zk;

    break;

    case 1:

    tmpEdge.x2 = xk + 1;

    tmpEdge.y2 = yk;

    tmpEdge.z2 = zk;

    break;

    case 2:

    tmpEdge.x2 = xk + 1;

    tmpEdge.y2 = yk;

    tmpEdge.z2 = zk + 1;

    break;

    case 3:

    tmpEdge.x2 = xk;

    tmpEdge.y2 = yk;

    tmpEdge.z2 = zk + 1;

    break;

    case 4:

    tmpEdge.x2 = xk;

    tmpEdge.y2 = yk + 1;

    tmpEdge.z2 = zk;

    break;

    case 5:

    tmpEdge.x2 = xk + 1;

    tmpEdge.y2 = yk + 1;

    tmpEdge.z2 = zk;

    break;

    case 6:

    tmpEdge.x2 = xk + 1;

    tmpEdge.y2 = yk + 1;

    tmpEdge.z2 = zk + 1;

    break;

    case 7:

    tmpEdge.x2 = xk;

    tmpEdge.y2 = yk + 1;

    tmpEdge.z2 = zk + 1;

    break;

    }



    final Integer index = interpol.get(tmpEdge);

    if(index != null) {

    return index;

    }

    float ratio = 0.5f;

    final float value1 = tmpEdge.getValue1(this);

    final float value2 = tmpEdge.getValue2(this);

    if(value1 != value2) {

    ratio = (value1 - iso) / (value1 - value2);

    }



    final int currentVertexIndex = vertexBuffer.position() / 3;



    calcVector1.set(cellPoints[v2].mult(ratio));

    calcVector.set(cellPoints[v1]).multLocal(1 - ratio).addLocal(calcVector1);

    addVertex(calcVector.x, calcVector.y, calcVector.z);



    scalarField.normal(calcVector, calcVector1);

    addNormal(calcVector1.x, calcVector1.y, calcVector1.z);



    scalarField.textureCoords(calcVector1, calcVector2f);

    addTextureCoord(calcVector2f.x, calcVector2f.y);



    scalarField.color(calcVector, calcColor);

    addColor(calcColor.r, calcColor.g, calcColor.b, calcColor.a);



    interpol.put(new Edge(tmpEdge), currentVertexIndex);



    return currentVertexIndex;

    }



    public void calculate(Mesh mesh, float iso) {

    precalc(mesh);



    clearField(); // tmp



    populateFieldArray(scalarField); // tmp



    calculateCells(iso); // tmp



    postcalc(mesh);

    }



    public void precalc(Mesh mesh) {

    vertexBuffer = mesh.getFloatBuffer(Type.Position);

    if(vertexBuffer == null) {

    vertexBuffer = BufferUtils.createFloatBuffer(16000 * 3);

    } else {

    vertexBuffer.clear();

    }



    normalBuffer = mesh.getFloatBuffer(Type.Normal);

    if(normalBuffer == null) {

    normalBuffer = BufferUtils.createFloatBuffer(16000 * 3);

    } else {

    normalBuffer.clear();

    }



    colorBuffer = mesh.getFloatBuffer(Type.Color);

    if(colorBuffer == null) {

    colorBuffer = BufferUtils.createFloatBuffer(16000 * 4);

    } else {

    colorBuffer.clear();

    }



    // final TexCoords texCoords = mesh.getTextureCoords(0);

    // if(texCoords != null) {

    // textureBuffer = texCoords.coords;

    // } else {

    // textureBuffer = null;

    // }

    textureBuffer = mesh.getFloatBuffer(Type.TexCoord);

    if(textureBuffer == null) {

    textureBuffer = BufferUtils.createFloatBuffer(16000 * 2);

    } else {

    textureBuffer.clear();

    }



    VertexBuffer vb = mesh.getBuffer(Type.Index);

    if(vb != null) {

    indexBuffer = (IntBuffer) vb.getData();

    } else {

    indexBuffer = null;

    }

    if(indexBuffer == null) {

    indexBuffer = BufferUtils.createIntBuffer(16000 * 1);

    } else {

    indexBuffer.clear();

    }

    }



    public void postcalc(Mesh mesh) {

    indexBuffer.flip();

    mesh.clearBuffer(Type.Index);

    mesh.setBuffer(Type.Index, 1, indexBuffer);

    vertexBuffer.flip();

    mesh.clearBuffer(Type.Position);

    mesh.setBuffer(Type.Position, 3, vertexBuffer);

    normalBuffer.flip();

    mesh.clearBuffer(Type.Normal);

    mesh.setBuffer(Type.Normal, 3, normalBuffer);

    colorBuffer.flip();

    mesh.clearBuffer(Type.Color);

    mesh.setBuffer(Type.Color, 4, colorBuffer);



    // mesh.setTriangleCount(indexBuffer.limit() / 3);

    // mesh.setVertexCount(vertexBuffer.limit() / 3);

    mesh.updateCounts();

    mesh.updateBound();



    textureBuffer.flip();

    mesh.clearBuffer(Type.TexCoord);

    mesh.setBuffer(Type.TexCoord, 2, textureBuffer);

    // mesh.setTextureCoords(new TexCoords(textureBuffer));

    }



    protected void clearField() {

    interpol.clear();



    for(int x = 0; x < xSize; x++) {

    for(int y = 0; y < ySize; y++) {

    for(int z = 0; z < zSize; z++) {

    field[x][y][z] = 0;

    }

    }

    }

    }



    protected void populateFieldArray(ScalarField field) {

    for(int x = 0; x < xSize; x++) {

    for(int y = 0; y < ySize; y++) {

    for(int z = 0; z < zSize; z++) {

    gridToWorld(x, y, z, calcVector);

    this.field[x][y][z] = field.weightAtPoint(calcVector);

    }

    }

    }

    }



    protected void gridToWorld(final int x, final int y, final int z, final Vector3f store) {

    store.setX(x * cubeSize - boxSize.x);

    store.setY(y * cubeSize - boxSize.y);

    store.setZ(z * cubeSize - boxSize.z);

    }



    protected void worldToGrid(final Vector3f world, final int[] store) {

    worldToGrid(world.getX(), world.getY(), world.getZ(), store);

    }



    protected void worldToGrid(final float x, final float y, final float z, final int[] store) {

    store[0] = new Float((x + boxSize.x) / cubeSize + 0.5f).intValue();

    store[1] = new Float((y + boxSize.y) / cubeSize + 0.5f).intValue();

    store[2] = new Float((z + boxSize.z) / cubeSize + 0.5f).intValue();

    }



    private void addIndex(int index) {

    indexBuffer = enlargeIfNeeded(indexBuffer);

    indexBuffer.put(index);

    }



    private void addVertex(float x, float y, float z) {

    vertexBuffer = enlargeIfNeeded(vertexBuffer);

    vertexBuffer.put(x).put(y).put(z);

    }



    private void addNormal(float x, float y, float z) {

    normalBuffer = enlargeIfNeeded(normalBuffer);

    normalBuffer.put(x).put(y).put(z);

    }



    private void addColor(float r, float g, float b, float a) {

    colorBuffer = enlargeIfNeeded(colorBuffer);

    colorBuffer.put®.put(g).put(b).put(a);

    }



    private void addTextureCoord(float x, float y) {

    textureBuffer = enlargeIfNeeded(textureBuffer);

    textureBuffer.put(x).put(y);

    }



    private IntBuffer enlargeIfNeeded(IntBuffer buffer) {

    // System.out.println("Enlarging");

    if(buffer.capacity() == buffer.position()) {

    final IntBuffer oldBuffer = buffer;

    buffer = BufferUtils.createIntBuffer(oldBuffer.capacity() * 2);

    oldBuffer.flip();

    buffer.put(oldBuffer);

    }

    return buffer;

    }



    private FloatBuffer enlargeIfNeeded(FloatBuffer buffer) {

    // System.out.println("Enlarging");

    if(buffer.capacity() < buffer.position() + 4) {

    final FloatBuffer oldBuffer = buffer;

    buffer = BufferUtils.createFloatBuffer(oldBuffer.capacity() * 2);

    oldBuffer.flip();

    buffer.put(oldBuffer);

    }

    return buffer;

    }



    static class Edge {



    int x1, y1, z1, x2, y2, z2;



    private Edge() { }



    public Edge(Edge e) {

    x1 = e.x1;

    y1 = e.y1;

    z1 = e.z1;

    x2 = e.x2;

    y2 = e.y2;

    z2 = e.z2;

    }



    @Override

    public int hashCode() {

    int hash = 3;

    hash = 59 * hash + this.x1;

    hash = 61 * hash + this.y1;

    hash = 67 * hash + this.z1;

    hash = 71 * hash + this.x2;

    hash = 73 * hash + this.y2;

    hash = 79 * hash + this.z2;

    return hash;

    }



    @Override

    public boolean equals(Object o) {

    if(o instanceof Edge) {

    Edge e = (Edge) o;

    return x1 == e.x1 && y1 == e.y1 && z1 == e.z1 && x2 == e.x2 && y2 == e.y2 && z2 == e.z2;

    }

    return false;

    }



    public float getValue1(ScalarFieldPolygonisator t) {

    return t.field[x1][y1][z1];

    }



    public float getValue2(ScalarFieldPolygonisator t) {

    return t.field[x2][y2][z2];

    }

    }



    }

    [/java]
1 Like

Cool, thanks, could you maybe upload the src in a rar? I get some serious parse errors.



EDIT: Nvm, found it. Its called cave3d for jme.

Did anyone do true voxels already (not polygonal ones) or is anybody experienced with that? Im about to read a paper on it, but is it possible at all in jme? I’m looking for an effect like voxelstein’s.

something like that?

http://hub.jmonkeyengine.org/groups/free-announcements/forum/topic/simple-voxel-engine-starter-kit/#post-126836

Ha, yeah, something like that, but not polygonal, but 100% voxels (yummi).