I’m having a problem doing collision detection with shared nodes.
I have tryed to use the code from posts in the forums (see links below), but when i use them they only detect collision for a single shared node. If I place normal Node objects in the scene, the code works like it should.
Does anyone know how I could alter one of these examples to work with SharedNode? I know its right in front of my face, but I just cant see it.
http://www.jmonkeyengine.com/jmeforum/index.php?topic=4031.0
http://www.jmonkeyengine.com/jmeforum/index.php?topic=4036.0
Thanks for any help that can be provided in pointing me in the right direction.
Can you give a little more information? I'm currently working on the collision system for our game and have many shared nodes and collision with a non-shared node. Are you saying shared node -> shared node collisions don't work? I'll make sure I take care of it while working on the system.
Here is my code for the building of the shared nodes (trying to make trees at the moment):
private Node baseTreeNode;
public void buildTrees()
{
//build node
Node treeNode = new Node("trees");
float[] x = new float[30];
float[] z = new float[30];
float treeMinHeight;
Random generator = new Random();
for (int cnt=0; cnt < x.length; cnt++)
{
x[cnt] = generator.nextInt(1500) + 1;
}
for (int cnt=0; cnt < z.length; cnt++)
{
z[cnt] = generator.nextInt(1500) + 1;
}
// Point to a URL of my model
URL treeModel=WorldData.class.getClassLoader().getResource("testgame/trees/Tree2.obj");
URL modelTextureDir=WorldData.class.getClassLoader().getResource("testgame/trees/");
// Create something to convert .obj format to .jme
FormatConverter converter=new ObjToJme();
// Point the converter to where it will find the .mtl file from
converter.setProperty("mtllib",treeModel);
// This byte array will hold my .jme file
ByteArrayOutputStream BO=new ByteArrayOutputStream();
try
{
//TextureKey.setOverridingLocation(new URL("file:.\Trees\"));
TextureKey.setOverridingLocation(modelTextureDir);
// Use the format converter to convert .obj to .jme
converter.convert(treeModel.openStream(), BO);
baseTreeNode=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
baseTreeNode.setModelBound(new BoundingBox());
baseTreeNode.updateModelBound();
for (int i = 0; i < x.length; i++)
{
//make shared node
SharedNode st = new SharedNode("Share" + i, baseTreeNode);
//get the terrain height at location of tree
treeMinHeight = terrain.getHeight(x[i],z[i]);
//place the tree
st.setLocalTranslation(new Vector3f(x[i],treeMinHeight, z[i]));
//attach list
treeNode.attachChild(st);
}
//tryed updating both collision trees
//treeNode.updateCollisionTree();
baseTreeNode.updateCollisionTree();
treeList.add(treeNode);
}
catch (IOException e)
{ // Just in case anything happens
System.out.println("Damn exceptions!" + e);
e.printStackTrace();
System.exit(0);
}
}
Code inside my update:
public void update(float tpf) {
if (pause)
return;
//store last location
prevLoc.set(player.getLocalTranslation());
// Update the InputHandler
input.update(tpf);
delta.set(player.getLocalTranslation().subtract(prevLoc)); // <- delta is another temp vector, how much we moved
checkForCollision();
//.....
}
And the collision code:
//
//Collision detection procs
//
final private void checkForCollision()
{
boundCollision.clear();
player.calculateCollisions(colidableNode, boundCollision);
// check for bounding collision
if(boundCollision.getNumber() > 0)
{
triCollision.clear();
player.calculateCollisions(colidableNode, triCollision);
// check for actual triangle collision (always true if bounds collision)
if(triCollision.getNumber() > 0)
{
temp.zero();
for(int index = 0; index < triCollision.getNumber(); index++)
temp.addLocal(getCollisionNormal(reCalcCollision(triCollision.getCollisionData(index))));
if(temp != Vector3f.ZERO)
{
System.out.println("Collision Surface Normal: " + temp.normalize());
}
temp.normalizeLocal();
temp.multLocal(delta.length()).multLocal(1.05f);
temp.addLocal(delta);
player.setLocalTranslation(prevLoc.add(temp));
}
}
}
final private Vector3f getCollisionNormal(CollisionData triData)
{
Vector3f normal = new Vector3f();
if(triData.getTargetTris().size() > 0)
{
TriMesh mesh = (TriMesh) triData.getTargetMesh();
Triangle[] triangles = mesh.getMeshAsTriangles(triData.getTargetBatchId(), null);
ArrayList<Integer> triIndex = triData.getTargetTris();
for(Integer i : triIndex)
{
Triangle t = triangles[i];
t.calculateNormal();
normal.addLocal(triData.getTargetMesh().getLocalRotation().mult(t.getNormal()));
}
}
return normal.normalizeLocal();
}
final private CollisionData reCalcCollision(CollisionData data)
{
TriangleCollisionResults tcr = new TriangleCollisionResults();
data.getSourceMesh().calculateCollisions(data.getTargetMesh(), tcr);
return (tcr.getNumber() > 0 ? tcr.getCollisionData(0) : null);
}
This might sound like a stupid question, but what is Temp, Delta and prevloc in your code??
if(temp != Vector3f.ZERO)
System.out.println("Collision Surface Normal: " + temp.normalize());
temp.normalizeLocal();
temp.multLocal(delta.length()); // try this instead if you still have probs : temp.multLocal(delta.length()).multLocal(1.05f);
temp.addLocal(delta);
player.setLocalTranslation(prevLoc.add(temp));
Thanx…
Ok, i understand now, sorry
Sorry about putting so many posts up, but im trying to get the code given above working for my collision detection for hundreds of trees but doesn't seem to work, could i use this code for what i am trying to do??