| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 | 
							- import {
 
- 	AnimationMixer,
 
- 	Box3,
 
- 	Mesh,
 
- 	MeshLambertMaterial,
 
- 	Object3D,
 
- 	TextureLoader,
 
- 	UVMapping,
 
- 	sRGBEncoding
 
- } from '../../../build/three.module.js';
 
- import { MD2Loader } from '../loaders/MD2Loader.js';
 
- class MD2Character {
 
- 	constructor() {
 
- 		this.scale = 1;
 
- 		this.animationFPS = 6;
 
- 		this.root = new Object3D();
 
- 		this.meshBody = null;
 
- 		this.meshWeapon = null;
 
- 		this.skinsBody = [];
 
- 		this.skinsWeapon = [];
 
- 		this.weapons = [];
 
- 		this.activeAnimation = null;
 
- 		this.mixer = null;
 
- 		this.onLoadComplete = function () {};
 
- 		this.loadCounter = 0;
 
- 	}
 
- 	loadParts( config ) {
 
- 		const scope = this;
 
- 		function createPart( geometry, skinMap ) {
 
- 			const materialWireframe = new MeshLambertMaterial( { color: 0xffaa00, wireframe: true } );
 
- 			const materialTexture = new MeshLambertMaterial( { color: 0xffffff, wireframe: false, map: skinMap } );
 
- 			//
 
- 			const mesh = new Mesh( geometry, materialTexture );
 
- 			mesh.rotation.y = - Math.PI / 2;
 
- 			mesh.castShadow = true;
 
- 			mesh.receiveShadow = true;
 
- 			//
 
- 			mesh.materialTexture = materialTexture;
 
- 			mesh.materialWireframe = materialWireframe;
 
- 			return mesh;
 
- 		}
 
- 		function loadTextures( baseUrl, textureUrls ) {
 
- 			const textureLoader = new TextureLoader();
 
- 			const textures = [];
 
- 			for ( let i = 0; i < textureUrls.length; i ++ ) {
 
- 				textures[ i ] = textureLoader.load( baseUrl + textureUrls[ i ], checkLoadingComplete );
 
- 				textures[ i ].mapping = UVMapping;
 
- 				textures[ i ].name = textureUrls[ i ];
 
- 				textures[ i ].encoding = sRGBEncoding;
 
- 			}
 
- 			return textures;
 
- 		}
 
- 		function checkLoadingComplete() {
 
- 			scope.loadCounter -= 1;
 
- 			if ( scope.loadCounter === 0 ) scope.onLoadComplete();
 
- 		}
 
- 		this.loadCounter = config.weapons.length * 2 + config.skins.length + 1;
 
- 		const weaponsTextures = [];
 
- 		for ( let i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ];
 
- 		// SKINS
 
- 		this.skinsBody = loadTextures( config.baseUrl + 'skins/', config.skins );
 
- 		this.skinsWeapon = loadTextures( config.baseUrl + 'skins/', weaponsTextures );
 
- 		// BODY
 
- 		const loader = new MD2Loader();
 
- 		loader.load( config.baseUrl + config.body, function ( geo ) {
 
- 			const boundingBox = new Box3();
 
- 			boundingBox.setFromBufferAttribute( geo.attributes.position );
 
- 			scope.root.position.y = - scope.scale * boundingBox.min.y;
 
- 			const mesh = createPart( geo, scope.skinsBody[ 0 ] );
 
- 			mesh.scale.set( scope.scale, scope.scale, scope.scale );
 
- 			scope.root.add( mesh );
 
- 			scope.meshBody = mesh;
 
- 			scope.meshBody.clipOffset = 0;
 
- 			scope.activeAnimationClipName = mesh.geometry.animations[ 0 ].name;
 
- 			scope.mixer = new AnimationMixer( mesh );
 
- 			checkLoadingComplete();
 
- 		} );
 
- 		// WEAPONS
 
- 		const generateCallback = function ( index, name ) {
 
- 			return function ( geo ) {
 
- 				const mesh = createPart( geo, scope.skinsWeapon[ index ] );
 
- 				mesh.scale.set( scope.scale, scope.scale, scope.scale );
 
- 				mesh.visible = false;
 
- 				mesh.name = name;
 
- 				scope.root.add( mesh );
 
- 				scope.weapons[ index ] = mesh;
 
- 				scope.meshWeapon = mesh;
 
- 				checkLoadingComplete();
 
- 			};
 
- 		};
 
- 		for ( let i = 0; i < config.weapons.length; i ++ ) {
 
- 			loader.load( config.baseUrl + config.weapons[ i ][ 0 ], generateCallback( i, config.weapons[ i ][ 0 ] ) );
 
- 		}
 
- 	}
 
- 	setPlaybackRate( rate ) {
 
- 		if ( rate !== 0 ) {
 
- 			this.mixer.timeScale = 1 / rate;
 
- 		} else {
 
- 			this.mixer.timeScale = 0;
 
- 		}
 
- 	}
 
- 	setWireframe( wireframeEnabled ) {
 
- 		if ( wireframeEnabled ) {
 
- 			if ( this.meshBody ) this.meshBody.material = this.meshBody.materialWireframe;
 
- 			if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialWireframe;
 
- 		} else {
 
- 			if ( this.meshBody ) this.meshBody.material = this.meshBody.materialTexture;
 
- 			if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialTexture;
 
- 		}
 
- 	}
 
- 	setSkin( index ) {
 
- 		if ( this.meshBody && this.meshBody.material.wireframe === false ) {
 
- 			this.meshBody.material.map = this.skinsBody[ index ];
 
- 		}
 
- 	}
 
- 	setWeapon( index ) {
 
- 		for ( let i = 0; i < this.weapons.length; i ++ ) this.weapons[ i ].visible = false;
 
- 		const activeWeapon = this.weapons[ index ];
 
- 		if ( activeWeapon ) {
 
- 			activeWeapon.visible = true;
 
- 			this.meshWeapon = activeWeapon;
 
- 			this.syncWeaponAnimation();
 
- 		}
 
- 	}
 
- 	setAnimation( clipName ) {
 
- 		if ( this.meshBody ) {
 
- 			if ( this.meshBody.activeAction ) {
 
- 				this.meshBody.activeAction.stop();
 
- 				this.meshBody.activeAction = null;
 
- 			}
 
- 			const action = this.mixer.clipAction( clipName, this.meshBody );
 
- 			if ( action ) {
 
- 				this.meshBody.activeAction = action.play();
 
- 			}
 
- 		}
 
- 		this.activeClipName = clipName;
 
- 		this.syncWeaponAnimation();
 
- 	}
 
- 	syncWeaponAnimation() {
 
- 		const clipName = this.activeClipName;
 
- 		if ( this.meshWeapon ) {
 
- 			if ( this.meshWeapon.activeAction ) {
 
- 				this.meshWeapon.activeAction.stop();
 
- 				this.meshWeapon.activeAction = null;
 
- 			}
 
- 			const action = this.mixer.clipAction( clipName, this.meshWeapon );
 
- 			if ( action ) {
 
- 				this.meshWeapon.activeAction = action.syncWith( this.meshBody.activeAction ).play();
 
- 			}
 
- 		}
 
- 	}
 
- 	update( delta ) {
 
- 		if ( this.mixer ) this.mixer.update( delta );
 
- 	}
 
- }
 
- export { MD2Character };
 
 
  |