Hey,
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.
[java]
package mygame;
import com.jme3.app.SimpleApplication;
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() {
super();
create(5, 5);
}
public void modify()
{
create(5, 5);
}
private void create(int iWidth, int iHeight) {
//clean
if(null != m_rVB)
{
clearBuffer(VertexBuffer.Type.Position);
m_rVB.clear();
m_rVB = null;
}
if(null != m_rIB)
{
clearBuffer(VertexBuffer.Type.Index);
m_rIB.clear();
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(iTotal233);
//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+x0.05f, seed+(yiVert)0.05f, 0) * 10.0f;
float fX = x;
float fY = y;
f = ImprovedNoise.noise(seed+(fX0.1f), seed+(fY0.1f), 0) * 2.0f;
m_rVB .put(x + sm_kaafVerts[iVert][0]) // x
.put(y + sm_kaafVerts[iVert][1]) // y
.put(f);// z
m_rIB.put((short)iInd++);
}
}
}
// flip
m_rVB.flip();
m_rIB.flip();
setBuffer(VertexBuffer.Type.Position, 3, m_rVB);
setBuffer(VertexBuffer.Type.Index, 1, m_rIB);
setMode(Mode.Triangles);
setDynamic();
updateCounts();
updateBound();
}
}
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();
app.setShowSettings(false);
app.start();
}
@Override
public void simpleInitApp() {
cam.setLocation(new Vector3f(0, 0, -10));
cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
flyCam.setMoveSpeed(15.0f);
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);
m_rCustomMesh_Geo.setMaterial(rMat);
m_rPickNode.attachChild(m_rCustomMesh_Geo);
rootNode.attachChild(m_rPickNode);
// 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);
rMat2.getAdditionalRenderState().setWireframe(true);
m_rDbgSphere.setMaterial(rMat2);
rootNode.attachChild(m_rDbgSphere);
initInput();
}
@Override
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())
{
m_rDbgSphere.setLocalTranslation(rResults.getClosestCollision().getContactPoint());
}
}
@Override
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)
{
((CustomMesh)m_rCustomMesh).modify();
m_rCustomMesh_Geo.updateModelBound();
}
}
}
[/java]
I’m most likely forgetting to do something as usual
Thanks to anyone who can help me out.