Animation

Support for animation based on dynamic CSG processing is not one of my design goals. I always anticipated severe performance hits due to matching all the surfaces in one shape against all the surfaces in some other set of shapes. I expected to use CSG as a loading operation, absorbing the performance cost as part of initial setup. If animation was desired, I assumed that some N number of frames would be pre-built.

But it is still a fun test to see just what CSG can do dynamically. A rather simple test case is to have two shapes with a common center rotating in opposite directions. Then display the intersection of the two. With simple boxes (12 triangles per box), you get pretty good response. Change one of those boxes to a somewhat smooth cylinder, and the frame rate takes a hit. You can interrogate the blended shape after regeneration to get a count of nanoseconds required to build the shape.

The setup is straight forward. Create two shapes and blend them into a third. In the update loop, apply rotation to the two primitives, and then regenerate the blended shape. The CSG code will rebuild the blend from scratch on every regenerate call.
download movie (which is rather choppy due to the recording being active, but which is rather smooth in real life)

Progressive Rebuild

A more practical form of semi-automation is applying progressive changes to a single target shape. These changes could be triggered by user action, or could be continuous, moving at whatever rate the underlying hardware can provide. CSG is structured to allow you to easily implement progressive changes. The key is that the return of the .regenerate() call is a CSGShape. This shape is the single result of the prior blend, and is ready for use.

A typical design pattern is to save the result of the initial .regenerate() in a 'priorResult' variable. The update action is to first remove all shapes from your target, blend in the priorResult, blend in any new changes, and then save the result of this new .regenerate() back into priorResult. This update loop can be run repetitively, incorporating whatever new changes are desired in each loop.

For example, CSGTestM starts with a cubic block of 'cheese'. The update loop is to randomly move a spherical 'mouse' within a single quadrant of the block, and then subtract the sphere from the cube. The result becomes the next starting point, so as the loop continues, more and more cheese is gnawed away by the mouse. While not smooth enough for true animation, it is still an effective display.
download movie

Multi-threading

To better support animation and progressive rebuild, the CSG construction process has been made thread aware. Regeneration has been broken into two distinct steps. The first includes all the heavy lifting of analyzing the blending shapes, resolving conflicts, and deciding on the structure of the final result. The second step is applying the final shape to the active visual scene.

By default, .regenerate() executes both steps. But you can use:

         myCSGSpatial.deferSceneChanges( true );
which subsequently causes regenerate to execute only the first step. The changes are held internally within the spatial until explicitly applied by:
         myCSGSpatial.applySceneChanges();
 
which updates the underlying scene. .regenerate() and .applySceneChanges() are thread-aware and properly synchronized. This means you can drive regeneration (the CPU intensive step) from a background thread, and call .applySceneChanges() from within the standard jme3 .update() thread. .applySceneChanges() returns true if work was done, false if no updates were applied.

As part of being thread-aware, the major internal processing loops monitor Thread.interrupted(). If such an interruption is detected, the regeneration process is aborted and a CSGConstructionException is thrown.

NOTE that CSGConstructionException is a RuntimeException, so that the caller is NOT required to explicitly code in exception handling. java.lang.InterruptedException is not used by the CSG process.