schteppe / cannon.js

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

concave mesh #59

Closed timoxley closed 11 years ago

timoxley commented 11 years ago

I have a custom mesh I want to load, it's a "voxel landscape" which is necessarily concave.

Any hints on how I can create a cannon.js concave mesh?

schteppe commented 11 years ago

You mean "voxel" as in a set of 3d cubes? In that case I think the best way is to create static Cannon.js boxes or spheres. Not sure about how performance would be there though. Probably not very good.

If you mean heightfield (2d map of height values): there is no such implementation in Cannon.js yet. Same with concave trimeshes.

The best way to get a performant landscape in Cannon.js would be to construct it manually, using the basic shapes: Sphere, Box, Plane, ConvexPolyhedron.

If you could give me more hints on how your landscape looks I could help you better.

timoxley commented 11 years ago

By Voxel Landscape, I'm talking about something like: http://maxogden.github.com/voxel-engine/

In fact, voxeljs is what I'm trying to integrate cannonjs with.

timoxley commented 11 years ago

Could get around this simply by decomposing the mesh into convex pieces, which should be real easy given a voxel landscape is all cubes, but my math brain is awol.

schteppe commented 11 years ago

Cool! So what features do you need from Cannon.js? Is it for enabling walking around in this landscape? In that case you could use some code from the FPS example, and generate the Cannon.js "mesh" from static CANNON.Box.

timoxley commented 11 years ago

walking/flying around + basic item physics

having each voxel = a cannon.Box seems like incredible overkill considering a normal chunk is 32 x 32 x 32 = 32768 voxels, and that's just a few meters around a player.

So, VoxelJS uses a mesher to optimise the number of polys for a voxel chunk, I'm thinking I need something similar, but geared around "minimum convex shapes" so I can pass it into a 3d physics engine

timoxley commented 11 years ago

…or the ability to create collidable concave meshes

schteppe commented 11 years ago

Oh, I see. Of course. Well, how about rolling an own simple merge algorithm? It does not have to be that complicated, and it gives you the ability to use Cannon.js basic shapes to your advantage (read: for better performance).

Sample algorithm: The lowest full box level can be represented by a CANNON.Plane. Two neighboring boxes (or whatever you use) can be merged into a bigger block. Repeat for each axis (I guess the axis order affects the total number of boxes) until you're out of mergeable boxes.

Perhaps only simulate the uppermost "surface" boxes? That's another idea.

For a flat landscape, such algorithm would generate one box. Worst case would not be too bad either if you only simulate the surface boxes.

Using an optimization algorithm to get minimum convex shapes would generate fewer landscape pieces than boxes, yes. But don't be so sure that it is faster in terms of game performance. Box nearphase intersection is in general faster than convex. On the other hand, fewer collision objects is faster in broadphase.

Also consider updating the physics landscape too (when the user removes a single block). Having to run an optimization algorithm at every such event can be expensive.

Concave meshes won't be implemented in Cannon.js in a near future for what I know.

timoxley commented 11 years ago

awww, roll my own??? But that requires thinking!

I may try combining your suggestions: find all visible blocks, then merge them into boxes.

schteppe commented 11 years ago

I like the way you think :P

Good luck! If you decide to use Cannon.js and release something cool, consider adding your project to the wiki.

timoxley commented 11 years ago

ok, so I followed your advice and optimised a bit, only generating collision boxes that fall in the AABB of my mesh… but… it gets very slow, very quickly, and is super jittery. Any ideas?

http://timoxley.github.io/voxel-real-physics/examples/simple/

timoxley commented 11 years ago

Also, I notice in all your examples you use extensive caching for mesh data etc… why is that?

timoxley commented 11 years ago

Also, If you're wondering why I turned off sleeping, it's because whenever something is woken, it seems to get incredibly startled and behaves erratically

schteppe commented 11 years ago

There is something wrong with your scene and I can't put my finger on what it is at the moment... physi.world.bodies.length tells me you have 745 bodies...? You did not do the merging yet did you? What caching are you talking about? I do caching for math objects, AABBs, etc etc. Why should I not? Yes, sleeping is a bit buggy. Need to read up a bit on how it should be done to work more properly.

Another thing that I think you could get use of is an AABB-based broadphase instead of the current which uses bounding spheres.

schteppe commented 11 years ago

Now bounding boxes should work for broadphase: https://github.com/schteppe/cannon.js/commit/fb972b7ee7072fe3afc49388f48e65bdbd2c8e61 Just set world.broadphase.useBoundingBoxes=true; and it will use AABBs instead of bounding spheres. That will be much more suitable for your scene where you have a lot of axis aligned box bodies.

schteppe commented 11 years ago

Made a small VoxelLandscape class for experimenting :) See live demo here. Yes, the rendering slows down a bit but I guess that's what your voxeljs is good at.

timoxley commented 11 years ago

alright dude, thanks heaps for that.

I integrated your algorithm with voxeljs, and result is much better:

http://timoxley.github.io/voxel-real-physics/examples/simple/

But wtf is up with the sticks being so aggravated and jiggly?? WHHHYYYY

code for world generation: https://github.com/timoxley/voxel-real-physics/blob/gh-pages/index.js#L71

code for stick generation: https://github.com/timoxley/voxel-real-physics/blob/gh-pages/examples/simple/index.js#L50

code for terrain boxes: https://github.com/timoxley/voxel-real-physics/blob/gh-pages/index.js#L46

schteppe commented 11 years ago

No probs, had a lot of fun :) Well, you could try using more solver iterations, a regularization time of at least 2 (this may be the setting you need to change the most)... And smaller tolerance?

For now it's looking really nice and runs fast!

timoxley commented 11 years ago

awesome, I've copied the solver settings from your example and that stopped things from jumping around. I don't really understand what I did, but it seems to have worked :D Thanks again.

schteppe commented 11 years ago

Nice :) Well, parameter tweaking is hard. Too many degrees of freedom. Can't wait to see what you come up with! Good luck!