欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

javascript 3d网页 简单的 图形界面 搭建几何体 示例 ( three.js r114 初探 五)

程序员文章站 2022-06-27 21:21:11
1 完整代码下载 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取码 3fzt (压缩包名: 2020-3-20-demo.zip) 2 图片展示 3 主要代码 1 /** HandCreate 简单的 图形界面 搭建几何体 2 construct ......
1 完整代码下载 https://pan.baidu.com/s/1jjyvcp2kqxsd5g6eaypghq 提取码 3fzt (压缩包名: 2020-3-20-demo.zip) 
 
2 图片展示
javascript 3d网页 简单的 图形界面 搭建几何体 示例 ( three.js r114 初探 五)
 
3 主要代码
  1 /** handcreate 简单的 图形界面 搭建几何体
  2     constructor:
  3     params:
  4     prototype:
  5     method:
  6 */
  7 class handcreate{
  8     
  9     constructor(func, view, three){
 10         this.func = func;
 11         this.view = view;
 12         this.three = three;
 13         this.size = 1;
 14         this.color = 0xdcdcdc;
 15         this.target = {};
 16         this.isoldaddmesh = true;
 17         
 18         this.group = new three.group();
 19         this.three.scene.add(this.group);
 20         this.group.name = "group_handcreate";
 21         
 22         this.raycaster = {
 23             raycaster:new three.raycaster(),
 24             vector2:new three.vector2(),
 25             childrens:[],
 26             result:[]
 27         }
 28         this.raycaster.raycaster.far = 100;
 29         
 30         this.materials = this.initmaterials();
 31         this.geometrys = this.initgeometrys();
 32         this.lands();
 33         this.controls();
 34         this.initgui();
 35     }
 36     
 37     initmaterials(){
 38         return new map([
 39             [0, new three.meshbasicmaterial({color:this.color})], 
 40             [1, new three.meshlambertmaterial({color:this.color})], 
 41             [2, new three.meshstandardmaterial({color:this.color})] 
 42         ]);
 43     }
 44     
 45     initgeometrys(){
 46         
 47         var geometrys = new map([
 48             [0, new three.boxgeometry(this.size, this.size, this.size, 1, 1, 1)],
 49             [1, new three.spheregeometry(this.size/2, 8, 6, 0, math.pi * 2, 0, math.pi)],
 50         ]);
 51         
 52         for(let k = 0; k < geometrys.size; k++){
 53             this.createshowmesh(k, new three.mesh(geometrys.get(k), this.materials.get(0)));
 54         }
 55         
 56         return geometrys;
 57         
 58     }
 59     
 60     initgui(){
 61         var g_c = ()=>{this.update();}
 62         new this.view.gui(
 63             {
 64                 translate:()=>{this.transformcontrol.setmode("translate")}, 
 65                 rotate:()=>{this.transformcontrol.setmode("rotate")}, 
 66                 scale:()=>{this.transformcontrol.setmode("scale")}
 67             }, 
 68             "控制类型(平移,旋转,缩放)"
 69         )
 70         .create(this, "isoldaddmesh", "是否添加共享物体").change(g_c)
 71     }
 72     
 73     addtarget(mesh){//当前物体
 74         if(this.target.mesh === mesh) return;
 75         
 76         this.removetarget(mesh);
 77         this.transformcontrol.attach(mesh);
 78         
 79         var upd = ()=>{this.update();}
 80         
 81         this.target.gui = new this.view.gui(mesh.material, "wireframe", "修改材质-"+mesh.material.type).change(upd);
 82 
 83         let g_rc, g_s = mesh.geometry.parameters; //克隆的物体没有 parameters 属性
 84         switch(mesh.geometry.type){
 85             case "boxgeometry" :
 86                 //g_s = {g_s.width, g_s.height, g_s.depth, g_s.widthsegments, g_s.heightsegments, g_s.depthsegments}
 87                 g_rc = {width:[0.1, 10, 0.1], height:[0.1, 10, 0.1], depth:[0.1, 10, 0.1], widthsegments:[1, 30, 1], heightsegments:[1, 30, 1], depthsegments:[1, 30, 1]}
 88                 this.target.gui.create(g_s, g_rc, "修改几何体-"+mesh.geometry.type)
 89                 .change(()=>{
 90                     this.updategeometry(mesh, new three.boxgeometry(g_s.width, g_s.height, g_s.depth, g_s.widthsegments, g_s.heightsegments, g_s.depthsegments));
 91                     upd();
 92                 })
 93                 
 94             break;
 95             
 96             case "spheregeometry" :
 97                 let pi2 = math.pi * 2;
 98                 g_rc = {radius:[0.5, 10, 0.1], widthsegments:[1, 30, 1], heightsegments:[1, 30, 1], phistart:[0, pi2, 0.1], philength:[0, pi2, 0.1], thetastart:[0, pi2, 0.1], thetalength:[0, pi2, 0.1]}
 99                 this.target.gui.create(g_s, g_rc, "修改几何体-"+mesh.geometry.type)
100                 .change(()=>{
101                     this.updategeometry(mesh, new three.spheregeometry(g_s.radius, g_s.widthsegments, g_s.heightsegments, g_s.phistart, g_s.philength, g_s.thetastart, g_s.thetalength));
102                     upd();
103                 })
104             break;
105             
106             default : break;
107         }
108         
109         this.target.mesh = mesh;
110     }
111     
112     removetarget(mesh){//移除当前物体
113         this.transformcontrol.detach(mesh);
114         if(this.target.gui){this.target.gui.remove(this.target.gui);}
115         for(let k in this.target){delete(this.target[k]);}
116     }
117     
118     lands(){//地面
119         var geometry = new three.planebuffergeometry(this.three.scenesize, this.three.scenesize);
120         geometry.rotatex( - math.pi / 2 );
121         var mesh = new three.mesh(
122             geometry,
123             new three.meshlambertmaterial({color:0x00ff00, visible:false})
124         );
125         mesh.receiveshadow = true;
126         mesh.matrixautoupdate = false;
127         this.gridhelper = new three.gridhelper(this.three.scenesize, this.three.scenesize/this.size);//每1米为一格
128         this.add(this.gridhelper, false);
129         this.add(mesh, false);
130     }
131     
132     controls(){//控件
133         //平移控件
134         var tc = new three.transformcontrols(this.three.camera, this.three.renderer.domelement);
135         tc.addeventlistener( 'dragging-changed', (e)=>{this.three.control.enabled = !e.value;});
136         tc.addeventlistener('change', ()=>{this.update();});
137         tc.addeventlistener('mousedown', ()=>{});
138         tc.addeventlistener('mouseup', ()=>{});
139         tc.addeventlistener('objectchange', ()=>{});
140         this.transformcontrol = tc;
141         this.three.scene.add(tc);
142         
143         //拖放控件
144         var dc = new three.dragcontrols(this.raycaster.childrens, this.three.camera, this.three.renderer.domelement);
145         dc.addeventlistener('hoveron', (e)=>{this.addtarget(e.object); this.update();});
146         dc.addeventlistener('hoveroff', ()=>{this.update();});
147         dc.enabled = false;
148         this.dragcontrols = dc;
149         
150         //轨道控件
151         this.three.control.addeventlistener("change", ()=>{this.update()});
152         //this.three.control.addeventlistener( 'start', ()=>{});
153         //this.three.control.addeventlistener( 'end', ()=>{});
154     }
155     
156     add(mesh, ischildrens){//添加
157         if(!mesh){return;}
158         this.group.add(mesh);
159         if(ischildrens !== false){this.raycaster.childrens.push(mesh);}
160         this.update();
161         return mesh;
162     }
163     
164     remove(mesh, group){//移除物体
165         if(!mesh){return;}
166         let arr = group || this.group, k = this.raycaster.childrens.indexof(mesh);
167         if(k !== -1){this.raycaster.childrens.splice(k, 1);}
168         arr.remove(mesh);
169         mesh.geometry.dispose();
170     }
171     
172     addmesh(gkey, mkey, ischildrens){//添加物体
173         let g = gkey || 0, m = mkey || 0, mesh;
174         if(this.isoldaddmesh === true){
175             mesh = new three.mesh(this.geometrys.get(g), this.materials.get(m));
176         }else{
177             mesh = new three.mesh(this.geometrys.get(g), this.materials.get(m).clone());
178         }
179         return this.add(mesh, ischildrens);
180     }
181     
182     addwireframe(geometry){//添加网格辅助线
183         var wireframe = new three.wireframegeometry(geometry);
184         var line = new three.linesegments(wireframe);
185         line.material.depthtest = false;
186         line.material.opacity = 0.25;
187         line.material.transparent = true;
188         return line;
189     }
190     
191     createshowmesh(elemid, mesh){//物体选项
192         if(!mesh){return;}
193         if(!this.minscenedom){
194             this.minscenedom = this.view.add(document.body, "div", null, "showmesh box-scroll-block");
195             this.view.addevent(this.minscenedom, 'mousedown', (e)=>{
196                 let key = parseint(e.target.id);
197                 if(typeof(key) !== "number" || isnan(key) === true){return;}
198                 this.addmesh(key, 0);
199             });
200         }
201         var scene = new three.scene();
202         scene.background = new three.color("black");
203         var camera = new three.perspectivecamera(45, 100/100, 0.1, 10);
204         camera.position.set(0, 1, 2);
205         camera.lookat(0, 0, 0);
206         var renderer = new three.webglrenderer({antialias : true});
207         renderer.setsize(100, 100);
208         renderer.domelement.id = elemid + "_showmeshid";
209         this.minscenedom.appendchild(renderer.domelement);
210         scene.add(camera, mesh);
211         mesh.material.wireframe = true;
212         mesh.matrixautoupdate = false;
213         this.update(scene, camera, renderer);
214     }
215     
216     update(scene, camera, renderer){//更新场景
217         this.three.render(scene, camera, renderer);
218     }
219     
220     updategeometry(mesh, geometry){
221         mesh.geometry.dispose();
222         mesh.geometry = geometry;
223     }
224     
225     //光线投射
226     runraycaster(x, y, recursive){
227         var c = this.raycaster;
228         c.result.length = 0;
229         c.vector2.set((x / this.view.client.w) * 2 - 1, -(y / this.view.client.h) * 2 + 1);
230         c.raycaster.setfromcamera(c.vector2, this.three.camera);
231         c.raycaster.intersectobjects(c.childrens, recursive, c.result);
232         //console.log(c.result[0]);
233     }
234     
235     //布尔运算 type = intersect    交集、重合的部分 union    并集、组合、相加 subtract    差集、相减
236     getbsp(mesha, meshb, type){
237         if(!mesha || !meshb || !type){return;}
238         var bsp_a = new threebsp(mesha);//生成threebsp对象
239         var bsp_b = new threebsp(meshb);//生成threebsp对象
240         var bsp = bsp_a[type](bsp_b);//进行 type 计算
241         var mesh = bsp.tomesh();//转换为mesh模型
242         mesh.geometry.computefacenormals();//更新模型的面
243         mesh.geometry.computevertexnormals();//更新模型的顶点
244         mesh.geometry = new three.buffergeometry().fromgeometry(mesh.geometry);//转换为 buff缓冲几何体
245         //mesh.geometry = new buffergeometry().fromgeometry(mesh.geometry);
246         mesh.material = mesha.material;//重赋值纹理
247         return mesh;
248     }
249     
250 }