Player falling into objects

Hello, we’ve had an issue for quite a while where the player which is a PlayerPhysicsNode can fall through objects, in particular our map’s floor. We’re able to reproduce it when we look up, then jump backwards which will usually cause it. Often it’ll just be caused by falling down even a short distance. Just yesterday I discovered that if the player runs under/behind a ramp that’s at say a 30 degree angle they will be pushed into the floor.



Many times the player won’t suddenly just fall through, but will hit the ground and start falling as if they’re in quicksand before hitting the bottom of the floor. Our floor is just a box, here’s the code we’re using:



[java] Box floorBox = new Box(Vector3f.ZERO, xLength/2f * Main.scale, .5f * Main.scale, zLength/2f * Main.scale);

Geometry floor = new Geometry(“floor”, floorBox);

floor.getMesh().scaleTextureCoordinates(new Vector2f(20f, 20f));

Material grassMaterial = new Material(main.getAssetManager(), “Common/MatDefs/Misc/SimpleTextured.j3md”);

TextureKey grassKey = new TextureKey(“Textures/grass_texture2.jpg”);

grassKey.setGenerateMips(true);

Texture grassTexture = main.getAssetManager().loadTexture(grassKey);

grassTexture.setWrap(Texture.WrapMode.Repeat);

grassTexture.setAnisotropicFilter(16);

grassMaterial.setTexture(“m_ColorMap”, grassTexture);

grassMaterial.setReceivesShadows(true);

floor.setMaterial(grassMaterial);



PhysicsNode floorNode = new PhysicsNode(floor, new MeshCollisionShape(floor.getMesh()), 0);

floorNode.setShadowMode(ShadowMode.Receive);

floorNode.setLocalTranslation(new Vector3f(xLength/2f * Main.scale, -.5f * Main.scale, zLength/2f * Main.scale));

ml.getFloors().attachChild(floorNode);

main.getPhysicsSpace().add(floorNode);[/java]



It seems like I’ve tried everything now. This has been happening in alpha 2 as well as the nightly build that we’re currently on (October 29th). Any help would be greatly appreciated!

There is no PlayerPhysicsNode I guess you mean PhysicsCharacterNode? How do you move it? It should only be moved using the walkDirection. Also how does your level mesh look? If theres gaps in the mesh errors might happen.

normen said:
There is no PlayerPhysicsNode I guess you mean PhysicsCharacterNode?


D'oh! Yeah, I meant PhysicsCharacterNode; I keep thinking in my head that it's called PlayerPhysicsNode.

normen said:
How do you move it? It should only be moved using the walkDirection.


The player is only moved with walkDirection, the one exception being at the start of the game when the player's starting position is set using setLocalTranslation.

normen said:
Also how does your level mesh look? If theres gaps in the mesh errors might happen.


By this you mean look at it with a wireframe material? When I did this I saw that each face was composed of two triangles, as I would expect. Nothing looked out of the ordinary. I've tried using a BoxCollisionShape several times over the past few weeks that I've attempted tackling this and the results are always the same.

Any updates yet?



I have just experienced the same a few times while testing physics. Here is my setup:


  • A simple horizontal 3x3 sized, single sided (2 triangles) Quad as a floor
  • a sphere, radius 0.5, falling from a height of 10.
  • Gravity set to 30, step size 0.05f (as in the hello physics tutorial)
  • no movent code, just gravity and initial translation.



    What you see is a sphere falling down, hitting the floor about half way in where it decelerates fast to zero (no instant stop), and

    then it starts to move down again, completing it’s fall though the quad.

    This happens 100% of the time for me with the code below.



    Here are the important bits:

    init:

    [java] Geometry floor = new Geometry(null, quad);

    floor.setMaterial(getSolidMat(ColorRGBA.Green));

    float angles[] = { -FastMath.HALF_PI, 0, 0.3f};

    floor.setLocalRotation(new Quaternion(angles));

    floor.setLocalTranslation(new Vector3f(-4,0,4));

    Node floorNode = new Node(“floorNode”); // CollisionShapFact only accepts Nodes

    floorNode.attachChild(floor);



    BulletAppState bulletAppState = new BulletAppState();

    stateManager.attach(bulletAppState);



    CompoundCollisionShape sceneShape =

    CollisionShapeFactory.createMeshCompoundShape((Node) floorNode);

    PhysicsNode landscape = new PhysicsNode(floorNode, sceneShape, 0);



    // java.lang.IllegalStateException: Spatial should not be attached to parent

    // while creating compound collision shape!

    rootNode.attachChild(floorNode);



    // player starting position

    Vector3f startPos = new Vector3f(-2, 10, 2);



    // for now a ball as a visible player object

    Sphere sphere = new Sphere(20,80,0.5f);

    playerGeom = new Geometry(null, sphere);

    playerGeom.setMaterial(getSolidMat(ColorRGBA.Blue));

    playerGeom.setLocalTranslation(startPos);

    rootNode.attachChild(playerGeom);



    // set up player physics params

    // note the .05f → max step height

    player =

    // new PhysicsCharacterNode(new CapsuleCollisionShape(1.5f, 6f, 1), .05f);

    new PhysicsCharacterNode(new SphereCollisionShape(0.5f), .05f);

    player.setJumpSpeed(20);

    player.setFallSpeed(30);

    player.setGravity(3);

    player.setLocalTranslation(startPos);



    // We attach the scene and the player to the rootnode and the physics space,

    // to make them appear in the game world.

    rootNode.attachChild(landscape);

    rootNode.attachChild(player);

    bulletAppState.getPhysicsSpace().add(landscape);

    bulletAppState.getPhysicsSpace().add(player);

    Geometry floor = new Geometry(null, quad);

    floor.setMaterial(getSolidMat(ColorRGBA.Green));

    float angles[] = { -FastMath.HALF_PI, 0, 0.3f};

    floor.setLocalRotation(new Quaternion(angles));

    floor.setLocalTranslation(new Vector3f(-4,0,4));

    Node floorNode = new Node(“floorNode”); // CollisionShapFact only accepts Nodes

    floorNode.attachChild(floor);



    BulletAppState bulletAppState = new BulletAppState();

    stateManager.attach(bulletAppState);



    CompoundCollisionShape sceneShape =

    CollisionShapeFactory.createMeshCompoundShape((Node) floorNode);

    PhysicsNode landscape = new PhysicsNode(floorNode, sceneShape, 0);



    // java.lang.IllegalStateException: Spatial should not be attached to parent

    // while creating compound collision shape!

    rootNode.attachChild(floorNode);



    // player starting position

    Vector3f startPos = new Vector3f(-2, 10, 2);



    // for now a ball as a visible player object

    Sphere sphere = new Sphere(20,80,0.5f);

    playerGeom = new Geometry(null, sphere);

    playerGeom.setMaterial(getSolidMat(ColorRGBA.Blue));

    playerGeom.setLocalTranslation(startPos);

    rootNode.attachChild(playerGeom);



    // set up player physics params

    // note the .05f → max step height

    player =

    // new PhysicsCharacterNode(new CapsuleCollisionShape(1.5f, 6f, 1), .05f);

    new PhysicsCharacterNode(new SphereCollisionShape(0.5f), .05f);

    player.setJumpSpeed(20);

    player.setFallSpeed(30);

    player.setGravity(3);

    player.setLocalTranslation(startPos);



    // We attach the scene and the player to the rootnode and the physics space,

    // to make them appear in the game world.

    rootNode.attachChild(landscape);

    rootNode.attachChild(player);

    bulletAppState.getPhysicsSpace().add(landscape);

    bulletAppState.getPhysicsSpace().add(player);



    cam.setLocation(new Vector3f(0,2,11));

    [/java]



    update (just syncing the sphere to the physics object):

    [java]playerGeom.setLocalTranslation(player.getLocalTranslation());[/java]



    I noticed this:

    This happens when gravity >= 30 at fall speed 30.

    When gravity is 30 and fall speed is between 20 and 29 the ball actually falls 90% through and gets stuck

    with the upper part in the floor, hanging there.

    If the fall speed or gravity is set sufficiently low, the ball stops on the floor.



    Another wierd thing i noticed;

    Apparently the position of the point of impact is relevant. If you shift the sphere a bit it might fall through

    faster or slower, or stay on top.

    [java] // player starting position

    Vector3f startPos = new Vector3f(-2f, 10, 2); // falls through

    Vector3f startPos = new Vector3f(-2.4f, 10, 2); // falls through fast

    Vector3f startPos = new Vector3f(-2.2f, 10, 2); // falls through slow

    Vector3f startPos = new Vector3f(-2.6f, 10, 2); // stays on

    Vector3f startPos = new Vector3f(-2.8f, 10, 2); // stays on

    [/java]

    I thought it fell in between the quad’s 2 triangles but that seems not the case.



    Any help or ideas? What’s causing this and more important, what can fix this?

    I am tied to using quads.

I’d try playing with the stepSize and look in the bullet forum maybe if somebody experienced that problem too. What I experienced is inaccuracies with mesh collision shapes and large triangles (more than 2-3x the size of the character node). To display a debug shape of the mesh that is used for the collision use physicsNode.attachDebugShape(assetManager);

Thanks.



Increasing stepside from 0.05 to 0.07 prevented falling through.

Also increasing the sphere radius from 0.5 to 0.6 prevented falling through.



I am going to assume it’s jBullet inaccuracies that are causing it. My shapes will be as large as the triangles, and I expect to use a much larger step size than 0.05 any way.

I guess I just hit an edge case.



Thanks on the debug physics wireframe. That will come in handy :slight_smile:

The physics character is only a very simple physics approximation, its not the “real” bullet physics. The step size is the vertical “resolution” of the physics character movements.