threejs合并模型的⼏何体提⾼渲染速度
对 dae 格式的三维模型进⾏合并,第⼀个函数对模型类型分类后合并,第⼆个函数对同⼀类的模型合并,第三个函数对模型的⼏何体合并;使⽤了 threejs 类库和 jQuery 类库的⽅法。合并后的模型由于数据没有共⽤,模型体积⽐合并之前的多个模型体积总和⼤;合并后的模型在渲染时⽐合并之前的多个模型减少了渲染的计算和处理次数,渲染速度⽐较快。下⾯是参考的代码:
// 模型操作类
var ObjectHelper=function(){
this.objectTag ='ObjectHelper';
}
// 合并模型
团结的成语ObjectByType=function( obj, refer ){
if(! obj ||! refer ||! Objects ||! BufferGeometry )return null;
console.time('合并模型 '+ obj.name );
var objAll, objCopy, matrixTemp;
升级win10objAll ={
'Mesh':[],
'SkinnedMesh':[],
'Line':[],
'LineSegments':[],
'other':[]
};
obj.updateMatrixWorld(true);
objCopy = child.clone(fal);
matrixTemp = objCopy.matrix.clone();
objCopy.applyMatrix( matrixTemp.clone());
objCopy.applyMatrix( child.matrixWorld.clone());
if( pe ==='Mesh'){
objCopy.name ='[已合并Mesh] '+ objCopy.name;
objAll[ pe ].push( objCopy );
}el if( pe ==='SkinnedMesh'){
objCopy.name ='[已合并SkinnedMesh] '+ objCopy.name;
objAll[ pe ].push( objCopy );
}el if( pe ==='Line'){
objCopy.name ='[已合并Line] '+ objCopy.name;
objAll[ pe ].push( objCopy );
}el if( pe ==='LineSegments'){
objCopy.name ='[已合并LineSegments] '+ objCopy.name;
objAll[ pe ].push( objCopy );
}el if( pe !=='Group'){
objCopy.name ='[未合并] '+ objCopy.name;
objAll['other'].push( objCopy );
});
var group =new THREE.Group();
for(var type in objAll ){
if( objAll[ type ].length <1)continue;
if( type ==='other'){
for(var i =0, l = objAll[ type ].length; i < l; i++){
group.add( objAll[ type ][ i ]);
}
}el{
objCopy = Objects( objAll[ type ], refer );
objCopy.name = objAll[ type ][0]['name'];
$.extend( objCopy.urData, objAll[ type ][0]['urData']);
group.add( objCopy );
}
}
group.name = obj.name;
$.extend( group.urData, obj.urData );
console.timeEnd('合并模型 '+ obj.name );
return group;
}
// 合并某个类型的所有模型
Objects=function( objs, refer ){
if(! objs || objs.length <1||! refer ||! BufferGeometry )return null;
var type = objs[0].type, geometries =[], materials ={}, materialsArr =[],
groups, materialTemp, geometryTemp, count =0, countTemp =0, startTemp,
uvAttr =fal, vertices, uvs, geometry =new THREE.BufferGeometry(),
geometry2, midNow;
if( type ==='Mesh'|| type ==='SkinnedMesh')
materialsArr.push(new THREE.MeshBasicMaterial({ side:THREE.BackSide, name:'默认背⾯材质'})); for(var i =0, l = objs.length; i < l; i++){
materialTemp = objs[ i ].material;
geometryTemp = objs[ i ].geometry.clone();
geometryTemp.applyMatrix( objs[ i ].matrix.clone());
objs[ i ].geometry.dispo();
if( geometryTemp.vertices ){
countTemp = geometryTemp.vertices.length;
if( objs[i].geometry.faceVertexUvs ) uvAttr =true;
}el{
countTemp = geometryTemp.unt;
if( objs[i].geometry.attributes.uv ) uvAttr =true;
if( ups.length ===0){
geometries.push({
geo: geometryTemp,
start:0,
count: countTemp,
mid: materialTemp.id
});
count += countTemp;
}el{
groups = ups;
for(var j =0, jl = groups.length; j < jl; j++){
attend过去式geometries.push({
geo: geometryTemp,
start: groups[ j ].start,
count: groups[ j ].count,
mid: materialTemp.id ? materialTemp.id : materialTemp[ groups[ j ].materialIndex ].id });
count += groups[ j ].count;战胜困难的名言名句
}
}
破蛋日什么意思if( materialTemp.id ){
materials[ materialTemp.id ]= materialTemp;
if( ansparent ){
materialTemp.side =THREE.DoubleSide;
if( materialTemp.opacity ===1) materialTemp.opacity =0.6;
}
}el{
for(var j =0, jl = materialTemp.length; j < jl; j++){
materials[ materialTemp[ j ].id ]= materialTemp[ j ];
if( materialTemp[ j ].transparent ){
materialTemp[ j ].side =THREE.DoubleSide;
if( materialTemp[ j ].opacity ===1) materialTemp[ j ].opacity =0.6;
}
}溜冰的作文
}
}
vertices =new Float32Array( count *3);
uvs =new Float32Array( count *2);
geometry.addAttribute('position',new THREE.BufferAttribute( vertices,3));
if( uvAttr ) geometry.addAttribute('uv',new THREE.BufferAttribute( uvs,2));
geometry2 = geometry.clone();
count =0;
while( geometries.length >0){
midNow = geometries[0].mid;
startTemp = count;
countTemp =0;
for(var i =0, l = geometries.length; i < l; i++){
if( geometries[ i ].mid === midNow ){
if( geometries[ i ].geo.isBufferGeometry ){
}el{
客中初夏
geometry2.fromGeometry( geometries[ i ].geo );鸡内金的副作用
}
count += geometries[ i ].count;
countTemp += geometries[ i ].count;
geometries[ i ].geo.dispo();
geometries.splice( i,1);
i--;
l--;
}
}
if( type ==='Mesh'|| type ==='SkinnedMesh'){
if(! materials[ midNow ].transparent )
geometry.addGroup(
startTemp,
countTemp,
);
}
console.log('合并模型:', materials[ midNow ].name );
materialsArr.push( materials[ midNow ]);
materials[ midNow ]= materialsArr.length -1;
geometry.addGroup(
startTemp,
countTemp,
materials[ midNow ]
);
}
var obj;
if( materialsArr.length ===1){
obj =new THREE[ type ]( geometry, materialsArr[0]);
}el{
obj =new THREE[ type ]( geometry, materialsArr );
}
return obj;
}
// 合并⼏何体
BufferGeometry=function( geometry1, offt, geometry2, start, count ){
if(
! geometry1 ||! geometry1.isBufferGeometry ||! geometry2 ||! geometry2.isBufferGeometry
|| offt <0|| start <0|| count <0
)return null;
var attributes1 = geometry1.attributes, attributes2 = geometry2.attributes,
attribute1, attributeArray1, attribute2, attributeArray2, attributeOfft, length,
attributeStart, attributeCount;
for(var key in attributes1 ){
if( attributes2[ key ]=== undefined )continue;
attribute1 = attributes1[ key ];
attributeArray1 = attribute1.array;
attribute2 = attributes2[ key ];
attributeArray2 = attribute2.array;
attributeOfft = attribute1.itemSize * offt;
attributeStart = attribute2.itemSize * start;
attributeCount = attribute2.itemSize * count;
length = Math.min( attributeCount, attributeArray1.length - attributeOfft );
for(var i = attributeStart, j = attributeOfft, z =0; z < length; i ++, j ++, z ++){
attributeArray1[ j ]= attributeArray2[ i ];
}
}
return geometry1;
}