关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

javascript 简单的3d网页应用(3d网页可视化编辑器), 搭建几何体 选配材质 纹理 , 导入 导出 示例 ( three.js 初探 六)

发布时间:2020-04-02 00:00:00

1 完整代码下载

  https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ  

  提取码 3fzt (压缩包名: 2020-3-24-demo.zip)

2 图片展示

 

 

3 主要代码

  布尔运算后的物体的几何体会自动 导入到 几何体列表选项中, 可自由选配材质 纹理

  挺简单, 都是中文

 

  1 "use strict"  2   3 var View = (function (){  4       5     var _View = function (){  6           7         if(this.__proto__.size === undefined){this.__proto__.size = this.getSize();}  8           9     } 10      11     _View.prototype = { 12          13         constructor: _View, 
 14          15         //创建html元素 16         add: function (fel, elemName, id, cls){ 17             let el = document.createElement(elemName); 18             if(id){el.setAttribute('id',id);} 19             if(cls){el.className = cls;} 20             if(fel){fel.appendChild(el);} 21             return el; 22         }, 
 23          24         //删除html元素 25         remove: function (){ 26             let k, arg = arguments, err = []; 27             for(k = 0; k < arg.length; k++){ 28                 if(this.isEl(arg[k]) === false){err.push(arg[k]); continue;} 29                 arg[k].parentNode.removeChild(arg[k]); 30             } 31             if(err.length > 0){return {err:'这里有一些删除失败的元素', arr:err};} 32             return true; 33         }, 
 34  35         //id获取html元素 36         get: function (id){ 37             return document.getElementById(id); 38         }, 
 39          40         //获取可视宽高 41         getSize: function (){ 42             let w = window.innerWidth ||  document.body.clientWidth || document.documentElement.clientWidth; 43             let h = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight; 44             return {w:w, h:h}; 45         }, 
 46           47         //通过parentNode检查元素是否存在于页面中 48         isEl: function (el){ 49             if(typeof(el) !== 'object'){return false;} 50             //被删除之后的html元素object的 parentNode等于null 51             if(!el.parentNode){return false;} 52             return true; 53          }, 
 54           55         //元素绑定事件 56         addEvent: function (target, ev, callback){ 57             target.addEventListener(ev, function(e){/* e.preventDefault(); */ if(callback){callback(e);}}, false); 58             return callback; 59         }, 
 60          61         removeEvent: function (target, ev, func){ 62             target.removeEventListener(ev, func); 63         }, 
 64          65         initBody: function (){ 66             document.body.style.width = this.size.w + "px"; 67             document.body.style.height = this.size.h + "px"; 68             document.body.style.overflow = "hidden"; 69             return this; 70         } 71          72     } 73      74     return _View; 75      76 })() 77  78  79  80 /** 81     限 谷歌 或 火狐 浏览器 82     依赖 View 类 83 */ 84 var Gui = (function (){ 85      86     //申明新的gui 87     var _Gui = function (obj, a, b, c, d){ 88         this.timer = 0; 89         this.info = new Map(); 90         //this.info.set(this.timer, this); 91         if(this.__proto__.timerAll_old.length !== 0){ 92             this.timerAll = this.__proto__.timerAll_old[0]; 93             this.__proto__.timerAll_old.splice(0, 1); 94         }else{ 95             this.__proto__.timerAll++; 96             this.timerAll = this.__proto__.timerAll; 97         } 98         this.elem = addBindMove(document.body, 'div', null, 'Gui box-shadown box-scroll-block'); 99         this.__proto__.objAll.set(this.timerAll, this);100         let dis = this.autoChangeStartPosition === false ? 1 : this.timerAll;101         this.setPos(15 * dis, 5 * dis, "right");102         if(typeof(obj) === "object" && Array.isArray(obj) === false){this.create(obj, a, b, c, d);}103         else{/* console.warn("_Gui: 参数中的对象 格式错误"); */}104     }105 106     _Gui.prototype.objAll = new Map();107     108     _Gui.prototype.timerAll = 0;109     110     _Gui.prototype.timerAll_old = [];111     112     _Gui.prototype.autoChangeStartPosition = true; //自动改变初始位置113     114     //创建新的块115     _Gui.prototype.create = function (obj, a, b, c, d){116         this.timer++;117         _start(obj, a, b, c, d, this.timer, this.elem, this.info, this.timerAll, this.objAll);118         return this;119     }120     121     //往块里添加新的控件122     _Gui.prototype.add = function (obj, a, b, c, d){123         _start(obj, a, b, c, d, this.timer, this.elem, this.info, this.timerAll, this.objAll);124         return this;125     }126     127     //添加 内容变动 回调(change 事件)128     _Gui.prototype.change = function (){//arr.concat(arr_a, arr_b)129         var arg = arguments, o = this.info.get(this.timer), tar = o.par.target;130         var arr = tar.bs.concat(tar.fs, tar.ns, tar.ss, tar.ts, tar.cs), len = arr.length;131         var arg_t_0 = typeof(arg[0]), call = o.objs.get(o.obj).callback;132         if(arg_t_0 === "function" && len === 1){133             call[arr[0]] = arg[0];134         }else if(arg_t_0 === "string" && typeof(arg[1]) === "function"){135             call[arg[0]] = arg[1];136         }else if(arg_t_0 === "function" && len > 1){137             for(let k = 0; k < len; k++){138                 call[arr[k]] = arg[0];139             }140         }else if(arg_t_0 === "object" && Array.isArray(arg[0]) === false){141             for(let k in arg[0]){142                 call[k] = arg[0][k];143             }144         }else{145             console.log("change方法参数错误,添加失败");146         }147         //console.log(this.info.get(this.timer).obj);148         return this;149     }150     151     //修改title152     _Gui.prototype.title = function (value){153         if(!this.info.get(this.timer)){console.log("找不到title"); return;}154         this.info.get(this.timer).title.innerHTML = ""+this.timerAll+""+"."+""+this.timer+""+" "+(value || "");155         return this;156     }157     158     //修改name159     _Gui.prototype.name = function (){160         let o = this.info.get(this.timer), objs;161         let arg = arguments, typ0 = typeof(arg[0]), typ1 = typeof(arg[1]);162         if(typeof(arg[2]) === "object" && Array.isArray(arg[2]) === false){objs = o.objs.get(arg[2]);}else{objs = o.objs.get(o.obj);}163         var tar = objs.parameter.target, nameEl = objs.nameEl;164         var arr = tar.bs.concat(tar.fs, tar.ns, tar.ss, tar.ts, tar.cs), len = arr.length;165         166         var setVal = (el, val)=>{if(el.value !== undefined){el.value = val;}else if(el.innerHTML !== undefined){el.innerHTML = val;}else{console.log("name修改失败");}}167 168         if(typ0 === "string" && typ1 === "undefined" && len === 1){//string169             setVal(nameEl[arr[0]], arg[0]);170 171         }else if(typ0 === "object" && Array.isArray(typ0) === false){//object172             let k;173             for(k in arg[0]){174                 setVal(nameEl[k], arg[0][k]);175             }176                 177         }else if(typ0 === "string" && typ1 === "string" && arg[1] !== "_Gui_func_showStop"){//string, string178             if(arr.indexOf(arg[0]) === -1 || !nameEl[arg[0]]){console.log("name修改失败,视图结构发生错误,请修复"); return;}179             setVal(nameEl[arg[0]], arg[1]);180             181         }else if(typ0 === "string" && arg[1] === "_Gui_func_showStop" && typeof(arg[2]) === "object"){182             if(nameEl[arg[0]] === undefined){console.log("showStop_name: 错误"); return;}183             if(arg[3] === false){184                 nameEl[arg[0]].style.color = "#2F4F4F";185             }else{186                 nameEl[arg[0]].style.color = "red";187             }188             189             190         }else{191             console.log("name方法参数错误,添加失败");192         }193             194         return this;195     }196     197     //获取当前view对象198     _Gui.prototype.getView = function (){199         return tar;200     }201     202     //设置 gui视图位置203     _Gui.prototype.setPos = function (x, y, dirX, dirY){204         205         let dirx = dirX || "left", diry = dirY || "top";206 207         if(dirx === "left" && this.elem.bindMove.style.right !== ""){208             this.elem.bindMove.style.right = "";209         }210         else if(dirx === "right" && this.elem.bindMove.style.left !== ""){211             this.elem.bindMove.style.left = "";212         }213         214         if(diry === "top" && this.elem.bindMove.style.bottom !== ""){215             this.elem.bindMove.style.bottom = "";216         }217         else if(diry === "bottom" && this.elem.bindMove.style.top !== ""){218             this.elem.bindMove.style.top = "";219         }220         221         if(x !== undefined) this.elem.bindMove.style[dirx] = x+"px";222         if(y !== undefined) this.elem.bindMove.style[diry] = y+"px";223         _setElemPos(this.elem);224         225         return this;226         227     }228     229     //隐藏gui230     _Gui.prototype.display = function (val){231         if(!this.elem){console.log("display, elem不存在"); return this;}232         if(val !== "block" && val !== "none"){console.log("display 参数错误"); return this;}233         this.elem.bindMove.style.display = val;234         this.elem.style.display = val;235         return this;236     }237     238     //关闭gui timer number, 可选, 关闭那个 timer块(默认关闭整个Gui)239     _Gui.prototype.close = function (timer){240         if(timer === "auto"){241             242             return this;243         }244         var o = this.info.get(timer);245         if(o === undefined){246             let k;247             for(k = 1; k <= this.timer; k++){248                 o = this.info.get(k);249                 o.hide = true;250                 hide(o.line, o.fel, this.elem, this.info, true);251             }252         }else{253             o.hide = true;254             hide(o.line, o.fel, this.elem, this.info, true);255         }256         return this;257     }258     259     //标记不可用项260     _Gui.prototype.showStop = function (){261         262         this.name(arguments[0], "_Gui_func_showStop", arguments[1], arguments[2]);263         264         return this;265         266     }267     268     //移除gui269     _Gui.prototype.remove = function(object){270         var o = object ? object : this;271         this.__proto__.timerAll_old.push(o.timerAll);272         this.__proto__.objAll.delete(o.timerAll);273         o.objAll.delete(o.timerAll);274         tar.remove(o.elem.bindMove, o.elem);275         delete(o.timerAll);276         delete(o.elem);277         delete(o.info);278         delete(o.timer);279         return;280     }281     282     283     284     285     var tar = new View(), tar_zIndex = {}, _osTitle = null;286 287     //创建视图288     var _start = function (obj, a, b, c, d, id, felem, map, timerAll, objAll){289             290             var fel, line, title, m = map.get(id), k, len, _name, isNewObj = false;291             292             //确认追加 obj293             if(m){294                 fel = m.fel;295                 if(!obj){296                     obj = m.obj;297                 }else{298                     if(m.objs.has(obj) === false) isNewObj = true;299                     m.obj = obj;300                 }301             }302 303             if(typeof(obj) !== "object" || !obj){console.log("引用对象错误, 新建块对象为必须"); return;}304             305             //确认参数 (target, title, isBind, range || select) || a = {target, title, isBind, range || select}306             var os = {}, nos = [];307             if(a !== undefined){nos.push(_getispro(obj, a, nos));}308             if(b !== undefined){nos.push(_getispro(obj, b, nos));}309             if(c !== undefined){nos.push(_getispro(obj, c, nos));}310             if(d !== undefined){nos.push(_getispro(obj, d, nos));}311             len = nos.length;312             for(k = 0; k < len; k++){313                 if(nos[k] === undefined){314                     if(typeof(a) === "object" && Array.isArray(a) === false){os = a;}315                 }else{316                     let val;317                     switch(k){318                         case 0 : val = a; break;319                         case 1 : val = b; break;320                         case 2 : val = c; break;321                         case 3 : val = d; break;322                         default : break;323                     }324                     if(val !== undefined){os[nos[k]] = val;}325                 }326             }327             328             //确认对象属性 os.target (target 如果为obj 则表示 只设置gui, 不添加控件)329             var arr = [], T = typeof(os.target), A = Array.isArray(os.target);330             if(!os.target){for(k in obj){arr.push(k);}}331             else if(A === true){arr = os.target;}332             else if(T !== "object"){arr.push(os.target);}333             else{return;} 
334             //boolean, function, number, text, select, color335             var bs = [], fs = [], ns = [], ts = [], cs = [], ss = [];336             if(Array.isArray(os.select) == true && arr.length === 1){337                 ss.push(arr[0]);338             }else if(typeof(os.select) === "object" && Array.isArray(os.select) == false){339                 let ks;340                 for(ks in os.select){341                     len = arr.length;342                     for(k = 0; k < len; k++){343                         if(ks === arr[k]){ss.push(arr[k]); arr.splice(k, 1);}344                     }345                 }346             }347             len = arr.length;348             for(k = 0; k < len; k++){349                 T = typeof(obj[arr[k]]);350                 if(T === "boolean"){bs.push(arr[k]);}351                 else if(T === "function"){fs.push(arr[k]);}352                 else if(T === "number"){ns.push(arr[k]);}353                 else if(T === "string"){354                     if(obj[arr[k]].length === 7 && obj[arr[k]].charAt(0) === "#"){cs.push(arr[k]);}//color355                     else{ts.push(arr[k]);}//string356                 }357             }358             var bs_len = bs.length, fs_len = fs.length, ns_len = ns.length, ts_len = ts.length, ss_len = ss.length, cs_len = cs.length;359             var lens = bs_len + fs_len + ns_len + ts_len + ss_len + cs_len;360             361             //确认 绑定362             var isB = false;363             if(typeof(os.isBind) === "boolean"){isB = os.isBind;}364             365             //确认 _name366             if(os.title && lens === 1){_name = os.title; delete(os.title);}367             368             //确认 新的块369             var par = {target:{bs:bs, fs:fs, ns:ns, ts:ts, cs:cs, ss:ss}, select:os.select, range:os.range, title:os.title, isBind:os.isBind};370             if(!m){371                 isNewObj = false;372                 line = _line(id, felem);373                 fel = _cons(line, id, felem, map);374                 title = _title(timerAll, id, _osTitle || os.title, fel);//os.title375                 _osTitle = null;376                 map.set(id, {377                     hide : false,378                     line : line, 
379                     fel : fel, 
380                     title : title, 
381                     obj : obj, 
382                     par : par,383                     objs : new Map([[obj, {384                         parameter : par,385                         callback : {},386                         nameEl : {}387                     }]])388                 });389                 m = map.get(id);390             }391             392             //更新 obj393             if(isNewObj === true){394                 m.objs.set(obj, {395                     parameter : par,396                     callback : {},397                     nameEl : {}398                 });399             }400             401             //更新参数402             m.par = par;403             var objs_g = m.objs.get(obj), pars = objs_g.parameter;404             for(k in os){if(k !== "target"){pars[k] = os[k];}}405             for(k = 0; k < bs_len; k++){if(pars.target.bs.indexOf(bs[k]) === -1){pars.target.bs.push(bs[k]);}}406             for(k = 0; k < fs_len; k++){if(pars.target.fs.indexOf(fs[k]) === -1){pars.target.fs.push(fs[k]);}}407             for(k = 0; k < ns_len; k++){if(pars.target.ns.indexOf(ns[k]) === -1){pars.target.ns.push(ns[k]);}}408             for(k = 0; k < ts_len; k++){if(pars.target.ts.indexOf(ts[k]) === -1){pars.target.ts.push(ts[k]);}}409             for(k = 0; k < ss_len; k++){if(pars.target.ss.indexOf(ss[k]) === -1){pars.target.ss.push(ss[k]);}}410             for(k = 0; k < cs_len; k++){if(pars.target.cs.indexOf(cs[k]) === -1){pars.target.cs.push(cs[k]);}}411 412             //console.log(objs_g.callback);413             //创建视图//os.select os.range os.isBind414             let che, cli, ran, tex, col, sel;415             if(bs_len > 0){ che = _check(obj, bs, fel, isB, objs_g.callback, _name); for(k in che.nameEl){objs_g.nameEl[k] = che.nameEl[k];} }416             if(ts_len > 0){ tex = _text(obj, ts, fel, isB, objs_g.callback, _name); for(k in tex.nameEl){objs_g.nameEl[k] = tex.nameEl[k];} }417             if(cs_len > 0){ col = _color(obj, cs, fel, isB, objs_g.callback, _name); for(k in col.nameEl){objs_g.nameEl[k] = col.nameEl[k];} }418             if(ss_len > 0){ sel = _select(obj, ss, os.select, fel, isB, objs_g.callback, _name); for(k in sel.nameEl){objs_g.nameEl[k] = sel.nameEl[k];} }419             if(ns_len > 0){ ran = _range(obj, ns, os.range || {}, fel, isB, objs_g.callback, timerAll, id, _name); for(k in ran.nameEl){objs_g.nameEl[k] = ran.nameEl[k];} }420             if(fs_len > 0){ cli = _click(obj, fs, fel, objs_g.callback, _name); for(k in cli.nameEl){objs_g.nameEl[k] = cli.nameEl[k];} }421             return {nowObject:obj};422     }423         424         //验证 并 获取 _start 参数425         var _getispro = function (obj, cons, nos){426             var o_t = typeof(cons), o_a = Array.isArray(cons), r;427             if(o_t === "string"){428                 if(obj[cons] !== undefined){429                     r = "target";430                 }else{431                     r = "title";432                 }433                 434             }else if(o_t === "boolean"){435                 r = "isBind";436                 437             }else if(o_t === "object"){438                 let k, len, isT = (arr, type)=>{439                     let ct = true;440                     len = cons.length;441                     for(k = 0; k < len; k++){if(typeof(cons[k]) !== type){ct = false; break;}}442                     return ct;443                 }444                 if(o_a === true){445                     if(isT(cons, "string") === true){r = "target";}446                     else if(isT(cons, "number") === true && (cons.length === 3 || cons.length === 0) && cons[0] < cons[1] && /* cons[2] < cons[1] &&  */cons[2] > 0){r = "range";}447                     else{console.log("忽略了参数");}448                 }else{449                     let isArr = true;450                     for(k in cons){if(Array.isArray(cons[k]) === false){isArr = false; break;}}451                     if(isArr === true){452                         let ka, isN; 
453                         for(k in cons){454                             len = cons[k].length;455                             if(len === 0 || len === 3){456                                 for(ka = 0; ka < len; ka++){457                                     if(typeof(cons[k][ka]) !== "number" || isNaN(cons[k][ka]) === true){isN = false; break;}458                                 }459                                 if(typeof(obj[k]) !== "number"){isN = false;}460                                 461                                 if(isN !== false && len === 3 && (obj[k] < cons[k][0] || obj[k] > cons[k][1] || cons[k][0] > cons[k][1] || cons[k][2] > cons[k][1] || cons[k][2] < 0)){isN = false;}462                             }else{463                                 isN = false;464                                 break;465                             }466                         }467                         if(isN === false){r = "select";}else{r = "range";}//数组长度为空也判定为 range, 因为range 有默认值468                     }else{469                         let isSel = true;470                         for(k in cons){if(obj[k] === undefined){isSel = false; break;}}471                         if(isSel === true){r = "select";}else{console.log("忽略了参数");}472                     }473                 }474             }475             476             if(nos.indexOf(r) !== -1){console.log("重复了参数"); return;}477             478             return r;479         }480         481         //隐藏视图482         var hide = function (l, f, elem, map, isHide){483             elem.bindMoveIsHideAll = false;484             if(isHide === false){485                 l.className = "line-block"; 
486                 f.style.display = "block";487                 elem.className = "Gui box-shadown box-scroll-block";488                 elem.bindMove.className = "bindMove_elemCla-up";489             }else{490                 l.className = "line-none"; 
491                 f.style.display = "none"; 
492                 let isAll = true, con, k, len = map.size;493                 for(k = 1; k <= len; k++){494                     con = map.get(k).fel.style.display;495                     if(con === "" || con === "block"){isAll = false; break;}496                 }497                 if(isAll === true){498                     elem.bindMoveIsHideAll = true;499                     elem.className = "Gui-none box-shadown box-scroll-block";500                     elem.bindMove.className = "bindMove_elemCla-hidden";501                 }502             }503             _setElemPos(elem);504         }505         506         //调整 son(this.elem)的位置507         var _setElemPos = function (son, father){508             if(!father){father = son.bindMove;}509             let s = 0;510             if(son.bindMoveIsHideAll === true) s = 10;511             //son.style.zIndex = "2"; father.style.zIndex = "1"; 512             son.style.left = father.offsetLeft-(son.clientWidth || son.offsetWidth)+(father.clientWidth || father.offsetWidth) +"px";513             son.style.top = father.offsetTop+(father.clientHeight || father.clientHeight)+ s -1 +"px";514         }515         516         //添加 内容 容器517         var _cons = function (line, id, fel, map){518             var f = tar.add(fel, "div", null, "Gui-content"), di;519             tar.addEvent(line, 'click', (e)=>{520                 di = map.get(id);521                 di.hide = !di.hide;522                 hide(line, f, fel, map, di.hide);523             });524             return f;525         }526         527         //添加 标题 ← ↑ → ↓ ↖ ↙ ↗ ↘ ↕528         var _title = function (timerAll, id, title, fel){529             var tf = tar.add(fel, "div");530             var t = tar.add(tf, "p");531             //var ts = tar.add(tf, "p");532             t.innerHTML = ""+timerAll+""+"."+""+id+""+" "+(title || "");533             //ts.style = "height:5px;";534             return t;535         }536         537         //添加 分块线538         var _line = function (id, fel){539             var toper = id === 1 ? 0 : 10;540             var l = tar.add(fel, 'p', null, "line-block");541             l.style= "cursor:pointer; margin-top:" + toper + "px";542             return l;543         }544         545         //创建 绑定 可移动 的html元素546         var addBindMove = function (fel, elemName, id, cls){547             var father = tar.add(fel, "div", null, "bindMove_elemCla-up");548             var son = tar.add(fel, elemName, id, cls);549 550             var isMove = false, sx, sy, tar_input, k, len, path;551             552             //初始化 father 位置553             var getFatherPosition = function (){554                 if(!son.offsetLeft || !(son.clientWidth || son.offsetWidth) || !(father.clientWidth || father.offsetWidth)){555                     setTimeout(()=>{getFatherPosition(); _setElemPos(son);}, 500);556                     console.log("调整father位置");557                     return;558                 }559                 father.style.left = son.offsetLeft + (son.clientWidth || son.offsetWidth) - (father.clientWidth || father.offsetWidth) +"px";560             }561             562             //更新 zIndex563             var setzIndex = function (e){564                 path = e.path || (e.composedPath && e.composedPath());565                 len = path.length;566                 for(k = 0; k < len; k++){567                     if(path[k].className === "bindMove_elemCla-up" || path[k].className === "bindMove_elemCla-down" || path[k].className === "bindMove_elemCla-hidden" || path[k].className === "Gui box-shadown box-scroll-block" || path[k].className === "Gui-none box-shadown box-scroll-block"){568                         if(tar_zIndex.move && tar_zIndex.elem){tar_zIndex.move.style.zIndex = "1"; tar_zIndex.elem.style.zIndex = "1";}569                         tar_zIndex.move = father; tar_zIndex.elem = son;570                         tar_zIndex.move.style.zIndex = "2"; tar_zIndex.elem.style.zIndex = "2";571                         break;572                     }573                 }574             }575             tar.addEvent(son, 'click', (e)=>{576                 setzIndex(e);577                 //if(e.target.type !== undefined){tar_input = e.target; e.target.focus();}else if(tar_input){tar_input.blur();}578             });579             580             //移动581             var down = tar.addEvent(father, 'mousedown', (e)=>{582                 setzIndex(e);583                 if(e.target.className === "bindMove_elemCla-up" || e.target.className === "bindMove_elemCla-hidden"){584                     sx = e.offsetX; sy = e.offsetY;585                     if(father.className === "bindMove_elemCla-up") father.className = "bindMove_elemCla-down";586                     isMove = true;587                 }588             });589             var up = tar.addEvent(father, 'mouseup', (e)=>{590                 isMove = false;591                 if(father.className === "bindMove_elemCla-down") father.className = "bindMove_elemCla-up";592                 tar.removeEvent(father, 'mousedown', down);593                 tar.removeEvent(document.body, 'mousemove', move);594                 tar.removeEvent(father, 'mouseup', up);595             });596             var move = tar.addEvent(document.body, 'mousemove', (e)=>{597                 if(isMove === true){598                     father.style.left = e.clientX - sx +"px";599                     father.style.top = e.clientY - sy +"px";600                     _setElemPos(son, father);601                 }602             });603             604             son.bindMove = father;605             son.bindMoveIsHideAll = false;606             //getFatherPosition();607             return son;608         }609         610         var _view = function (obj, arr, fel, isBind, type, name, clas, event_fun, bind_fun){611             612             var p = tar.add(fel, 'p'), info = {p:p, nameEl:{}}, k, len = arr.length, vn = "value", cla = clas || "p-float-"+type;613             var nameer;614             if(type === "checkbox"){vn = "checked";}615             616             var create = (val)=>{617                 let _val = obj[val];618                 let f = tar.add(p, 'p', null, cla);619                 let i = tar.add(f, 'input');620                 let fgx = tar.add(f, 'input', null, "gui-mesh-fgx"); fgx.readOnly = "true";621                 let s = tar.add(f, 'span');622                 fgx = tar.add(f, 'input', null, "gui-mesh-fgx"); fgx.readOnly = "true";623                 nameer = val;624                 if(type === "color"){nameer = _val;}625                 i.type = type;626                 i[vn] = _val;627 628                 s.innerHTML = name || nameer+"";629                 630                 tar.addEvent(i, 'change', (e)=>{631                     _val = e.target[vn];632                     if(!isBind) obj[val] = _val;633                     if(type === "color") s.innerHTML = _val;634                     if(typeof(event_fun[val]) === "function") event_fun[val](e);635                 });636 637                 //bind(obj, arr[k], _val, (now)=>{el_f.i.checked = now;});638                 if(isBind === true){639                     Object.defineProperty(obj, val, {640                         get(){return _val;},641                         set(v){642                             _val = v;643                             i[vn] = v;644                             if(typeof(bind_fun) === "function"){bind_fun(v);}645                         }646                     });647                 }648                 649                 info.nameEl[val] = s;650             }651 652             for(k = 0; k < len; k++){create(arr[k]);}653             654             return info;655         }656         657         //添加 text输入框(string)658         var _text = function (obj, arr, fel, isBind, callbacks, name){659             return _view(obj, arr, fel, isBind, "text", name, "p-text", callbacks);660         }661         662         //添加 复选框(boolean)663         var _check = function (obj, arr, fel, isBind, callbacks, name){664             return _view(obj, arr, fel, isBind, "checkbox", name, null, callbacks);665         }666         667         //添加 下拉选项框()668         var _select = function (obj, arr, info, fel, isBind, callbacks, name){669             //小狗670             var infos = {nameEl:{}}, k, len = arr.length;671             672             var create = (val, cons)=>{673                 let _val = obj[val];674                 let p = tar.add(fel, 'p');675                 let f = tar.add(p, 'p', null, "p-float-select");676                 let i = tar.add(f, "select");677                 let fgx = tar.add(f, 'input', null, "gui-mesh-fgx"); fgx.readOnly = "true";678                 let s = tar.add(f, 'span'); s.innerHTML = name || val;679                 fgx = tar.add(f, 'input', null, "gui-mesh-fgx"); fgx.readOnly = "true";680                 let ka, lena, T = typeof(cons), A = Array.isArray(cons);681                 if(T === "object" && A === false){682                     for(ka in cons){683                         let opt = tar.add(i, "option");684                         opt.value = cons[ka];685                         opt.innerHTML = ka;686                     }687                 }else if(A === true){688                     lena = cons.length;689                     for(ka = 0; ka <  lena; ka++){690                         if(Array.isArray(cons[ka]) === true && cons[ka].length === 2){691                             let opt = tar.add(i, "option");692                             opt.value = cons[ka][1];693                             opt.innerHTML = cons[ka][0];694                             continue;695                         }696                         let opt = tar.add(i, "option");697                         opt.value = cons[ka];698                         opt.innerHTML = cons[ka];699                     }700                 }701                 tar.addEvent(i, 'change', (e)=>{702                     if(typeof(callbacks[val]) === "function") callbacks[val](e);703                 });704                 705                 infos.nameEl[val] = s;706             }707             708             if(len === 1){709                 if(typeof(info) === "object"){710                     create(arr[0], info[arr[0]]);711                 }else{712                     create(arr[0], info);713                 }714             }else{715                 for(k = 0; k < len; k++){716                     create(arr[k], info[arr[k]]);717                 }718             }719             720             return infos;721         }722         723         //添加 颜色选择器724         var _color = function (obj, arr, fel, isBind, callbacks, name){725             return _view(obj, arr, fel, isBind, "color", name, null, callbacks);726         }727         728         //添加 按钮(function)729         var _click = function (obj, arr, fel, callbacks, name){730             var p = tar.add(fel, 'p'), info = {p:p, nameEl:{}}, k, len = arr.length, ends = [];731             var create = (val)=>{732                 let f = tar.add(p, 'p', null, "p-float-button");733                 let i = tar.add(f, 'input');734                 i.type = "button";735                 i.value = name || val;736                 tar.addEvent(i, 'click', ()=>{737                     obj[val]();738                     if(typeof(callbacks[val]) === "function"){callbacks[val](e);}739                 });740                 info.nameEl[val] = i;741             }742             for(k = 0; k < len; k++){create(arr[k]);}743             return info;744         }745         746         //添加 计量控制器(number) info: object 可选 默认[min, max, step]747         //注意: number属性的初始值不能 小于min 和 大于max; step不能大于max-min 否则会被判定为 下拉选项框 的参数748         var _range = function (obj, arr, info, fel, isBind, callbacks, timerAll, id, name){749             var create = (val)=>{750                 let c = info[val] || di;751                 if(obj[val] < c[0] || obj[val] > c[1] || typeof(obj[val]) !== "number" || isNaN(obj[val]) === true){return;}752                 let p = tar.add(fel, 'p'), i = tar.add(p, 'input');753                 i.type = "range"; i.value = obj[val]; i.min = c[0]; i.max = c[1]; i.step = c[2];754                 let nul = tar.add(p, 'span'); nul.innerHTML = " ";755                 let is = tar.add(p, 'input'); is.type = "tel"; is.value = obj[val];756                 let key = false, x, xs, spva = name || val, s = tar.add(p, 'span'); s.innerHTML = "" + spva;757                 let _val = obj[arr[k]];758                 759                 let getNum = (num)=>{760                     //if(num === _val){return _val;}761                     if(typeof(num) !== "number" || isNaN(num) === true){762                         return _val;763                     }764                     if(num > c[0] && num < c[1]){765                         return num;766                     }else if(num > c[0]){767                         return c[1];768                     }else if(num < c[1]){769                         return c[0];770                     }771                     return _val;772                 }773                 774                 let setNum = (num, e)=>{775                     if(num !== undefined){776                         i.value = num;777                         is.value = num;778                         _val = num;779                         if(!isBind){obj[val] = _val;}780                         if(typeof(callbacks[val]) === "function"){callbacks[val](_val);}781                     }782                 }783                 784                 tar.addEvent(is, 'blur', (e)=>{setNum(getNum(Math.round(Number(e.target.value)/c[2])*c[2]), e);});785                 tar.addEvent(i, 'change', (e)=>{786                     setNum(getNum(e.target.valueAsNumber), e);787                 });788 789                 if(isBind === true){790                     Object.defineProperty(obj, arr[k], {791                         get() {return _val;},792                         set(v) {793                             _val = getNum(Math.round(Number(v)/c[2])*c[2]);794                             i.value = _val;795                             is.value = _val;796                         }797                     });798                 }799                 infos.nameEl[val] = s;800             }801             var di = [0, 100, 1], k, len = arr.length, infos = {p:null, nameEl:{}};802             if(Array.isArray(info) === true){di = info;}803             for(k = 0; k < len; k++){create(arr[k]);}804             return infos;805         }806 807     return _Gui;808 809 })()
View.js

 

   1 "use strict"   2    3 ;(function (){   4        5     //是否支持WebGL   6     if(WEBGL.isWebGLAvailable() === false){   7         document.body.appendChild(WEBGL.getWebGLErrorMessage());   8         return;   9     }  10       11     THREE.Cache.enabled = true;//加载器启用缓存  12       13     Gui.prototype.autoChangeStartPosition = false; //不自动改变初始位置  14       15     var _view = new View().initBody();  16     var _width = _view.size.w;  17     var _height = _view.size.h;  18     var _minDistance = 0.1;  19     var _maxDistance = 5000;  20       21       22     //three  23     var _Three = function (){}  24       25     Object.assign(_Three.prototype, {  26           27         constructor: _Three,  28           29         depthMaterial: new THREE.MeshDepthMaterial({depthPacking: THREE.RGBADepthPacking}),  30           31         createScene: function (bg, fog){//场景  32             let scene = new THREE.Scene();  33             if(typeof(bg) === "number"){scene.background = bg;}  34             else if(Array.isArray(bg) === true){  35                 scene.background = new THREE.CubeTextureLoader()  36                 .setPath('img/cube/skyboxsun25deg/')  37                 .load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );  38             }  39             if(fog) scene.fog = new THREE.Fog(fog.color, fog.near, fog.far);  40             return scene;  41         },  42           43         createCamera: function (fov, width, height, near, far){//相机  44             let w = width === undefined ? _width : width;  45             let h = height === undefined ? _height : height;  46             let camera = new THREE.PerspectiveCamera(fov || 45, w / h, near || _minDistance, far || _minDistance * 1000);  47             camera.position.set(0, 0, _maxDistance * 0.001);  48             camera.lookAt( 0, 0, 0 );  49             return camera;  50         },  51           52         createRenderer: function (felem, width, height, antialias, lights, shadow, checkShaderErrors){//渲染器  53             let fel = felem || document.body;  54             let renderer = new THREE.WebGLRenderer({  55                 antialias : antialias || false, //抗割齿  56                 powerPreference:"high-performance" //选择高性能GPU渲染  57             });  58             renderer.setSize(width || _width, height || _height);  59             renderer.setPixelRatio(window.devicePixelRatio);  60             renderer.gammaFactor = 2.2; //着色校正  61             renderer.physicallyCorrectLights = lights || false; //使其精确照明  62             renderer.shadowMap.enabled = shadow || false; //渲染阴影  63             renderer.debug.checkShaderErrors = checkShaderErrors || false; //  64             if(!renderer.extensions.get('WEBGL_depth_texture')){console.log("深度纹理扩展获取失败:WEBGL_depth_texture");}  65             fel.appendChild(renderer.domElement);  66             return renderer;  67         },  68           69         addLinghts: function (scene, hc){//灯光  70             let a = new THREE.AmbientLight(0x696969);//环境光(无处不在的光,太阳光)  71               72             let b = new THREE.DirectionalLight(0xFFFFFF, 1);//平行光(产生阴影的光)  73             b.position.set(0, 50, 50);//位置  74             b.castShadow = true;// 产生动态阴影  75             //b.target = Object3D; //平行光的方向是从它的位置到目标位置。默认的目标位置为原点 (0,0,0)。  76             b.shadow.radius = 1;//使阴影边缘变模糊  77             b.shadow.bias = 0.0001;  78             b.shadow.mapSize.width = 1024;//阴影质量w  79             b.shadow.mapSize.height = 1024;//阴影质量h  80               81             //下面属性默认不自动更新  82         /*     let l_d = 20; //光照区域的大小 100 * 100  83             b.shadow.camera.left = -l_d;  84             b.shadow.camera.right = l_d;  85             b.shadow.camera.top = l_d;  86             b.shadow.camera.bottom = -l_d; */  87             b.shadow.camera.near = 0.1;//最近  88             b.shadow.camera.far = 100;//最远  89               90               91             /* var helperShadow = new THREE.CameraHelper(b.shadow.camera);  92             scene.add(a, b, helperShadow);  93             var c = ()=>{()=>{helperShadow.update(); hc.update(); }}  94             new Gui(b.position, ["x", "y", "z"], [-2500, 2500, 1]).change(c)  95             .add(b.shadow, "radius", [-1, 1, 0.1]).change(c)  96             .add(b.shadow.mapSize, ["width", "height"], [0, 2048, 1]).change(c)  97             .title("调试灯光"); */  98             scene.add(a, b);  99             return [a, b]; 100         }, 101          102         addControls: function (scene, camera, renderer, children, hc){//控件 103  104             //拖放控件 105             let drag = new THREE.DragControls(children, camera, renderer.domElement); 106             //drag.addEventListener('hoveron', (e)=>{this.addTarget(e.object);}); 107             drag.enabled = false; 108             //this.dragcontrols = dc; 109              110             //轨道控件 111             let orbit = new THREE.OrbitControls(camera, renderer.domElement); 112             orbit.target = new THREE.Vector3(0, 0, 0);//控件焦点 113             //orbit.minPolarAngle = Math.PI * 0.3;//向上最大角度 114             //orbit.maxPolarAngle = Math.PI * 0.4;//向下最大角度 115             orbit.minDistance = _minDistance;//最小距离 116             orbit.maxDistance = _maxDistance;//最大距离 117             orbit.autoRotateSpeed = 10;//自动旋转速度 118             //orbit.panSpeed = 100;//鼠标旋转速度 119             orbit.enableZoom = true;//是否启用缩放 120             orbit.enableKeys = true;//是否启用键盘 121             orbit.panSpeed = 1;//鼠标平移速度 122             orbit.keyPanSpeed = 100;//按键平移的速度 123             orbit.keys.LEFT = 65;//key a左 124             orbit.keys.UP = 87;//key w前 125             orbit.keys.RIGHT = 68;//key d右 126             orbit.keys.BOTTOM = 83;//key s后 127             orbit.addEventListener("change", ()=>{this.render(scene, camera, renderer);}); 128              129              130             //平移控件 131             var transform = new THREE.TransformControls(camera, renderer.domElement); 132             transform.addEventListener( 'dragging-changed', (e)=>{orbit.enabled = !e.value;}); 133             transform.size = 1; 134             scene.add(transform); 135              136             return {drag: drag, orbit: orbit, transform: transform}; 137         }, 138          139         updateGeometry: function (mesh, geometry){//更换几何体 140             if(!mesh || !geometry){ 141                 console.log("_Three: 几何体更换失败"); 
 142                 return; 143             } 144             mesh.geometry.dispose(); 145             mesh.geometry = geometry; 146         }, 147          148         updateMaterial: function (mesh, material){//更换材质 149             if(!mesh || !material){ 150                 console.log("_Three: 材质更换失败"); 
 151                 return; 152             } 153             let newMat = material.clone(true); 154             //newMat.color.copy(mesh.material.color); 155             newMat.transparent = true; 156             if(mesh.material.map !== null){this.updateTexture(newMat, mesh.material.map);} 157             mesh.material.dispose(); 158             mesh.material = newMat; 159         }, 160          161         updateTexture: function (material, texture){//更换纹理 162             if(!material || !texture){ 163                 console.log("_Three: 纹理更换失败"); 
 164                 return; 165             } 166             let map = new THREE.Texture(texture.image); 167             map.wrapS = THREE.RepeatWrapping; 168             map.wrapT = THREE.RepeatWrapping; 169             map.repeat.set(1, 1); 170             map.minFilter = THREE.NearestFilter; 171             map.magFilter = THREE.NearestFilter; 172             if(material.map !== null){ 173                 map.wrapS = material.map.wrapS; 174                 map.wrapT = material.map.wrapT; 175                 map.repeat.copy(material.map.repeat); 176                 map.anisotropy = material.map.anisotropy; 177                 material.map.dispose(); 178             } 179             material.map = map; 180             material.map.needsUpdate = true; 181             material.needsUpdate = true; 182         }, 183          184         getBox3: function (mesh){//获取Box3 185             mesh.geometry.computeBoundingBox();//计算mesh获取box3对象 186             return mesh.geometry.boundingBox.applyMatrix4(mesh.matrixWorld); 187         }, 188          189         render: function (scene, camera, renderer){//渲染 190             renderer.render(scene, camera); 191         }, 192  193         getBSP: function (meshA, meshB, type){//剪裁 添加 重合 194             if(!meshA || !meshB || !type || meshA === meshB){console.log("getBSP:参数错误, 请选择1至2个物体进行运算"); return;} 195             if(!meshA.geometry || !meshB.geometry) return; 196             if(meshA.geometry.isGeometry !== true || meshB.geometry.isGeometry !== true) return; 197             let bsp_a = new ThreeBSP(meshA);//生成ThreeBSP对象 198             let bsp_b = new ThreeBSP(meshB);//生成ThreeBSP对象 199             let bsp = bsp_a[type](bsp_b);//进行 type 计算 200             let geo = bsp.toGeometry();//console.log(bsp); 201             geo.computeFaceNormals();//更新geo的面 202             geo.computeVertexNormals();//更新geo的顶点 203             return geo; 204         }, 205          206         toBuffer: function (geometry){//几何体 转为缓存几何体 207             if(geometry.isGeometry !== true) return; 208             return new THREE.BufferGeometry().fromGeometry(geometry); 209         }, 210          211         loadingGLTF: function (url, scene){//导入 212             if(!this.loadGLTF){this.__proto__.loadGLTF = new THREE.GLTFLoader();} 213             if(!scene) return; 214             this.loadGLTF.load(url, (gltf)=>{ 215                 scene.add(gltf.scene); 216             }); 217         }, 218          219         exporterGLTF: function (mesh, fileType){//导出物体(限谷歌浏览器) 220             if(!this.exportGLTF){this.__proto__.exportGLTF = new THREE.GLTFExporter();} 221             if(!mesh){console.log("mesh 错误"); return;} 222             // 使用MeshBasicMaterial 或 MeshStandardMaterial 材质 效果会更好 223             //使用 BufferGeometry 缓存几何体 文件体积会更小 224             //if(mesh.geometry.isGeometry === true){mesh.geometry = new THREE.BufferGeometry().fromGeometry(mesh.geometry);} 225             var opt = { 226                 binary: fileType || this.exportGLTFFileType || false, 227                 embedImages: true, 228                 onlyVisible: true, 229                 truncateDrawRange: true, 230                 trs: false 231             }; 232             var download = ( blob, filename )=>{ 233                 let link = _view.add(document.body, "a"); 234                 link.style.display = 'none'; 235                 link.href = URL.createObjectURL( blob ); console.log(link.href); 236                 link.download = filename; 237                 link.click(); 238                 _view.remove(link); 
 239             } 240              241             this.exportGLTF.parse(mesh, function ( result ){ 242                 if(result instanceof ArrayBuffer){ 243                     download(new Blob([result], {type: 'application/octet-stream'}), 'scene.glb'); 244                 }else{ 245                     download(new Blob([JSON.stringify( result, null, 2 )], {type: 'text/plain'}), 'scene.gltf'); 246                 } 247             }, opt); 248         }, 249          250         runRaycaster: function (o, w, h){//光线投射 251             o.result.length = 0; 252             o.vector2.set((o.x / w || _width) * 2 - 1, -(o.y / h || _height) * 2 + 1); 253             o.raycaster.setFromCamera(o.vector2, o.camera); 254             o.raycaster.intersectObjects(o.children, o.recursive, o.result); 255         }, 256          257         createClipPlane: function (handCreate){//添加 面 和 点 剪裁面 258             let pa = new THREE.Plane(new THREE.Vector3( 1, 0, 0 ), 1); 259             let pb = new THREE.Plane(new THREE.Vector3( 0, -1, 0 ), 1); 260             let pc = new THREE.Plane(new THREE.Vector3( 0, 0, -1), 1); 261             let pd = new THREE.Plane(new THREE.Vector3( 0, 1, 1), 1); 262              263             let hg = new THREE.Group(); 264             hg.add(new THREE.PlaneHelper(pa, 2, 0xff0000), new THREE.PlaneHelper(pb, 2, 0x00ff00), new THREE.PlaneHelper(pc, 2, 0x0000ff), new THREE.PlaneHelper(pd, 2, 0x0000ff)); 265             return { 266                 planes: [pa, pb, pc, pd], 267                 helpers: hg 268             }; 269             var geometry = new THREE.SphereGeometry(1, 48, 24); 270             var material = new THREE.MeshLambertMaterial({ 271                 color: new THREE.Color("#666666"), 272                 side: THREE.DoubleSide, 273                 clippingPlanes: clipPlane, 274                 clipIntersection: true 275             }); 276             console.log(helper0); console.log(material); 277             handCreate.add(new THREE.Mesh(geometry, material), helperGroup); 278              279             handCreate.renderer.localClippingEnabled = true; 280              281             //clipPlane.constant = 0.1; 282             new Gui({constant:0}, [-1, 1, 0.01]) 283             .change((val)=>{ 284                 for(let k = 0; k < clipPlane.length; k++){ 285                     clipPlane[k].constant = val; 286                 } 287                 handCreate.update(); 288             }) 289             .add(material, "clipIntersection") 290             .add(helper0, "size", [0, 10, 0.1]) 291             .change(()=>{handCreate.update();}) 292         } 293          294     }); 295      296      297      298     //几何体 299     var _Geometry = function (){ 300         _Three.call(this); 301         //this.width = 100; _width 302         this.height = 100; 303         this.y = this.campos.y; 304         this.dis = 0.5; 305         this.backMesh = {distance: 0, nowDistance: 0}; 306         this.targetChange = null; 307         this.objects = []; 308     } 309      310     _Geometry.prototype = Object.assign(Object.create(_Three.prototype), { 311          312         constructor: _Geometry, 313          314         config: [ 315             new THREE.BoxGeometry(1, 1, 1, 1, 1, 1), 
 316             new THREE.SphereGeometry(0.5, 8 , 6, 0, Math.PI * 2, 0, Math.PI), 317             new THREE.PlaneGeometry(1, 1, 1, 1) 318         ], 319  320         campos: {x: _width/110, y: 0, z: 1.5}, 321          322         isGoToPosition: true, 323  324         defaultMaterial: new THREE.MeshBasicMaterial({wireframe: true}), 325          326         init: function (){//初始化 327             if(this.scene === undefined)  this.addScene(); 328             if(this.show === undefined)  this.setShow(); 329             if(this.target === undefined) this.setTarget(); 330             this.renderView(this.config); 331             return this; 332         }, 333          334         addScene: function (){//添加 场景 335             let elem = _view.add(document.body, "div", null, "ShowObject box-scroll-block"); 336             _view.addEvent(elem, 'click', (e)=>{this.addTarget(e);}); 337              338             let scene = this.createScene(0x000000, false); 339             var camera = new THREE.OrthographicCamera(_width/-100, _width/100, this.height/100, this.height/-100, 0.1, 10); 340             camera.lookAt(0, 0, 0); 341             let renderer = this.createRenderer(elem, _width, this.height, true, true, true, true); 342             let linghts = this.addLinghts(scene); 343             let drag = new THREE.DragControls(scene.children, camera, renderer.domElement); 344             drag.enabled = false; 345             this.__proto__.scene = {e: elem, s:scene, c: camera, r: renderer, l: linghts, drag: drag, target: null} 346             drag.enabled = false; 347             drag.addEventListener('drag', (e)=>{ 348                 this.update(); 349             }); 350             drag.addEventListener('hoveron', (e)=>{ 351                 if(drag.enabled === true) return; 352                 this.scene.target = e.object; 353             }); 354             drag.addEventListener('hoveroff', ()=>{ 355                 this.scene.target = null; 356             }); 357              358             this.goToPosition(); 359         }, 360          361         addLinghts: function (scene){//重写添加灯光 362             let a = new THREE.AmbientLight(0x696969); 363             let b = new THREE.DirectionalLight(0xFFFFFF, 1); 364             b.position.set(0, 5, 5); 365             scene.add(a, b); 366             return [a, b]; 367         }, 368          369         goToPosition: function (){//跳转到 geometry 坐标 370             if(this.isGoToPosition === false) return; 371             this.scene.c.position.set(this.campos.x, this.campos.y, this.campos.z); 372             this.update(); 373         }, 374          375         setPos: function (mesh, k){//renderView-> 设置物体之间的距离 376             mesh.position.set(this.backMesh.distance, this.y, 0); 377             //let size = box3.getSize(new THREE.Vector3()); 378             let box3 = this.getBox3(mesh); 379             let width = box3.getSize(new THREE.Vector3()).x; 380             let center = box3.getCenter(new THREE.Vector3()).x; 381              382             //let dtp = box3.distanceToPoint(new THREE.Vector3(this.backMesh.distance, this.y, 0)); 383             //console.log(width); 384             this.backMesh.distance += width + this.dis; 385              386             //this.backMesh.left = this.backMesh.distance - width + center; 387              388             //this.backMesh.nowDistance = width / 2 - center + this.backMesh.distance; 389             //var helper = new THREE.Box3Helper(box3, 0xffff00); 390             //helper.position.copy(mesh.position); 391             //this.scene.s.add(helper); 392              393             //console.log(this.backMesh) 394             //console.log(width, center); 395         }, 396          397         addMesh: function (object, key){//renderView-> 添加物体 398             let mesh = new THREE.Mesh(object, this.defaultMaterial); 399             mesh.HandCreate = {type: "_Geometry", index: key, MatIndex: 0} 400             this.scene.s.add(mesh); 401             return mesh; 402         }, 403  404         renderView: function (arr){//渲染场景视图 405             for(let k = 0; k < arr.length; k++){ 406                 let mesh = this.addMesh(arr[k], k); 407                 this.setPos(mesh, k); 408                 this.objects.push(mesh); 409             } 410             this.update(); 411         }, 412          413         setShow: function (){//是否显示场景的html元素 414             let _show = false; 415             Object.defineProperties(this.__proto__, { 416                 show: { 417                     get:()=>{return _show;}, 418                     set:(v)=>{ 419                         if(v === true){ 420                             this.scene.e.style.display = "block"; 421                         }else{ 422                             this.scene.e.style.display = "none"; 423                         } 424                         _show = v; 425                     } 426                 } 427             }); 428         }, 429          430         addTarget: function (e){//addScene event->场景html元素的事件回调函数 431             if(!this.scene.target) return; 432             this.target = this.scene.target; 433         }, 434          435         setTarget: function (){//配置 target 436             let _target = null; 437             Object.defineProperties(this.__proto__, { 438                 target: { 439                     get:()=>{return _target;}, 440                     set:(v)=>{ 441                         if(typeof(this.targetChange) === "function") this.targetChange(v); 442                         _target = v; 443                     } 444                 } 445             }); 446         }, 447          448         exportObject: function (){//导出 几何体 449              450         }, 451          452         importObject: function (object){//导入 几何体 453             if(object.isGeometry !== true) return; 454             let nowKey = this.config.length; 455             let mesh = this.addMesh(object, nowKey); 456             this.setPos(mesh, nowKey); 457             this.config.push(object); 458             this.objects.push(mesh); 459             this.update(); 460         }, 461          462         update: function (){//更新场景 463             this.render(this.scene.s, this.scene.c, this.scene.r); 464         }, 465          466         updateObjectColors: function (color){ 467             for(let k = 0; k < this.objects.length; k++){ 468                 this.objects[k].material.color.set(color); 469             } 470             this.update(); 471         }, 472          473         debugCamera: function (){//gui调试 正交相机 474             let c = this.scene.c; 475             let pos = {x: _width/110, y: 0, lookAt: true, position: false}; 476             let upd = ()=>{ 477                 if(pos.lookAt) c.lookAt(pos.x, pos.y, 0); 
 478                 if(pos.position) c.position.set(pos.x, pos.y, 5); 479                 this.update(); 480             } 481  482             new Gui(pos, [0, 10, 0.1], "调试正交相机") 483             .change({ 484                 x: (v)=>{pos.x = v; upd();}, 485                 y: (v)=>{pos.y = v;  upd();} 486             }) 487  488         } 489          490     }); 491      492      493      494     //材质 495     var _Material = function (){ 496         _Geometry.call(this); 497     } 498      499     _Material.prototype = Object.assign(Object.create(_Geometry.prototype), { 500          501         constructor: _Material, 502          503         config:[ 504             new THREE.MeshBasicMaterial(), 505             new THREE.MeshLambertMaterial(), 506             new THREE.MeshStandardMaterial() 507         ], 508          509         defaultGeometry: new THREE.BoxGeometry(1, 1, 1, 1, 1, 1), 510          511         campos: {x: _width/110, y: 1.5, z: 1.5}, 512          513         addMesh: function (object, key){ 514             let mesh = new THREE.Mesh(this.defaultGeometry, object); 515             mesh.HandCreate = {type: "_Material", index: key}; 516             this.scene.s.add(mesh); 517             return mesh; 518         }, 519          520         goToPosition: function (mesh){ 521             if(!mesh || this.isGoToPosition === false) return; this.mesh = mesh; 522             let geometry = _Geometry.prototype.config[mesh.HandCreate.GeoCI].clone(); 523             for(let k = 0; k < this.objects.length; k++){ 524                 this.updateGeometry(this.objects[k], geometry); 525             } 526             this.scene.c.position.set(this.campos.x, this.campos.y, this.campos.z); 527             this.update(); 528         } 529          530     }); 531      532      533      534     //纹理 map 535     var _Texture = function (){ 536         _Material.call(this); 537         this.textureLen = 12; 538         this.setTexture(); 539     } 540      541     _Texture.prototype = Object.assign(Object.create(_Material.prototype), { 542          543         constructor: _Texture, 544          545         config: [], 546          547         campos: {x: _width/110, y: 3, z: 1.5}, 548          549         defaultMaterial: new THREE.MeshBasicMaterial(), 550          551         load: new THREE.TextureLoader(), 552          553         loaded: 0, 554          555         setTexture: function (){ 556             let k, texture; 557             for(k = 0; k < this.textureLen; k++){ 558                 texture = this.load.load("img/texture/"+k+".jpg", ()=>{this.__proto__.loaded++;}); 559                 texture.wrapS = THREE.RepeatWrapping; 560                 texture.wrapT = THREE.RepeatWrapping; 561                 texture.repeat.set(1, 1); 562                 this.__proto__.config.push(texture); 563             } 564             if(this.loaded !== this.textureLen){this.awaitLoad();} 565         }, 566          567         awaitLoad: function (){ 568             let interval = setInterval(()=>{ 569                 if(this.loaded === this.textureLen){ 570                     this.update(); 571                     clearInterval(interval); 572                     console.log("load texture: "+this.loaded+"/"+this.textureLen); 573                 }else{ 574                     console.log("load texture: "+this.loaded+"/"+this.textureLen); 575                 } 576             }, 300); 577         }, 578  579         addMesh: function (object, key){ 580             let mesh = new THREE.Mesh(this.defaultGeometry, new THREE.MeshBasicMaterial({map: object})); 581             //let mesh = new THREE.Mesh(this.defaultGeometry, this.defaultMaterial); 582             //this.updateTexture(mesh, object); 583             mesh.HandCreate = {type: "_Texture", index: key}; 584             this.scene.s.add(mesh); 585             return mesh; 586         }, 587          588         goToPosition: function (mesh){ 589             if(!mesh || this.isGoToPosition === false) return; this.mesh = mesh; 590             let geometry = _Geometry.prototype.config[mesh.HandCreate.GeoCI].clone(); 591             let material = _Material.prototype.config[mesh.HandCreate.MatCI].clone(); 592             for(let k = 0; k < this.objects.length; k++){ 593                 this.updateGeometry(this.objects[k], geometry); 594                 this.updateMaterial(this.objects[k], material); 595             } 596             this.scene.c.position.set(this.campos.x, this.campos.y, this.campos.z); 597             this.update(); 598         } 599          600     }); 601      602     //物体 603     var _Mesh = function (){} 604      605     //gui 606     var SetView = function (HC, newMesh, oldMesh){ 607         this.HC = HC; 608         this.newMesh = newMesh; 609         this.oldMesh = oldMesh; 610         return this.init(); 611     } 612      613     Object.assign(SetView.prototype, { 614          615         constructor: SetView, 616          617         init: function (){ 618             if(this.globalGui === undefined) this.createGlobal(); 619             this.gui = new Gui().display("none"); 620              621             this.createMesh(); 622             this.createGeometry(); 623             this.createMaterial(); 624             return this; 625         }, 626          627         createMesh: function (){ 628             let o = { 629                 exportGltf: ()=>{this.HC.Three.exporterGLTF(this.newMesh);}, 630                 removeMesh: ()=>{this.HC.remove(this.newMesh);}, 631                 getBSP: "intersect", 632                 runGetBSP: ()=>{ 633                     if(this.HC.targets[0] === undefined){console.log("请在global里勾选'选择物体'选项进行选择物体"); return;} 634                     let meshB = this.HC.targets[0].mesh; 635                     if(this.newMesh === meshB && this.HC.targets[1] !== undefined) meshB = this.HC.targets[1].mesh; 636                     this.HC.geometry.importObject(this.HC.Three.getBSP(this.newMesh.clone(true), meshB.clone(true), o.getBSP)); 637                     this.HC.removeTargets(); //this.HC.isSelectTargets = false; 638                 } 639             } 640             let m = { 641                 visible: this.newMesh.visible, 642                 frustumCulled: this.newMesh.frustumCulled, 643                 castShadow: this.newMesh.castShadow, 644                 receiveShadow: this.newMesh.receiveShadow, 645             } 646              647             this.gui.create(m, true).name({visible: "显示物体", castShadow: "投射阴影", receiveShadow: "接收阴影"}) 648             .change({ 649                 visible: ()=>{ 650                     if(this.newMesh.visible === undefined) return; 651                     this.newMesh.visible = m.visible; 652                     this.HC.update(); 653                 }, 654                 frustumCulled: ()=>{ 655                     if(this.newMesh.frustumCulled === undefined) return; 656                     this.newMesh.frustumCulled = m.frustumCulled; 657                     this.HC.update(); 658                 }, 659                 castShadow: ()=>{ 660                     if(this.newMesh.castShadow === undefined) return; 661                     this.newMesh.castShadow = m.castShadow; 662                     this.HC.update(); 663                 }, 664                 receiveShadow: ()=>{ 665                     if(this.newMesh.receiveShadow === undefined) return; 666                     this.newMesh.receiveShadow = m.receiveShadow; 667                     this.HC.update(); 668                 } 669             }) 670              671             .add(o, {getBSP:[["交集", "intersect"], ["并集", "union"], ["差集", "subtract"]]}, true) 672             .name({exportGltf: "导出物体", removeMesh: "移除物体", getBSP: "布尔运算类型(选择一个物体)", runGetBSP: "布尔运算"}) 673             .change({ 674                 getBSP: (e)=>{o.getBSP = e.target.value;} 675             }) 676              677             .add(this.newMesh.HandCreate.position, true, [-(_maxDistance/2), _maxDistance/2, _minDistance]) 678             .name({x: "位置X轴", y: "位置Y轴", z: "位置Z轴"}) 679             .change({ 680                 x: (v)=>{this.newMesh.position.x = v; this.HC.update();}, 681                 y: (v)=>{this.newMesh.position.y = v; this.HC.update();}, 682                 z: (v)=>{this.newMesh.position.z = v; this.HC.update();} 683             }) 684              685             .add(this.newMesh.HandCreate.rotation, true, [-Math.PI, Math.PI, 0.001]) 686             .name({x: "旋转X轴", y: "旋转Y轴", z: "旋转Z轴"}) 687             .change({ 688                 x: (v)=>{this.newMesh.rotation.x = v; this.HC.update();}, 689                 y: (v)=>{this.newMesh.rotation.y = v; this.HC.update();}, 690                 z: (v)=>{this.newMesh.rotation.z = v; this.HC.update();} 691             }) 692              693             .add(this.newMesh.HandCreate.scale, true, [-(_maxDistance * 0.5), _maxDistance * 0.5, _minDistance]) 694             .name({x: "缩放X轴", y: "缩放Y轴", z: "缩放Z轴"}) 695             .change({ 696                 x: (v)=>{this.newMesh.scale.x = v; this.HC.update();}, 697                 y: (v)=>{this.newMesh.scale.y = v; this.HC.update();}, 698                 z: (v)=>{this.newMesh.scale.z = v; this.HC.update();} 699             }) 700              701             .add(this.newMesh.HandCreate, "isSelect", true, "是否可选取").change(()=>{this.HC.removeTarget(this.newMesh);}) 702              703             .title("物体-"+this.newMesh.type+"-"+this.newMesh.id); 704         }, 705          706         createGeometry: function (){ 707             if(this.oldMesh.geometry.parameters === undefined){console.log("SetView: 忽略了geometry"); return;} 708             let o, p = {}, geo; 709             for(let k in this.oldMesh.geometry.parameters){p[k] = this.oldMesh.geometry.parameters[k];} 710             switch(this.oldMesh.geometry.type){ 711              712                 case "BoxGeometry": 
 713                     o = { 714                         width:[0.1, 10, 0.1], 
 715                         height:[0.1, 10, 0.1], 
 716                         depth:[0.1, 10, 0.1], 
 717                         widthSegments:[1, 30, 1], 
 718                         heightSegments:[1, 30, 1], 
 719                         depthSegments:[1, 30, 1] 720                     } 721                     this.gui.create(p, o, true) 722                     .name({width: "宽度", height: "高度", depth: "深度", widthSegments: "宽段数", heightSegments: "高段数", depthSegments: "深段数"}) 723                     .change(()=>{ 724                         geo = new THREE.BoxGeometry(p.width, p.height, p.depth, p.widthSegments, p.heightSegments, p.depthSegments); 725                         this.HC.Three.updateGeometry(this.newMesh, geo); 726                         this.HC.update(); 727                     }); 728                      729                 break; 730                  731                 case "SphereGeometry": 
 732                     o = { 733                         radius:[0.1, 10, 0.1], 
 734                         widthSegments:[1, 30, 1], 
 735                         heightSegments:[1, 30, 1], 
 736                         phiStart:[0, Math.PI*2, 0.1], 
 737                         phiLength:[0, Math.PI*2, 0.1], 
 738                         thetaStart:[0, Math.PI*2, 0.1], 
 739                         thetaLength:[0, Math.PI*2, 0.1] 740                     } 741                     this.gui.create(p, o, true) 742                     .name({radius: "半径", widthSegments: "宽段数", heightSegments: "高段数", phiStart: "经线起始角度", phiLength: "经线起始角度大小", thetaStart: "纬线起始角度", thetaLength: "纬线起始角度大小",}) 743                     .change(()=>{ 744                         geo = new THREE.SphereGeometry(p.radius, p.widthSegments, p.heightSegments, p.phiStart, p.phiLength, p.thetaStart, p.thetaLength); 745                         this.HC.Three.updateGeometry(this.newMesh, geo); 746                         this.HC.update(); 747                     }); 748                      749                 break; 750                  751                 case "PlaneGeometry": 
 752                     o = { 753                         width: [1, 100, 0.1], 754                         height: [1, 100, 0.1], 755                         widthSegments: [1, 30, 1], 756                         heightSegments: [1, 30, 1] 757                     } 758                     this.gui.create(p, o, true) 759                     .name({width: "宽度", height: "高度", widthSegments: "宽段数", heightSegments: "高段数"}) 760                     .change(()=>{ 761                         geo = new THREE.PlaneGeometry(p.width, p.height, p.widthSegments, p.heightSegments); 762                         this.HC.Three.updateGeometry(this.newMesh, geo); 763                         this.HC.update(); 764                     }); 765                 break; 766                      767                 default : break; 768             } 769             this.gui.title("几何体-"+this.newMesh.geometry.type+"-"+this.newMesh.id); 770         }, 771          772         createMaterial: function (){ 773             let mat = this.newMesh.material; 774             let o = { 775                 color: "#" + mat.color.getHexString(), 776                 emissive: mat.emissive === undefined ? "#000000" : "#" + mat.emissive.getHexString(), 777                 updateMaterial: ()=>{this.HC.material.goToPosition(this.newMesh);}, 778                 updateTexture: ()=>{this.HC.texture.goToPosition(this.newMesh);} 779             } 780             let m = { 781                 wireframe: mat.wireframe, 
 782                 visible: mat.visible, 
 783                 side: mat.side, 
 784                 fog: mat.fog, 
 785                 aoMapIntensity: mat.aoMapIntensity, 
 786                 colorWrite: mat.colorWrite, 
 787                 transparent: mat.transparent, 
 788                 opacity: mat.opacity, 
 789                 alphaTest: mat.alphaTest, 
 790                 flatShading: mat.flatShading, 791                 emissiveIntensity: mat.emissiveIntensity === undefined ? 0 : mat.emissiveIntensity, 792                 repeatU: 1, 793                 repeatV: 1, 794                 anisotropy: 1 795             } 796              797             let num = { 798                 aoMapIntensity: [0, 1, 0.1], 
 799                 opacity: [0, 1, 0.1], 
 800                 alphaTest: [0, 1, 0.1], 
 801                 emissiveIntensity: [0, 1, 0.1], 802                 repeatU: [1, 100, 1], 803                 repeatV: [1, 100, 1], 804                 anisotropy: [1, this.HC.renderer.capabilities.getMaxAnisotropy() || 2, 1] 805             }; 806             let sel = { 807                 side: [["外面", THREE.FrontSide], ["里面", THREE.BackSide], ["双面", THREE.DoubleSide]] 808             }; 809             let name = { 810                 wireframe:"网格模式", 
 811                 visible:"显示材质", 
 812                 side: "材质显示那一面", 
 813                 fog: "受雾气影响", 
 814                 aoMapIntensity: "遮挡效果", 
 815                 colorWrite: "渲染颜色", 
 816                 transparent: "渲染透明度", 
 817                 opacity: "透明度", 
 818                 alphaTest: "alpha值", 
 819                 flatShading: "平面着色", 820                 emissiveIntensity: "放射光强度", 821                 repeatU: "重复量,纹理U面", 822                 repeatV: "重复量,纹理V面", 823                 anisotropy: "纹理清晰度" 824             }; 825             let c = { 826                 wireframe: ()=>{if(this.newMesh.material.wireframe === undefined){this.gui.showStop("wireframe", m); return;}else{this.gui.showStop("wireframe", m, false);}  this.newMesh.material.wireframe = m.wireframe; this.HC.update();}, 827                 visible: ()=>{if(this.newMesh.material.visible === undefined){this.gui.showStop("visible", m); return;}else{this.gui.showStop("visible", m, false);}  this.newMesh.material.visible = m.visible; this.HC.update();}, 828                 side: (e)=>{if(this.newMesh.material.side === undefined){this.gui.showStop("side", m); return;}else{this.gui.showStop("side", m, false);}  this.newMesh.material.side = eval(e.target.value); this.HC.update();}, 829                 fog: ()=>{if(this.newMesh.material.fog === undefined){this.gui.showStop("fog", m); return;}else{this.gui.showStop("fog", m, false);}  this.newMesh.material.fog = m.fog; this.HC.update();}, 830                 aoMapIntensity: ()=>{if(this.newMesh.material.aoMapIntensity === undefined){this.gui.showStop("aoMapIntensity", m); return;}else{this.gui.showStop("aoMapIntensity", m, false);}  this.newMesh.material.aoMapIntensity = m.aoMapIntensity; this.HC.update();}, 831                 colorWrite: ()=>{if(this.newMesh.material.colorWrite === undefined){this.gui.showStop("colorWrite", m); return;}else{this.gui.showStop("colorWrite", m, false);}  this.newMesh.material.colorWrite = m.colorWrite; this.HC.update();}, 832                 transparent: ()=>{if(this.newMesh.material.transparent === undefined){this.gui.showStop("transparent", m); return;}else{this.gui.showStop("transparent", m, false);}  this.newMesh.material.transparent = m.transparent; this.HC.update();}, 833                 opacity: ()=>{if(this.newMesh.material.opacity === undefined){this.gui.showStop("opacity", m); return;}else{this.gui.showStop("opacity", m, false);}  this.newMesh.material.opacity = m.opacity; this.HC.update();}, 834                 alphaTest: ()=>{if(this.newMesh.material.alphaTest === undefined){this.gui.showStop("alphaTest", m); return;}else{this.gui.showStop("alphaTest", m, false);}  this.newMesh.material.alphaTest = m.alphaTest; this.HC.update();}, 835                 flatShading: ()=>{if(this.newMesh.material.flatShading === undefined){this.gui.showStop("flatShading", m); return;}else{this.gui.showStop("flatShading", m, false);}  this.newMesh.material.flatShading = m.flatShading; this.HC.update();}, 836                 emissiveIntensity: ()=>{if(this.newMesh.material.emissiveIntensity === undefined){this.gui.showStop("emissiveIntensity", m); return;}else{this.gui.showStop("emissiveIntensity", m, false);}  this.newMesh.material.emissiveIntensity = m.emissiveIntensity; this.HC.update();}, 837                 repeatU: ()=>{if(this.newMesh.material.map === null){this.gui.showStop("repeatU", m); return;}else{this.gui.showStop("repeatU", m, false);} this.newMesh.material.map.repeat.set(m.repeatU, m.repeatV);this.HC.update();}, 838                 repeatV: ()=>{if(this.newMesh.material.map === null){this.gui.showStop("repeatV", m); return;}else{this.gui.showStop("repeatV", m, false);} this.newMesh.material.map.repeat.set(m.repeatU, m.repeatV); this.HC.update();}, 839                 anisotropy: ()=>{if(this.newMesh.material.map === null || (m.anisotropy !== 1 && (m.anisotropy / 2 % 1) !== 0)){this.gui.showStop("anisotropy", m); return;}else{this.gui.showStop("anisotropy", m, false);}this.newMesh.material.map.anisotropy = m.anisotropy;this.HC.update();}, 840                  841             }; 842              843             this.gui.create(m, num, true, sel).name(name).change(c) 844              845             .add(o, true) 846             .name({color: "材质颜色", emissive: "放射光颜色", updateMaterial: "替换材质", updateTexture: "替换纹理"}) 847             .change({ 848                 color: (e)=>{if(this.newMesh.material.color === undefined){this.gui.showStop("color", o); return;}else{this.gui.showStop("color", o, false);}  this.newMesh.material.color.set(e.target.value); this.HC.update();}, 849                 emissive: (e)=>{if(this.newMesh.material.emissive === undefined){this.gui.showStop("emissive", o); return;}else{this.gui.showStop("emissive", o, false);} this.newMesh.material.emissive.set(e.target.value); this.HC.update();} 850             }) 851              852             .title("材质-"+this.newMesh.material.type+"-"+this.newMesh.id); 853         }, 854          855         createGlobal: function (){ 856             let o = { 857                 setMode: "translate", 858                 exportAll: ()=>{console.log("导出全部物体")}, 859                 updateMaterialAll: ()=>{console.log("替换全部材质")}, 860                 isgltf: true, 861                 dragEnabled: false, 862                 addMesh: ()=>{this.HC.geometry.goToPosition();} 863             } 864  865             let gui = new Gui(this.HC.geometry, "show", "显示选项栏") 866              867             .add(o, true, {dragEnabled: [["创建模式", false], ["编辑模式", true]], isgltf: [[".gltf", false], [".glb", true]], setMode: [["平移", "translate"], ["旋转", "rotate"], ["缩放", "scale"]]}) 868             .name({exportAll: "导出全部物体", updateMaterialAll: "替换全部材质", setMode: "控制模式", isgltf: "导出类型", addMesh: "添加物体", dragEnabled: "底部物体选项栏的状态(创建 或 调整其位置)"}) 869             .change({ 870                 isgltf: (e)=>{this.HC.Three.exportGLTFFileType = eval(e.target.value);}, 871                 setMode: (e)=>{this.HC.control.transform.setMode(e.target.value);}, 872                 dragEnabled: (e)=>{ 873                     let ty = "geometry"; 874                     if(this.HC.geometry.scene.c.position.y === this.HC.material.campos.y){ty = "material";} 875                     else if(this.HC.geometry.scene.c.position.y === this.HC.texture.campos.y){ty = "texture";} 876  877                     this.HC.geometry.scene.drag.enabled = eval(e.target.value); 878                     if(this.HC.geometry.scene.drag.enabled === true){ 879                         this.HC.geometry.__proto__.isGoToPosition = false; 880                         this.HC[ty].updateObjectColors(0xff0000); 881                     }else{ 882                         this.HC[ty].updateObjectColors(0xffffff); 883                         this.HC.geometry.__proto__.isGoToPosition = true; 884                     } 885                  886                 } 887             }) 888              889             .add(this.HC, true, ["lockTarget", "isSelectTargets"]) 890             .name({lockTarget: "是否可选取", isSelectTargets: "标记物体"}) 891             .change({ 892                 isSelectTargets: ()=>{ 893                     if(this.HC.isSelectTargets === false){ 894                         this.HC.removeTargets(); 895                     } 896                      897                 }, 898                 lockTarget: ()=>{ 899                     if(this.HC.lockTarget === false){ 900                         this.HC.removeTargets(); 901                     } 902                 } 903             }) 904              905             .setPos(310, 10) 906              907             .title("global"); 908              909             this.__proto__.globalGui = gui; 910         } 911          912     }); 913      914      915      916     //main 917     var HandCreate = function (){ 918         this.Three = new _Three(); 919         this.group = new THREE.Group(); 920         this.target = {}; 921         this.isSelectTargets = false; 922         this.targets = []; 923         this.backMesh = null; 924         this.lockTarget = false; 925         this.scene = this.Three.createScene([], false); 926         this.renderer = this.Three.createRenderer(document.body, _width, _height, true, true, true, true); 927          928     } 929      930     Object.assign(HandCreate.prototype, { 931          932         constructor: HandCreate, 933          934         init: function (){ 935             this.intersects = { 936                 raycaster: new THREE.Raycaster(), 937                 group: new THREE.Group(), 938                 vector2: new THREE.Vector2(), 939                 result: [], 940                 camera: this.camera, 941                 recursive: true, 942                 x: 0, 943                 y: 0, 944             }; 945             this.renderer.domElement.style = "position:absolute; top:0; left:0";//如果不定位, gui的移动块会不正常显示 946             //this.renderer.localClippingEnabled = true;//是否渲染 平面剪裁 947             this.camera = this.Three.createCamera(45, _width, _height, _minDistance, _maxDistance * _minDistance * 0.2); 948             this.camera.position.set(0, _maxDistance * 0.001, _maxDistance * 0.001); 949             this.linghts = this.Three.addLinghts(this.scene, this); 950             this.control = this.Three.addControls(this.scene, this.camera, this.renderer, this.intersects.group.children, this); 951             this.control.drag.addEventListener('hoveron', (e)=>{this.setTarget(e.object);}); 952             this.control.transform.addEventListener('change', ()=>{ 953                 if(!this.target || !this.target.mesh || !this.target.mesh.HandCreate){return;} 954                 let type = this.control.transform.getMode(); 955                 switch(type){ 956                     case "translate": 
 957                         this.target.mesh.HandCreate.position.x = this.target.mesh.position.x; 958                         this.target.mesh.HandCreate.position.y = this.target.mesh.position.y; 959                         this.target.mesh.HandCreate.position.z = this.target.mesh.position.z; 960                     break; 961                      962                     case "rotate": 
 963                         this.target.mesh.HandCreate.rotation.x = this.target.mesh.rotation.x; 964                         this.target.mesh.HandCreate.rotation.y = this.target.mesh.rotation.y; 965                         this.target.mesh.HandCreate.rotation.z = this.target.mesh.rotation.z; 966                     break; 967                      968                     case "scale": 
 969                         this.target.mesh.HandCreate.scale.x = this.target.mesh.scale.x; 970                         this.target.mesh.HandCreate.scale.y = this.target.mesh.scale.y; 971                         this.target.mesh.HandCreate.scale.z = this.target.mesh.scale.z; 972                     break; 973                      974                     default: break; 975                 } 976                 this.update(); 977             }); 978              979             this.geometry = new _Geometry().init(); 980             this.geometry.targetChange = (v)=>{this.createObject(v);}; 981             this.geometry.show = true; 982              983             this.material = new _Material().init(); 984              985             this.texture = new _Texture().init(); 986              987             this.gridHelper = new THREE.GridHelper(_maxDistance, _maxDistance/1); 988             this.scene.add(this.group, this.intersects.group, this.camera, this.gridHelper); 989              990             //this.clip = this.Three.createClip(); 991             //this.globalView(); 992             //this.Three.loadingGLTF("img/gltfs/scene.gltf", this.intersects.group); 993             //this.Three.loadingGLTF("img/gltfs/scene.glb", this.intersects.group); 994             return this; 995         }, 996          997         add: function (mesh, group){ 998             if(!mesh) return; 999             let gro = group || this.intersects.group;1000             if(Array.isArray(mesh) === true){1001                 let k, len = mesh.length;1002                 for(k; k < len; k++){1003                     if(!mesh[k]) continue;1004                     gro.add(mesh[k]);1005                 }1006             }else{1007                 gro.add(mesh);1008             }1009             this.update();1010         },1011         1012         remove: function (mesh, group){1013             if(!mesh){console.log("remove: mesh不存在"); return;}1014             let arr = group || this.intersects.group;1015             if(!arr.remove){console.log("remove: group错误"); return;}1016             this.removeTarget();1017             if(mesh.gui) mesh.gui.remove();1018             mesh.HandCreate.SV.gui.remove();1019             if(mesh.material.map){mesh.material.map.dispose();}1020             mesh.material.dispose();1021             mesh.geometry.dispose();1022             arr.remove(mesh);1023             this.update();1024         },1025         1026         update: function (){1027             this.Three.render(this.scene, this.camera, this.renderer);1028         },1029 1030         setTarget: function (mesh){1031             if(mesh.HandCreate.isSelect === false) return;1032             if(this.isSelectTargets === true) this.setTargets(mesh);1033             if(this.target.mesh === mesh || this.lockTarget === true) return;1034             if(mesh.HandCreate === undefined || mesh.HandCreate.SV === undefined){1035                 mesh.HandCreate.isSelect = false;1036                 this.lockTarget = true; 
1037                 console.log("setTarget: mesh 错误,取消选择"); 
1038                 return;1039             }1040 1041             this.removeTarget();1042             1043             this.target.mesh = mesh;1044             this.control.transform.attach(mesh);1045             mesh.HandCreate.SV.gui.display("block");1046             this.geometry.goToPosition();1047             this.update();1048         },1049         1050         removeTarget: function (){1051             if(!this.target.mesh) return;1052             this.control.transform.detach(this.target.mesh);1053             this.target.mesh.HandCreate.SV.gui.display("none");1054             delete(this.target.mesh);1055             this.update();1056         },1057         1058         setTargets: function (mesh){1059             //if(this.targets.indexOf(mesh) !== -1){return;}1060             for(let k = 0; k < this.targets.length; k ++){if(this.targets[k].mesh === mesh){return;}}1061             this.isSelectTargets = true;1062             this.lockTarget = true;1063             this.targets.push({mesh: mesh, color: mesh.material.color.getHex()}); 
1064             mesh.material.color.set("red");1065             this.update();1066         },1067         1068         removeTargets: function (){1069             this.isSelectTargets = false;1070             this.lockTarget = false;1071             for(let k = 0; k < this.targets.length; k++){1072                 this.targets[k].mesh.material.color.set(this.targets[k].color);1073             }1074             this.targets.length = 0; 
1075             this.update();1076         },1077         1078         createObject: function (v){1079             1080             let geo = ()=>{1081                 let mesh = new THREE.Mesh(v.geometry.clone(), v.material.clone());1082                 mesh.material.transparent = true;1083                 mesh.castShadow = true;1084                 mesh.receiveShadow = true;1085                 mesh.customDepthMaterial = new THREE.MeshDepthMaterial({depthPacking: THREE.RGBADepthPacking});1086                 1087                 mesh.HandCreate = {1088                     SV: null,1089                     GeoCI: v.HandCreate.index, 
1090                     MatCI: v.HandCreate.MatIndex,1091                     TexCI: null,1092                     isSelect: true,1093                     position: {x: mesh.position.x, y: mesh.position.y, z: mesh.position.z},1094                     rotation: {x: mesh.rotation.x, y: mesh.rotation.y, z: mesh.rotation.z},1095                     scale: {x: mesh.scale.x, y: mesh.scale.y, z: mesh.scale.z}1096                 };1097                 1098                 mesh.HandCreate.SV = new SetView(this, mesh, v);1099                 1100                 this.backMesh = mesh;1101                 1102                 this.add(mesh);1103                 this.setTarget(mesh);1104             }1105             1106             let mat = ()=>{1107                 this.Three.updateMaterial(this.material.mesh, v.material);1108                 this.material.mesh.HandCreate.MatCI = v.HandCreate.index;1109                 this.update();1110             }1111             1112             let tex = ()=>{1113                 this.Three.updateTexture(this.texture.mesh.material, v.material.map);1114                 this.texture.mesh.HandCreate.TexCI = v.HandCreate.index;1115                 this.update();1116             }1117             1118             switch(v.HandCreate.type){1119                 case "_Geometry": geo(); break;1120                 case "_Material": mat(); break;1121                 case "_Texture": tex(); break;1122                 default: break;1123             }1124 1125         }1126         1127     });1128     1129     //代理1130     /* this.ForCreate = new Proxy(new HandCreate().init(), {1131         get(o, k){1132             return o[k];1133         },1134         set(o, k, v){1135             o[k] = v;1136         }1137     }); */1138     1139     this.ForCreate = new HandCreate().init();1140     1141 }).call(this)
Main.js

 


/template/Home/Zkeys/PC/Static