three.js使用(6)网页导入不同格式的模型文件

1,101 阅读3分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

1. 加载模型文件(通过3Dmax、blender等软件导出的三维模型文件)

  • .stl格式模型文件加载(.stl格式的三维模型不包含材质Material信息,只包含几何体顶点数据的信息) 三个位置坐标和一个三角形面的法线方向向量是一组数据,这一组数据表示一个三角形面的信息,下面是.syl文件里的内容
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加载.stl文件

1.首先导入STLLoader的js文件

 <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/STLLoader.js">

2.通过构造函数THREE.STLLoader()可以把.stl文件中几何体顶点信息提取出来转化为Three.js自身格式的几何体对象BufferGeometry

3.加载完成后会返回一个几何体对象BufferGeometry,你可以通过Mesh、Points等方式渲染该几何体

var loader = new THREE.STLLoader();
loader.load('立方体.stl',function (geometry) {
  // 加载完成后会返回一个几何体对象BufferGeometry,你可以通过Mesh、Points等方式渲染该几何体
  //网格渲染模式
  var material = new THREE.MeshLambertMaterial({
    color: 0x0000ff,
  }); //材质对象Material
  var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  scene.add(mesh); //网格模型添加到场景中
	//点渲染模式
	//var material = new THREE.PointsMaterial({
     //color: 0x000000,
     //size: 0.5//点对象像素尺寸
   //}); //材质对象
   //var points = new THREE.Points(geometry, material); //点模型对象
   //scene.add(points); //点对象添加到场景中
})
  • .obj格式模型文件加载(.使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的信息一样都是几何体顶点相关数据,材质文件.mtl包含的是模型的材质信息,比如颜色、贴图路径等)

** 通过OBJLoader.js加载.mtl,.obj文件**

1.首先导入OBJLoader和MTLLoader的js文件

 <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/OBJLoader.js"></script>
 <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/MTLLoader.js"></script>

然后通过Loader加载完成之后显示在页面上

/**
 * OBJ和材质文件mtl加载
 */
var OBJLoader = new THREE.OBJLoader();//obj加载器
var MTLLoader = new THREE.MTLLoader();//材质文件加载器
MTLLoader.load('./立方体/box.mtl', function(materials) {
  // 返回一个包含材质的对象MaterialCreator
  console.log(materials);
  //obj的模型会和MaterialCreator包含的材质对应起来
  OBJLoader.setMaterials(materials);
  OBJLoader.load('./立方体/box.obj', function(obj) {
    console.log(obj);
    obj.scale.set(10, 10, 10); //放大obj组对象
    scene.add(obj);//返回的组对象插入场景中
  })
})
obj文件可以包含多个网格模型对象,不一定就是一个,这些网格模型对象全部是并列关系,无法通过父子关系构建一个树结构层级模型。
***注意当Loader加载模型文件时,如果没设置材质文件,系统自动设置Phong网格材质***

可以通过.children[index]属性查看某个模型,像数组一样

// 没有材质文件,系统自动设置Phong网格材质
OBJLoader.load('./多个模型/model.obj',function (obj) {
  // 控制台查看返回结构:包含一个网格模型Mesh的组Group
  console.log(obj);
  scene.add(obj);
  // 加载后的一些编辑操作
  obj.scale.set(20,20,20);//网格模型缩放
  // 设置其中一个网格模型的颜色
  obj.children[0].material.color.set(0xff0000);
})

.obj文件不包含场景的相机Camera、光源Light等信息,不能导出骨骼动画、变形动画,如果希望导出光照信息、相机信息、骨骼动画信息、变形动画信息,可以选择.fbx、.gltf等格式。

  • FBX格式模型文件加载 通过FBXLoader加载.fbx文件(stl、obj都是静态模型,不可以包含动画,fbx除了包含几何、材质信息,可以存储骨骼动画等数据。)

1.首先导入FBXLoader的js文件和辅助文件

2.加载fbx模型文件

3.解析fbx模型骨骼动画

<!-- 引入fbx模型加载库FBXLoader -->
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/loaders/FBXLoader.js"></script>
<!-- 辅助文件 -->
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/libs/inflate.min.js"></script>
var loader = new THREE.FBXLoader();//创建一个FBX加载器
loader.load("SambaDancing.fbx", function(obj) {
  // console.log(obj);//查看加载后返回的模型对象
  scene.add(obj)
  // 适当平移fbx模型位置
  obj.translateY(-80);
})
var mixer=null;//声明一个混合器变量
var loader = new THREE.FBXLoader();//创建一个FBX加载器
loader.load("SambaDancing.fbx", function(obj) {
  // console.log(obj)
  scene.add(obj)
  obj.translateY(-80);
  // obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据
  mixer = new THREE.AnimationMixer(obj);
  // 查看动画数据
  console.log(obj.animations)
  // obj.animations[0]:获得剪辑对象clip
  var AnimationAction=mixer.clipAction(obj.animations[0]);
  // AnimationAction.timeScale = 1; //默认1,可以调节播放速度
  // AnimationAction.loop = THREE.LoopOnce; //不循环播放
  // AnimationAction.clampWhenFinished=true;//暂停在最后一帧播放的状态
  AnimationAction.play();//播放动画
})
// 创建一个时钟对象Clock
var clock = new THREE.Clock();
// 渲染函数
function render() {
  renderer.render(scene, camera); //执行渲染操作
  requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧

  if (mixer !== null) {
    //clock.getDelta()方法获得两帧的时间间隔
    // 更新混合器相关的时间
    mixer.update(clock.getDelta());
  }
}
render();