[Solved] Collision check problem

Ok, so I have been fighting this problem for 3h now and I have now found a really weird cause for it.



Problem: Getting stuck into a wall



Cause: First collision check fails or program moves node without me knowing about it.



This is what I get in console when walking towards a wall and colliding with it.

MOVING
MOVING
MOVING
MOVING
We are already in a wall....
COLLISION
We are already in a wall....
COLLISION
We are already in a wall....
COLLISION



Ok this code isn't enough for testing it yourself but you can see the problem.

        if(node.hasCollision(walls, false)) {
            System.out.println("We are already in a wall....");
            /*Vector3f loc = new Vector3f(node.getLocalTranslation().clone());
            loc.addLocal(node.getLocalRotation().getRotationColumn(1, tempVa).multLocal(node.getSpeed() * evt.getTime() * 0.5f));
            node.getLocalTranslation().set(loc);
            return;*/
        }

        Vector3f oldLoc = new Vector3f(node.getLocalTranslation().clone());
        Vector3f loc = new Vector3f(node.getLocalTranslation().clone());
        loc.subtractLocal(node.getLocalRotation().getRotationColumn(1, tempVa).multLocal(node.getSpeed() * evt.getTime() * 0.5f));
       

        node.getLocalTranslation().set(loc);
        if(node.hasCollision(walls, false) || node.hasCollision(creatures, false)) {

            System.out.println("COLLISION");
            node.getLocalTranslation().set(oldLoc);
        } else {
            System.out.println("MOVING");
        }




As you can see from the log and code. It seems that my node gets mysteriously inside a wall.

Seems like you have commented out a chunk including the return statement?

So as far as I can see, even if you are already in a wall, it will still overwrite oldLoc, then the second check will find a collision and set you back to a position that was already in the wall.



Another thing, you shouldn't need to do those Vector clones - just doing new Vector3f(v) will create a copy of v.

Well maybe this will make it clearer


if(node.hasCollision(walls, false)) {

            System.out.println("We are already in a wall.... " + node.getLocalTranslation());
            /*Vector3f loc = new Vector3f(node.getLocalTranslation().clone());
            loc.addLocal(node.getLocalRotation().getRotationColumn(1, tempVa).multLocal(node.getSpeed() * evt.getTime() * 0.5f));
            node.getLocalTranslation().set(loc);
            return;*/
        }

        Vector3f oldLoc = new Vector3f(node.getLocalTranslation());
        Vector3f loc = new Vector3f(node.getLocalTranslation());
        loc.subtractLocal(node.getLocalRotation().getRotationColumn(1, tempVa).multLocal(node.getSpeed() * evt.getTime() * 0.5f));
       

        node.getLocalTranslation().set(loc);
        if(node.hasCollision(walls, false) || node.hasCollision(creatures, false)) {

            System.out.println("COLLISION " + node.getLocalTranslation());
            node.getLocalTranslation().set(oldLoc);
        } else {
            System.out.println("MOVING " + node.getLocalTranslation());
        }



With that code the print is:

MOVING com.jme.math.Vector3f [X=0.0, Y=-13.87107, Z=0.0]
MOVING com.jme.math.Vector3f [X=0.0, Y=-13.93982, Z=0.0]
MOVING com.jme.math.Vector3f [X=0.0, Y=-14.007789, Z=0.0]
We are already in a wall.... com.jme.math.Vector3f [X=0.0, Y=-14.007789, Z=0.0]
COLLISION com.jme.math.Vector3f [X=0.0, Y=-14.075757, Z=0.0]
We are already in a wall.... com.jme.math.Vector3f [X=0.0, Y=-14.007789, Z=0.0]
COLLISION com.jme.math.Vector3f [X=0.0, Y=-14.076539, Z=0.0]



Meaning that the first time we collide with the wall at (0, -14,  0) the hasCollision fails to notice it,  but the next time we come to move we check the same position and that time we are inside a wall.

PS.
Alric said:

Another thing, you shouldn't need to do those Vector clones - just doing new Vector3f(v) will create a copy of v.


That just came after I was trying everything and anything to fix the problem...

Ok this is solved, needed to add  node.updateGeometricState(evt.getTime(), false); after node.getLocalTranslation().set(loc);



Code:


if(node.hasCollision(walls, false)) {

            System.out.println("We are already in a wall.... " + node.getLocalTranslation());
            /*Vector3f loc = new Vector3f(node.getLocalTranslation().clone());
            loc.addLocal(node.getLocalRotation().getRotationColumn(1, tempVa).multLocal(node.getSpeed() * evt.getTime() * 0.5f));
            node.getLocalTranslation().set(loc);
            return;*/
        }

        Vector3f oldLoc = new Vector3f(node.getLocalTranslation());
        Vector3f loc = new Vector3f(node.getLocalTranslation());
        loc.subtractLocal(node.getLocalRotation().getRotationColumn(1, tempVa).multLocal(node.getSpeed() * evt.getTime() * 0.5f));
       

        node.getLocalTranslation().set(loc);
        node.updateGeometricState(evt.getTime(), false);
       
        if(node.hasCollision(walls, false) || node.hasCollision(creatures, false)) {

            System.out.println("COLLISION " + node.getLocalTranslation());
            node.getLocalTranslation().set(oldLoc);
        } else {
            System.out.println("MOVING " + node.getLocalTranslation());
            System.out.println("Check2: " + node.hasCollision(walls, false));
        }