背景:需要在墙上 创建窗户和门
方案:使用 ThreeBSP.JS库
ThreeBSP.JS库介绍:
名称 | 描述 |
---|---|
intersect(交集) | 使用该函数可以基于两个现有几何体的重合的部分定义此几何体的形状。 |
union(并集) | 使用该函数可以将两个几何体联合起来创建出一个新的几何体。 |
subtract(差集) | 使用该函数可以在第一个几何体中移除两个几何体重叠的部分来创建新的几何体。 |
主要使用可以参考下郭大神的这篇文章:http://www.yanhuangxueyuan.com/three.js_course/boolean.html,写的很详细
这次使用的是ThreeBSP.JS 的差集(subtract)
主要代码逻辑:
import './ThreeBSP.js'
//墙上挖门,通过两个几何体生成BSP对象
let createResultBsp = function (bsp, objects_cube) {
let material = new THREE.MeshPhongMaterial({
map: textureLoaderRes(static_url + 'img/idc/boliqiang.png'),
overdraw: true,
specular: 0x9cb2d1,
shininess: 30,
transparent: true,
opacity: 0.5
});
let BSP = new ThreeBSP(bsp);
for (let i = 0; i < objects_cube.length; i++) {
let less_bsp = new ThreeBSP(objects_cube[i]);
BSP = BSP.subtract(less_bsp);
}
let result = BSP.toMesh(material);
result.material.flatshading = THREE.FlatShading;
result.geometry.computeFaceNormals(); //重新计算几何体侧面法向量
result.geometry.computeVertexNormals();
result.material.needsUpdate = true; //更新纹理
result.geometry.buffersNeedUpdate = true;
result.geometry.uvsNeedUpdate = true;
scene.add(result);
}
//返回墙对象
let returnWallObject = function (width, height, depth, angle, material, x, y, z, name) {
let cubeGeometry = new THREE.BoxGeometry(width, height, depth);
let cube = new THREE.Mesh(cubeGeometry, material);
cube.position.x = x;
cube.position.y = y;
cube.position.z = z;
cube.rotation.y += angle * Math.PI;
cube.name = name;
return cube;
}
//左墙门
let objects_cube_left = [];
//创建门的逻辑就不写了
let door_cube1 = returnWallObject(wallWidth, doorHeight, doorWidth, 0, matArrayB, -offsetX, startY, 0, "door"); //正门
//调用即可
createResultBsp(left_wall, objects_cube_left);