Thursday, February 12, 2015

CSG BSP and THREE (JS)

Luke, this is your past self the day after you figured out how to handle Binary Space Partitioning with THREE JS. I'm writing this down because you're about to forget all of this and will inevitably need  a reference later. 

That CSG library that looked so good has changed on Github to something with a different API and the old version, referenced in this blog post, doesn't work with MrDoob's orbital camera controller.

The important bit is an 8 step process:

  1. create a geometry (like a cube or sphere)
  2. create a mesh with that geometry
  3. convert that mesh to a format that BSP can operate on using the ThreeBSP function
  4. repeat steps 1-3 with a new geometry (make sure to position it so the two shapes overlap properly)
  5. use the .subtract (or .add or .intersect) method of one of the BSP representations of the two shapes, passing in the other shape's BSP representation as the only argument (this will return a new BSP mesh - not mutate the original, so you'll want to set it to a new variable).
  6. call the .toMesh method on the returned BSP representation of your composite shape - this will return a THREE JS representation of the composite
  7. call the .geometry.computeVertexNormals method of that new THREE object (this will mutate the object)
  8. finally you can add the THREE object to the scene


All in all, that should look something like this:
//csg experiment
var cube_geometry = new THREE.CubeGeometry( 30, 30, 300 );
var cube_mesh = new THREE.Mesh( cube_geometry );
//cube_mesh.position.x = -7;
var cube_bsp = new ThreeBSP( cube_mesh );
var sphere_geometry = new THREE.SphereGeometry( 50, 32, 32 );
var sphere_mesh = new THREE.Mesh( sphere_geometry );
sphere_mesh.position.x = -7;
var sphere_bsp = new ThreeBSP( sphere_mesh );
var subtract_bsp = cube_bsp.subtract( sphere_bsp );
var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading}) );
result.geometry.computeVertexNormals();
scene.add( result );
//end experiment