javascript 3d网页 原创简单的Gui控制视图类 和 ThreeBSP网格组合 ( three.js r114 初探 三)

Posted weihexincode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript 3d网页 原创简单的Gui控制视图类 和 ThreeBSP网格组合 ( three.js r114 初探 三)相关的知识,希望对你有一定的参考价值。

1 完整代码下载

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

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

2 图片展示

  技术图片

技术图片技术图片

3 代码展示

 

技术图片
  1 (function(v, f){
  2     ‘use strict‘;
  3     
  4     if(!v || !f || window.Three !== undefined){return;}
  5     
  6     if(WEBGL.isWebGLAvailable() === false){//是否支持WebGL
  7         document.body.appendChild(WEBGL.getWebGLErrorMessage());
  8         return;
  9     }
 10     
 11     THREE.Cache.enabled = true;//加载器启用缓存
 12     
 13     var Three = function (){
 14         //鼠标平移视角功能 的 属性
 15         this.cmtp = {
 16             speed:10, //平移速度
 17             state:{x:0, y:0}, //平移状态
 18             size:20, //鼠标距显示器边框的大小(如果鼠标当前位置符合这个范围则平移视角)
 19             run:false //是否启用鼠标平移视角功能
 20         };
 21         
 22         this.animateFunc = [];//每帧自动执行的函数列表
 23         this.sceneSize = sceneSize;//场景大小
 24         this.clock = new THREE.Clock();//跟踪时间
 25         this.scene = scene//场景
 26         this.camera = createCamera(this.sceneSize);//相机
 27         this.renderer = createRenderer();//渲染器
 28         this.light = createLight(this.scene);//灯光
 29         this.control = createControl(this.camera, this.renderer, this.clock, this.animateFunc, this.cmtp);//控制器
 30         this.Land = Land;
 31         
 32         animate(this.scene, this.camera, this.renderer, this.animateFunc);//动画循环
 33     }
 34     
 35     //布尔运算 type = intersect    交集、重合的部分 union    并集、组合、相加 subtract    差集、相减
 36     Three.prototype.getBSP = (meshA, meshB, type)=>{
 37         if(!meshA || !meshB || !type){return;}
 38         var bsp_a = new ThreeBSP(meshA);//生成ThreeBSP对象
 39         var bsp_b = new ThreeBSP(meshB);//生成ThreeBSP对象
 40         var bsp = bsp_a[type](bsp_b);//进行 type 计算
 41         var mesh = bsp.toMesh();//转换为mesh模型
 42         mesh.geometry.computeFaceNormals();//更新模型的面
 43         mesh.geometry.computeVertexNormals();//更新模型的顶点
 44         mesh.geometry = new THREE.BufferGeometry().fromGeometry(mesh.geometry);//转换为 buff缓冲几何体
 45         mesh.material = meshA.material;//重赋值纹理
 46         return mesh;
 47     }
 48     
 49     //创建 场景
 50     var createScene = ()=>{
 51         var sce = new THREE.Scene();
 52         //sce.fog = new THREE.Fog(0xcce0ff, 800, 1000);//线性雾
 53         sce.background = new THREE.CubeTextureLoader()
 54         .setPath(‘img/cube/skyboxsun25deg/‘)
 55         .load( [ ‘px.jpg‘, ‘nx.jpg‘, ‘py.jpg‘, ‘ny.jpg‘, ‘pz.jpg‘, ‘nz.jpg‘ ] );
 56         return sce;
 57     }
 58     
 59     //创建 相机
 60     var createCamera = (sceneSize)=>{
 61         var camera = new THREE.PerspectiveCamera(75, v.client.w/v.client.h, 1, sceneSize/2);
 62         camera.position.set(0, 0, 100);//相机起始位置
 63         return camera;
 64     }
 65     
 66     //创建 渲染器
 67     var createRenderer = ()=>{
 68         var renderer = new THREE.WebGLRenderer({
 69             antialias : true,//抗割齿
 70             powerPreference:"high-performance"//选择高性能GPU渲染
 71         });
 72         renderer.setSize(v.client.w, v.client.h);//设置渲染大小
 73         renderer.setPixelRatio(window.devicePixelRatio);//渲染矫正
 74         renderer.gammaFactor = 2.2;//着色校正
 75         renderer.physicallyCorrectLights = true;//使其精确照明
 76         renderer.shadowMap.enabled = true;//渲染阴影
 77         //renderer.autoClear = true;//每帧自动清理缓存
 78         if(!renderer.extensions.get(‘WEBGL_depth_texture‘)){console.log("深度纹理扩展获取失败:WEBGL_depth_texture");}
 79         renderer.domElement.style.zIndex = "0";
 80         renderer.domElement.style.position = "absolute";
 81         renderer.domElement.style.top = "0px";
 82         renderer.domElement.style.left = "0px";
 83         document.body.appendChild(renderer.domElement);
 84         return renderer;
 85     }
 86     
 87     //创建 灯光
 88     var createLight = (scene)=>{
 89         scene.add(new THREE.AmbientLight(0x696969));//环境光(无处不在的光,太阳光)
 90         var l_d = 1000, light = new THREE.DirectionalLight(0xF0F8FF, 1);//平行光(产生阴影的光)
 91         light.position.set(-3000, 3000, -3000);
 92         light.position.multiplyScalar(1);
 93         //阴影
 94         light.castShadow = true;
 95         light.shadow.mapSize.width = 1024;
 96         light.shadow.mapSize.height = 1024;
 97         light.shadow.camera.left = -l_d;
 98         light.shadow.camera.right = l_d;
 99         light.shadow.camera.top = l_d;
100         light.shadow.camera.bottom = -l_d;
101         light.shadow.camera.near = 1;
102         light.shadow.camera.far = 6000;
103         scene.add(light);
104         return light;
105     }
106     
107     //创建 控制器
108     var createControl = (camera, renderer, clock, animateFunc, cmtp)=>{
109         var control = new THREE.OrbitControls(camera, renderer.domElement);
110         control.target = new THREE.Vector3(0, 0, 0);//相机焦点
111         //control.minPolarAngle = Math.PI * 0.3;//向上最大角度
112         //control.maxPolarAngle = Math.PI * 0.4;//向下最大角度
113         control.minDistance = 1;//最小距离
114         control.maxDistance = 10000;//最大距离
115         control.autoRotateSpeed = 10;//自动旋转速度
116         //control.panSpeed = 100;//鼠标旋转速度
117         control.enableZoom = true;//是否启用缩放
118         control.enableKeys = true;//是否启用键盘
119         control.panSpeed = 1;//鼠标平移速度
120         control.keyPanSpeed = 100;//按键平移的速度
121         control.keys.LEFT = 65;//key a左
122         control.keys.UP = 87;//key w前
123         control.keys.RIGHT = 68;//key d右
124         control.keys.BOTTOM = 83;//key s后
125         controlMousePanTargetInit(control, cmtp);//初始化鼠标平移
126         animateFunc.push(()=>{//加入实时更新队列
127             if(!control || !clock){return;}
128             control.update(clock.getDelta());//更新控制器
129             //鼠标平移视角, myRunPan 方法是我在控制器插件上新加的方法(OrbitControls.js/900)
130             //有些用户的浏览器设置并占用了鼠标右键(默认平移键), 
131             if(cmtp.run === true){control.myRunPan(cmtp);}
132         });
133         return control;
134     }
135     
136     //控制鼠标平移视角 初始化
137     var controlMousePanTargetInit = (control, cmtp)=>{
138         var w, h;
139         v.addEvent(document.body, "mousemove", (e)=>{
140             e.preventDefault();
141             if(cmtp.run !== true){return;}
142             w = v.client.w - e.clientX;
143             h = v.client.h - e.clientY;
144             
145             if(w < cmtp.size){cmtp.state.x = 2;}
146             else if(w > v.client.w - cmtp.size){cmtp.state.x = 1;}
147             else{cmtp.state.x = 0;}
148             
149             if(h < cmtp.size){cmtp.state.y = 2;}
150             else if(h > v.client.h - cmtp.size){cmtp.state.y = 1;}
151             else{cmtp.state.y = 0;}
152         });
153     }
154     
155     //创建 动画循环
156     var k, len, animate = (scene, camera, renderer, animateFunc)=>{
157         requestAnimationFrame(()=>{animate(scene, camera, renderer, animateFunc);});
158         len = animateFunc.length;
159         for(k = 0; k < len; k++){animateFunc[k]();}
160         renderer.render(scene, camera);
161     }
162     
163     
164 
165     var Land = function (){
166         land.group.add(new THREE.GridHelper(sceneSize, 100));//添加网格辅助线
167         scene.add(land.group);
168         this.name = land.name;
169         this.group = land.group;
170         this.meshs = land.meshs;
171     }
172 
173     //创建 所有的成形纹理
174     var land_texture = (object)=>{
175     //parameter:
176         //texNum:number 加载纹理数量 默认值为最大值 this.textureMax
177         //texture.repeat.set(25, 25);//x y 贴图平铺次数
178         //texture.anisotropy = 1024;//纹理的清晰度(值为2的幕:1, 2, 4, 8, ... 512, 1024, 2048, ...)
179         //texture.matrixAutoUpdate = false;//是否自动更新矩阵
180         //texture.updateMatrix();//手动更新矩阵
181         //texture.needsUpdate = true;//下次使用纹理时触发一次更新
182         var o = object || {};
183         var num = o.texNum === undefined ? land.textureMax : o.texNum;
184         if(typeof(num) !== "number" || num === 0){return;}
185         
186         var map = new Map(), load = new THREE.TextureLoader();
187         var k, loading = (index, url)=>{
188             let texture = load.load(url);
189             texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
190             texture.anisotropy = 1024;
191             texture.matrixAutoUpdate = false;
192             texture.updateMatrix();
193             map.set(index, texture);
194         }
195         for(k = 0; k < num; k++){loading(k, "img/texture/land/"+k+".jpg");}
196         //setTimeout(()=>{if(map.size === num){console.log("下载图片完成");}}, 3000);
197         return map;
198     }
199     
200     //创建 所有的 成形材质
201     var land_material = ()=>{
202         var k, map = new Map();
203         for(k = 0; k < land.textures.size; k++){
204             map.set(k, new THREE.MeshLambertMaterial({map:land.textures.get(k), transparent:false}));
205         }
206         map.set(land.textures.size, new THREE.MeshLambertMaterial({color:land.color, transparent:false}));
207         return map;
208     }
209     
210     //创建 所有的 成形的几何体
211     var land_geometry = ()=>{
212         
213     }
214     
215     //all mesh
216     var land_mesh = ()=>{
217         var map = new Map();
218         var g = new THREE.BoxGeometry(256, 256, 50);
219         map.set(0, new THREE.Mesh(g, land.materials.get(0)));
220         map.set(1, new THREE.Mesh(g, land.materials.get(1)));
221         
222         return map;
223     }
224 
225 
226 
227     var sceneSize = 5000;
228     var scene = createScene();
229     var land = {
230         name : "land",
231         textureMax : 5, 
232         color : 0x00ff00,
233         group : new THREE.Group()
234     }
235     land.group.name = "group_land";
236     land.textures = land_texture();
237     land.materials = land_material();
238     land.geometrys = land_geometry();
239     land.meshs = land_mesh();
240     
241     
242     
243     window.Three = new Three();
244 
245 }(new View(), new Func()))
initThree.js

 

技术图片
  1 /** 视图类
  2     Gui(a, b, c, d, e):
  3         //介绍: 通过 修改控制器可视视图 来 更新 a引用对象里的属性值, (Gui类的位置在View类的原型里)
  4         //暂支持属性类型: number(计量控制器), function(按钮), boolean(复选框)
  5         //在默认渲染所有a对象属性的时候,不符合的属性会自动忽略掉
  6         //控制器视图 与 a引用对象 默认是双向绑定的, 所以它会覆盖掉原有的get与set
  7         a : object 必须, 目标对象(引用)
  8         b : array 可选, 选择性的渲染a里面属性, 如果不等于array则默认渲染全部a对应的属性名, 反之通过b数组里的字符串渲染对应a对象里的属性名
  9         c : array[min -1, max 1, step 0.1] 可选, a对象如果有多个number类型并有不同的min max step值,则需要用对象包裹,{string:[min, max, step], ...} (string必须对应a对象的属性名)
 10         d : string 可选, 块的标题, 默认 "class"
 11         e : boolean 可选, 是否双向绑定, 默认为 true
 12     例: v = new View()//,每new一次Gui都会新增一个 标题分格线 就是 块, 点击title会隐藏此块
 13         new v.View().Gui(THREE);
 14         new v.Gui(THREE);//渲染全部THREE对象里符合类型的属性
 15         new v.Gui(THREE, ["NeverDepth"]);//c默认为[-1, 1, 0.1]
 16         new v.Gui(THREE, ["NeverDepth"], {NeverDepth:[-200, 200, 10]});
 17         new v.Gui(THREE, ["NeverDepth"], [-200, 200, 10]);
 18         new new View().Gui(THREE, null, {NeverDepth:[-200, 200, 10]});
 19 */
 20 class View{
 21     
 22     constructor(){
 23         if(!this.client){this.getClient();}
 24         if(!this.Gui){this.getGui();}
 25     }
 26     
 27     //创建html元素
 28     add(fel, elemName, id, cls){
 29         //创建一个元素
 30         let el = document.createElement(elemName);
 31         //设置el id 和 class
 32         if(id){el.setAttribute(‘id‘,id);}
 33         if(cls){el.className = cls;}
 34         //把el添加到fel并显示(渲染el)
 35         if(fel){fel.appendChild(el);}
 36         return el;
 37     }
 38 
 39     //删除html元素
 40     remove(){
 41         let k, arg = arguments, err = [];
 42         for(k = 0; k < arg.length; k++){
 43             if(this.isEl(arg[k]) === false){err.push(arg[k]); continue;}
 44             arg[k].parentNode.removeChild(arg[k]);
 45         }
 46         if(err.length > 0){return {err:‘这里有一些删除失败的元素‘, arr:err};}
 47         return true;
 48     }
 49 
 50     //id获取html元素
 51     get(id){
 52         return document.getElementById(id);
 53     }
 54     
 55     //获取可视宽高
 56     getClient(){
 57         View.prototype.client = {
 58             w:document.documentElement.clientWidth || document.body.clientWidth || window.innerWidth, 
 59             h:document.documentElement.clientHeight || document.body.clientHeight || window.innerHeight,
 60         };
 61     }
 62     
 63     //通过parentNode检查元素是否存在于页面中
 64     isEl(el){
 65         if(typeof(el) !== ‘object‘){return false;}
 66         //被删除之后的html元素object的 parentNode等于null
 67         if(!el.parentNode){return false;}
 68         return true;
 69     }
 70     
 71    //元素绑定事件
 72    addEvent(target, ev, callback){
 73         target.addEventListener(ev, function(e){e.preventDefault(); if(callback){callback(e);}}, false);
 74    }
 75     
 76     removeEvent(target, ev, callback){
 77         target.removeEventListener(ev, (e)=>{if(callback)callback(e);}, false);
 78     }
 79     
 80     //创建控制器元素
 81     getGui(){
 82         var tar = this, timer = 0, timerMax = 10, _isBind = true;
 83         var elem = this.add(document.body, ‘div‘, ‘GuiId‘, ‘box-shadown box-scroll-block‘);
 84         
 85         var o = function (obj, data, info, title, isBind){
 86             this.obj = obj;
 87             if(typeof(this.obj) !== "object"){return;}
 88             if(typeof(isBind) === "boolean"){_isBind = isBind;}
 89             this.arr = [];
 90             var k, bs = [], fs = [], ns = [];
 91             var ti = title || "calss", fel = line(ti, timer++);
 92             var T = typeof(data), A = Array.isArray(data);
 93             
 94             if(!data){for(k in this.obj){this.arr.push(k);}}
 95             else if(A === true){this.arr = data;}
 96             else if(T !== "object"){this.arr.push(data);}
 97             else{return;}
 98             
 99             var len = this.arr.length;
100             for(k = 0; k < len; k++){
101                 T = typeof(this.obj[this.arr[k]]);
102                 if(T === "boolean"){bs.push(this.arr[k]);}
103                 else if(T === "function"){fs.push(this.arr[k]);}
104                 else if(T === "number"){ns.push(this.arr[k]);}
105                 else{continue;}
106             }
107             check(obj, bs, fel);
108             click(obj, fs, fel);
109             range(obj, ns, info || {}, fel);
110         }
111         
112         o.prototype.elem = elem;
113         
114         //添加 复选框(boolean) fel.appendChild(el);
115         var check = function (obj, arr, fel){
116             var p = tar.add(fel, ‘p‘), size = 0;
117             
118             var create = (val)=>{
119                 let i = tar.add(p, ‘input‘);
120                 let s = tar.add(p, ‘span‘);
121                 i.type = "checkbox";
122                 i.checked = obj[val];
123                 s.innerHTML = " "+val+", ";
124                 tar.addEvent(i, ‘change‘, (e)=>{obj[val] = e.target.checked;});
125                 size += i.offsetWidth;
126                 size += s.offsetWidth;
127                 return {i:i, s:s};
128             }
129             
130             var k, len = arr.length;
131             for(k = 0; k < len; k++){
132                 let el_f = create(arr[k]);
133                 if(size > 280 && k !== 0){
134                     tar.remove(el_f.i, el_f.s); 
135                     arr.splice(0, k); 
136                     check(obj, arr, fel);
137                     return;
138                 }
139                 bind(obj, arr[k], (old, now)=>{el_f.i.checked = now; return now;});
140             }
141         }
142         
143         //添加 按钮(function)
144         var click = function (obj, arr, fel){
145             var p = tar.add(fel, ‘p‘), size = 0;
146             
147             var create = (val)=>{
148                 let i = tar.add(p, ‘input‘);
149                 let s = tar.add(p, ‘span‘);
150                 i.type = "button";
151                 i.value = val;
152                 s.innerHTML = ", ";
153                 tar.addEvent(i, ‘click‘, obj[val]);
154                 size += i.offsetWidth;
155                 size += s.offsetWidth;
156                 return {i:i, s:s};
157             }
158             
159             var k, len = arr.length;
160             for(k = 0; k < len; k++){
161                 let el_f = create(arr[k]);
162                 if(size > 280 && k !== 0){
163                     tar.remove(el_f.i, el_f.s);
164                     arr.splice(0, k); 
165                     click(obj, arr, fel);
166                     return;
167                 }
168             }
169         }
170         
171         //添加 计量控制器(number) info: object 可选 默认[min -1, max 1, step0.1]
172         var range = function (obj, arr, info, fel){
173             var di = [-1, 1, 0.1]; if(Array.isArray(info) === true){di = info;}
174             
175             var create = (val)=>{
176                 let c = info[val] || di; if(c[2] < 0){c[2] = 1;}
177                 if(obj[val] < c[0] || obj[val] > c[1]){return;}
178                 let p = tar.add(fel, ‘p‘), i = tar.add(p, ‘input‘);
179                 i.type = "range"; i.value = obj[val]; i.min = c[0]; i.max = c[1]; i.step = c[2];
180                 let nul = tar.add(p, ‘span‘); nul.innerHTML = " ";
181                 let is = tar.add(p, ‘input‘); is.type = "tel"; is.value = obj[val];
182                 let key = false, x, xs, s = tar.add(p, ‘span‘); s.innerHTML = " "+val;
183                 
184                 let getNum = (num)=>{
185                     if(num === obj[val]){return;}
186                     if(typeof(num) !== "number" || isNaN(num) === true){
187                         i.value = obj[val]; is.value = obj[val]; 
188                         return;
189                     }
190                     if(num > c[0] && num < c[1]){
191                         return num;
192                     }else if(num > c[0]){
193                         return c[1];
194                     }else if(num < c[1]){
195                         return c[0];
196                     }
197                 }
198                 
199                 let setNum = (num)=>{
200                     if(num !== undefined){
201                         i.value = num;
202                         is.value = num;
203                         obj[val] = num;
204                     }
205                 }
206                 
207                 tar.addEvent(is, ‘blur‘, (e)=>{setNum(getNum(Math.round(Number(e.target.value)/c[2])*c[2]));});
208                 tar.addEvent(i, ‘mousedown‘, (e)=>{i.focus(); x = e.offsetX; key = true;});
209                 tar.addEvent(document.body, ‘mouseup‘, (e)=>{key = false;});
210                 tar.addEvent(document.body, ‘mousemove‘, (e)=>{
211                     if(key === true){
212                         if(e.offsetX < x){xs = obj[val] - c[2];}
213                         else if(e.offsetX > x){xs = obj[val] + c[2];}
214                         setNum(getNum(xs));
215                         
216                         x = e.offsetX;
217                     }
218                 });
219                 
220                 bind(obj, arr[k], (old, now)=>{
221                     let num = getNum(Math.round(Number(now)/c[2])*c[2]);
222                     i.value = num; 
223                     is.value = num;
224                     return num;
225                 });
226             }
227             
228             var k, len = arr.length;
229             for(k = 0; k < len; k++){create(arr[k]);}
230         }
231         
232         //添加 颜色选择器(16进制数)
233         var color = function (){
234             
235         }
236         
237         //添加 标题, 分格功能, 隐藏或显示 ← ↑ → ↓ ↖ ↙ ↗ ↘ ?
238         var line = function (title, timer){
239             var t_con_b = timer + " " + title + " " + " ↓";
240             var t_con_t = timer + " " + title + " " + " ↑";
241             var l = tar.add(elem, ‘p‘, null, "p-min-shadown-a");
242             l.style.cursor = "pointer";
243             var t = tar.add(elem, "p");
244             t.innerHTML = t_con_b;
245             t.style = "color:#bd810e; cursor:pointer;";
246             var fel = tar.add(elem, "div"), dis = false;
247             
248             var ev_run = ()=>{
249                 dis = !dis;
250                 if(dis === true){
251                     fel.style.display = "none"; l.className = "p-min-shadown-b";
252                     t.innerHTML = t_con_t;
253                 }else{
254                     fel.style.display = "block"; l.className = "p-min-shadown-a";
255                     t.innerHTML = t_con_b;
256                 }
257             }
258             
259             tar.addEvent(l, ‘click‘, ev_run);
260             tar.addEvent(t, ‘click‘, ev_run);
261             return fel;
262         }
263         
264         //绑定 obj属性
265         var bind = function (obj, pro, fun){
266             if(_isBind === false){return;}
267             var _val = obj[pro];
268             Object.defineProperty(obj, pro, {
269                 get(){return _val;},
270                 set(val){
271                     if(fun) _val = fun(_val, val);
272                 }
273             });
274         }
275         
276         View.prototype.Gui = o;
277         delete(View.prototype.getGui);
278     }
279 
280 }
View/Gui 一个简单的Gui类

 

index.js

 1 //创建 主页 3d 视图 键盘 w a s d移动 鼠标 点击滑动旋转
 2 function showThreeView(v){
 3     var o = {
 4         aaa : false,
 5         bbb : true,
 6         ccc: true,
 7         eee : 0,
 8         fff : 25,
 9         ggg : 52,
10         hhh : ()=>{console.log(1);},
11         iii : ()=>{},
12         mmm : ()=>{},
13         
14         j : "123",
15         k : {},
16         p : [],
17         q : null,
18         u : undefined
19     }
20     var ceshi = new v.Gui(o, null, [0, 100, 0.1]); console.log(ceshi);
21     new v.Gui(Three, null, null, "Three");
22     new v.Gui(Three.cmtp, null, [0, 100, 1], "鼠标平移功能");
23     
24     
25     
26     var land = new Three.Land(); //地面
27     //land.group.remove(mesh)
28     
29     var mesh_a = land.meshs.get(0);//创建物体 a
30     var mesh_b = land.meshs.get(1);//创建物体 b
31     mesh_a.rotateX(Math.PI * 0.5);
32     land.group.add(mesh_a, mesh_b);
33     
34     //组合运算
35     var mesh_BSP = Three.getBSP(mesh_a, mesh_b, "subtract");//获取组合后的 物体 bsp(已经转换为buff缓冲几何体了)
36     mesh_BSP.position.set(300, 0, 0);
37     land.group.add(mesh_BSP);
38     
39 
40 }

技术图片

  1 "use strict"
  2 
  3 function loadFile(data, success, run){
  4     var arr = [];
  5     if(typeof(data) === ‘string‘) arr.push(data);
  6     if(Array.isArray(data) === true) arr = data;
  7     var max = 50, len = arr.length, t = 0, load = (url)=>{
  8         if(run) run(t, len);
  9         if(t === len || t > max){
 10             if(success) success(t, len); 
 11             return;
 12         }
 13         let script = document.createElement(‘script‘);
 14         script.type = "text/javascript";
 15         script.src = url;
 16         document.body.appendChild(script);
 17         script.onload = (e)=>{t++; load(arr[t]);}
 18     }
 19     load(arr[t]);
 20 }
 21 
 22 loadFile([
 23     "./js/lib/WebGL.js", //是否支持webGL
 24     "./js/lib/three_114.min.js", //ThreeJS 3d库
 25     "./js/lib/OrbitControls.js", //控制器
 26     "./js/lib/Tween.min.js", //动画库
 27     "./js/lib/ThreeBSP.js", //布尔运算
 28                 
 29     "js/func.js", //methods
 30     "js/initThree.js" //init ThreeJS r114
 31 ], main, (num, allnum)=>{console.log("已下载: " + num + "/ " + allnum);});
 32 
 33 //创建一个ajax请求, 前往index.php验证用户是否已登录
 34 //如果Ajax返回的是false说明用户还没有登录成功,并前往 view.php, 
 35 //否则ajax返回用户信息对象
 36 function main(){
 37     new Ajax({
 38         url:"./php/index.php",
 39         method:"get",
 40         success:(data)=>{
 41             let d = JSON.parse(data), v = new View();
 42             if(d === false){location.href = "./login/view.php"; return;}
 43             showUserInfo(d.val, v);//用户信息视图
 44             showThreeView(v);//场景3d视图
 45         }
 46     });
 47 }
 48 
 49 //退出
 50 function exit(){
 51     if(new Func().isRun({id:"testId"}) !== true){console.log("你点得太快了,服务器跟不上"); return;}
 52     new Ajax({
 53         url:"./php/exit.php",
 54         method:"get",
 55         success:(data)=>{main();}
 56     });
 57 }
 58 
 59 //创建html p元素
 60 function create(v, fel, content){
 61     let p = v.add(fel, "p");
 62     p.innerHTML = content || "";
 63     return p;
 64 }
 65 
 66 //创建登录成功后的主页内容
 67 function showUserInfo(user, v){//console.log(user);
 68     
 69     var lid = v.get("loginBoxId");
 70     
 71     var elem_name = create(v, lid, "你好: " + user.UserName);
 72     elem_name.innerHTML += "<input type = ‘button‘ id = ‘exitId‘ value = ‘退 出‘ />";
 73     v.get(‘exitId‘).onclick = ()=>{exit();}//退出按钮
 74     
 75     create(v, lid, "我知道你的邮箱是: " + user.Email);
 76     
 77     switch(user.Like.length){
 78         case 1 : 
 79             create(v, lid, "我还知道你喜欢: " + user.Like[0]); 
 80             break;
 81         case 2 : 
 82             create(v, lid, "我还知道你喜欢: " + user.Like[0]); 
 83             create(v, lid, "还有: " + user.Like[1]); 
 84             break;
 85         case 3 : 
 86             create(v, lid, "我还知道你喜欢: " + user.Like[0]); 
 87             create(v, lid, "还有: " + user.Like[1]); 
 88             create(v, lid, "还有: " + user.Like[2]); 
 89             break;
 90         default : break;
 91     }
 92     lid.style = "visibility:visible;";
 93     //lid居中显示
 94     /* let x = Math.round((v.client.w/2) - (lid.offsetWidth/2));
 95     let y = Math.round((v.client.h/2) - (lid.offsetHeight/2)) - 16;
 96     lid.style = "left:"+x+"px; top:"+y+"px; visibility:visible;"; */
 97 }
 98 
 99 
100 
101 //创建 主页 3d 视图 键盘 w a s d移动 鼠标 点击滑动旋转
102 function showThreeView(v){
103     var o = {
104         aaa : false,
105         bbb : true,
106         ccc: true,
107         eee : 0,
108         fff : 25,
109         ggg : 52,
110         hhh : ()=>{console.log(1);},
111         iii : ()=>{},
112         mmm : ()=>{},
113         
114         j : "123",
115         k : {},
116         p : [],
117         q : null,
118         u : undefined
119     }//Gui使用示例:
120     new v.Gui(o);
121     new v.Gui(Three, null, null, "Three");
122     new v.Gui(Three.cmtp, null, [0, 100, 1], "鼠标平移功能");
123     
124     
125     
126     var land = new Three.Land(); //地面
127     //land.group.remove(mesh)
128     
129     var mesh_a = land.meshs.get(0);//物体a
130     var mesh_b = land.meshs.get(1);//物体b
131     mesh_a.rotateX(Math.PI * 0.5);
132     land.group.add(mesh_a, mesh_b);
133     //物体 bsp
134     var mesh_BSP = Three.getBSP(mesh_a, mesh_b, "subtract");//组合运算
135     mesh_BSP.position.set(300, 0, 0);
136     land.group.add(mesh_BSP);
137     
138 
139 }

 

以上是关于javascript 3d网页 原创简单的Gui控制视图类 和 ThreeBSP网格组合 ( three.js r114 初探 三)的主要内容,如果未能解决你的问题,请参考以下文章

javascript 3d网页 简单的 可视化编辑 图形界面 搭建几何体 带导出物体 示例 ( three.js r114 初探 六)

UNITY3D 游戏开发之二高级组件(GUI:LABELSCROLLVIEWTEXTFIELD…等)入门篇

网页3D编辑器Stone教程:如何创建管道模型

网页3D编辑器Stone教程:如何创建管道模型

3D可旋转粒子矩阵

3D可旋转粒子矩阵