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 ) { };