javascript 3d網頁 簡單的 圖形界面 搭建幾何體 示例 ( three.js r114 初探 五)

来源:https://www.cnblogs.com/weihexinCode/archive/2020/03/22/12543925.html
-Advertisement-
Play Games

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 圖片展示   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 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 網路上有很多MySQL表碎片整理的問題,大多數是通過demo一個表然後參考data free來進行碎片整理,這種方式對myisam引擎或者其他引擎可能有效(本人沒有做詳細的測試).對Innodb引擎是不是準確的,或者data free是不是可以參考,還是值得商榷的。本文基於MySQL的Innodb存 ...
  • 前言:昨日與今日重裝SQL Server2016,報了"Polybase要求安裝Oracle JRE 7更新51(64位)或更高版本"規則失敗的錯誤,網上查詢資料,有兩種解決方式,一種是安裝JDK、另一種是不安裝此功能。通過對Polybase功能的瞭解,決心安裝一下SDK。沒想到遇到了茫茫多的坑。總 ...
  • 安裝 第一步:打開百度雲鏈接,下載安裝包 鏈接:https://pan.baidu.com/s/1gE96PTcuMovmqE4TEFHvwA 提取碼:rm6g 第二步:雙擊打開,等待5s,點擊下一步 第三步:接受協議,點擊下一步 第四步:選擇安裝類型,有“Typical(預設)”、“Complet ...
  • 最近在學習springboot,想整理一篇博客,關於springboot整合mybatis並配置主從資料庫的,但是電腦win10系統上並沒有配置mysql主從資料庫。所以花了幾天的時間終於整好了。在這裡記錄一下。 首先是關於在win10上安裝兩個mysql8的步驟,我找到了一篇博客,按照上面的步驟, ...
  • 今遇到問題: 查看表空間,發現表空間大小已達到32G,但創建表空間時已設置了無限擴展(初始空間為1G),磁碟空間沒滿,說明表空間無法進行自動擴展了。 問題原因: 查找資料瞭解到Oracle單個表空間數據文件的最大值為: 最大數據塊 * DB_BLOCK_SIZE 查看Oracle的 DB_BLOCK ...
  • (1)用戶標識和鑒別: 該方法由系統提供一定的方式讓用戶標識自己的名字或身份。每次用戶要求進入系統時,由系統進行核對,通過鑒定後才能提供系統的使用權 (2)存取控制 通過用戶許可權定義和合法權檢查確保只有合法許可權的用戶訪問資料庫,所有未授權的人員無法存取數據 (3)視圖機制 為不同的用戶定義視圖,通過 ...
  • 註意:無特殊說明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 MaterialApp 在學習Flutter的過程中我們第一個看見的控制項應該就是MaterialApp,畢竟創建一個新的Flutter項目的時候,項目第一個組 ...
  • JAVA 簡介 1. 面向對象的特征主要有哪些: 封裝 繼承 多態 抽象 1. 輸入,輸出 1. 輸出:System.out.println\("Hello"\); 1. 輸入: 1. 標識符的組成: 1. Java標識符由:字母,數字,下劃線,美元符號$組成,並且只能以字元,下劃線,$開頭。 1. ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...