加载三维模型
直接使用three.js编程建模比较麻烦,实际开发的时候往往会借助一些可视化的3D建模工具,比如SolidWorks、Blender、C4D、3Dmax。不同领域的三维软件支持导出的文件有所差异,比如工业设计、机械设计类的三维软件往往支持导入静态的3D模型,游戏开发常常使用的Blender等三维软件,除了静态的三维模型,还可以导出含有动画信息的三维模型。three.js针对不同的文件格式,提供了许多对应的.js加载文件,使用的时候和相机控件一样先引入html文件中。
.STL格式
stl三维模型
基本所有的三维软件都支持导出.stl格式三维模型,stl三维模型不包含材质信息,你可以简单地把stl文件理解为几何体对象Geometry,本节课素材box.STL是一个立方体, 用记事本打开文件你可以看到里面的数据三个位置坐标和一个顶点法向量是一组数据,在第二章点线面的课程中讲解过三个顶点可以构成一个三角面,对于一个立方体而言需要至少12个三角面构成立方体的6个矩形平面。
stl文件数据结构
solid box //文件名字
//三角面1
facet normal 0 0 -1 //顶点法向量
outer loop
vertex 50 50 -50 //顶点位置
vertex 50 -50 -50 //顶点位置
vertex -50 50 -50 //顶点位置
endloop
endfacet
//三角面2
facet normal 0 0 -1 //顶点法向量
outer loop
vertex -50 50 -50 //顶点位置
vertex 50 -50 -50 //顶点位置
vertex -50 -50 -50 //顶点位置
endloop
endfacet
facet normal 0 1 0
.....
.....
//三角面12
facet normal -1 0 0
outer loop
vertex -50 -50 -50
vertex -50 50 50
vertex -50 50 -50
endloop
endfacet
endsolid
加载文件
可以在下载的STLLoader.js文件中找到FirstPersonControls.js控件,路径是three.js-master\examples\js\loaders。
<!--引入STLLoader.js文件--> <script src="STLLoader.js"></script>
加载文件
可以在下载的STLLoader.js文件中找到FirstPersonControls.js控件,路径是three.js-master\examples\js\loaders。
通过构造函数THREE.STLLoader()可以把.stl三维模型转化为网格模型的几何体对象Geometry,具体点说就是执行语句loader.load("box.STL", stlMesh),box.STL文件的几何数据转化为一个几何体对象, 几何体对象作为函数stlMesh()的参数使用,然后在stlMesh()函数中作为Mesh构造函数的参数来生成网格模型。
/** * 加载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);//网格模型添加到场景中 }
.OBJ格式
OBJ三维模型
使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的数据一样都是几何体对象的顶点位置、顶点法向量等顶点相关数据, 材质文件.mtl包含的是RGB颜色值等材质信息。
加载.obj三维模型的时候,可以只加载.obj文件,然后借助three.js引擎自定义材质对象Material,也可以同时加载obj和mtl文件。
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对象插入场景对象 }