第5章 使用ThreeBSP库进行Three.js网格组合

it2023-06-29  73

简介

之前我们一直使用Three.js默认提供的几何体,今天我们使用ThreeBSP库,可以将现有的模型组合出更多个性的模型来使用。我们可以使用ThreeBSP库里面的三个函数进行现有模型的组合,分别是:差集(相减)、并集(组合、相加)、交集(两几何体重合的部分)。下面我们介绍一下三个函数,并提供每个方法的简单案例。

使用方法:

<script src="../../lib/ThreeBSP.js"></script> var sphereBSP = new ThreeBSP(sphere); var cubeBSP = new ThreeBSP(cube); var resultBSP = sphereBSP.intersect(cubeBSP); var result = resultBSP.toMesh();

相关函数

名称描述intersect(交集)使用该函数可以基于两个现有几何体的重合的部分定义此几何体的形状。union(并集)使用该函数可以将两个几何体联合起来创建出一个新的几何体。subtract(差集)使用该函数可以在第一个几何体中移除两个几何体重叠的部分来创建新的几何体。

创建两个几何体,一个球形sphere一个立方体cube。

//创建球形几何体 var sphereGeometry = new THREE.SphereGeometry(50, 20, 20); var sphere = createMesh(sphereGeometry); //创建立方体几何体 var cubeGeometry = new THREE.BoxGeometry(30, 30, 30); var cube = createMesh(cubeGeometry); cube.position.x = -50; scene.add(sphere); scene.add(cube);1234567891011

两个立方体的效果就是这样,有一部分重叠。 我们就创建出重叠的这一部分的图形,具体代码是这样的

//创建球形几何体 var sphereGeometry = new THREE.SphereGeometry(50, 20, 20); var sphere = createMesh(sphereGeometry); //创建立方体几何体 var cubeGeometry = new THREE.BoxGeometry(30, 30, 30); var cube = createMesh(cubeGeometry); cube.position.x = -50; //生成ThreeBSP对象 var sphereBSP = new ThreeBSP(sphere); var cubeBSP = new ThreeBSP(cube); //进行并集计算 var resultBSP = sphereBSP.intersect(cubeBSP); //从BSP对象内获取到处理完后的mesh模型数据 var result = resultBSP.toMesh(); //更新模型的面和顶点的数据 result.geometry.computeFaceNormals(); result.geometry.computeVertexNormals(); //重新赋值一个纹理 var material = new THREE.MeshPhongMaterial({color: 0x00ffff}); result.material = material; //将计算出来模型添加到场景当中 scene.add(result);12345678910111213141516171819202122232425262728

按上面的步骤,我们就可以获得交集的模型了。

使用union(并集)创建新几何体

代码和上面交集的方法一样的,只是改成了并集计算

var resultBSP = sphereBSP.union(cubeBSP);1

就实现了如下的效果。

使用subtract(差集)创建新几何体

如上,直接把调用方法改掉即可

var resultBSP = sphereBSP.subtract(cubeBSP);1

项目应用: 利用我们以上的知识,我们可以创建一个墙体,然后再墙体上挖出一些洞,从而实现墙面上的窗户,门等效果,具体代码如下: 下面是一个主业务的方法,再加上配置文件就可以了

function ObjectCombine(original,other,operationType) { let resultBsp=null; let originalBsp=new ThreeBSP(original); let otherBsp=new ThreeBSP(other); if(operationType==OperationType.intersrct) { resultBsp=originalBsp.intersect(otherBsp); } else if(operationType==OperationType.union) { resultBsp=originalBsp.union(otherBsp); } else { resultBsp=originalBsp.subtract(otherBsp); } let material=new THREE.MeshPhongMaterial({color:0x000000}); if(CommonFunction.contains(CommonFunction.getObjectType(original.material),"Array")) { material=original.material[0]; } else{ material=original.material; } var result= resultBsp.toMesh(material); result.material.flatShading = true; result.geometry.computeFaceNormals(); result.geometry.computeVertexNormals(); result.material.needsUpdate = true; //更新纹理 result.geometry.buffersNeedUpdate = true; result.geometry.uvsNeedUpdate = true; result.castShadow=true; result.receivedAlert=true; return result; }

项目代码

如果大家需要更加详细的讲解和全部源代码的话,可以看一下我的网易云课堂。当然剩下的博客我也会把核心代码给大家列出来。 大家可以看看我的网易云课堂

网易云课堂-threejs3D智能工厂应用

最新回复(0)