直接使用three.js编程建模比较麻烦,实际开发的时候往往会借助一些可视化的3D建模工具,比如SolidWorks、Blender、C4D、3Dmax。不同领域的三维软件支持导出的文件有所差异,比如工业设计、机械设计类的三维软件往往支持导入静态的3D模型,游戏开发常常使用的Blender等三维软件,除了静态的三维模型,还可以导出含有动画信息的三维模型。three.js针对不同的文件格式,提供了许多对应的.js加载文件,使用的时候和相机控件一样先引入html文件中。

threejs读取Blender 模型参数 threejs 加载模型_加载器

(1)在加载外部3维模型的时候会出现跨域错误,导致模型加载不出来,(通过Three.js加载obj、FBX等格式外部模型文件的时候是ajax异步加载数据的过程,需要建立本地服务器来解决,如果不这样直接使用浏览器打开加载三维模型的.html文件,会出现报错无法模型文件无法加载,浏览器控制报错跨域问题的情况。)

threejs读取Blender 模型参数 threejs 加载模型_加载器_02

解决方案

解决方案就是在本地自定义服务器,可以通过nodejs、python等任何一个你熟悉的语言来实现。

使用Nodejs自定义服务器很简单,首先是你要先百度Nodejs安装的相关文章,先在你的电脑上安装配置好Nodejs,熟悉下NPM的使用,然后使用npm执行npm install http-server安装http-server模块,如果想创建创建一个自定义的服务器,打开命令行,在你要打开的html文件所在的目录下,执行http-server就可以完成服务器创建,具体不了解的可以百度相关内容。

浏览器访问http://localhost:8080http://127.0.0.1:8080地址打开相应的.html文件就可以显示三维模型效果。

1. npm i http-server -g // 安装node的本地服务器

2. cd <path>;  // path 是想要访问文件的目录;比如我想访问 d/test 文件夹;

3. 打开终端,启动服务器,http-server -p 8000

4. 终端会提示访问哪个端口,然后在浏览器上通过这个端口,在后接访问文件路径就可以访问了;

threejs读取Blender 模型参数 threejs 加载模型_加载_03

 

(2)如何加载外部3维模型

.STL格式

 基本所有的三维软件都支持导出.stl格式三维模型,stl三维模型不包含材质信息,你可以简单地把stl文件理解为几何体对象Geometry

(1)引入js文件

<!--引入STLLoader.js文件-->
    <script src="STLLoader.js"></script>

(2)把模型放在文件夹下

(3)代码引入

/**
     * 加载stl立方体,生成网格模型
     */
    var loader = new THREE.STLLoader();//创建stl模型加载器对象
    loader.load("box.STL", stlMesh);//加载stl完成后执行函数stlMesh()
    //stl加载完成后等待执行的函数
    function stlMesh(stlGeometry) {
        var material=new THREE.MeshLambertMaterial({color:0x0000ff});//材质对象
        var mesh=new THREE.Mesh(stlGeometry,material);//网格模型对象
        scene.add(mesh);//网格模型添加到场景中
    }

代码解释:通过构造函数THREE.STLLoader()可以把.stl三维模型转化为网格模型的几何体对象Geometry,具体点说就是执行语句loader.load("box.STL", stlMesh),box.STL文件的几何数据转化为一个几何体对象, 几何体对象作为函数stlMesh()的参数使用,然后在stlMesh()函数中作为Mesh构造函数的参数来生成网格模型。

1.加载obj文件

引入OBJLoader.js文件

  OBJLoader.js文件封装的构造函数THREE.OBJLoader()用来加载.obj模型文件。

<!--引入OBJLoader.js文件-->
    <script src="OBJLoader.js"></script>

加载obj文件

  通过stl加载器返回的结果是几何体对象Geometry,而通过obj加载器返回的结果是网格模型数组组成的object3D对象,

  object3D对象具有children属性,children属性值是数组,数组的子元素可以是网格模型对象,可以是光源对象,也可以是网格模型对象mesh组成的Object3D对象。 对于obj加载器返回的object3D对象而言,都是网格模型对象,本obj模型只有一个立方体,所以object3D.children返回的数组只有一个元素,如果有多个零件组成的装配体, 数组就会有多个元素。

/**
     * 加载立方体obj文件,自定义材质的对象,生成网格模型
     */
    var loader = new THREE.OBJLoader();//创建obj模型加载器对象
    loader.load("box.obj",obj);//加载obj完成后执行函数stl()
    //stl加载完成后等待执行的函数
    function obj(object3D) {
        object3D.scale.set(100,100,100);//放大object3D对象
        var material=new THREE.MeshLambertMaterial({color:0xff00ff});//材质对象
        object3D.children.forEach(function (child) {
            child.material = material;//object3D对象的子对象网格模型赋予材质对象
        });
        scene.add(object3D);//网格模型添加到场景中
    }

2.同时加载obj和mtl文件

引入OBJLoader.js和MTLLoader.js文件

  MTLLoader.js文件封装的构造函数THREE.MTLLoader()用来加载.mtl材质文件。

!--引入OBJLoader.js文件-->
    <script src="OBJLoader.js"></script>
    <!--引入MTLLoader.js文件-->
    <script src="MTLLoader.js"></script>
/**
     * 加载红色立方体的.obj和.mtl文件,生成网格模型
     */
    var mtlLoader = new THREE.MTLLoader();//mtl材质加载器
    mtlLoader.load( 'box.mtl', mtl);//加载.mtl文件,执行mtl函数
    /**声明函数mtl*/
    function mtl( material ) {
        var objLoader = new THREE.OBJLoader();//obj模型加载器
        objLoader.setMaterials( material );//mtl材质赋值给obj模型
        objLoader.load( 'box.obj',obj );//加载.obj文件,执行obj函数
    }
    /**声明函数obj*/
    function obj( object3D ) {
        object3D.scale.set(100,100,100);//放大object3D对象
        scene.add( object3D );//object3D对象插入场景对象
    }