three.js:通過包圍盒將物體移到世界座標中心 | 通過包圍盒計算模型的長寬高尺寸

25. 通過包圍盒將物體移到世界座標中心

讀取OBJ的例子,官方文檔有,許多教程也有,在此不贅述。

我讀取到的模型不在座標原點,且長寬高也與我要的實際大小不一致,故此將模型的大小調整成實際大小,並且移到座標原點。

25.1 介紹尺寸調整

  • 現已通過語句var LongMenJia = object;加載了模型LongMenJia
  • 語句1新建一個3維包圍盒。官網介紹其爲“在3D空間中表示一個盒子或立方體。其主要用於表示物體在世界座標中的邊界框。”
  • 語句2獲取到LongMenJia的包圍盒,即可以把模型LongMenJia包圍起來的最小的長方體
  • 語句3得到包圍盒的大小,即加載的模型的長寬高
  • 語句4將真實的模型尺寸/模型的尺寸,得到一個縮放因子,根據該因子縮放即可。比如真實的尺寸爲(100,100,74),模型的尺寸爲(25,50,37),那麼縮放因子爲(4,2,2)——模型比實際小,放大模型
var box3 = new THREE.Box3();
box3.setFromObject( LongMenJia ); //獲取包圍盒
var size = box3.getSize();        //獲取包圍盒的大小,即模型的長寬高
LongMenJia.scale.set(100/size.x, 100/size.y*1.5, 74/size.z); //見本段註釋。換算得到實際大小。

25.2 介紹將模型移到原點

注意,我自己的模型根據場景需要旋轉90度,其他模型是否旋轉根據需求,如果要旋轉,必須將旋轉語句放在var bbox = new THREE.Box3();前面

  • 語句1旋轉模型
  • 語句2新建一個包圍盒。注意:25.1中改變了模型尺寸,這兒必須新建一個包圍盒,因爲前面的包圍盒包圍的是未縮放之前的模型,參數不同
  • 語句3獲取到LongMenJia的包圍盒
  • 語句4、5、6獲取到包圍盒的長、寬、高
  • 語句8、9、10計算包圍盒中心點的座標
  • 語句11將模型移到原點。比如計算得到包圍盒長爲L = 100,其定點距離原點的距離爲20,那麼顯然,L的中點的座標爲70。要將模型移到原點,則座標x減去70即可。
LongMenJia.rotation.y = 90*3.14159265/180;
var bbox = new THREE.Box3();
bbox.setFromObject( LongMenJia ); //獲取包圍盒
var mdlen=bbox.max.x-bbox.min.x;
var mdwid=bbox.max.z-bbox.min.z;
var mdhei=bbox.max.y-bbox.min.y;
//var centerpoint = new THREE.Vector3();
var x1=bbox.min.x+mdlen/2;
var y1=bbox.min.y+mdhei/2;
var z1=bbox.min.z+mdwid/2;
LongMenJia.position.set(-x1,-y1,-z1); //將模型移到原點

此部分代碼如下

//讀取OBJ和MTL
var mtlLoader = new THREE.MTLLoader();

mtlLoader.load('./threeModels/LongMenJia/LongMenJia.mtl', function(materials) {
materials.preload();
//實例化obj加載方法
var objLoader = new THREE.OBJLoader();
//設置mtl文件的材質
objLoader.setMaterials(materials);
objLoader.load('./threeModels/LongMenJia/LongMenJia.obj', function(object) {

    var LongMenJia = object;

    //----獲取長寬高並設置成實際長寬高 ---------- 開始 -----------
    var box3 = new THREE.Box3();
    box3.setFromObject( LongMenJia ); //獲取包圍盒
    var size = box3.getSize();        //獲取包圍盒的大小,即模型的長寬高
    LongMenJia.scale.set(100/size.x, 100/size.y*1.5, 74/size.z); //見本段註釋。換算得到實際大小。

    //----獲取長寬高並設置成實際長寬高 ---------- 結束 ----------

    //----旋轉90度,獲取位置偏移並移到場景中心 ---------- 開始 -----------
    LongMenJia.rotation.y = 90*3.14159265/180;

    var bbox = new THREE.Box3();
    bbox.setFromObject( LongMenJia ); //獲取包圍盒
    var mdlen=bbox.max.x-bbox.min.x;
    var mdwid=bbox.max.z-bbox.min.z;
    var mdhei=bbox.max.y-bbox.min.y;
    var centerpoint = new THREE.Vector3();
    var x1=bbox.min.x+mdlen/2;
    var y1=bbox.min.y+mdhei/2;
    var z1=bbox.min.z+mdwid/2;
    LongMenJia.position.set(-x1,5,-z1); //set(-x1,5,-z1)將模型移到原點,x,z爲相對於原點的座標
    //----旋轉90度,獲取位置偏移並移到場景中心 ---------- 結束 -----------

    var boxHelper;
    boxHelper = new THREE.BoxHelper( LongMenJia, 0x000000 ); //顯示包圍盒

    scene.add(boxHelper);
    scene.add(LongMenJia);

}, onProgress, onError);

//加載過程中回調
var onProgress = function ( xhr ) {
    if ( xhr.lengthComputable ) {
        var percentComplete = xhr.loaded / xhr.total * 100;
        console.log( Math.round(percentComplete, 2) + '% downloaded' );
    }
};

//加載出錯回調
var onError = function ( xhr ) { };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章