当前位置: 移动技术网 > IT编程>开发语言>JavaScript > javascript 简单的3d网页应用(3d网页可视化编辑器), 搭建几何体 选配材质 纹理 , 导入 导出 示例 ( three.js 初探 六)

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

2020年04月01日  | 移动技术网IT编程  | 我要评论

1 完整代码下载

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

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

2 图片展示

 

 

3 主要代码

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

  挺简单的 都是中文

   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     var _view = new view().initbody();
  14     var _width = _view.size.w;
  15     var _height = _view.size.h;
  16     var _mindistance = 0.1;
  17     var _maxdistance = 5000;
  18     
  19     //three
  20     var _three = function (){}
  21     
  22     object.assign(_three.prototype, {
  23         
  24         constructor: _three,
  25         
  26         depthmaterial: new three.meshdepthmaterial({depthpacking: three.rgbadepthpacking}),
  27         
  28         createscene: function (bg, fog){//场景
  29             let scene = new three.scene();
  30             if(typeof(bg) === "number"){scene.background = bg;}
  31             else if(array.isarray(bg) === true){
  32                 scene.background = new three.cubetextureloader()
  33                 .setpath('img/cube/skyboxsun25deg/')
  34                 .load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );
  35             }
  36             if(fog) scene.fog = new three.fog(fog.color, fog.near, fog.far);
  37             return scene;
  38         },
  39         
  40         createcamera: function (fov, width, height, near, far){//相机
  41             let w = width === undefined ? _width : width;
  42             let h = height === undefined ? _height : height;
  43             let camera = new three.perspectivecamera(fov || 45, w / h, near || _mindistance, far || _mindistance * 1000);
  44             camera.position.set(0, 0, _maxdistance * 0.001);
  45             camera.lookat( 0, 0, 0 );
  46             return camera;
  47         },
  48         
  49         createrenderer: function (felem, width, height, antialias, lights, shadow, checkshadererrors){//渲染器
  50             let fel = felem || document.body;
  51             let renderer = new three.webglrenderer({
  52                 antialias : antialias || false, //抗割齿
  53                 powerpreference:"high-performance" //选择高性能gpu渲染
  54             });
  55             renderer.setsize(width || _width, height || _height);
  56             renderer.setpixelratio(window.devicepixelratio);
  57             renderer.gammafactor = 2.2; //着色校正
  58             renderer.physicallycorrectlights = lights || false; //使其精确照明
  59             renderer.shadowmap.enabled = shadow || false; //渲染阴影
  60             renderer.debug.checkshadererrors = checkshadererrors || false; //
  61             if(!renderer.extensions.get('webgl_depth_texture')){console.log("深度纹理扩展获取失败:webgl_depth_texture");}
  62             fel.appendchild(renderer.domelement);
  63             return renderer;
  64         },
  65         
  66         addlinghts: function (scene, hc){//灯光
  67             let a = new three.ambientlight(0x696969);//环境光(无处不在的光,太阳光)
  68             
  69             let b = new three.directionallight(0xffffff, 1);//平行光(产生阴影的光)
  70             b.position.set(0, 50, 50);//位置
  71             b.castshadow = true;// 产生动态阴影
  72             //b.target = object3d; //平行光的方向是从它的位置到目标位置。默认的目标位置为原点 (0,0,0)。
  73             b.shadow.radius = 1;//使阴影边缘变模糊
  74             b.shadow.bias = 0.0001;
  75             b.shadow.mapsize.width = 1024;//阴影质量w
  76             b.shadow.mapsize.height = 1024;//阴影质量h
  77             
  78             //下面属性默认不自动更新
  79         /*     let l_d = 20; //光照区域的大小 100 * 100
  80             b.shadow.camera.left = -l_d;
  81             b.shadow.camera.right = l_d;
  82             b.shadow.camera.top = l_d;
  83             b.shadow.camera.bottom = -l_d; */
  84             b.shadow.camera.near = 0.1;//最近
  85             b.shadow.camera.far = 100;//最远
  86             
  87             
  88            /* var helpershadow = new three.camerahelper(b.shadow.camera);
  89             scene.add(a, b, helpershadow);
  90             var c = ()=>{()=>{helpershadow.update(); hc.update(); }}
  91             new gui(b.position, ["x", "y", "z"], [-2500, 2500, 1]).change(c)
  92             .add(b.shadow, "radius", [-1, 1, 0.1]).change(c)
  93             .add(b.shadow.mapsize, ["width", "height"], [0, 2048, 1]).change(c)
  94             .title("调试灯光");*/
  95             scene.add(a, b);
  96             return [a, b];
  97         },
  98         
  99         addcontrols: function (scene, camera, renderer, children){//控件
 100 
 101             //拖放控件
 102             let drag = new three.dragcontrols(children, camera, renderer.domelement);
 103             //drag.addeventlistener('hoveron', (e)=>{this.addtarget(e.object);});
 104             drag.enabled = false;
 105             //this.dragcontrols = dc;
 106             
 107             //轨道控件
 108             let orbit = new three.orbitcontrols(camera, renderer.domelement);
 109             orbit.target = new three.vector3(0, 0, 0);//控件焦点
 110             //orbit.minpolarangle = math.pi * 0.3;//向上最大角度
 111             //orbit.maxpolarangle = math.pi * 0.4;//向下最大角度
 112             orbit.mindistance = _mindistance;//最小距离
 113             orbit.maxdistance = _maxdistance;//最大距离
 114             orbit.autorotatespeed = 10;//自动旋转速度
 115             //orbit.panspeed = 100;//鼠标旋转速度
 116             orbit.enablezoom = true;//是否启用缩放
 117             orbit.enablekeys = true;//是否启用键盘
 118             orbit.panspeed = 1;//鼠标平移速度
 119             orbit.keypanspeed = 100;//按键平移的速度
 120             orbit.keys.left = 65;//key a左
 121             orbit.keys.up = 87;//key w前
 122             orbit.keys.right = 68;//key d右
 123             orbit.keys.bottom = 83;//key s后
 124             orbit.addeventlistener("change", ()=>{this.render(scene, camera, renderer);});
 125             
 126             
 127             //平移控件
 128             var transform = new three.transformcontrols(camera, renderer.domelement);
 129             transform.addeventlistener( 'dragging-changed', (e)=>{orbit.enabled = !e.value;});
 130             transform.addeventlistener('change', ()=>{this.render(scene, camera, renderer);});
 131             scene.add(transform);
 132             
 133             return {drag: drag, orbit: orbit, transform: transform};
 134         },
 135         
 136         updategeometry: function (mesh, geometry){//更换几何体
 137             if(!mesh || !geometry){
 138                 console.log("_three: 几何体更换失败"); 
 139                 return;
 140             }
 141             mesh.geometry.dispose();
 142             mesh.geometry = geometry;
 143         },
 144         
 145         updatematerial: function (mesh, material){//更换材质
 146             if(!mesh || !material){
 147                 console.log("_three: 材质更换失败"); 
 148                 return;
 149             }
 150             let newmat = material.clone(true);
 151             //newmat.color.copy(mesh.material.color);
 152             newmat.transparent = true;
 153             if(mesh.material.map !== null){this.updatetexture(newmat, mesh.material.map);}
 154             mesh.material.dispose();
 155             mesh.material = newmat;
 156         },
 157         
 158         updatetexture: function (material, texture){//更换纹理
 159             if(!material || !texture){
 160                 console.log("_three: 纹理更换失败"); 
 161                 return;
 162             }
 163             let map = new three.texture(texture.image);
 164             map.wraps = three.repeatwrapping;
 165             map.wrapt = three.repeatwrapping;
 166             map.repeat.set(1, 1);
 167             map.minfilter = three.nearestfilter;
 168             map.magfilter = three.nearestfilter;
 169             if(material.map !== null){
 170                 map.wraps = material.map.wraps;
 171                 map.wrapt = material.map.wrapt;
 172                 map.repeat.copy(material.map.repeat);
 173                 map.anisotropy = material.map.anisotropy;
 174                 material.map.dispose();
 175             }
 176             material.map = map;
 177             material.map.needsupdate = true;
 178             material.needsupdate = true;
 179         },
 180         
 181         render: function (scene, camera, renderer){//渲染
 182             renderer.render(scene, camera);
 183         },
 184 
 185         getbsp: function (mesha, meshb, type){//剪裁 添加 重合
 186             if(!mesha || !meshb || !type || mesha === meshb){console.log("getbsp:参数错误, 请选择1至2个物体进行运算"); return;}
 187             if(!mesha.geometry || !meshb.geometry) return;
 188             if(mesha.geometry.isgeometry !== true || meshb.geometry.isgeometry !== true) return;
 189             let bsp_a = new threebsp(mesha);//生成threebsp对象
 190             let bsp_b = new threebsp(meshb);//生成threebsp对象
 191             let bsp = bsp_a[type](bsp_b);//进行 type 计算
 192             let mesh = bsp.tomesh();//转换为mesh模型
 193             mesh.geometry.computefacenormals();//更新模型的面
 194             mesh.geometry.computevertexnormals();//更新模型的顶点
 195             mesh.material = mesha.material;//重赋值纹理
 196             return mesh;
 197         },
 198         
 199         tobuffer: function (geometry){//几何体 转为缓存几何体
 200             if(geometry.isgeometry !== true) return;
 201             return new three.buffergeometry().fromgeometry(geometry);
 202         },
 203         
 204         loadinggltf: function (url, scene){//导入
 205             if(!this.loadgltf){this.__proto__.loadgltf = new three.gltfloader();}
 206             if(!scene) return;
 207             this.loadgltf.load(url, (gltf)=>{
 208                 scene.add(gltf.scene);
 209             });
 210         },
 211         
 212         exportergltf: function (mesh, filetype){//导出物体(限谷歌浏览器)
 213             if(!this.exportgltf){this.__proto__.exportgltf = new three.gltfexporter();}
 214             if(!mesh){console.log("mesh 错误"); return;}
 215             // 使用meshbasicmaterial 或 meshstandardmaterial 材质 效果会更好
 216             //使用 buffergeometry 缓存几何体 文件体积会更小
 217             //if(mesh.geometry.isgeometry === true){mesh.geometry = new three.buffergeometry().fromgeometry(mesh.geometry);}
 218             var opt = {
 219                 binary: filetype || this.exportgltffiletype || false,
 220                 embedimages: true,
 221                 onlyvisible: true,
 222                 truncatedrawrange: true,
 223                 trs: false
 224             };
 225             var download = ( blob, filename )=>{
 226                 let link = _view.add(document.body, "a");
 227                 link.style.display = 'none';
 228                 link.href = url.createobjecturl( blob ); console.log(link.href);
 229                 link.download = filename;
 230                 link.click();
 231                 _view.remove(link); 
 232             }
 233             
 234             this.exportgltf.parse(mesh, function ( result ){
 235                 if(result instanceof arraybuffer){
 236                     download(new blob([result], {type: 'application/octet-stream'}), 'scene.glb');
 237                 }else{
 238                     download(new blob([json.stringify( result, null, 2 )], {type: 'text/plain'}), 'scene.gltf');
 239                 }
 240             }, opt);
 241         },
 242         
 243         runraycaster: function (o, w, h){//光线投射
 244             o.result.length = 0;
 245             o.vector2.set((o.x / w || _width) * 2 - 1, -(o.y / h || _height) * 2 + 1);
 246             o.raycaster.setfromcamera(o.vector2, o.camera);
 247             o.raycaster.intersectobjects(o.children, o.recursive, o.result);
 248         },
 249         
 250         createclipplane: function (handcreate){//添加 面 和 点 剪裁面
 251             let pa = new three.plane(new three.vector3( 1, 0, 0 ), 1);
 252             let pb = new three.plane(new three.vector3( 0, -1, 0 ), 1);
 253             let pc = new three.plane(new three.vector3( 0, 0, -1), 1);
 254             let pd = new three.plane(new three.vector3( 0, 1, 1), 1);
 255             
 256             let hg = new three.group();
 257             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));
 258             return {
 259                 planes: [pa, pb, pc, pd],
 260                 helpers: hg
 261             };
 262             var geometry = new three.spheregeometry(1, 48, 24);
 263             var material = new three.meshlambertmaterial({
 264                 color: new three.color("#666666"),
 265                 side: three.doubleside,
 266                 clippingplanes: clipplane,
 267                 clipintersection: true
 268             });
 269             console.log(helper0); console.log(material);
 270             handcreate.add(new three.mesh(geometry, material), helpergroup);
 271             
 272             handcreate.renderer.localclippingenabled = true;
 273             
 274             //clipplane.constant = 0.1;
 275             new gui({constant:0}, [-1, 1, 0.01])
 276             .change((val)=>{
 277                 for(let k = 0; k < clipplane.length; k++){
 278                     clipplane[k].constant = val;
 279                 }
 280                 handcreate.update();
 281             })
 282             .add(material, "clipintersection")
 283             .add(helper0, "size", [0, 10, 0.1])
 284             .change(()=>{handcreate.update();})
 285         }
 286         
 287     });
 288     
 289     
 290     
 291     //几何体
 292     var _geometry = function (){
 293         _three.call(this);
 294         //this.width = 100; _width
 295         this.height = 100;
 296         this.y = this.campos.y;
 297         this.dis = 1.5;
 298         this.targetchange = null;
 299         this.objects = [];
 300     }
 301     
 302     _geometry.prototype = object.assign(object.create(_three.prototype), {
 303         
 304         constructor: _geometry,
 305         
 306         config: [
 307             new three.boxgeometry(1, 1, 1, 1, 1, 1), 
 308             new three.spheregeometry(0.5, 8 , 6, 0, math.pi * 2, 0, math.pi),
 309             new three.planegeometry(1, 1, 1, 1)
 310         ],
 311 
 312         campos: {x: _width/110, y: 0, z: 1.5},
 313 
 314         defaultmaterial: new three.meshbasicmaterial({wireframe: true}),
 315         
 316         init: function (){//初始化
 317             if(this.scene === undefined)  this.addscene();
 318             if(this.show === undefined)  this.setshow();
 319             if(this.target === undefined) this.settarget();
 320             this.renderview(this.config);
 321             return this;
 322         },
 323         
 324         addscene: function (){//添加 场景
 325             let elem = _view.add(document.body, "div", null, "showobject box-scroll-block");
 326             _view.addevent(elem, 'click', (e)=>{this.addtarget(e);});
 327             
 328             let scene = this.createscene(0x000000, false);
 329             var camera = new three.orthographiccamera(_width/-100, _width/100, this.height/100, this.height/-100, 0.1, 10);
 330             camera.lookat(0, 0, 0);
 331             let renderer = this.createrenderer(elem, _width, this.height, true, true, true, true);
 332             let linghts = this.addlinghts(scene);
 333             let drag = new three.dragcontrols(scene.children, camera, renderer.domelement);
 334             drag.enabled = false;
 335             this.__proto__.scene = {e: elem, s:scene, c: camera, r: renderer, l: linghts, drag: drag, target: null}
 336             drag.addeventlistener('hoveron', (e)=>{this.scene.target = e.object;});
 337             drag.addeventlistener('hoveroff', ()=>{this.scene.target = null;});
 338             this.gotoposition();
 339         },
 340         
 341         addlinghts: function (scene){//重写添加灯光
 342             let a = new three.ambientlight(0x696969);
 343             let b = new three.directionallight(0xffffff, 1);
 344             b.position.set(0, 5, 5);
 345             scene.add(a, b);
 346             return [a, b];
 347         },
 348         
 349         gotoposition: function (){//跳转到 geometry 坐标
 350             this.scene.c.position.set(this.campos.x, this.campos.y, this.campos.z);
 351             this.update();
 352         },
 353         
 354         setpos: function (k, mesh){//renderview-> 设置物体之间的距离
 355             mesh.position.set(k * this.dis, this.y, 0);
 356         },
 357         
 358         addmesh: function (object, key){//renderview-> 添加物体
 359             let mesh = new three.mesh(object, this.defaultmaterial);
 360             mesh.handcreate = {type: "_geometry", index: key, matindex: 0}
 361             this.scene.s.add(mesh);
 362             return mesh;
 363         },
 364         
 365         renderview: function (arr){//渲染场景视图
 366             for(let k = 0; k < arr.length; k++){
 367                 let mesh = this.addmesh(arr[k], k);
 368                 this.setpos(k, mesh);
 369                 this.objects.push(mesh);
 370             }
 371             this.update();
 372         },
 373         
 374         setshow: function (){//是否显示场景的html元素
 375             let _show = false;
 376             object.defineproperties(this.__proto__, {
 377                 show: {
 378                     get:()=>{return _show;},
 379                     set:(v)=>{
 380                         if(v === true){
 381                             this.scene.e.style.display = "block";
 382                         }else{
 383                             this.scene.e.style.display = "none";
 384                         }
 385                         _show = v;
 386                     }
 387                 }
 388             });
 389         },
 390         
 391         addtarget: function (e){//addscene event->场景html元素的事件回调函数
 392             if(!this.scene.target) return;
 393             this.target = this.scene.target;
 394         },
 395         
 396         settarget: function (){//配置 target
 397             let _target = null;
 398             object.defineproperties(this.__proto__, {
 399                 target: {
 400                     get:()=>{return _target;},
 401                     set:(v)=>{
 402                         if(typeof(this.targetchange) === "function") this.targetchange(v);
 403                         _target = v;
 404                     }
 405                 }
 406             });
 407         },
 408         
 409         exportobject: function (){//导出 几何体
 410             
 411         },
 412         
 413         importobject: function (object){//导入 几何体
 414             if(object.isgeometry !== true) return;
 415             let nowkey = this.config.length;
 416             let mesh = this.addmesh(object, nowkey);
 417             this.setpos(nowkey, mesh);
 418             this.config.push(object);
 419             this.objects.push(mesh);
 420             this.update();
 421         },
 422         
 423         update: function (){//更新场景
 424             this.render(this.scene.s, this.scene.c, this.scene.r);
 425         },
 426         
 427         debugcamera: function (){//gui调试 正交相机
 428             let c = this.scene.c;
 429             let pos = {x: _width/110, y: 0, lookat: true, position: false};
 430             let upd = ()=>{
 431                 if(pos.lookat) c.lookat(pos.x, pos.y, 0); 
 432                 if(pos.position) c.position.set(pos.x, pos.y, 5);
 433                 this.update();
 434             }
 435 
 436             new gui(pos, [0, 10, 0.1], "调试正交相机")
 437             .change({
 438                 x: (v)=>{pos.x = v; upd();},
 439                 y: (v)=>{pos.y = v;  upd();}
 440             })
 441 
 442         }
 443         
 444     });
 445     
 446     
 447     
 448     //材质
 449     var _material = function (){
 450         _geometry.call(this);
 451     }
 452     
 453     _material.prototype = object.assign(object.create(_geometry.prototype), {
 454         
 455         constructor: _material,
 456         
 457         config:[
 458             new three.meshbasicmaterial(),
 459             new three.meshlambertmaterial(),
 460             new three.meshstandardmaterial()
 461         ],
 462         
 463         defaultgeometry: new three.boxgeometry(1, 1, 1, 1, 1, 1),
 464         
 465         campos: {x: _width/110, y: 1.5, z: 1.5},
 466         
 467         addmesh: function (object, key){
 468             let mesh = new three.mesh(this.defaultgeometry, object);
 469             mesh.handcreate = {type: "_material", index: key};
 470             this.scene.s.add(mesh);
 471             return mesh;
 472         },
 473         
 474         gotoposition: function (mesh){
 475             if(!mesh) return; this.mesh = mesh;
 476             let geometry = _geometry.prototype.config[mesh.handcreate.geoci].clone();
 477             for(let k = 0; k < this.objects.length; k++){
 478                 this.updategeometry(this.objects[k], geometry);
 479             }
 480             this.scene.c.position.set(this.campos.x, this.campos.y, this.campos.z);
 481             this.update();
 482         }
 483         
 484     });
 485     
 486     
 487     
 488     //纹理 map
 489     var _texture = function (){
 490         _material.call(this);
 491         this.texturelen = 12;
 492         this.settexture();
 493     }
 494     
 495     _texture.prototype = object.assign(object.create(_material.prototype), {
 496         
 497         constructor: _texture,
 498         
 499         config: [],
 500         
 501         campos: {x: _width/110, y: 3, z: 1.5},
 502         
 503         defaultmaterial: new three.meshbasicmaterial(),
 504         
 505         load: new three.textureloader(),
 506         
 507         loaded: 0,
 508         
 509         settexture: function (){
 510             let k, texture;
 511             for(k = 0; k < this.texturelen; k++){
 512                 texture = this.load.load("img/texture/"+k+".jpg", ()=>{this.__proto__.loaded++;});
 513                 texture.wraps = three.repeatwrapping;
 514                 texture.wrapt = three.repeatwrapping;
 515                 texture.repeat.set(1, 1);
 516                 this.__proto__.config.push(texture);
 517             }
 518             if(this.loaded !== this.texturelen){this.awaitload();}
 519         },
 520         
 521         awaitload: function (){
 522             let interval = setinterval(()=>{
 523                 if(this.loaded === this.texturelen){
 524                     this.update();
 525                     clearinterval(interval);
 526                     console.log("load texture: "+this.loaded+"/"+this.texturelen);
 527                 }else{
 528                     console.log("load texture: "+this.loaded+"/"+this.texturelen);
 529                 }
 530             }, 300);
 531         },
 532 
 533         addmesh: function (object, key){
 534             let mesh = new three.mesh(this.defaultgeometry, new three.meshbasicmaterial({map: object}));
 535             //let mesh = new three.mesh(this.defaultgeometry, this.defaultmaterial);
 536             //this.updatetexture(mesh, object);
 537             mesh.handcreate = {type: "_texture", index: key};
 538             this.scene.s.add(mesh);
 539             return mesh;
 540         },
 541         
 542         gotoposition: function (mesh){
 543             if(!mesh) return; this.mesh = mesh;
 544             let geometry = _geometry.prototype.config[mesh.handcreate.geoci].clone();
 545             let material = _material.prototype.config[mesh.handcreate.matci].clone();
 546             for(let k = 0; k < this.objects.length; k++){
 547                 this.updategeometry(this.objects[k], geometry);
 548                 this.updatematerial(this.objects[k], material);
 549             }
 550             this.scene.c.position.set(this.campos.x, this.campos.y, this.campos.z);
 551             this.update();
 552         }
 553         
 554     });
 555     
 556     //物体
 557     var _mesh = function (){}
 558     
 559     //gui
 560     var setview = function (hc, newmesh, oldmesh){
 561         this.hc = hc;
 562         this.newmesh = newmesh;
 563         this.oldmesh = oldmesh;
 564         return this.init();
 565     }
 566     
 567     object.assign(setview.prototype, {
 568         
 569         constructor: setview,
 570         
 571         init: function (){
 572             if(this.globalgui === undefined) this.createglobal();
 573             this.gui = new gui().display("none");
 574             
 575             this.createmesh();
 576             this.creategeometry();
 577             this.creatematerial();
 578             return this;
 579         },
 580         
 581         createmesh: function (){
 582             let o = {
 583                 exportgltf: ()=>{this.hc.three.exportergltf(this.newmesh);},
 584                 addmesh: ()=>{this.hc.geometry.gotoposition();},
 585                 removemesh: ()=>{this.hc.remove(this.newmesh);},
 586                 getbsp: "intersect",
 587                 rungetbsp: ()=>{
 588                     let meshb = this.hc.targets[0].mesh;
 589                     if(this.newmesh === meshb) meshb = this.hc.targets[1].mesh;
 590                     let result = this.hc.three.getbsp(this.newmesh, meshb, o.getbsp);
 591                     this.hc.geometry.importobject(result.geometry);
 592                     this.hc.isselecttargets = false;
 593                 }
 594             }
 595             let m = {
 596                 visible: this.newmesh.visible,
 597                 frustumculled: this.newmesh.frustumculled,
 598                 castshadow: this.newmesh.castshadow,
 599                 receiveshadow: this.newmesh.receiveshadow,
 600             }
 601             
 602             this.gui.create(m, true).name({visible: "显示物体", castshadow: "投射阴影", receiveshadow: "接收阴影"})
 603             .change({
 604                 visible: ()=>{
 605                     if(this.newmesh.visible === undefined) return;
 606                     this.newmesh.visible = m.visible;
 607                     this.hc.update();
 608                 },
 609                 frustumculled: ()=>{
 610                     if(this.newmesh.frustumculled === undefined) return;
 611                     this.newmesh.frustumculled = m.frustumculled;
 612                     this.hc.update();
 613                 },
 614                 castshadow: ()=>{
 615                     if(this.newmesh.castshadow === undefined) return;
 616                     this.newmesh.castshadow = m.castshadow;
 617                     this.hc.update();
 618                 },
 619                 receiveshadow: ()=>{
 620                     if(this.newmesh.receiveshadow === undefined) return;
 621                     this.newmesh.receiveshadow = m.receiveshadow;
 622                     this.hc.update();
 623                 }
 624             })
 625             
 626             .add(o, {getbsp:[["交集", "intersect"], ["并集", "union"], ["差集", "subtract"]]}, true)
 627             .name({exportgltf: "导出物体", addmesh: "添加物体", removemesh: "移除物体", getbsp: "布尔运算类型(选择一个物体)", rungetbsp: "布尔运算"})
 628             .change({
 629                 getbsp: (e)=>{o.getbsp = e.target.value;}
 630             })
 631             
 632             .title("物体-"+this.newmesh.type+"-"+this.newmesh.id);
 633         },
 634         
 635         creategeometry: function (){
 636             if(this.oldmesh.geometry.parameters === undefined){console.log("setview: 忽略了geometry"); return;}
 637             let o, p = {}, geo;
 638             for(let k in this.oldmesh.geometry.parameters){p[k] = this.oldmesh.geometry.parameters[k];}
 639             switch(this.oldmesh.geometry.type){
 640             
 641                 case "boxgeometry": 
 642                     o = {
 643                         width:[0.1, 10, 0.1], 
 644                         height:[0.1, 10, 0.1], 
 645                         depth:[0.1, 10, 0.1], 
 646                         widthsegments:[1, 30, 1], 
 647                         heightsegments:[1, 30, 1], 
 648                         depthsegments:[1, 30, 1]
 649                     }
 650                     this.gui.create(p, o, true)
 651                     .name({width: "宽度", height: "高度", depth: "深度", widthsegments: "宽段数", heightsegments: "高段数", depthsegments: "深段数"})
 652                     .change(()=>{
 653                         geo = new three.boxgeometry(p.width, p.height, p.depth, p.widthsegments, p.heightsegments, p.depthsegments);
 654                         this.hc.three.updategeometry(this.newmesh, geo);
 655                         this.hc.update();
 656                     });
 657                     
 658                 break;
 659                 
 660                 case "spheregeometry": 
 661                     o = {
 662                         radius:[0.1, 10, 0.1], 
 663                         widthsegments:[1, 30, 1], 
 664                         heightsegments:[1, 30, 1], 
 665                         phistart:[0, math.pi*2, 0.1], 
 666                         philength:[0, math.pi*2, 0.1], 
 667                         thetastart:[0, math.pi*2, 0.1], 
 668                         thetalength:[0, math.pi*2, 0.1]
 669                     }
 670                     this.gui.create(p, o, true)
 671                     .name({radius: "半径", widthsegments: "宽段数", heightsegments: "高段数", phistart: "经线起始角度", philength: "经线起始角度大小", thetastart: "纬线起始角度", thetalength: "纬线起始角度大小",})
 672                     .change(()=>{
 673                         geo = new three.spheregeometry(p.radius, p.widthsegments, p.heightsegments, p.phistart, p.philength, p.thetastart, p.thetalength);
 674                         this.hc.three.updategeometry(this.newmesh, geo);
 675                         this.hc.update();
 676                     });
 677                     
 678                 break;
 679                 
 680                 case "planegeometry": 
 681                     o = {
 682                         width: [1, 100, 0.1],
 683                         height: [1, 100, 0.1],
 684                         widthsegments: [1, 30, 1],
 685                         heightsegments: [1, 30, 1]
 686                     }
 687                     this.gui.create(p, o, true)
 688                     .name({width: "宽度", height: "高度", widthsegments: "宽段数", heightsegments: "高段数"})
 689                     .change(()=>{
 690                         geo = new three.planegeometry(p.width, p.height, p.widthsegments, p.heightsegments);
 691                         this.hc.three.updategeometry(this.newmesh, geo);
 692                         this.hc.update();
 693                     });
 694                 break;
 695                     
 696                 default : break;
 697             }
 698             this.gui.title("几何体-"+this.newmesh.geometry.type+"-"+this.newmesh.id);
 699         },
 700         
 701         creatematerial: function (){
 702             let mat = this.newmesh.material;
 703             let o = {
 704                 color: "#" + mat.color.gethexstring(),
 705                 emissive: mat.emissive === undefined ? "#000000" : "#" + mat.emissive.gethexstring(),
 706                 updatematerial: ()=>{this.hc.material.gotoposition(this.newmesh);},
 707                 updatetexture: ()=>{this.hc.texture.gotoposition(this.newmesh);}
 708             }
 709             let m = {
 710                 wireframe: mat.wireframe, 
 711                 visible: mat.visible, 
 712                 side: mat.side, 
 713                 fog: mat.fog, 
 714                 aomapintensity: mat.aomapintensity, 
 715                 colorwrite: mat.colorwrite, 
 716                 transparent: mat.transparent, 
 717                 opacity: mat.opacity, 
 718                 alphatest: mat.alphatest, 
 719                 flatshading: mat.flatshading,
 720                 emissiveintensity: mat.emissiveintensity === undefined ? 0 : mat.emissiveintensity,
 721                 repeatu: 1,
 722                 repeatv: 1,
 723                 anisotropy: 1
 724             }
 725             
 726             let num = {
 727                 aomapintensity: [0, 1, 0.1], 
 728                 opacity: [0, 1, 0.1], 
 729                 alphatest: [0, 1, 0.1], 
 730                 emissiveintensity: [0, 1, 0.1],
 731                 repeatu: [1, 100, 1],
 732                 repeatv: [1, 100, 1],
 733                 anisotropy: [1, this.hc.renderer.capabilities.getmaxanisotropy() || 2, 1]
 734             };
 735             let sel = {
 736                 side: [["外面", three.frontside], ["里面", three.backside], ["双面", three.doubleside]]
 737             };
 738             let name = {
 739                 wireframe:"网格模式", 
 740                 visible:"显示材质", 
 741                 side: "材质显示那一面", 
 742                 fog: "受雾气影响", 
 743                 aomapintensity: "遮挡效果", 
 744                 colorwrite: "渲染颜色", 
 745                 transparent: "渲染透明度", 
 746                 opacity: "透明度", 
 747                 alphatest: "alpha值", 
 748                 flatshading: "平面着色",
 749                 emissiveintensity: "放射光强度",
 750                 repeatu: "重复量,纹理u面",
 751                 repeatv: "重复量,纹理v面",
 752                 anisotropy: "纹理清晰度"
 753             };
 754             let c = {
 755                 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();},
 756                 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();},
 757                 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();},
 758                 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();},
 759                 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();},
 760                 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();},
 761                 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();},
 762                 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();},
 763                 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();},
 764                 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();},
 765                 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();},
 766                 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();},
 767                 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();},
 768                 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();},
 769                 
 770             };
 771             
 772             this.gui.create(m, num, true, sel).name(name).change(c)
 773             
 774             .add(o, true)
 775             .name({color: "材质颜色", emissive: "放射光颜色", updatematerial: "替换材质", updatetexture: "替换纹理"})
 776             .change({
 777                 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();},
 778                 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();}
 779             })
 780             
 781             .title("材质-"+this.newmesh.material.type+"-"+this.newmesh.id);
 782         },
 783         
 784         createglobal: function (){
 785             let o = {
 786                 setmode: "translate",
 787                 exportall: ()=>{console.log("导出全部物体")},
 788                 updatematerialall: ()=>{console.log("替换全部材质")},
 789                 isgltf: true
 790             }
 791 
 792             let gui = new gui(this.hc.geometry, "show", "显示创建选项")
 793             
 794             .add(o, true, {isgltf: [[".gltf", false], [".glb", true]], setmode: [["平移", "translate"], ["旋转", "rotate"], ["缩放", "scale"]]})
 795             .name({exportall: "导出全部物体", updatematerialall: "替换全部材质", setmode: "控制模式", isgltf:"导出类型"})
 796             .change({
 797                 isgltf: (e)=>{this.hc.three.exportgltffiletype = eval(e.target.value);},
 798                 setmode: (e)=>{this.hc.control.transform.setmode(e.target.value);}
 799             })
 800             
 801             .add(this.hc, true, ["locktarget", "isselecttargets"])
 802             .name({locktarget: "锁定物体", isselecttargets: "选择物体"})
 803             .change({
 804                 isselecttargets: ()=>{
 805                     if(this.hc.isselecttargets === false){
 806                         this.hc.removetargets();
 807                     }
 808                 },
 809                 locktarget: ()=>{
 810                     if(this.hc.locktarget === false){
 811                         this.hc.removetargets();
 812                     }
 813                 }
 814             })
 815             
 816             .title("global");
 817             this.__proto__.globalgui = gui;
 818         }
 819         
 820     });
 821     
 822     
 823     
 824     //main
 825     var handcreate = function (){
 826         this.three = new _three();
 827         this.group = new three.group();
 828         this.target = {};
 829         this.isselecttargets = false;
 830         this.targets = [];
 831         this.backmesh = null;
 832         this.locktarget = false;
 833         this.scene = this.three.createscene([], false);
 834         this.renderer = this.three.createrenderer(document.body, _width, _height, true, true, true, true);
 835         
 836     }
 837     
 838     object.assign(handcreate.prototype, {
 839         
 840         constructor: handcreate,
 841         
 842         init: function (){
 843             this.intersects = {
 844                 raycaster: new three.raycaster(),
 845                 group: new three.group(),
 846                 vector2: new three.vector2(),
 847                 result: [],
 848                 camera: this.camera,
 849                 recursive: true,
 850                 x: 0,
 851                 y: 0,
 852             };
 853             this.renderer.domelement.style = "position:absolute; top:0; left:0";//如果不定位, gui的移动块会不正常显示
 854             //this.renderer.localclippingenabled = true;//是否渲染 平面剪裁
 855             this.camera = this.three.createcamera(45, _width, _height, _mindistance, _maxdistance * _mindistance * 0.2);
 856             this.camera.position.set(0, _maxdistance * 0.001, _maxdistance * 0.001);
 857             this.linghts = this.three.addlinghts(this.scene, this);
 858             this.control = this.three.addcontrols(this.scene, this.camera, this.renderer, this.intersects.group.children);
 859             this.control.drag.addeventlistener('hoveron', (e)=>{this.settarget(e.object);});
 860             
 861             this.geometry = new _geometry().init();
 862             this.geometry.targetchange = (v)=>{this.createobject(v);};
 863             this.geometry.show = true;
 864             
 865             this.material = new _material().init();
 866             
 867             this.texture = new _texture().init();
 868             
 869             this.gridhelper = new three.gridhelper(_maxdistance, _maxdistance/1);
 870             this.scene.add(this.group, this.intersects.group, this.camera, this.gridhelper);
 871             
 872             //this.clip = this.three.createclip();
 873             //this.globalview();
 874             //this.three.loadinggltf("img/gltfs/scene.gltf", this.intersects.group);
 875             //this.three.loadinggltf("img/gltfs/scene.glb", this.intersects.group);
 876             return this;
 877         },
 878         
 879         add: function (mesh, group){
 880             if(!mesh) return;
 881             let gro = group || this.intersects.group;
 882             if(array.isarray(mesh) === true){
 883                 let k, len = mesh.length;
 884                 for(k; k < len; k++){
 885                     if(!mesh[k]) continue;
 886                     gro.add(mesh[k]);
 887                 }
 888             }else{
 889                 gro.add(mesh);
 890             }
 891             this.update();
 892         },
 893         
 894         remove: function (mesh, group){
 895             if(!mesh){console.log("remove: mesh不存在"); return;}
 896             let arr = group || this.intersects.group;
 897             if(!arr.remove){console.log("remove: group错误"); return;}
 898             this.removetarget();
 899             if(mesh.gui) mesh.gui.remove();
 900             mesh.handcreate.sv.gui.remove();
 901             if(mesh.material.map){mesh.material.map.dispose();}
 902             mesh.material.dispose();
 903             mesh.geometry.dispose();
 904             arr.remove(mesh);
 905             this.update();
 906         },
 907         
 908         update: function (){
 909             this.three.render(this.scene, this.camera, this.renderer);
 910         },
 911 
 912         settarget: function (mesh){
 913             if(this.isselecttargets === true){this.settargets(mesh);}
 914             if(this.target.mesh === mesh || this.locktarget === true){return;}
 915             if(mesh.handcreate === undefined || mesh.handcreate.sv === undefined){this.locktarget = true; console.log("settarget: mesh 错误,取消选择"); return;}
 916 
 917             this.removetarget();
 918             
 919             this.target.mesh = mesh;
 920             this.control.transform.attach(mesh);
 921             mesh.handcreate.sv.gui.display("block");
 922             this.geometry.gotoposition();
 923             this.update();
 924         },
 925         
 926         removetarget: function (){
 927             if(!this.target.mesh) return;
 928             this.control.transform.detach(this.target.mesh);
 929             this.target.mesh.handcreate.sv.gui.display("none");
 930             delete(this.target.mesh);
 931             this.update();
 932         },
 933         
 934         settargets: function (mesh){
 935             //if(this.targets.indexof(mesh) !== -1){return;}
 936             for(let k = 0; k < this.targets.length; k ++){if(this.targets[k].mesh === mesh){return;}}
 937             this.isselecttargets = true;
 938             this.locktarget = true;
 939             this.targets.push({mesh: mesh, color: mesh.material.color.gethex()}); 
 940             mesh.material.color.set("red");
 941             this.update();
 942         },
 943         
 944         removetargets: function (){
 945             this.isselecttargets = false;
 946             this.locktarget = false;
 947             for(let k = 0; k < this.targets.length; k++){
 948                 this.targets[k].mesh.material.color.set(this.targets[k].color);
 949             }
 950             this.targets.length = 0; 
 951             this.update();
 952         },
 953         
 954         createobject: function (v){
 955             
 956             let geo = ()=>{
 957                 let mesh = new three.mesh(v.geometry.clone(), v.material.clone());
 958                 mesh.material.transparent = true;
 959                 mesh.castshadow = true;
 960                 mesh.receiveshadow = true;
 961                 mesh.customdepthmaterial = new three.meshdepthmaterial({depthpacking: three.rgbadepthpacking});
 962                 
 963                 mesh.handcreate = {
 964                     sv: new setview(this, mesh, v),
 965                     geoci: v.handcreate.index, 
 966                     matci: v.handcreate.matindex,
 967                     texci: null
 968                 };
 969                 
 970                 this.backmesh = mesh;
 971                 this.add(mesh);
 972                 this.settarget(mesh);
 973             }
 974             
 975             let mat = ()=>{
 976                 this.three.updatematerial(this.material.mesh, v.material);
 977                 this.material.mesh.handcreate.matci = v.handcreate.index;
 978                 this.update();
 979             }
 980             
 981             let tex = ()=>{
 982                 this.three.updatetexture(this.texture.mesh.material, v.material.map);
 983                 this.texture.mesh.handcreate.texci = v.handcreate.index;
 984                 this.update();
 985             }
 986             
 987             switch(v.handcreate.type){
 988                 case "_geometry": geo(); break;
 989                 case "_material": mat(); break;
 990                 case "_texture": tex(); break;
 991                 default: break;
 992             }
 993 
 994         }
 995         
 996     });
 997     
 998     //代理
 999     /* this.forcreate = new proxy(new handcreate().init(), {
1000         get(o, k){
1001             return o[k];
1002         },
1003         set(o, k, v){
1004             o[k] = v;
1005         }
1006     }); */
1007     
1008     this.forcreate = new handcreate().init();
1009     
1010 }).call(this)

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网