2010-08-23

First Steps in Bullet physics

I've played with ODE for several small projects, but recently discovered Bullet physics while looking through ROS (Robot Operating System) documentation. The difference in rigid body simulation between the two is not that obvious, the Bullet rigid body demos seem very impressive and perhaps speedier than ODE. But the soft body physics have no equivalent in ODE, and seem very worthy of investigation- and equally intriguing are the decomposition capabilities, where objects can be shattered into smaller pieces with a function call (it may be more difficult than that, I haven't looked at the code yet).



There is a good forum, not a ton of documentation or second-party dispersed know-how in the form of tutorials especially for the soft body physic, but the demo code is great- and beyond that it comes down to experimentation.

Soft bodies from 3d files

A long time ago I made my own soft body physics simulation code where I would load an .obj file and replace all vertex edges with spring-dampers, and also create a grid of internal springs to give the body volume. It worked okay in the best conditions but would frequently explode in others. Now in bullet there is a toolchain to take a 3d object and turn it volumetric, and then simulate much more robustly than in my amateur effort (though explosions still can occur).

The bunny.inl and cube.inl files in Demos/SoftDemo provide the first clues, they have auto-generated comments like '# Generated by tetgen -YY bunny.smesh'.

Installation of tools

Tetgen is in the Ubuntu repositories, but tetview has to be downloaded as a binary. libg2c isn't in Ubuntu 10.04 lucid lynx, I had to download prebuilt version here http://www.fluvial.ch/d/libg2c.tgz , and also libstdc++.so.5 from http://packages.debian.org/lenny/i386/libstdc++5/download (extract with dpkg-deb file.deb .).

Wings3D is a good program for generating 3d meshes, and is in Ubuntu repositories.



The stl it exports in binary and doesn't work for tetgen ("wrong number of vertices"), use meshlab (also in ubuntu repos) to save it as an stl but uncheck binary. Objects with holes in them didn't work right, tetview kind of locks up on them. Concave areas don't seem quite right either.



I used 'tetgen -p file.stl' and it outputs file.1.ele, file.1.face, file.1.node, and file.1.smesh. 'tetview file.1' will view the output. In the bunny.inl file there is a getElements() and getNodes() function, the data there corresponds to the lists in file.1.ele and file.1.node. Cut and paste the lists into the functions, then use a text editor to put the quotes and line breaks in as seen in bunny.inl.

On trying to use the inl in SoftDemo I get this error
./AppSoftBodyDemo
*** glibc detected *** ./AppSoftBodyDemo: malloc(): memory corruption: 0x090f5c38 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x75f591]
/lib/tls/i686/cmov/libc.so.6(+0x6e395)[0x762395]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x5c)[0x763f9c]
/usr/lib/nvidia-current/libGL.so.1(+0x33e80)[0x2fae80]


Building the debug version helps out (cmake -DCMAKE_BUILD_TYPE=debug), but I haven't been able to figure it out yet.

Here is the backtrace:

Program received signal SIGABRT, Aborted.
0x0012d422 in __kernel_vsyscall ()
(gdb) bt
#0 0x0012d422 in __kernel_vsyscall ()
#1 0x003ff651 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0x00402a82 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0x0043649d in ?? () from /lib/tls/i686/cmov/libc.so.6
#4 0x00440591 in ?? () from /lib/tls/i686/cmov/libc.so.6
#5 0x00443395 in ?? () from /lib/tls/i686/cmov/libc.so.6
#6 0x00444f9c in malloc () from /lib/tls/i686/cmov/libc.so.6
#7 0x08157d51 in btAllocDefault (size=1195)
at /home/bm/other/bullet-2.77/src/LinearMath/btAlignedAllocator.cpp:24
#8 0x08157e6f in btAlignedAllocInternal (size=1176, alignment=16)
at /home/bm/other/bullet-2.77/src/LinearMath/btAlignedAllocator.cpp:170
#9 0x080b4803 in btCollisionObject::operator new (sizeInBytes=1176)
at /home/bm/other/bullet-2.77/src/BulletCollision/CollisionDispatch/btCollisionObject.h:115
#10 0x080e9e85 in btSoftBodyHelpers::CreateFromTetGenData (worldInfo=...,
ele=0x81707e4 "48 4 0\n 1 26 28 16 12\n 2 28 21 16 12\n 3 25 19 2 20\n 4 28 27 10 14\n 5 17 3 20 1\n 6 20 24 18 19"...,
face=0x0, node=0x81707bb "# Generated by tetgen -YY test.1.smesh \n",
bfacelinks=false, btetralinks=true, bfacesfromtetras=true)
at /home/bm/other/bullet-2.77/src/BulletSoftBody/btSoftBodyHelpers.cpp:957
#11 0x080b0bc5 in Init_TetraCube (pdemo=0x8309c60)
---Type to continue, or q to quit---
at /home/bm/other/bullet-2.77/Demos/SoftDemo/SoftDemo.cpp:1315
#12 0x080b122c in SoftDemo::clientResetScene (this=0x8309c60)
at /home/bm/other/bullet-2.77/Demos/SoftDemo/SoftDemo.cpp:1451
#13 0x080b383f in SoftDemo::initPhysics (this=0x8309c60)
at /home/bm/other/bullet-2.77/Demos/SoftDemo/SoftDemo.cpp:1849
#14 0x080a5b90 in main (argc=1, argv=0xbffff384)
at /home/bm/other/bullet-2.77/Demos/SoftDemo/main.cpp:28


I put the question to the forum here but no responses- not many people are that adept at the soft body physics yet.

Something functional

But I've been able to create a trivial example from scratch that works:

static const char* getNodes() { return(
"8 3 0 0\n"
" 0 1 1 1\n"
" 1 1 1 -1\n"
" 2 1 -1 -1\n"
" 3 1 -1 1\n"
" 4 -1 -1 1\n"
" 5 -1 1 1\n"
" 6 -1 1 -1\n"
" 7 -1 -1 -1\n"
"# \n"); }

static const char* getElements() { return(
"4 4 0\n"
" 0 0 1 3 5\n"
" 1 4 7 5 3\n"
" 2 6 5 1 7\n"
" 3 2 1 7 3\n"
"# \n"); }




Maybe I should try to corrupt the above into provoking the same kind of crash?

Update- Solution Found

tetgen by default is creating 1-based vertex indices, while Bullet is expecting 0-based indices- the -z flag will make tetgen output zero-based. So no more crashing.

Bullet Soft Body Physics from binarymillenium on Vimeo.