cannon.js icon indicating copy to clipboard operation
cannon.js copied to clipboard

friction and restitution question

Open Doidel opened this issue 12 years ago • 9 comments

Hi

I'm trying to have an object ( a player ) move and immediately stop when the arrow key isn't pressed anymore. I altered my contact material to have resitution 0 and friction 1, still the same thing happens: the character glides forward after keyUp for a while. Currently I'm using velocity for player movement, is that the wrong approach after all? Or should I set velocity=0 after keyUp? (what I consider wrong since then velocity=0 would also apply if the player'd be mid-air or so. But ofc I could check whether he touches ground before. But it feels "wrong" somehow) Thanks for some hint there! I want to know what we would be the "most correct" approach here :)

Kind regards, Doidel

Doidel avatar Jun 13 '13 13:06 Doidel

Just a thought - does the player have mass?

corpr8 avatar Jun 13 '13 21:06 corpr8

Yes it has a mass of 5. I wouldn't want to change the mass though, or the gravity would seem weird when falling down, and the gliding would still slightly be there

Doidel avatar Jun 14 '13 07:06 Doidel

Are you sure the friction is applied at all? If you tilt the gravity direction, does the player slide (it should not)? See the friction demo.

Velocity based movement is an okay solution. I guess your alternative is to make own position integration (compute dx and dz) and just do playerBody.position.set(x+dx, y, z+dz). But this won't be stable at all when interacting with other things in the scene.

Doing playerBody.velocity.set(0,vy,0) would be an okay solution too. At least it does not add energy to the system. You could also experiment with playerBody.linearDamping, or implement player motion damping by setting playerBody.velocity.set(damping_x*vx,vy,damping_z*vz)

schteppe avatar Jun 14 '13 07:06 schteppe

You're right, it doesn't get applied. With horizontal gravity the player glides. It's weird though, because I just checked: I have a contact material between two slippery materials:

this._slipperyNormalCm = new CANNON.ContactMaterial(
            this._slipperyMaterial,
            this._slipperyMaterial,
            0.0, // friction coefficient
            0.3  // restitution
        );
this._world.addContactMaterial(this._slipperyNormalCm);

then I create the floor AND the player with slippery material. I checked, they both have slippery material (both id 0). Isn't that all that's necessary?

Doidel avatar Jun 14 '13 16:06 Doidel

I'm having this very same problem. Changing any of the arguments (and even the world defaults) doesn't seem to have any effect. I will create a test case to post later today.

ghost avatar Jun 07 '15 02:06 ghost

Hi, I had the same problem today and couldn't figure out how to fix it using the contact material's friction and/or the body's angularDamping properties which helped but did not fix the issue completely.

I got this working perfectly using this onKeyChange where "is_running" is onKeyDown (or when the player should move) and !is_running is most likely onKeyUp (or when the player should stand still):

cameraBody.fixedRotation = (!is_running); cameraBody.updateMassProperties();

It still allows for more realistic stopping thanks to the linearDamping property, so that it does not break abruptly/instantaneously onKeyUp. I didn't find any better way to achieve this, but it works perfectly here.

that-ben avatar Aug 08 '15 01:08 that-ben

you could just add to the position of the object of a certain key is pressed, and not add to the position when the key isn't pressed. that would cause the object to be able to start and stop on a dime.

Dannie226 avatar Feb 08 '21 01:02 Dannie226

This thread is 8 years old, Dannie226 ! WTF

that-ben avatar Feb 09 '21 20:02 that-ben

Better late than never. At least it Is a solution to the issue

Dannie226 avatar Feb 09 '21 20:02 Dannie226