Threejs系列:md2模型
本文介绍如何将md2模型,导进我们的页面中
前面有介绍过使用gltf的loader,加载glb模型。那么针对古老的md2模型文件,如何操作呢?
1. 导入md2库
import { MD2Character } from 'three/examples/jsm/misc/MD2Character.js';
2. 加入一个平面贴图当作草地
const gt = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big.jpg' );
const gg = new THREE.PlaneGeometry( 20, 20 );
const gm = new THREE.MeshPhongMaterial( { color: 0xffffff, map: gt } );
const ground = new THREE.Mesh( gg, gm );
ground.rotation.x = - Math.PI / 2;
ground.material.map.repeat.set( 8, 8 );
ground.material.map.wrapS = ground.material.map.wrapT = THREE.RepeatWrapping;
ground.material.map.colorSpace = THREE.SRGBColorSpace;
ground.receiveShadow = true;
scene.add( ground );
3. 模型导入
let character = new MD2Character();
const playbackConfig = {
speed: 1.0,
wireframe: false
};
const config = {
baseUrl: 'models/md2/ratamahatta/',
body: 'ratamahatta.md2',
skins: [ 'ratamahatta.png', 'ctf_b.png', 'ctf_r.png', 'dead.png', 'gearwhore.png' ],
weapons: [[ 'weapon.md2', 'weapon.png' ],
[ 'w_bfg.md2', 'w_bfg.png' ],
[ 'w_blaster.md2', 'w_blaster.png' ],
[ 'w_chaingun.md2', 'w_chaingun.png' ],
[ 'w_glauncher.md2', 'w_glauncher.png' ],
[ 'w_hyperblaster.md2', 'w_hyperblaster.png' ],
[ 'w_machinegun.md2', 'w_machinegun.png' ],
[ 'w_railgun.md2', 'w_railgun.png' ],
[ 'w_rlauncher.md2', 'w_rlauncher.png' ],
[ 'w_shotgun.md2', 'w_shotgun.png' ],
[ 'w_sshotgun.md2', 'w_sshotgun.png' ]
]
};
const labelize = ( text ) => {
const parts = text.split( '.' );
if ( parts.length > 1 ) {
parts.length -= 1;
return parts.join( '.' );
}
return text;
}
const setupGUIAnimations =( character ) => {
const folder = gui.addFolder( 'Animations' );
const generateCallback = function ( animationClip ) {
return function () {
character.setAnimation( animationClip.name );
};
};
const guiItems = [];
const animations = character.meshBody.geometry.animations;
for ( let i = 0; i < animations.length; i ++ ) {
const clip = animations[ i ];
playbackConfig[ clip.name ] = generateCallback( clip );
guiItems[ i ] = folder.add( playbackConfig, clip.name, clip.name );
}
}
const setupWeaponsGUI = ( character ) => {
const folder = gui.addFolder( 'Weapons' );
const generateCallback = function ( index ) {
return function () {
character.setWeapon( index );
character.setWireframe( playbackConfig.wireframe );
};
};
const guiItems = [];
for ( let i = 0; i < character.weapons.length; i ++ ) {
const name = character.weapons[ i ].name;
playbackConfig[ name ] = generateCallback( i );
guiItems[ i ] = folder.add( playbackConfig, name ).name( labelize( name ) );
}
}
const setupSkinsGUI = ( character ) => {
const folder = gui.addFolder( 'Skins' );
const generateCallback = function ( index ) {
return function () {
character.setSkin( index );
};
};
const guiItems = [];
for ( let i = 0; i < character.skinsBody.length; i ++ ) {
const name = character.skinsBody[ i ].name;
playbackConfig[ name ] = generateCallback( i );
guiItems[ i ] = folder.add( playbackConfig, name ).name( labelize( name ) );
}
}
character.scale = 0.03;
character.onLoadComplete = function () {
setupSkinsGUI( character );
setupWeaponsGUI( character );
setupGUIAnimations( character );
character.setAnimation( character.meshBody.geometry.animations[ 0 ].name );
};
character.loadParts( config );
scene.add( character.root );
4. 最终效果
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
