How can I change the position of my CSG object before subtraction when usingThreejs and ThreeCSG

624 Views Asked by At

I'm trying to subtract "holes" in platforms using ThreeCSG. I want the holes to be subtracted in specific locations on the larger platform.

  var geometry = new THREE.CubeGeometry( 500, 10, 500 );
  var hole_geometry = new THREE.CubeGeometry( 50, 11, 50 );

  var material = Physijs.createMaterial( new THREE.MeshLambertMaterial( { color: 0xEEEEEE } ), 0.2, 0.8  );
  var hole_material = Physijs.createMaterial( new THREE.MeshLambertMaterial( { color: 0x000000, side: THREE.DoubleSide } ), 0.2, 0.8  );

  var platform = { platform: null, hole: null };

  // platform
  platform.platform = new Physijs.BoxMesh(geometry, material, 0);
  platform.platform.position.y = -i*300;
  var platformBSP = new ThreeBSP( platform.platform );

  // hole
  platform.hole = new Physijs.BoxMesh(hole_geometry, hole_material, 0);
  platform.hole.position.y = -i*300;
  platform.hole.position.x = Math.floor(Math.random()*(251))*(Math.random() < 0.5 ? -1 : 1);
  platform.hole.position.z = Math.floor(Math.random()*(251))*(Math.random() < 0.5 ? -1 : 1);
  var holeBSP = new ThreeBSP( platform.hole );

  platformBSP = platformBSP.subtract(holeBSP);
  platform.platform = platformBSP.toMesh(material);
  platform.platform.position.y = -i*300;


  scene.add( platform_array[i].platform );
  scene.add( platform_array[i].hole );

My problem is whenever the hole is converted from Threejs to ThreeCSG is doesn't take the position into account so every hole created in a platform is dead center instead of a random place.

I can't seem to find any documentation on how to reposition the "hole" after it is converted to a ThreeCSG object.

2

There are 2 best solutions below

0
On

The technique used in the ThreeCSG source is to transform the geometry into a mesh, then to translate the mesh, and then to make a BSP from the translated mesh. See the 2nd line here:

var cube_geometry = new THREE.CubeGeometry( 3, 3, 3 );
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( 1.8, 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, map: THREE.ImageUtils.loadTexture('texture.png') }) );
result.geometry.computeVertexNormals();
scene.add( result );
0
On

In order to set your mesh in the correct place before cutting, you can perform a matrix transform on the geometry itself.

platform.platform = new Physijs.BoxMesh(geometry, material, 0);
platform.platform.geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, -i * 300, 0 ) );

It's possible a bug is preventing THREEBSP to use the position attribute (does Physijs mess with this? I have never used it).