Closed timoxley closed 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.
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.
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.
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.
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
…or the ability to create collidable concave meshes
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.
awww, roll my own??? But that requires thinking!
I may try combining your suggestions: find all visible blocks, then merge them into boxes.
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.
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/
Also, I notice in all your examples you use extensive caching for mesh data etc… why is that?
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
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.
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.
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.
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
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!
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.
Nice :) Well, parameter tweaking is hard. Too many degrees of freedom. Can't wait to see what you come up with! Good luck!
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?