schteppe / cannon.js

A lightweight 3D physics engine written in JavaScript.
http://schteppe.github.com/cannon.js
MIT License
4.67k stars 709 forks source link

Heightfield and vehicle interaction #153

Open pixelmike opened 9 years ago

pixelmike commented 9 years ago

So, I've started to progress a bit with cannon. It's pretty fun seeing stuff start to behave physically!

Anyway, I'm trying to set up a vehicle that can drive around on a heightfield. For reference I'm using the raycastVehicle demo as well as the cannon docs.

I've come across 2 things that are confusing me, you can see them in this demo here:

http://www.spacejack.ca/ctest/

  1. It seems the vehicle falls through the ground on any flat surface. When you first run it, the vehicle falls through the road. If you hit reset, it will respawn on a hill, and will not fall through. There's also a ball in the scene which seems to roll along the terrain just fine, on hills or flat ground. (Set the Y coordinate to 0 and click reset to see the vehicle fall through the road again. Sorry about the cheap UI so far.)
  2. If you reset the vehicle, you can press the CTRL key to applyEngineForce to 2 of the wheels (I tried to do it like in the raycastVehicle demo.) The wheels spin however the vehicle goes nowhere. In the raycastVehicle demo I saw that two CANNON.Materials and a CANNON.ContactMaterial were created, but as far as I could tell they were never applied to anything. I tried applying the materials to my objects, but there was no difference.

If you want to look at the source, the bulk of the cannon setup happens in http://www.spacejack.ca/ctest/js/TT.js in the onLoadedHF function and the makeVehicle function.

Any help appreciated, thanks.

pixelmike commented 9 years ago

Ok, I figured out a couple of things:

  1. It seems that if a heightfield height is 0, the vehicle falls through. I raised everything by 1 and now the vehicle doesn't fall through anymore. (A sphere does not fall through at height 0 though.)
  2. My bad here, my world is at a different scale than the cannon demo so when I scaled everything up, I missed the wheel 'radius' option, so I guess the physical wheel was just spinning without touching the ground (although it looked like the vehicle was resting on larger wheels, so I'm not sure why that is.)

So what I'm wondering now is why the friction is so low. I have default world friction at 1. I tried applying the Materials and ContactMaterial, then removed them, the same thing - the wheels mostly just slip.

My updated demo is here: http://www.spacejack.ca/ctest/

Hold CTRL to apply engine force.

schteppe commented 9 years ago

Hi, That drop through thing is really bad, need to fix it. It must be a bug in Heightfield.prototype.getConvexTrianglePillar. Btw, make sure you're on the very latest cannon.js by building it locally.

Did you try changing frictionSlip when creating the wheels? Also, looks like the suspension is a lot stiffer than it needs to be. Try changing the parameters. Sorry to say this, but by changing scale, you're pretty much on your own. An interactive parameter GUI can help. Check out http://schteppe.github.io/vehicle-editor/

Do you think that the friction parameter should be using the Material and ContactMaterial? Because right now they don't.

pixelmike commented 9 years ago

Thanks. I tried tweaking the other parameters and that changes how it behaves. I'll try returning the scale back to what your demo was using and building cannon.js locally.

Which friction parameter is unaffected by Material/ContactMaterial? world.defaultContactMaterial.friction? I assumed that was only used in the absense of custom contact materials. Or are they not yet implemented?

The vehicle editor is cool! Thanks a lot for your help.

schteppe commented 9 years ago

Cool. It's the .frictionSlip parameter is unaffected by the material classes. You have to set it manually on each wheel like so:

vehicle.addWheel({
    ...
    frictionSlip: 10
});

For all contacts, Material/ContactMaterial are used (world.defaultContactMaterial is used if no ContactMaterial match was found). RaycastVehicle is a special case, where you have to set frictionSlip manually, and no material/contactmaterial is involved.

pixelmike commented 9 years ago

Deleting this comment - some more wrong assumptions on my part, sorry.

pixelmike commented 9 years ago

Oh one other question: Is Heightfield.getHeightAt() implemented yet? It always seems to return the minimum height regardless of x,y coordinate.

schteppe commented 9 years ago

Not yet! You could implement it if you want :)

pixelmike commented 9 years ago

Well I'm not using it at the moment but I think it would definitely be a useful function for the Heightfield. Also to know whether local or world coordinates should be used.