<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      之前三節(jié)都沒涉及到機(jī)房,只是一些零零散散的知識(shí)點(diǎn),這一節(jié)我們就開始正式畫外墻。


      首先我了明顯理解以下啥是墻?其實(shí)說白了就是一個(gè)長方體,長不確定,寬一般也就是40cm,高也就是兩米,這就是一個(gè)簡單的墻,當(dāng)然很多墻上都有窗戶、門啥的,其實(shí)也就是在長方體的固定的位置掏個(gè)洞,然后放上我們需要方的東西,比如門,窗戶。

      在畫墻之前我們需要對(duì)一個(gè)機(jī)房的俯視圖進(jìn)行分析,就比如下面這張機(jī)房的圖片



      (圖片來自網(wǎng)絡(luò))

      就像圖片中顯示的一樣,這個(gè)機(jī)房非常標(biāo)準(zhǔn),是個(gè)很標(biāo)準(zhǔn)的長方形機(jī)房,長900cm, 寬600cm,左側(cè)的墻體是玻璃隔斷,還有一扇門,


      那好,我們就可以開干了,首先我們要初始化一個(gè)機(jī)房的結(jié)構(gòu)布局的Json,注意門不能和窗戶重合,有門的地方窗戶需要分成門左邊和門右邊兩個(gè)數(shù)組(當(dāng)然你也可以寫多個(gè)判斷進(jìn)行操作,但是比較麻煩)。
      {   houseWidth: 900, // 房間長度   houseHeight: 600, // 房間寬   angle: 45, // 房間朝向
        wall: [     {position:{x: 0, y: 0, endX: 900, endY: 0}, door: {isDoor:
      false}, windows: {isWindows:false}},     {position:{x: 900, y: 0, endX: 900,
      endY: 600}, door: {isDoor: false}, windows: {isWindows: false}},
          {position:{x: 0, y: 600, endX: 900, endY: 600}, door: {isDoor: false},
      windows: {isWindows:false}},     {position:{x: 0, y: 0, endX: 0, endY: 600},
      door: {isDoor: true, doorNum: 2, door_PointL [{x: 0, y: 200, endX: 0, endY:
      400, doorDirection: 2}]}, windows: {isWindows: true, windows__Point: [{x: 0, y:
      0, endX: 0, endY: 150}, {x: 0, y: 450, endX: 0, endY: 600}]}}   ] },
        接下來我們開始畫地板,我們目前就將地板和機(jī)房大小做一樣:
      createFloor() { let _self = this; this.imgRendering.load("地板的圖片", texture =>
      { texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(8,
      8); var floorGeometry = new THREE.BoxGeometry(this.houseWidth,
      this.houseHeight, 1); var floorMaterial = new THREE.MeshBasicMaterial({ map:
      texture, side: THREE.DoubleSide }); floorMaterial.opacity = 1;
      floorMaterial.transparent = true; var floor = new THREE.Mesh(floorGeometry,
      floorMaterial); floor.position.y = 0; floor.rotation.x = Math.PI / 2;
      _self.scene.add(floor); }) }
        執(zhí)行效果如下圖:



      紫色是我加給整個(gè)Html的顏色,主要是方便觀看地板,接下來我們就開始畫墻了,在畫墻之前我們先初始化一個(gè)畫長方體(窗寬高均默認(rèn)為1)的函數(shù):
      initLambert() {   var cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
        this.initLambertMod = new THREE.Mesh(cubeGeometry, this.wallMatArray); };
      封裝好之后我們在畫墻的時(shí)候就不用每畫一道墻就新建一個(gè)幾何體和材質(zhì),我們只需要克隆我們剛才初始化的墻體就好了

      之后我們正式封裝具有具體長度、角度和位置在的墻
      /** * 畫長方體 * @param { 長方體的長度 } width * @param { 長方體的高度 } height * @param {
      長方體的厚度 } depth * @param { 長方體旋轉(zhuǎn)的角度 } angle * @param { 長方體的材質(zhì) } material *
      @param { 長方體的X軸坐標(biāo) } x * @param { 長方體的Y軸坐標(biāo) } y * @param { 長方體的Z軸坐標(biāo) } z */
      createLambert(width, height, depth, angle, material, x, y, z) { var code =
      this.initLambertMod.clone(); code.scale.set(width, height, depth)
      code.position.set(x, y, z); code.rotation.set(0, angle * Math.PI, 0);
      //-逆時(shí)針旋轉(zhuǎn),+順時(shí)針 return code; };
        這樣我們就將一個(gè)具有長寬高、方向、位置的長方體就畫出來了,

      只是畫出來還不行,我們需要將數(shù)據(jù)和模型關(guān)聯(lián)起來,我們先對(duì)?this.data.wall
      進(jìn)行遍歷得到這道墻的具體信息,是否有門窗,墻的起始點(diǎn)和結(jié)束點(diǎn),知道了起始點(diǎn)和結(jié)束點(diǎn),我們就能算出這道墻具體有多長,還有這道墻的角度



      如上圖,有以上兩個(gè)點(diǎn)我們能得出該條線的信息

        長度:Math.sqrt(Math.pow(Math.abs(300 -0), 2) +Math.pow(Math.abs(0 -300), 2));

        角度:Math.asin((300- 0) / (0 - 300)) / Math.PI

      這樣我們就知道了該條線的具體信息,下面我們就能畫墻了:
      createHouseWall() {   this.data.wall.map((item) => {     var position =
      item.position;     var w = position.endX - position.x;     var h =
      position.endY - position.y;     var x = (position.x + w / 2) - (this.houseWidth
      / 2);     var z = (position.y + h / 2) - (this.houseHeight / 2);     var width
      = Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));     var angle = Math.asin(h /
      width) / Math.PI;     if (item.windows.isWindows || item.door.isDoor) {
            // 有窗戶或有門或都有     } else {       // 沒門、沒窗戶       let code =
      this.createLambert(width, 200, 10, angle, this.matArrayB, x, 100, z);
            this.scene.add(code);     }   }); };
       執(zhí)行完我們就能看到如下圖這樣的結(jié)果了



      還差一面墻,上面既有門又有窗戶,那我們就先作既有門又有窗戶的,獻(xiàn)上一張圖爽一下



      要實(shí)現(xiàn)這樣,那我們首先要封裝一個(gè)幾何ti裁切函數(shù):
      /** * 幾何體裁切函數(shù) * @param { 被采裁切的集合體 } bsp * @param { 要裁掉的集合體 } less_bsp * @param
      { 區(qū)分是機(jī)房的墻還是機(jī)柜裁切的 } mat */ returnResultBsp(bsp, less_bsp, mat) { switch (mat) {
      case 1: var material = new THREE.MeshPhongMaterial({ color: 0x9cb2d1, specular:
      0x9cb2d1, shininess: 30, transparent: true, opacity: 1 }); break; case 2: var
      material = new THREE.MeshPhongMaterial({ color: 0x42474c, specular: 0xafc0ca,
      shininess: 30, transparent: true, opacity: 1 }); break; default: } var
      sphere1BSP = new ThreeBSP(bsp); var cube2BSP = new ThreeBSP(less_bsp);
      //0x9cb2d1 淡紫,0xC3C3C3 白灰 , 0xafc0ca灰 var resultBSP =
      sphere1BSP.subtract(cube2BSP); var result = resultBSP.toMesh(material);
      result.material.flatshading = THREE.FlatShading;
      result.geometry.computeFaceNormals(); //重新計(jì)算幾何體側(cè)面法向量
      result.geometry.computeVertexNormals(); result.material.needsUpdate = true;
      //更新紋理 result.geometry.buffersNeedUpdate = true; result.geometry.uvsNeedUpdate
      = true; if (mat == 2) { result.nature = "Cabinet"; } return result; };
        之后我們就開始對(duì)有門或者有窗戶的墻面開始處理,先整理數(shù)據(jù),將數(shù)據(jù)整理成我么能夠最簡單就能處理的
      createHouseWall() {   this.data.wall.map((item) => {     var position =
      item.position;     var w = position.endX - position.x;     var h =
      position.endY - position.y;     var x = (position.x + w / 2) - (this.houseWidth
      / 2);     var z = (position.y + h / 2) - (this.houseHeight / 2);     var width
      = Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));     var angle = Math.asin(h /
      width) / Math.PI;     if (item.windows.isWindows || item.door.isDoor) {
            // 有窗戶或有門或都有 // 當(dāng)然判斷里面還是分開成有門或者有窗戶,但互不干涉 var window__List = []; //
      盛放窗戶的數(shù)組 var door__List = []; // 盛放門的數(shù)組 if (item.windows.isWindows) {
        item.windows.windows__Point.map((windows__Point, window__index) => { let
      window__Json = {}; let windows__w = windows__Point.endX - windows__Point.x;
      let windows__h = windows__Point.endY - windows__Point.y;
      window__Json.window__x = (windows__Point.x + windows__w / 2) - (this.houseWidth
      / 2); window__Json.window__z = (windows__Point.y + windows__h / 2) -
      (this.houseHeight / 2); window__Json.window__width =
      Math.sqrt(Math.pow(windows__w, 2) + Math.pow(windows__h, 2));
      window__Json.w_Height = 120; window__Json.window__y = 100;
      window__List.push(window__Json); }); }       if (item.door.isDoor) { var
      door__num = item.door.doorNum || 1; item.door.door_Point.map((door__Point,
      door__index) => { var door__Json = {}; var windows__w = door__Point.endX -
      door__Point.x; var windows__h = door__Point.endY - door__Point.y; if (door__num
      == 2) { let doubleDoorList = []; for (var i = 0; i < 2; i++) { door__Json = {};
      door__Json.door__x = (door__Point.x + windows__w / 2) - (this.houseWidth / 2) +
      (door__Point.endX - door__Point.x) / 2 * i; door__Json.door__z = (door__Point.y
      + windows__h / 2) - (this.houseHeight / 2) + (door__Point.endY - door__Point.y)
      / 2 * i; door__Json.door__width = (Math.sqrt(Math.pow(windows__w, 2) +
      Math.pow(windows__h, 2))) / 2; door__Json.door__height = 180;
      door__Json.door__y = 100; door__Json.doorDirection = door__Point.doorDirection;
      if (door__Point.doorDirection < 2) { doubleDoorList.unshift(door__Json); } else
      { doubleDoorList.push(door__Json); } } door__List.push(doubleDoorList); } else
      { door__Json.door__x = (door__Point.x + windows__w / 2) - (this.houseWidth /
      2); door__Json.door__z = (door__Point.y + windows__h / 2) - (this.houseHeight /
      2); door__Json.door__width = Math.sqrt(Math.pow(windows__w, 2) +
      Math.pow(windows__h, 2)); door__Json.door__height = 180; door__Json.door__y =
      100; door__Json.doorDirection = door__Point.doorDirection;
      door__List.push(door__Json); } }); }     } else {       // 沒門、沒窗戶       let
      code = this.createLambert(width, 200, 10, angle, this.matArrayB, x, 100, z);
            this.scene.add(code);     }   }); };
        整理完成之后我們就要開始對(duì)以上數(shù)據(jù)進(jìn)行操作了,此時(shí)我們就需要?jiǎng)?chuàng)建函數(shù)cerateWallHadDoorOrGlass來開始畫有玻璃和門的墻了
      //畫有門和有窗子的墻(工具函數(shù)) cerateWallHadDoorOrGlass(width, height, depth, angle,
      material, x, y, z, door__list, windows__List) { //茶色:0x58ACFA 透明玻璃色:0XECF1F3
      var glass_material = new THREE.MeshBasicMaterial({ color: 0XECF1F3 });
      glass_material.opacity = 0.5; glass_material.transparent = true; var wall =
      this.returnLambertObject(width, height, depth, angle, material, x, y, z);
      windows__List.map((item, index) => { var window_cube =
      this.returnLambertObject(item.window__width, item.w_Height, depth, angle,
      material, item.window__x, item.window__y, item.window__z); wall =
      this.returnResultBsp(wall, window_cube, 1); let code =
      this.returnLambertObject(item.window__width, item.w_Height, 2, angle,
      glass_material, item.window__x, item.window__y, item.window__z);
      this.scene.add(code); }); var status__result = [0.5, 0.5, 0, 0, ]
      door__list.map((item, index) => { if (item.length == 2) { item.map((c_item,
      c_index) => { let door_cube = this.returnLambertObject(c_item.door__width,
      c_item.door__height, 10, angle, this.matArrayB, c_item.door__x, c_item.door__y,
      c_item.door__z); wall = this.returnResultBsp(wall, door_cube, 1); let
      doorgeometry = new THREE.BoxGeometry(100, 180, 2); let door = ""; if (c_index
      == 0) { door = new THREE.Mesh(doorgeometry, this.LeftDoorRenderingList); } else
      { door = new THREE.Mesh(doorgeometry, this.DoorRenderingList); }
      door.position.set(c_item.door__x, c_item.door__y, c_item.door__z);
      door.rotation.y = status__result[c_item.doorDirection] * Math.PI; door.nature =
      "door"; door.direction = c_item.doorDirection; door.isClose = 1; door.doorIndex
      = c_index; this.scene.add(door); }); } else { let door_cube =
      this.returnLambertObject(item.door__width, item.door__height, 10, angle,
      this.matArrayB, item.door__x, item.door__y, item.door__z); wall =
      this.returnResultBsp(wall, door_cube, 1); let doorgeometry = new
      THREE.BoxGeometry(100, 180, 2); let door = new THREE.Mesh(doorgeometry,
      this.DoorRenderingList); door.position.set(item.door__x, item.door__y,
      item.door__z); door.rotation.y = status__result[item.doorDirection] * Math.PI;
      door.nature = "door"; door.direction = item.doorDirection; door.isClose = 1;
      this.scene.add(door); } }); this.scene.add(wall); };
        如此,大功告成,我們在放一面沒有門但有玻璃的墻看看



      畫墻這塊就到這兒,這篇文章整整花費(fèi)了我一下午的時(shí)間,項(xiàng)目是直接從vue init webpack dome
      開始的,各位看客如果覺得還行,麻煩給個(gè)“推薦”,哈哈哈,全當(dāng)我一下午的辛苦沒白費(fèi)! * _ *

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          天天干狠狠操 | 在线视频亚洲欧美 | 国产成人精品无码区免费福利 | 亚洲高潮 | 天天日天天操综合 | 黄片成人免费 | 日韩人妻无码一区二区三区视频 | 久久久久久99 | www91色 | 日韩人妻无码一区二区三区 |