three.js中合並多個BufferGeometry類型的模型


在three.js中,合並模型可以通過它的擴展庫ThreeBsp.js來辦到。不過當模型稍微較復雜時,操作時間會延長,且瀏覽器容易崩潰。其實three.js自己也提供了這個功能,那就是通過THREE.GeometryUtils.merge來實現。

 

具體實現:

  假如要合並模型A、B、C。

var mesh = new THREE.Geometry();

THREE.GeometryUtils.merge(mesh,A);
THREE.GeometryUtils.merge(mesh,B);
THREE.GeometryUtils.merge(mesh,C);
var material = new THREE.MeshLambertMaterial({ color: '0xff074f' });
var result = new THREE.Mesh(mesh, material);

此時的result便是合並后的模型了。

但是,存在一個問題,對於類型為BufferGeometry的模型來說,此方法是無效的。

幸運的是,在THREE.BufferGeometry中也存在着merge方法,因此試着將代碼改為了

var mesh = new THREE.BufferGeometry();

mesh.merge(A.geometry);
mesh.merge(B.geometry);
mesh.merge(C.geometry);

var material = new THREE.MeshLambertMaterial({ 
  color: '0xff074f'
});

var result = new THREE.Mesh(mesh, material);

 

結果報了錯

試了幾種方法,都失敗了,然后在網上找到了一種解決方法:

var model = [A, B, C];
var mesh = new THREE.BufferGeometry();    
var posLen = 0;
var normLen = 0;
var sumPosCursor = 0;
var sumNormCursor = 0;

for (var i=0;i<model.length;i++)
{
    posLen += model[i].geometry.getAttribute('position').array.length;
    normLen += model[i].geometry.getAttribute('normal').array.length;
}
                
var sumPosArr = new Float32Array(posLen);
var sumNormArr = new Float32Array(normLen);
                
for (var i=0;i<model.length;i++)
{
    var posAttArr = model[i].geometry.getAttribute('position').array;
    for (var j=0;j<posAttArr.length;j++)
    {
        sumPosArr[j+sumPosCursor] = posAttArr[j];
    }
    sumPosCursor += posAttArr.length;
                
    var numAttArr = model[i].geometry.getAttribute('normal').array;
    for (var j=0;j<numAttArr.length;j++)
    {
        sumNormArr[j+sumNormCursor] = numAttArr[j];
    }
    sumNormCursor += numAttArr.length;
}
    
mesh.addAttribute('position', new THREE.BufferAttribute(sumPosArr, 3 ));
mesh.addAttribute('normal', new THREE.BufferAttribute(sumNormArr, 3 ));

var material = new THREE.MeshLambertMaterial({
  color: '0xff074f'
});
var result = new THREE.Mesh(mesh, material);

 3個BufferGeometry類型的模型成功合並,但是,存在一個問題,合並后的模型丟失了之前3個模型的獨自的位置信息,導致合並之后3個模型重合到了一起。

因此,選擇了另外一種方案:首先將這三個模型都轉換為Geometry類型的模型,然后進行合並。

var model = [A, B, C];

for(var i=0;i<model.length;i++){
    model[i].geometry = new THREE.Geometry().fromBufferGeometry(model[i].geometry);
}

var mesh = new THREE.Geometry();
for(var i=0;i<model.length;i++){
    THREE.GeometryUtils.merge(mesh,model[i]);
}

var material = new THREE.MeshLambertMaterial({ 
  color: '0xff074f'
});

var result = new THREE.Mesh(mesh, material);

測試發現,成功合並了3個模型,且保留了各自之前所在的位置,旋轉等信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM