溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

three.js利用uv和ThreeBSP制作一個快遞柜功能的案例分析

發(fā)布時間:2020-08-19 10:07:28 來源:億速云 閱讀:264 作者:小新 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)three.js利用uv和ThreeBSP制作一個快遞柜功能的案例分析,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1. 主角是一個JSON

這樣一個快遞柜的核心是JSON數(shù)據(jù)的創(chuàng)建,有了jSON數(shù)據(jù),我們就可以通過循環(huán)遍歷出柜子,柜門和uv映射關(guān)系。那面下面來看看我們的JSON數(shù)據(jù)(部分代碼)。

var doorArray = [
  [94, 10, -176, 196, false], [94, 10, -76, 196, false], [94, 10, 76, 196, false], [94, 10, 176, 196, false], [46, 15, 0, 186, false], [46, 60, 0, 147, false],
  [46, 21, 0, 105.5, true], [46, 10, 0, 89, true], [46, 10, 0, 78, true], [46, 20, 0, 62, true], [46, 20, 0, 41, true], [46, 20, 0, 20, true]
]

他是以一個數(shù)組的形式表現(xiàn)的,每一個數(shù)組代表一個柜子數(shù)據(jù),每一個數(shù)組中的第一項(xiàng)為當(dāng)前柜子寬度,第二項(xiàng)為高度,第三項(xiàng)為中心x位置,第四項(xiàng)而中心y位置,第五項(xiàng)為柜子是否能打開(因?yàn)橛械牡胤綖椴僮髅姘宓龋?/p>

2. ThreeBSP繪制柜子的整體架構(gòu)。

說完核心,我們在看看柜子的整體框架。下面是柜子的側(cè)面圖,通過側(cè)面圖我們可以很清晰的看出我們做了什么

three.js利用uv和ThreeBSP制作一個快遞柜功能的案例分析

其實(shí)加的不多,就是在上面加了一個檐,下面加了兩個底座,還有就是在每個小快遞柜中掏出一個洞。
我們看代碼

var texture = new THREE.TextureLoader().load('/static/images/base/cabinet.jpg')
let pubMate = new THREE.MeshNormalMaterial();
let frameGeom = new THREE.BoxGeometry(450, 200, 50);
let frameMesh = new THREE.Mesh(frameGeom, pubMate);
frameMesh.position.y = 106;

let footShape = new THREE.Shape();
footShape.moveTo(0, 2);
footShape.lineTo(8, -2);
footShape.lineTo(8, -4);
footShape.lineTo(0, -4);
footShape.lineTo(0, 0);
footShape.lineTo(-12, 0);
footShape.lineTo(-12, 2);
footShape.lineTo(0, 2);

let footExtrudeSettings = {
  steps: 5,
  depth: 450,
  bevelEnabled: false
};
let footGeom = new THREE.ExtrudeGeometry(footShape, footExtrudeSettings);
let footMesh = new THREE.Mesh(footGeom, pubMate);
let footMesh2 = footMesh.clone();
footMesh2.rotation.y = -Math.PI / 2;
footMesh2.position.x = 225;
footMesh2.position.y = 4;
footMesh2.position.z = 25;
let footMesh3 = footMesh.clone();
footMesh3.rotation.y = Math.PI / 2;
footMesh3.position.x = -225;
footMesh3.position.y = 4;
footMesh3.position.z = -25;

let headGeom = new THREE.BoxGeometry(450, 5, 20);
let headMesh = new THREE.Mesh(headGeom, pubMate);
headMesh.position.z = 23;
headMesh.position.y = 206 - 2.5;

let framebsp = new ThreeBSP(frameMesh);
let foot1bsp = new ThreeBSP(footMesh2);
let foot2bsp = new ThreeBSP(footMesh3);
let headbsp = new ThreeBSP(headMesh);

res = framebsp.union(foot1bsp).union(foot2bsp).union(headbsp);

for(var i=0; i<doorArray.length; i++) {
  let geom = new THREE.BoxGeometry(doorArray[i][0]-1, doorArray[i][1]-1, 50);
  let mesh = new THREE.Mesh(geom, pubMate);
  mesh.position.set(doorArray[i][2], doorArray[i][3], 4)
  let meshbsp = new ThreeBSP(mesh);
  res = res.subtract(meshbsp);
}

let cabinetGeom = res.toGeometry();
let cabinetMate = new THREE.MeshPhongMaterial({color: 0xD8C513, specular: 0xD8C513, shininess: 10});
let cabinetMesh = new THREE.Mesh(cabinetGeom, cabinetMate);
cabinetMesh.position.y = 106;

scene.add(cabinetMesh);

這里就是在框架BoxGeometry的基礎(chǔ)上加了兩個底座ExtrudeGeometry,和一個檐BoxGeometry,然后遍歷減去小柜子。掌握好各自的空間位置,制作其實(shí)并不難。

3. 柜子的統(tǒng)一貼圖

將一張圖作為貼圖,貼到所有的mesh上,如最上面圖的效果,因?yàn)樯瞎?jié)課已經(jīng)大致的說了關(guān)于uv的一點(diǎn)知識。

for(var i=0; i<doorArray.length; i++) {
    let a0 = doorArray[i][0];
  let a1 = doorArray[i][1];
  let a2 = doorArray[i][2];
  let a3 = doorArray[i][3];

  let x1 = ((a2 - a0 / 2) + 223) / 446;
  let x2 = ((a2 + a0 / 2) + 223) / 446;
  let y1 = ((a3 - a1 / 2) - 10) / 191;
  let y2 = ((a3 + a1 / 2) - 10) / 191;

  doorMesh.geometry.faceVertexUvs[0][8] = [new THREE.Vector2(x1, y2), new THREE.Vector2(x1, y1), new THREE.Vector2(x2, y2)];
  doorMesh.geometry.faceVertexUvs[0][9] = [new THREE.Vector2(x1, y1), new THREE.Vector2(x2, y1), new THREE.Vector2(x2, y2)];
}

上面已經(jīng)說過,這里的a0是柜子的寬,a1是柜子的高,a2是柜子中心x的坐標(biāo)值,a3是柜子中心y的坐標(biāo)值。因?yàn)楣褡诱wx的范圍是[-223, 223],y的范圍的[10, 201]。經(jīng)過換算x1是紋理x坐標(biāo)的最小值,x2是紋理x坐標(biāo)的最大值,y1是紋理y坐標(biāo)的最小值,y2是紋理y坐標(biāo)的最大值,最后設(shè)置數(shù)組索引為8和9小三角面的uv映射(因?yàn)槲覀円O(shè)置的面為長方體的左面,就是8和9控制的面)。

最后加上一點(diǎn)點(diǎn)開柜子的動畫就大功告成了。

關(guān)于three.js利用uv和ThreeBSP制作一個快遞柜功能的案例分析就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI