zoukankan      html  css  js  c++  java
  • 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;

                   }

              }

  • 相关阅读:
    关于使用quartz动态增删改定时任务
    关于chrome被篡改主页修复方法
    关于git被误删除的分支还原问题
    mysql数据库备份bat脚本
    同步数据库bat脚本
    读取spring boot项目中resource目录下的文件
    使用Java进行udp-demo编程时碰到的consumer和producter无法连接并报出“java.net.SocketException: Can't assign requested address”问题
    关于在项目中遇到MySQL数据库死锁的问题
    Gitlab仓库搭建及在Linux/windows中的免密使用
    GIT
  • 原文地址:https://www.cnblogs.com/sunqq/p/10438882.html
Copyright © 2011-2022 走看看