Three.js 開發機房(四)


這一節我們講講怎么畫機櫃,其實機櫃如果作的復雜一點、逼真一點可以用3D建模工具,不過一般的項目中也不用做的那么麻煩,那我們就可以將機櫃抽象以下,首先它是一塊具有長寬高的立方體鐵塊,然后我們從中間在掏掉一個小一號的立方體同時掏出出一個門的位置就好了,代碼如下

 initCabient() {
    let _self = this;
    // 用打組有個好處是我們不用管group中的Mesh的位置,我們只需要操控Group的位置
    this.initCabientObject = new Group();
    var Cabinet_material = new THREE.MeshPhongMaterial({
        color: 0x42474c,
    });
    // 注意此處不能用之前初始化同來克隆的幾何體,因為用來克隆的集合體的長寬高都為1,我們看到的都是放大的,而本體尺寸其實並沒有改變,所以用幾何體做減法的時候會被減沒了
    var Cabinet = _self.returnLambertObject(60, 200, 60, 0, Cabinet_material, 0, 0, 0);
    var Cabinet_inside = _self.returnLambertObject(54, 196, 56, 0, Cabinet_material, 3, 0, 0);
    this.initCabientObject.add(_self.returnResultBsp(Cabinet, Cabinet_inside, 2, 0)); // 這一步一個掏空的盒子已經出現了

    // 以下三行代碼僅做演示用
    this.initCabientObject.position.set(0, 100, 0);
    this.initCabientObject.rotation.y = 1 * Math.PI;
    this.scene.add(this.initCabientObject);
}

  代碼運行結果如下圖(注意要在init方法中調用以下):

就這樣一個被掏空的盒子就出現了,盒子出來了還缺啥?眼尖的朋友已經看出來了,缺個門,對,缺門我們就畫個門,門的素材上篇文章畫牆的時候已經引進來了,那我么直接拿素材用就好了,

var doorgeometry = new THREE.BoxGeometry(55, 190, 2);
var door = new THREE.Mesh(doorgeometry, _self.DoorRenderingList);
door.position.set(30, 0, 0);
door.rotation.y = 0.5 * Math.PI; //-逆時針旋轉,+順時針
door.nature = "Cabinet__door";
door.isClose = 1;
this.initCabientObject.add(door);

  把門初始化完成后然后塞到initCabientObject中即可,效果如下(小了看不太清楚)

這樣一個機櫃就成型了,是不是很簡單呢!當然我們這個 initCabient 方法大家從名字上就能看出他只是初始化而不是畫機櫃,所以在這個函數里以下三那句話就得刪掉了

this.initCabientObject.position.set(0, 100, 0);
this.initCabientObject.rotation.y = 1 * Math.PI;
this.scene.add(this.initCabientObject);

    這里一個機櫃(不包含設備)的組就完成了,雖說Group不能被raycaster鐳射器選中,可是其優越性在這塊就很突出了,我們不需要管不同方向時機櫃的門怎么開,不同方向不同位置機櫃里面的設備的方向和位置是不是也要發生改變,我們只需要控制整個組的位置和角度就好了,就像本來廣場上有很多人,我們需要控制每個人的位置和面對的方向很麻煩,但是如果我們讓廣場上的人上了一輛汽車(假設汽車很大,能容納下廣場上的所有人),那么要控制車里面的乘客的位置和方向就很簡單了,我們不用管里面的乘客的位置,只需要知道汽車的位置和方向就OK了。

      既然initCabient這個方法不是用來畫機櫃的,那它是用來干啥的呢?當然是做模型,就像工廠要生產一批機櫃,他不需要每件產品都單獨生產,只需要先生產一個模板,然后其他的就按照這個模板克隆就好了,這個模板一般情況下並不會交給買家,而是當作模板,不管你什么時候再要,我只需要繼續按照模板克隆就好了,這也是我從上面將我的模板添加到場景中的那幾句代碼刪掉的原因。

  接下來我們定義一組機櫃的位置的數據

cabient: [
    { x: 130, z: 120, codeID: "XZ100001", angle: 0 },
    { x: 230, z: 120, codeID: "XZ100002", angle: 0.5 },
    { x: 330, z: 120, codeID: "XZ100003", angle: 1 },
    { x: 430, z: 120, codeID: "XZ100004", angle: 1.5 },

]

  然后我們開始封裝通過數據畫機櫃的方法:

/**
   * 往機房里面添加機櫃的方法
   * @param { 機櫃的數據信息 } result 
   */
createCabient(result) {
    let _self = this;
    result.map((item) => {
        let cabientMod = _self.initCabientObject.clone();
        cabientMod.position.set(item.x - _self.houseWidth / 2, 100, item.z - _self.houseHeight / 2);
        cabientMod.rotation.y = item.angle * Math.PI;
        // 此處給每個機櫃設置name為 cabient 標識加 _ 再加機櫃ID,后面會用到
        cabientMod.name="cabient_" + item.codeID;
        _self.scene.add(cabientMod);
    })
};

  這樣我們就已經將數據化的機櫃信息添加到了場景中,看下圖

到這一步機櫃就已經畫好了,下一片文章我將詳細介紹怎么最簡單的畫設備以及設備的一些簡單的動效,好了,這一篇文章到這里就結束了,如果各位看客覺得這篇文章還行,麻煩點個“推薦”,謝謝!


 

順便說一下,前篇文章發布一天就有好幾百的瀏覽量,說明鑽研這塊東西的人不少,歡迎各位在評論區指出Three.js系列文章的缺點和不足,之前寫的亂七八糟的文章如果哪有不合適也請不吝賜教,技術文章寧可不寫也不能因為寫的里面有錯而誤導別人


免責聲明!

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



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