89 Three.js 匯入dae格式的骨骼繫結動畫模型
阿新 • • 發佈:2019-01-28
var renderer, camera, scene, gui, light, stats, controls, meshHelper, mixer, action;
var clock = new THREE.Clock();
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xeeeeee );
renderer.shadowMap.enabled = true;
//告訴渲染器需要陰影效果
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200);
camera.position.set(5, 10, 15 );
}
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa0a0a0 );
scene.fog = new THREE.Fog( 0xa0a0a0, 20, 100 );
}
//初始化dat.GUI簡化試驗流程
function initGui() {
//宣告一個儲存需求修改的相關資料的物件
gui = {
animation: true,
helper:true //模型輔助線
};
var datGui = new dat.GUI();
//將設定屬性新增到gui當中,gui.add(物件,屬性,最小值,最大值)
datGui.add(gui, "animation").onChange(function (e) {
if (e) {
action.play();
}
else {
action.stop();
}
});
datGui.add(gui, "helper").onChange(function (e) {
meshHelper.visible = e;
})
}
function initLight() {
scene.add(new THREE.AmbientLight(0x444444));
light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 10 );
light.castShadow = true;
light.shadow.camera.top = 10;
light.shadow.camera.bottom = -10;
light.shadow.camera.left = -10;
light.shadow.camera.right = 10;
//告訴平行光需要開啟陰影投射
light.castShadow = true;
scene.add(light);
}
function initModel() {
//輔助工具
var helper = new THREE.AxesHelper(50);
scene.add(helper);
// 地板
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 200, 200 ), new THREE.MeshPhongMaterial( { color: 0xffffff, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
//新增地板割線
var grid = new THREE.GridHelper( 200, 50, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
//載入模型
var loader = new THREE.ColladaLoader();
loader.load("/lib/models/collada/stormtrooper/stormtrooper.dae", function (mesh) {
console.log(mesh);
var obj = mesh.scene; //獲取到模型物件
//新增骨骼輔助
meshHelper = new THREE.SkeletonHelper(obj);
scene.add(meshHelper);
//設定模型的每個部位都可以投影
obj.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
//AnimationMixer是場景中特定物件的動畫播放器。當場景中的多個物件獨立動畫時,可以為每個物件使用一個AnimationMixer
mixer = obj.mixer = new THREE.AnimationMixer(obj);
//mixer.clipAction 返回一個可以控制動畫的AnimationAction物件 引數需要一個AnimationClip 物件
//AnimationAction.setDuration 設定一個迴圈所需要的時間,當前設定了一秒
//告訴AnimationAction啟動該動作
action = mixer.clipAction(mesh.animations[0]);
action.play();
obj.rotation.z += Math.PI;
scene.add(obj);
});
}
//初始化效能外掛
function initStats() {
stats = new Stats();
document.body.appendChild(stats.dom);
}
function initControls() {
controls = new THREE.OrbitControls(camera, renderer.domElement);
//設定控制器的中心點
//controls.target.set( 0, 100, 0 );
// 如果使用animate方法時,將此函式刪除
//controls.addEventListener( 'change', render );
// 使動畫迴圈使用時阻尼或自轉 意思是否有慣性
controls.enableDamping = true;
//動態阻尼係數 就是滑鼠拖拽旋轉靈敏度
//controls.dampingFactor = 0.25;
//是否可以縮放
controls.enableZoom = true;
//是否自動旋轉
controls.autoRotate = false;
controls.autoRotateSpeed = 0.5;
//設定相機距離原點的最遠距離
controls.minDistance = 1;
//設定相機距離原點的最遠距離
controls.maxDistance = 2000;
//是否開啟右鍵拖拽
controls.enablePan = true;
}
function render() {
var time = clock.getDelta();
if (mixer) {
mixer.update(time);
}
controls.update();
}
//視窗變動觸發的函式
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
//更新控制器
render();
//更新效能外掛
stats.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
function draw() {
//相容性判斷
if (!Detector.webgl) Detector.addGetWebGLMessage();
initGui();
initRender();
initScene();
initCamera();
initLight();
initModel();
initControls();
initStats();
animate();
window.onresize = onWindowResize;
}