Hi again…
I have another problem…I did my CollisionHandler, and it works fine with TriMesh and Nodes, but it doesn't work with my trees witch are SharedNodes
I made a small example
this is the creation of the two sharednodes:
/** Start collision test */
Node tree = ModelLoader.loadModel( "game/data/models/vegetation/tree1.3ds",
"game/data/models/vegetation/tree1.png", 2f );
SharedNode tree1 = new SharedNode( "tree1", tree );
tree1.setModelBound( new BoundingBox() );
tree1.updateModelBound();
tree1.setLocalTranslation(new Vector3f(-1000, environment.getTerrain().getHeight(-1000,-1100)-20, -1100));
tree1.lock();
SharedNode tree2 = new SharedNode( "tree2", tree );
tree2.setModelBound( new BoundingBox() );
tree2.updateModelBound();
tree2.setLocalTranslation(new Vector3f(-1050, environment.getTerrain().getHeight(-1050,-1100)-20, -1100));
tree2.lock();
collisionNode.attachChild(tree1);
collisionNode.attachChild(tree2);
/** End collision test */
and this is my CollisionHandler update method:
/** Check for front or back collision here */
if( player.getChild("frontal").hasCollision( collisionNode, true ) ) {
inputHandler.setCanMoveForward(false);
inputHandler.setGoingForward(false);
} else if( player.getChild("backy").hasCollision( collisionNode, true ) ) {
inputHandler.setCanMoveBackward(false);
inputHandler.setGoingBackwards(false);
} else {
inputHandler.setCanMoveForward(true);
inputHandler.setCanMoveBackward(true);
}
/** Check for lateral collision */
if( player.getChild("left").hasCollision( collisionNode, true ) ) {
inputHandler.setCanStrafeLeft(false);
inputHandler.setTurningLeft(false);
} else if( player.getChild("right").hasCollision( collisionNode, true ) ) {
inputHandler.setCanStrafeRight(false);
inputHandler.setTurningRight(false);
} else {
inputHandler.setCanStrafeLeft(true);
inputHandler.setCanStrafeRight(true);
}
It seems that the collision is detected just with the last attached sharedNode, infact in this example I can't go throw the tree2 but I can go throw the tree1
what's wrong in my code?
it works fine with Node and TriMesh
Hello.
I have never used sharednodes, but I think updateWorldBound() could help.
joliver82 said:
Hello.
I have never used sharednodes, but I think updateWorldBound() could help.
it's not needed...and calling it nothing change...
it's not needed...
An uptodate worldbound is one of most important things in jME's collision detection. So it is needed but in another way.
Only if both worldbounds intersects the trianglecollsion is checked. In your case updateWorldBound on the node doesn't change anything cause the worldbound of the underlying spatial have to be updated before.
Using
node.updateGeometricState(0,true)
after you changed translation,rotation,etc will help you to keep all of this values uptodate.
UPDATE: Actually simpleGame uses an updateGeometricState on the rootNode so normally this data for the inital-scene should be fine. As long as you don't lock the nodes....(as you do) Try:
SharedNode tree1 = new SharedNode( "tree1", tree );
tree1.setModelBound( new BoundingBox() );
tree1.updateModelBound();
tree1.setLocalTranslation(new Vector3f(-1000, environment.getTerrain().getHeight(-1000,-1100)-20, -1100));
SharedNode tree2 = new SharedNode( "tree2", tree );
tree2.setModelBound( new BoundingBox() );
tree2.updateModelBound();
tree2.setLocalTranslation(new Vector3f(-1050, environment.getTerrain().getHeight(-1050,-1100)-20, -1100));
collisionNode.attachChild(tree1);
collisionNode.attachChild(tree2);
collisionNode.updateGeometricState(0,true);
tree1.lock();
tree2.lock();
PS: and don't forget to keep the players worldbounds uptodate....otherwise you will post here quite fast again :D
PPS: CollisionDetection is really not the easiest and jME with all its necessary updates makes it quite complicated. In order to understand it I can only advice you to see whats going on inside of jME by debugging the collision-calls. That makes all a bit clearer....
I thought it wasn't needed because of the updateGeometricState on the rootNode in each update…
However, the collision isn't working yet…
I really can't understand why I have this problem…now I'm using Node instead of sharedNode, so the loading time is very big (about 2k trees) but the collisionHandler works fine…
So the problem exists just with SharedNode…
I've done a test class extending SimpleGame, and here the collision is detected…
here's the code, following your advises:
protected void simpleInitGame() {
collisionNode = new Node("collision");
rootNode.attachChild(collisionNode);
player = new Node("player");
Box box = new Box( "player", Vector3f.ZERO, 0.2f, 0.2f, 0.2f );
box.setModelBound( new BoundingBox() );
box.updateModelBound();
player.attachChild(box);
rootNode.attachChild(player);
/** Start collision test */
Node tree = ModelLoader.loadModel( "game/data/models/vegetation/tree1.3ds",
"game/data/models/vegetation/tree1.png", 2f );
SharedNode tree1 = new SharedNode( "tree1", tree );
tree1.setModelBound( new BoundingBox() );
tree1.updateModelBound();
tree1.setLocalTranslation(new Vector3f( -100, 0, 30 ));
SharedNode tree2 = new SharedNode( "tree2", tree );
tree2.setModelBound( new BoundingBox() );
tree2.updateModelBound();
tree2.setLocalTranslation(new Vector3f( 100, 0, 30 ));
collisionNode.attachChild(tree1);
collisionNode.attachChild(tree2);
collisionNode.updateGeometricState(0,true);
tree1.lock();
tree2.lock();
}
@Override
protected void simpleUpdate() {
player.setLocalTranslation( cam.getLocation().clone() );
player.updateWorldBound();
player.updateGeometricState(0, true);
collisionNode.updateWorldBound();
collisionNode.updateGeometricState(0, true);
if( player.hasCollision( collisionNode, true )) {
System.out.println("Collision Detected");
}
}
in this few lines of code I just make a very little box following the camera, and ceck for its collision with my collisionNode, and the detection is correct...
while in my game the same code doesent's work..my game extends from my class PhysicsGame (witch extends AbstractGame), a mix between BaseSimpleGame and SimplePhysicsGame, with all the necessary for physics, pass etc...there's also the rootNode.updateGeometricState() call in the update...
I thought it wasn't needed because of the updateGeometricState on the rootNode in each update...
Yes, you're right! My fault...you just have to call it manually if you want to check the position you just set. Otherwise you will be one step back every time because even you changed the location the worldbound will be updated in the next step.
UPDATE:
I'm at home now and made a test-case. And yes you are right! hasCollision(...) only works for bounding-pecision. But SharedMesh (which is the Class that is used for the Geometry) has the hasTriangleCollision(..)-method. So and because I'm happy right now, here a quick sollution for you:
public boolean hasTriangleCollision(Node n1,Node nodeWithSharedNodes)
{
List<TriMesh> geosN1 = n1.descendantMatches(TriMesh.class);
for (TriMesh triN1 : geosN1)
{
if (hasTriangleCollision(triN1, nodeWithSharedNodes))
return true;
}
return false;
}
public boolean hasTriangleCollision(TriMesh sp,Node nodeWithSharedNodes)
{
List<TriMesh> geosN2 = nodeWithSharedNodes.descendantMatches(TriMesh.class);
for (TriMesh triN2 : geosN2)
{
if (triN2.hasTriangleCollision(sp))
return true;
}
return false;
}
Just copy and past this to place where you do the check...in my test-case it works. (Also have a look at the boundings use 'b'-key)
n1 is your player and the other parameter your Node with the sharednodes. Hope that helps.
ttrocha said:
I thought it wasn't needed because of the updateGeometricState on the rootNode in each update...
Yes, you're right! My fault...you just have to call it manually if you want to check the position you just set. Otherwise you will be one step back every time because even you changed the location the worldbound will be updated in the next step.
Well,...time to start debugging and see what's going on
What is shown if you show the boundingboxes (press 'b' in simplegame)
I added the showbounds view in my PhysicsGame class too, and all seems to be correct....I see just the same boundingboxes I see in my simple test...
moreover if I make my simple test extends PhysicsGame and it keeps working well....so now I know there's no problem in that class....
this is the screen the two shared trees, the little boundingbox in front of them is the player (the model is hidden)
I updated my message. pls have a look
ttrocha said:
I updated my message. pls have a look
now it works fine! thanks a lot for spending your time!
I think this will help lot of people :)
np, you're welcome! Good luck with your project.