I'm building a visualizer using some custom data that I am converting into a TriMesh object. However, if I add the TriMesh to the root node, nothing shows up. If I first export and immediately import the mesh, it shows up beautifully as expected. Thanks in advance for any help!
If you comment out the EXPORT/IMPORT block in the code, I get a JVM crash:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x031f9e38, pid=5556, tid=3912
#
# JRE version: 6.0_14-b08
# Java VM: Java HotSpot(TM) Client VM (14.0-b16 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [ig4icd32.dll+0x49e38]
#
# 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.
#
The Java frames from the log indicates the following:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.lwjgl.opengl.GL11.nglDrawElements(IIILjava/nio/Buffer;IJ)V+0
j org.lwjgl.opengl.GL11.glDrawElements(ILjava/nio/IntBuffer;)V+38
j com.jme.renderer.lwjgl.LWJGLRenderer.draw(Lcom/jme/scene/TriMesh;)V+202
j com.jme.scene.TriMesh.draw(Lcom/jme/renderer/Renderer;)V+23
j com.jme.scene.Spatial.onDraw(Lcom/jme/renderer/Renderer;)V+120
j com.jme.scene.Node.draw(Lcom/jme/renderer/Renderer;)V+44
j com.jme.scene.Spatial.onDraw(Lcom/jme/renderer/Renderer;)V+120
j com.jme.renderer.lwjgl.LWJGLRenderer.draw(Lcom/jme/scene/Spatial;)V+20
j com.jme.app.SimpleGame.render(F)V+18
j com.jme.app.BaseGame.start()V+46
j Test.main([Ljava/lang/String;)V+9
v ~StubRoutines::call_stub
My code is as follows:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.scene.TexCoords;
import com.jme.scene.TriMesh;
import com.jme.util.export.xml.XMLExporter;
import com.jme.util.export.xml.XMLImporter;
public class Test extends SimpleGame {
@Override
protected void simpleInitGame() {
int width = 10;
int length = 10;
int meshSize = width * length;
float[] vertices = new float[3 * meshSize];
/*
* calculate and assign vertex locations here. The result is currently a
* grid of points with varying heights. I'm not using normal terrain
* rendering for texture flexibility and the fact that it may not always
* be able to be reduced to a height field in the future.
*
* For this example, I have just made a very simple mesh calculation
*/
for (int zi = 0; zi < length; zi++) {
for (int xi = 0; xi < width; xi++) {
int vertexIndex = zi * width * 3 + xi * 3;
vertices[vertexIndex] = (float) xi;
vertices[vertexIndex + 1] = (float) (xi - zi) / (float) 2
* (float) Math.random();
vertices[vertexIndex + 2] = (float) zi;
}
}
// Create index buffer to store the mesh faces
ByteBuffer bb = ByteBuffer.allocateDirect((width - 1) * (length - 1)
* 2 * 12);
IntBuffer indices = bb.asIntBuffer();
for (int zi = 0; zi < length - 1; zi++) {
for (int xi = 0; xi < width - 1; xi++) {
// triangle 1 - half of quad
indices.put(zi * width + xi);
indices.put((zi + 1) * width + xi);
indices.put((zi + 1) * width + (xi + 1));
// triangle 2 - the other half of the quad
indices.put((zi + 1) * width + (xi + 1));
indices.put(zi * width + (xi + 1));
indices.put(zi * width + xi);
}
}
indices.flip();
// Put vertices into a direct bytebuffer
bb = ByteBuffer.allocateDirect(meshSize * 12);
for (int zi = 0; zi < length; zi++) {
for (int xi = 0; xi < width; xi++) {
int base = zi * width * 3 + xi * 3;
bb.putFloat(vertices[base]);
bb.putFloat(vertices[base + 1]);
bb.putFloat(vertices[base + 2]);
}
}
bb.flip();
FloatBuffer vertBuffer = bb.asFloatBuffer();
bb = ByteBuffer.allocateDirect(meshSize * 12);
FloatBuffer normals = bb.asFloatBuffer();
// just point the normals up for now
for (int zi = 0; zi < length; zi++) {
for (int xi = 0; xi < width; xi++) {
normals.put(0);
normals.put(1);
normals.put(0);
}
}
normals.flip();
// Assign empty tex coords for now
float[] texCoordsArray = new float[meshSize * 2];
TexCoords texCoords = TexCoords.makeNew(texCoordsArray);
texCoords.perVert = 2;
//Create tri mesh
TriMesh triMesh = new TriMesh("GeneratedTriMesh", vertBuffer, normals,
null, texCoords, indices);
// BEGIN EXPORT/IMPORT BLOCK
try {
XMLExporter.getInstance().save(triMesh, new File("meshOutput.xml"));
triMesh = (TriMesh) XMLImporter.getInstance().load(
new FileInputStream("meshOutput.xml"));
triMesh.setModelBound(new BoundingBox());
triMesh.updateModelBound();
} catch (IOException e) {
e.printStackTrace();
}
// END EXPORT/IMPORT BLOCK
rootNode.attachChild(triMesh);
}
/**
* @param args
*/
public static void main(String[] args) {
Test test = new Test();
test.start();
}
}