John Ratcliff's Code Suppository

A place where I insert my code into the anus of the Internet.

 

Thursday, July 07, 2011

HACD : Hierarchical Approximate Convex Decomposition by Khaled Mamou Sample Application


I have just created and made available a test application for people to use/experiment with Khaled Mamou's excellent HACD system.

TestHACD on Google Code

Due to requirements that I have at my job, I had to refactor the code so that it did not use any of the standard template library (STL) and 100% of all memory allocations had to be trapped by a user provided allocator. (i.e. no global new/delete, malloc, free).

One of the more challenging things to factor out regarding the STL was the use of the STL set and map containers.  To accomplish this what I did was refactor a copy of the EASTL (written by Paul Pedriana).  Even though Paul's EASTL is a dramatically smaller code base than the full STL implementation, I went a step further and refactored his code so that I extracted *only* the STL map/set containers and nothing else.  I then put this refactored code into just three small source files where all memory allocations and data types could be trapped and revectored.

There is a single header file in the provided project 'PxSimpleTypes.h'.  You can modify the data types and memory allocation macros in this one header file to make the source conform to the coding standard of your own game engine, or at least it provides a single easy location to do some global find/replace on the source to make it conform to your internal standards.

Khaled's algorithm produces absolutely amazing results much better than my version ever did.  However, one thing I have yet to be able to get his to do is produce just one our two hulls.

With the provided sample mesh no matter what I set the concavity threshold to, no matter how high, I still get 14 convex hulls.  I don't know if this is a limitation of his algorithm or I am not exposing all of the correct parameters at this time.

If you wish to make improvements to this code, please let me know and I will add you to the Google Code project so you can make changes.  Also, sometime in the next week, I am going to revise the code to auto-generate a skeletal deformed mesh from the HACD output.  I will add this to the TestHACD open source project.

Be aware that Khaled's algorithm can be extremely CPU intensive.  With triangle meshes with very large vertex counts; it could possibly take an extremely lengthy period of time.

13 Comments:

  • At 9:45 AM, Blogger Khaled said…

    Great job!
    Regarding the generation of a low number of hulls, the problem comes from the fact that the test mesh (i.e. “hornbug.obj”) is composed of multiple Connected Components (CCs http://en.wikipedia.org/wiki/Connected_component_(graph_theory)). It has exactly 13 CCs. The current version of HACD is not able to merge different CCs into one cluster. In fact, two clusters are considered as candidates to be merged only if they share an edge (i.e. there is an edge connecting two vertices each belonging to one of the two clusters). So, if the concavity criterion is not considered, the algorithm should produce 13 hulls not 14. That difference comes from the fact that I was simplifying the mesh while having at least one edge, which is not necessary. I just fixed it. So, with the new version you should probably get 13.
    To be able to get a lower number of hulls for “hornbug.obj”, a straightforward solution would be to preprocess the mesh in order to merge the CCs. I don’t know if that is feasible in MAX or Maya…
    The best solution would be to make the algorithm handle this case. So, if you have ideas, I would be glad to discuss them with you.

     
  • At 9:49 AM, Blogger John said…

    Yes, I have a fix for that. I'll be checking in a revision today.

    Here's what I'm doing today.

    (1) Adding support for my mesh importer library which can import a number of common graphics file formats; including FBX which is used by both 3D Studio Max and Maya (this is a windows only feature).

    (2) Adding support for a hull-merging post processing stop to fix the problem you just described.

    (3) Adding support for automatic constraint generation so that people can create constrained rigid body systems (skeletons) from the output of the HACD algorithm. Constraints are placed at the closest point that two neighboring hulls touch.

    (4) Adding support to automatically generate a deformed graphics mesh which can be simulated as a softbody or ragdoll in a runtime simulation.

     
  • At 11:42 AM, Blogger Erwin Coumans said…

    It would be good to add the option in HACD (upstream) to choose custom container classes or STL. That way you don't need to fork HACD.

    For our Bullet project, I probably want to use our container classes and not the physx: types.

    Do you have any thoughts on this? We could create some header file with typedefs/customizations in HACD

     
  • At 11:47 AM, Blogger John said…

    Yes, I will do that today. You will be able to invisibly switch between custom containers or STL with the next code drop which should be in a couple of hours.

    john

     
  • At 12:04 PM, Blogger John said…

    Ok, that's done and checked in. You can now change a single pre-processor define in PlatformConfig.h and it will either compile with the STL or the custom containers provided.

    John

     
  • At 12:09 PM, Blogger Bryce said…

    Thanks. I will definitely get use out of this, eventually.

     
  • At 1:11 PM, Blogger John said…

    Ok guys, I just revised the project so that it can perform a post-processing merge step on the output convex hulls.

    Just pass the command line argument '-merge 10' for example and it will merge any convex hulls who's difference in volume combined, versus separate, is less than 10%.

    John

     
  • At 3:20 PM, Blogger Erwin Coumans said…

    Hi John,

    Thanks for dealing with the containers!

    The other thing in HACD is replacing the (physx::PxU32) by some non-physx version. Perhaps add some typedefs in PlatformConfig.h?

     
  • At 8:42 AM, Blogger John said…

    Ok, I changed the 'physx' namespace to the 'hacd' namespace and changed all 'Px' prefixes to 'Ha' prefixes. Hopefully this makes the code generic enough now for everyone, but won't complicate my efforts to keep it synchronized with my internal copy at work.

    Thanks,

    John

     
  • At 7:00 PM, Blogger Khaled said…

    I have just committed a new version of the HACD library which handles meshes wit multiples Connected Components (CCs). The approach I implemented is a little bit different from the one you proposed John. The main idea is to add "virtual edges" between triangles belonging to different CCs. More precisely, if the distance between two triangles T1 and T2 belonging each to a different CC is lower than a threshold distConnect then an edge connecting T1 to T2 is added to the graph. That's the only modification w.r.t. the original algorithm.

    The advantages of this approach are over the hull-merging technique:
    1) Precisely control over the number of clusters to be generated
    2) Merging the CCs is still guided by a concavity criterion

    However, the current implementation need to be optimized in order to compute the real distance between triangles instead of the distance between vertices. A kd-tree may also be used to reduce the computation time...

     
  • At 5:26 AM, Anonymous krk realty said…

    Thanks for an excellent article! I appreciate your insights and agree with what you wrote.

     
  • At 5:08 PM, Blogger Kristafer said…

    Could anyone make a Maya Plugin that would generate collision models with this awesome algorithm? Preferable from a selection of points? I'd be willing to donate! :)

     
  • At 3:01 PM, Blogger carl can said…

    Sounds very interesting! I will check this out! krk realty

     

Post a Comment

<< Home