WebGL10---3D模型的加載與使用


1、關於模型的基礎知識

      3D模型由頂點(vertex)組成,頂點之間連成三角形或四邊形(在一個平面上),多個三角形或四邊形就能夠組成復雜的立體模型;

使用ParaView查看3D模型

 

2、模型在three.js中的表示

      模型由面組成,面分為三角形和四邊形。三角形和四邊形面組成了網格模型。在three.js中用THREE.Mesh來表示網格模式。

THREE.Mesh可以和THREE.Line相提並論;區別是THREE.Line表示的是線條,THREE.Mesh表示面的集合;

       THREE.Mesh = function(geometry,material)

       參數說明:① geometry 是一個THREE.Geometry類型的對象,是一個包含頂點和頂點之間的連接關系對象;

                        ② Material:是一個定義的材質;

 

3、模型的加載

     

      ① 服務器上的模型文件大多是存儲模型的頂點信息,這些信息可以以文本的方式存儲的(並不一定需要文本的方式存儲)。

Three.js支持很多種3D模型格式,例如:ply,stl,obj,vtk等等。隨着three.js的升級,會支持越來越多的文件格式;

      ② 第二步是瀏覽器下載文本文件,這是一件很普通的事情,只需要使用javascript的異步請求就可以實現;

      ③ javascript 解析文本並生成一個geometry,最終生成Mesh;

 

4、頂點和面索引之間的關系

        加載vtk模型,主要分為2步:

        ① 將vtk文件中的點,轉換為geometry的vertices數組中;

         ② 將vtk文件中每個點的索引,轉換為geometry的faces中;

    

 

 關於vtk文件的加載

        //構造函數

        THREE.VTKLoader = function(){

                 THREE.EventDispatcher.call(this);//繼承自監聽器,使這個類有監聽的功能;

         };

         //VTKLoader的原型函數,里面包含了VTKLoader的成員函數,成員變量的定義;

         THREE.VTKLoader.prototype = {

                 //構造函數

                 constructor: THREE.VTKLoader,

                //加載函數:url表示要加載的vtk文件的url路徑,callback表示加載完成后要調用的后續處理函數;

                load: function(url,callback){

                       //將類自身保存在scope中,scope表示域的意思,這里為了避免this的歧義

                       var scope = this;

                       //ajax異步請求

                       var request = new XMLHttpRequest();

                       //加載完成的監聽器,加載完成后,將調用第二個參數定義的回調函數

                       request.addEventListener('load',function(event){

                              //對服務器加載下來的數據進行解析;

                             var geometry = scope.parse(event.target.responseText);

                             //解析完成后,發一個load事件,表示數據解析完成

                             scope.dispatchEvent({ type:'load',content: geometry });

                             //如果設置了回調函數,那么調用回調函數

                             if(callback) callback(geometry);

                       },false);

                       //加載過程中,向自身發送進度progress信息,信息中包含了已經加載的數據的字節數和文件總共的字節數

                       //通過兩者的比例了解加載的進度;

                      request.addEventListener('progress',function(event){

                              //發送正在加載的信息,兩個參數分別是已經加載了多少字節,總共多少字節

                              scope.dispatchEvent({ type:'progress',loader:event.loader,total: event.total});

                      },false);

                      //加載出錯的監聽器,加載的過程中也可能出錯;

                      request.addEventListener('error',function(){

                               //加載出錯后需要發布的錯誤消息

                               scope.dispatchEvent({ type:'error',message: 'could not  load url'});

                      },false);

                      //初始化HTTP請求參數,例如: url和http方法,但是並不發送請求。

                      request.open('get',url,true);

                      //發送http請求,開始下載

                      request.send(null);

                },

               //data是從服務器傳過來的數據,其實就是vtk文件中的文本數據;

                parse:function(data){

                       //new 一個幾何體

                       var geometry = new THREE.Geometry();

                       //定義一個內部函數vertex,用參數x,y,z生成一個頂點,並放入geometry的vertices數組中

                      function vertex(x,y,z){

                             geometry.vertices.push(new THREE.Vector3(x,y,z));

                      }

                      //定義一個面索引函數face3,將面的3個點的索引放入geometry的faces數組中;

                      function face3(x,y,z){

                              geometry.faces.push(new THREE.Face3(x,y,z));

                       }

                       //定義一個面索引函數face4,將面的四個點的索引放入;

                       function face4(a,b,c,d){

                              geometry.faces.push(new THREE.Face4(a,b,c,d));

                       }

                       //pattern存放模式字符串,result是臨時變量;

                      var pattern,result;

                      //float float float ,pattern是一個正在表達式,能夠匹配3個空格隔開的float

                      pattern = /([\+|\-]?[\d]+[\.][\d|\-|e]+)[ ]+([\+|\-]?[\d]+[\.][\d|\-|e]+)[ ]+([\+|\-]?[\d]+[\.][\d|\-|e]+)/g;                  

 // exec是正則表達式的執行匹配函數,result返回一個包含3個字符串的數組,如果data讀到了最后,那么result將返回null // while 循環在data中,尋找符合正則表示式的數據,將符合條件的數據,轉換為一個頂點 while ( ( result = pattern.exec( data ) ) != null ) { // ["1.0 2.0 3.0", "1.0", "2.0", "3.0"] // 將字符串轉換為float,並放入geometry中 vertex( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) ); }
// 3 int int int,這里匹配面數據,如3 21216 21215 20399,這類數據是面索引數據 pattern = /3[ ]+([\d]+)[ ]+([\d]+)[ ]+([\d]+)/g; // 取出data中的所有面索引數據, while ( ( result = pattern.exec( data ) ) != null ) { // ["3 1 2 3", "1", "2", "3"] // 將面數據放入geometry的faces中 face3( parseInt( result[ 1 ] ), parseInt( result[ 2 ] ), parseInt( result[ 3 ] ) ); } // 4 int int int int // 這里是4個頂點一個面的情況,本例的vtk文件,沒有這種情況 pattern = /4[ ]+([\d]+)[ ]+([\d]+)[ ]+([\d]+)[ ]+([\d]+)/g; while ( ( result = pattern.exec( data ) ) != null ) { // ["4 1 2 3 4", "1", "2", "3", "4"] face4( parseInt( result[ 1 ] ), parseInt( result[ 2 ] ), parseInt( result[ 3 ] ), parseInt( result[ 4 ] ) ); } // 這里的4個函數,在后面解釋 geometry.computeCentroids(); geometry.computeFaceNormals(); geometry.computeVertexNormals(); geometry.computeBoundingSphere(); return geometry;

 

               }

          }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM