Modified mesh with node.collideWith()


I have a slight issue with the collideWith() function on a node with a mesh being modified and a ray object.

The collideWith() seems to collide with the old mesh that was there after I modify it.

For instance I have a few triangles that are flat, the CollisionResult’s contact point is correct, however, when I modify that mesh and move a few vertices, it doesn’t collide with the new visual, instead it collides with those flat triangles.

Here is a simple test case that i wrote. It puts a small sphere at the contact point. Each press of the Spacebar changes the triangles using the perlin noise.


package mygame;


import com.jme3.collision.CollisionResults;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Ray;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.Mesh;

import com.jme3.scene.Node;

import com.jme3.scene.VertexBuffer;

import com.jme3.scene.shape.Sphere;

import com.jme3.terrain.noise.basis.ImprovedNoise;

import com.jme3.util.BufferUtils;

import java.nio.FloatBuffer;

import java.nio.ShortBuffer;


  • test
  • @author normenhansen


    public class Main extends SimpleApplication implements ActionListener {

    private static class CustomMesh extends Mesh {

    private static final float[][] sm_kaafVerts =


    {0, 0, 0}, {0, 1, 0}, {1, 0, 0}, // tri 1

    {1, 0, 0}, {0, 1, 0}, {1, 1, 0}, // tri 2


    private FloatBuffer m_rVB;

    private ShortBuffer m_rIB;

    private int m_iWidth;

    private int m_iHeight;

    public CustomMesh() {


    create(5, 5);


    public void modify()


    create(5, 5);


    private void create(int iWidth, int iHeight) {


    if(null != m_rVB)




    m_rVB = null;


    if(null != m_rIB)




    m_rIB = null;


    m_iWidth = iWidth;

    m_iHeight = iHeight;

    // size

    int iTotal = iWidth * iHeight;

    // create buffers

    //num blocks * two tris per block * three verts per tri * three floats per vert

    m_rVB = BufferUtils.createFloatBuffer(iTotal

    //num blocks * two tris per block * three verts per tri * one index per vert

    m_rIB = BufferUtils.createShortBuffer(iTotal231);


    // init data //


    int iInd = 0;

    int seed = (int)(FastMath.rand.nextFloat() * 20);

    for(int x = 0; x < iWidth; ++x)


    for(int y = 0; y < iHeight; ++y)


    for(int iVert = 0; iVert < 6; ++iVert)


    float f = 0.0f;//ImprovedNoise.noise(seed+x
    0.05f, seed+(yiVert)0.05f, 0) * 10.0f;

    float fX = x;

    float fY = y;

    f = ImprovedNoise.noise(seed+(fX
    0.1f), seed+(fY
    0.1f), 0) * 2.0f;

    m_rVB .put(x + sm_kaafVerts[iVert][0]) // x

    .put(y + sm_kaafVerts[iVert][1]) // y

    .put(f);// z





    // flip



    setBuffer(VertexBuffer.Type.Position, 3, m_rVB);

    setBuffer(VertexBuffer.Type.Index, 1, m_rIB);







    public Node m_rPickNode;

    public Geometry m_rDbgSphere;

    public Geometry m_rCustomMesh_Geo;

    public CustomMesh m_rCustomMesh;

    public static void main(String[] args) {

    Main app = new Main();





    public void simpleInitApp() {

    cam.setLocation(new Vector3f(0, 0, -10));

    cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);


    m_rPickNode = new Node(“NodeBeingPicked”);

    // custom mesh - changes

    m_rCustomMesh = new CustomMesh();

    m_rCustomMesh_Geo = new Geometry(“CustomMesh”, m_rCustomMesh);

    Material rMat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

    rMat.setColor(“Color”, ColorRGBA.Red);




    // Debug sphere - used to show the picked point

    m_rDbgSphere = new Geometry(“DbgSphere”, new Sphere(5, 5, 0.25f));

    Material rMat2 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

    rMat2.setColor(“Color”, ColorRGBA.Green);







    public void simpleUpdate(float tpf) {

    Ray rRay = new Ray(cam.getLocation(), cam.getDirection());

    CollisionResults rResults = new CollisionResults();

    m_rPickNode.collideWith(rRay, rResults);

    if(0 != rResults.size())






    public void simpleRender(RenderManager rm) {

    //TODO: add render code


    private void initInput() {

    inputManager.addMapping(“mod”, new KeyTrigger(KeyInput.KEY_SPACE));

    inputManager.addListener(this, “mod”);


    public void onAction(String name, boolean isPressed, float tpf) {

    if(name.equals(“mod”) && isPressed)








    I’m most likely forgetting to do something as usual :slight_smile:

    Thanks to anyone who can help me out.

You have to call mesh.updateCollisionData() (or smething like that) after modifying the mesh.

Ahh I see, the collideWith calls createCollisionData() only if the collision hasn’t been created, so I needed to call the createCollisionData() after I had modified the mesh.

If you remove the updateModelBound() call on the geometry after modifying it doesn’t work again. So that has to stay, however, it’s giving me a warning and saying I shouldn’t need to call this, is there a better way of doing this? or is it one of those things you just have to do?

@normen Thanks for the help

Its ok to call this for now, it will probably set the flag fro refresh by itself at some point though.