[Solved] Simple Dynamic Mesh Example with JME3

Hi all - this seems a little goofy but I’m trying to break it down to a simple example - dynamic Lines drawn on the screen. Let’s start here…



Let’s say I have a vertex and index buffer and I’m trying to dynamically update the index buffer with different lines randomly quickly updating on the screen (just so I can see the basic principle!). Here is where I am right now:



[java]

import java.util.Random;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.scene.Geometry;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer;



public class DynamicMesh extends SimpleApplication {

Geometry lineGeometry ;

short indexbuffer[];



@Override

public void simpleInitApp() {

indexbuffer = new short[]{ 1, 2 };

Mesh lineMesh = new Mesh();

lineMesh.setMode(Mesh.Mode.Lines);

lineMesh.setDynamic();

lineMesh.setStreamed();



lineMesh.setBuffer(VertexBuffer.Type.Position, 3, new float[]{ 0, 0, 0, 0, 3, 0, 3, 0, 0, -3, 0, 0});

lineMesh.setBuffer(VertexBuffer.Type.Index, 1, indexbuffer);



lineGeometry = new Geometry(“line”, lineMesh);





Material mat = new Material(assetManager,

“Common/MatDefs/Misc/Unshaded.j3md”); // create a simple material

mat.setColor(“Color”, ColorRGBA.Red); // set color of material to blue



lineGeometry.setMaterial(mat);

rootNode.attachChild(lineGeometry);



rootNode.updateGeometricState();

lineGeometry.updateGeometricState();



}



public void simpleUpdate(float time) {

System.out.println(“called”);

Random r = new Random();

indexbuffer[0] = (short)r.nextInt(4);

indexbuffer[1] = (short)r.nextInt(4);



lineGeometry.getMesh().setBuffer(VertexBuffer.Type.Index, 1, indexbuffer);

lineGeometry.updateGeometricState();



System.out.println(" -> " + indexbuffer[0] + ", " + indexbuffer[1]);



rootNode.updateGeometricState();

}



public static void main(String[] args){

DynamicMesh app = new DynamicMesh();

app.start();

}



[/java]



What am I doing wrong?

I don’t know if you missed anything else but it looks like you don’t create any triangles.

Thanks to everyone on #jme on IRC. Here’s the solve:



[java]

import java.nio.ShortBuffer;

import java.util.Random;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.scene.Geometry;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer;

import com.jme3.scene.VertexBuffer.Type;



public class DynamicMesh extends SimpleApplication {

VertexBuffer indexBuffer;

ShortBuffer indices;



@Override

public void simpleInitApp() {

short[] indexbuffer = new short[]{ 1, 2 };

float[] vertexbuffer = new float[]{ 0, 0, 0, 0, 3, 0, 3, 0, 0, -3, 0, 0};

Mesh lineMesh = new Mesh();

lineMesh.setMode(Mesh.Mode.Lines);

lineMesh.setDynamic();



lineMesh.setBuffer(VertexBuffer.Type.Position, 3, vertexbuffer);

lineMesh.setBuffer(VertexBuffer.Type.Index, 1, indexbuffer);



Geometry lineGeometry = new Geometry(“line”, lineMesh);



Material mat = new Material(assetManager,

“Common/MatDefs/Misc/Unshaded.j3md”); // create a simple material

mat.setColor(“Color”, ColorRGBA.Red); // set color of material to blue



lineGeometry.setMaterial(mat);

rootNode.attachChild(lineGeometry);



rootNode.updateGeometricState();



//THESE are the buffers I need.

indexBuffer = (VertexBuffer)lineGeometry.getMesh().getBuffer(Type.Index);

indices = (ShortBuffer)indexBuffer.getData();

}



public void simpleUpdate(float time) {

Random r = new Random();

indices.put(0, (short)r.nextInt(4));

indices.put(1, (short)r.nextInt(4));

indexBuffer.setUpdateNeeded();

}



public static void main(String[] args){

DynamicMesh app = new DynamicMesh();

app.start();

}

}

[/java]



The float/short buffers on the java side aren’t native format so once you set it, they aren’t being watched. You have to get the native buffers from the mesh itself (the vertexbuffer) which isn’t really a vertex - it holds arbitrary data. You can then cast the generic “buffer” to a shortbuffer and use it as such. I then modify these native buffers with the .put method and then tell jme to update their structures. At least this is my interpretation of the solve.



Thanks again all!

1 Like

Just a note. You do not need to call this:

rootNode.updateGeometricState();



But you should call http://hub.jmonkeyengine.org/javadoc/com/jme3/scene/Geometry.html#updateModelBound() after changing the mesh.

1 Like