第8章 关于merge方法合并对效率的影响并搭建仓库和货架

it2024-07-05  41

1、merge方法合并

多数情况下使用组可以很容易地操纵和管理大量网格。但是当对象的数量非常多时,性能就会成为一个瓶颈。使用组,每个对象还是独立的,仍然需要对它们分别进行处理和渲染。通过THREE.Geometry.merge()函数,你可以将多个几何体合并起来创建一个联合体。

当我们使用普通组的情况,绘制20000个立方体,帧率在15帧左右,如果我们选择合并以后,再绘制两万,就会发现,我们可以轻松的渲染20000个立方体,而且没有性能的损失。合并的代码如下:

//合并模型,则使用merge方法合并 var geometry = new THREE.Geometry(); //merge方法将两个几何体对象或者Object3D里面的几何体对象合并,(使用对象的变换)将几何体的顶点,面,UV分别合并. //THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead. for(var i=0; i<gui.numberOfObjects; i++){ var cube = addCube(); cube.updateMatrix(); geometry.merge(cube.geometry, cube.matrix); } scene.add(new THREE.Mesh(geometry, cubeMaterial));

THREE.GeometryUtils.merge()已经将此方法移动到了THREE.Geometry对象的上面了,我们使用addCube方法进行立方体的创建,为了确保能正确的定位和旋转合并的THREE.Geometry对象,我们不仅向merge函数提供THREE.Geometry对象,还提供该对象的变换矩阵。当我们将此矩阵添加到merge函数后,那么合并的方块将被正确定位。

和组的优缺点对比

缺点:组能够对每个单独的个体进行操作,而合并网格后则失去对每个对象的单独控制。想要移动、旋转或缩放某个方块是不可能的。优点:性能不会有损失。因为将所有的的网格合并成为了一个,性能将大大的增加。如果需要创建大型的、复杂的几何体。我们还可以从外部资源中创建、加载几何体。

2、搭建架子的思路

假设变量含义如下:

最底层的高度:bottomHight

每排库位组X轴位置:positionX

每排库位组Y轴位置:positionY

每排库位组Z轴位置:positionZ

每排库位组X轴方向数量:binXNum

每排库位组Y轴方向数量:binYNum

每排库位组Z轴方向数量:binZNum

库位长:binLength

库位宽:binWidth

库位高:binHeight

a、货架的柱子

长:可配置的固定数值(rackLengh = 3)

宽:可配置的固定数值 ( rackWidth = 3)

高(rackHeight):bottomHight+(binYNum-1)*binHeight

左侧柱子X: positionX-binLength/2+rackLengh /2

右侧柱子X:positionX+binLength/2-rackLengh /2

柱子Y轴坐标:positionY-binHeight/2

柱子Z轴坐标:positionZ-(this.binZNum * this.binWidth/2)+i * binWidth+rackWidth/2

b、托板

长:库位的长

宽:库位的宽

高:默认为2

X轴:positionX

Y轴坐标:bottomHight+positionY-binHeight/2-rackHeight/2+ j * this.binHeight

Z轴坐标:positionZ - shelfWidth/2+binWidth/2+i * this.binWidth

项目应用:

下面是我们创建货架的核心代码:

unction StoreShelf(option) { this.binLength = option.BinLength||50;//库位长度 this.binWidth = option.BinWidth||50;//库位宽 this.binHeight = option.BinHeight||50;//库位高 this.binXNum = option.BinXNum||1;//库位X轴方向库位数量 this.binZNum = option.BinZNum||10;//库位Z轴方向库位数量 this.binYNum = option.BinYNum||10;//库位Y轴库位数量 this.bottomHight = option.BottomHeight||20;//底层高度,底层 this.positionX = option.Position.X||0;//库位位置 this.positionY = option.Position.Y||0;//库位位置 this.positionZ = option.Position.Z||0;//库位位置 this.rackLengh = 3;//支架的长度,默认设动为3 this.rackWidth = 3;//支架的宽度,默认设定为3 this.intervalRackNum=2;//间隔多少库位有一个主支架 let binHolderPlane=new THREE.BoxGeometry(this.binLength,2,this.binWidth);//定义一个跟库位长宽相同的几何体,作为托盘 let shlefMat = new THREE.MeshLambertMaterial({color:0x175EC0});//定义支架和托盘的材质 let group = new THREE.Group();//定义一个组合体 //合并模型,则使用merge方法合并 let combineGeometry = new THREE.Geometry(); /* 支架的高=最底层的高度+(库位数-1)*库位的高度 */ let rackHeight=this.bottomHight+(this.binYNum-1)*this.binHeight; /* 支架的宽=库位数乘以库位的宽度 */ let shelfWidth=this.binZNum*this.binWidth; let rackBoxGeometry=new THREE.BoxGeometry(this.rackLengh,rackHeight,this.rackWidth);//定义一个支架网格 let rackObject=new THREE.Mesh( rackBoxGeometry, shlefMat, 0 ); let plane = new THREE.BoxGeometry(this.binLength, 2, this.binWidth); let holderObject = new THREE.Mesh(plane, shlefMat,0); let leftPositionX=this.positionX-this.binLength/2+this.rackLengh/2;//左侧支架柱的X轴条码 let rightPositionX=this.positionX+this.binLength/2-this.rackLengh/2;//右侧支架柱的X轴条码 let positionY=this.positionY-this.binHeight/2;//支架柱的Y轴坐标 for(let i=0;i<this.binZNum+this.intervalRackNum;i++) { let isRack=i%this.intervalRackNum; if(isRack==0) { let PositionZ=this.positionZ-shelfWidth/2+i*this.binWidth+this.rackWidth/2; if(i>=this.binZNum) { PositionZ=PositionZ-this.rackWidth; } let leftRack=rackObject.clone(); leftRack.position.set(leftPositionX,positionY,PositionZ); leftRack.updateMatrix(); combineGeometry.merge(leftRack.geometry, leftRack.matrix); let rightRack=rackObject.clone(); rightRack.position.set(rightPositionX,positionY,PositionZ); rightRack.updateMatrix(); combineGeometry.merge(rightRack.geometry, rightRack.matrix); } } //创建托板 for(let i=0;i<this.binZNum;i++) { for (let j = 0; j < this.binYNum; j++) { let positionY=this.positionY-this.binHeight/2-rackHeight/2+this.bottomHight+j*this.binHeight; let positionZ=this.positionZ-shelfWidth/2+this.binWidth/2 + i * this.binWidth let holderObj= holderObject.clone(); holderObj.position.set(this.positionX,positionY,positionZ); holderObj.updateMatrix(); combineGeometry.merge(holderObj.geometry, holderObj.matrix); } } let shelf= new THREE.Mesh(combineGeometry, shlefMat); shelf.uuid=option.No; shelf.name=option.Name; shelf.type="StoreShelf"; return shelf; }

创建完成后我们的效果如下:

项目代码

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

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

最新回复(0)