1. obj格式
    1. 方法
      1. load 加载文件
      2. parse 解析obj文本
  2. mlt格式
    1. 方法
      1. load 加载mtl文件
      2. setPath 设置基本路径
      3. setCrossOrigin 允许跨域
      4. setMaterialOptions ?
  3. MMDLoader.js
  4. MMDLoader
    1. 方法
      1. load 加载模型和动作文件
      2. loadModel 加载pmd|pmx
      3. loadVmd 加载vmd文件
      4. loadVmds 加载多个vmd文件
      5. loadAudio 加载音频文件
    2. loadVpd 加载姿势文件
  5. MMDHelper
    1. add
    2. setAudio 设置音频文件
    3. setCamera 加载相机
    4. setPhysics 设置物理效果(重力,碰撞之类的)
    5. setAnimation 设置动画
    6. setCameraAnimation 设置相机动画
    7. unifyAnimationDuration

Three.js 模型载入

obj格式

THREE.OBJLoader(manager)

  • manager 加载器使用的loadingManager,默认为THREE.DefaultLoadingManager

方法

load 加载文件

.load( url, onLoad, onProgress, onError)

  • url 路径
  • onLoad (可选)加载完成后调用的函数,接收Object3D作为参数
  • onProgress (可选)加载过程中调用的函数,接收XMLHttpRequest实例作为参数,其中包含加载内容的总大小和已加载大小
  • onError (可选)出错时调用的函数,接收错误信息作为参数

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var model;
var loader = new THREE.OBJLoader();
loader.load('model/tree/model.obj', function(obj) {
// 储存模型对象到全局变量中
model = obj;
// obj是一个THREE.Group实例,
// 要用.children获取其包含的所有THREE.Mesh实例
var children = obj.children;
for (var i = 0; i < children.length; i++) {
//添加阴影
children[i].castShadow= true;
}
// 添加模型到scene
scene.add(obj);
},function(xhr){
// 显示加载进度
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},function(error){
// 显示错误信息
console.log(error);
});

parse 解析obj文本

直接加载obj文件文本内容
.parse ( text )

  • test obj文件文本

mlt格式

mlt是obj模型的材质文件
MTLLoader 官方文档
MTLLoader(loadingManager)

  • loadingManager 默认值为DefaultLoadingManager

方法

load 加载mtl文件

从url加载mlt文件并返回加载的材质
.load ( url, onLoad, onProgress, onError )

  • onLoad (可选)加载完成后调用的函数,接收MTLLoader.MaterialCreator实例作为参数
1
2
3
4
5
6
7
8
9
10
11
var model;
var mtlLoader = new THREE.MTLLoader();
var objLoader = new THREE.OBJLoader();
mtlLoader.load('model/tree/materials.mtl', function(materials){
// 设置材质
objLoader.setMaterials(materials);
objLoader.load('model/tree/model.obj', function(obj) {
model = obj;
scene.add(obj);
});
});

setPath 设置基本路径

.setPath ( path )

1
2
3
4
5
6
7
8
var mtlLoader = new THREE.MTLLoader();
// 记得用"/"作为路径结尾,例如 'model/tree'中的tree会被忽略
mtlLoader.setPath('model/tree/');
mtlLoader.load('materials.mtl',function(){});

// 相当于
new THREE.MTLLoader().load('model/tree/model.obj',function(){});

setCrossOrigin 允许跨域

.setCrossOrigin ( useCrossOrigin )
如果需要从其他源加载纹理文件,设置为true

1
2
var mtl = new THREE.MTLLoader();
mtl.setCrossOrigin(true);

setMaterialOptions ?

.setMaterialOptions ( options )

  • side THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
  • wrap
  • normalizeRGB
  • ignoreZeroRGBs

MMDLoader.js

MMDLoader.js插件包含两个构造函数
THREE.MMDLoader() 用于加载模型/骨骼等文件
THREE.MMDHelper() 用于设置物理/骨骼/声音选项

更多方法请参考MMDLoader
源代码

载入MMDLoader插件挺麻烦的,需要的依赖太多,可以在example目录下找到这些文件

1
2
3
4
5
6
7
8
9
10
11
12
<script src="js/loaders/MMDLoader.js"></script>
<!--MMDLoader依赖下列库-->
<script src="js/loaders/TGALoader.js"></script>
<script src="js/libs/mmdparser.min.js"></script>
<!--物理引擎-->
<script src="js/libs/ammo.js"></script>
<!--描边效果-->
<script src="js/effects/OutlineEffect.js"></script>
<!--骨骼-->
<script src="js/animation/CCDIKSolver.js"></script>
<!--物理-->
<script src="js/animation/MMDPhysics.js"></script>

MMDLoader

THREE.MMDLoader()

方法

load 加载模型和动作文件

load = function ( modelUrl, vmdUrls, callback, onProgress, onError )

  • modelUrl pmd|pmx模型文件路径
  • vmdUrls 一个数组,内含一组vmd动作文件路径
  • callback 回调函数,模型加载完毕后调用
  • onProgress (可选)加载过程中调用
  • onError (可选)出错时调用
1
2
3
4
5
6
7
8
9
10
var model;
var mmdLoader = new THREE.MMDLoader;
var mmdPath = 'model/kizunaai/kizunaai.pmx';
var vmdPath = ['model/vmd/Ririri.vmd',];

mmdLoader.load(mmdPath, vmdPath,function(object){
model = object;
scene.add(object);
});

loadModel 加载pmd|pmx

loadModel( url, callback, onProgress, onError )
loadModel在内部使用this.createModel()创建模型

1
2
3
4
5
6
7
8
9
10
11
12
13
var model;
var mmdFile = 'model/ia/IA.pmx';
var mmdLoader = new THREE.MMDLoader();
//加载模型
mmdLoader.loadModel(mmdFile, function(object){
model = object;
object.scale.set(40, 40, 40);
// 更改坐标位置
object.position.x = 500;
// 添加阴影
object.castShadow = true;
scene.add(object);
});

loadVmd 加载vmd文件

.loadVmd( url, callback, onProgress, onError )

1
2
3
4
5
var vmd;
var mmdLoader = new THREE.MMDLoader();
mmdLoader.loadVmd('model/vmd/Ririri.vmd',function(obj){
vmd = obj;
})

loadVmds 加载多个vmd文件

.loadVmds( url, callback, onProgress, onError )

  • url 一个队列,内含一组vmds文件的url
1
2
3
4
5
6
var vmd;
var mmdLoader = new THREE.MMDLoader();
var vmdPath = ['model/vmd/Ririri.vmd','model/vmd/Ririri1.vmd']
mmdLoader.loadVmds(vmdPath ,function(obj){
vmd = obj;
})

loadAudio 加载音频文件

.loadAudio( url, callback, onProgress, onError )

1
2
3
4
5
6
7
8
var mp3;
var lter;
var mmdLoader = new THREE.MMDLoader();
mmdLoader.loadVmds(vmdPath ,function(audio, listener){
mp3 = obj;
// listener 是一个THREE.AudioListener实例
lter = listener;
})

loadVpd 加载姿势文件

.loadVpd( url, callback, onProgress, onError, params )

MMDHelper

add

.add(mesh)

  • mesh 用MMDLoader().load()获取到的模型
1
2
3
4
5
6
7
var mmdHelper = new THREE.MMDHelper();
var mmdLoader = new THREE.MMDLoader();
var mmdPath = 'model/kizunaai/kizunaai.pmx';
var vmdPath = ['model/vmd/Ririri.vmd',];
mmdLoader.load(mmdPath, vmdPath,function(object){
mmdHelper.add(object);
});

setAudio 设置音频文件

.setAudio( audio, listener, params );

  • params 对象,内含一组音频参数
    • delayTime 声音播放延迟,单位为秒

setCamera 加载相机

.setCamera( camera )

setPhysics 设置物理效果(重力,碰撞之类的)

.setPhysics( mesh, params )

  • params (可选)物理参数

setAnimation 设置动画

.setAnimation( mesh )

setCameraAnimation 设置相机动画

.setCameraAnimation( camera )

unifyAnimationDuration

检测动作/音频/相机的时间长度,使其自动同步
.unifyAnimationDuration( params )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
var mmdModel,mmdCamera,mmdAudio,mmdListener,ready;
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
var mmdHelper = new THREE.MMDHelper();
var mmdLoader = new THREE.MMDLoader();
var mmdPath = 'model/kizunaai/kizunaai.pmx';
var vmdPath = ['model/vmd/Ririri.vmd'];
var mmdCameraPath = ['model/vmd/wavefile_camera.vmd'];
var AudioPath = 'mp3/Ririri.mp3';
mmdLoader.load(mmdPath, vmdPath,function(object){
mmdModel = object;
callback();
});
mmdLoader.loadVmds(mmdCameraPath, function ( vmd ){
mmdCamera = vmd;
callback();
});
mmdLoader.loadAudio( AudioPath, function (audio, listener) {
mmdAudio = audio;
mmdListener = listener;
callback();
});

function callback(){
if(!mmdModel || !mmdCamera || !mmdAudio || !mmdListener) {
return;
}
mmdHelper.add(mmdModel);
// 加载摄像机运动轨迹
mmdHelper.setCamera(camera);
// 绑定vmd轨迹到相机对象
mmdLoader.pourVmdIntoCamera(camera, mmdCamera);
// 开启相机动画,在pourVmdIntoCamera后调用
mmdHelper.setCameraAnimation(camera);
// 加载物理效果
mmdHelper.setPhysics(mmdModel);
// 开启动作
mmdHelper.setAnimation(mmdModel);
mmdListener.position.z = 1;
// 加载声音,延迟1s播放
mmdHelper.setAudio(mmdAudio,mmdListener, { delayTime: 1});
// 同步声音和动作
mmdHelper.unifyAnimationDuration();
scene.add(mmdModel,mmdAudio,mmdListener);
ready = true;
}

var clock = new THREE.Clock();
function animation(){
if (ready) {
mmdHelper.animate(clock.getDelta());
}
requestAnimationFrame(animation);
}

注 给mmd模型设置Physics后,不要再用scale修改模型大小(会导致模型变成一坨不明物体)