Selaa lähdekoodia

JSM: Added module and TS file for MorphBlendMesh.

Mugen87 6 vuotta sitten
vanhempi
commit
4498fa52a8

+ 1 - 0
docs/manual/en/introduction/Import-via-modules.html

@@ -211,6 +211,7 @@
 						<li>Car</li>
 						<li>Gyroscope</li>
 						<li>MD2Character</li>
+						<li>MorphBlendMesh</li>
 						<li>Ocean</li>
 					</ul>
 				</li>

+ 0 - 0
examples/js/MorphBlendMesh.js → examples/js/misc/MorphBlendMesh.js


+ 26 - 0
examples/jsm/misc/MorphBlendMesh.d.ts

@@ -0,0 +1,26 @@
+import {
+  BufferGeometry,
+  Geometry,
+  Material,
+  Mesh
+} from '../../../src/Three';
+
+export class MorphBlendMesh extends Mesh {
+  constructor(geometry: BufferGeometry | Geometry, material: Material);
+  animationsMap: object;
+  animationsList: object[];
+
+  createAnimation(name: string, start: number, end: number, fps: number): void;
+  autoCreateAnimations(fps: number): void;
+  setAnimationDirectionForward(name: string): void;
+  setAnimationDirectionBackward(name: string): void;
+  setAnimationFPS(name: string, fps: number): void;
+  setAnimationDuration(name: string, duration: number): void;
+  setAnimationWeight(name: string, weight: number): void;
+  setAnimationTime(name: string, time: number): void;
+  getAnimationTime(name: string): number;
+  getAnimationDuration(name: string): number;
+  playAnimation(name: string): void;
+  stopAnimation(name: string): void;
+  update(delta: number): void;
+}

+ 326 - 0
examples/jsm/misc/MorphBlendMesh.js

@@ -0,0 +1,326 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ */
+
+import {
+	Math as _Math,
+	Mesh
+} from "../../../build/three.module.js";
+
+var MorphBlendMesh = function ( geometry, material ) {
+
+	Mesh.call( this, geometry, material );
+
+	this.animationsMap = {};
+	this.animationsList = [];
+
+	// prepare default animation
+	// (all frames played together in 1 second)
+
+	var numFrames = Object.keys( this.morphTargetDictionary ).length;
+
+	var name = '__default';
+
+	var startFrame = 0;
+	var endFrame = numFrames - 1;
+
+	var fps = numFrames / 1;
+
+	this.createAnimation( name, startFrame, endFrame, fps );
+	this.setAnimationWeight( name, 1 );
+
+};
+
+MorphBlendMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
+
+	constructor: MorphBlendMesh,
+
+	createAnimation: function ( name, start, end, fps ) {
+
+		var animation = {
+
+			start: start,
+			end: end,
+
+			length: end - start + 1,
+
+			fps: fps,
+			duration: ( end - start ) / fps,
+
+			lastFrame: 0,
+			currentFrame: 0,
+
+			active: false,
+
+			time: 0,
+			direction: 1,
+			weight: 1,
+
+			directionBackwards: false,
+			mirroredLoop: false
+
+		};
+
+		this.animationsMap[ name ] = animation;
+		this.animationsList.push( animation );
+
+	},
+
+	autoCreateAnimations: function ( fps ) {
+
+		var pattern = /([a-z]+)_?(\d+)/i;
+
+		var firstAnimation, frameRanges = {};
+
+		var i = 0;
+
+		for ( var key in this.morphTargetDictionary ) {
+
+			var chunks = key.match( pattern );
+
+			if ( chunks && chunks.length > 1 ) {
+
+				var name = chunks[ 1 ];
+
+				if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };
+
+				var range = frameRanges[ name ];
+
+				if ( i < range.start ) range.start = i;
+				if ( i > range.end ) range.end = i;
+
+				if ( ! firstAnimation ) firstAnimation = name;
+
+			}
+
+			i ++;
+
+		}
+
+		for ( var name in frameRanges ) {
+
+			var range = frameRanges[ name ];
+			this.createAnimation( name, range.start, range.end, fps );
+
+		}
+
+		this.firstAnimation = firstAnimation;
+
+	},
+
+	setAnimationDirectionForward: function ( name ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.direction = 1;
+			animation.directionBackwards = false;
+
+		}
+
+	},
+
+	setAnimationDirectionBackward: function ( name ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.direction = - 1;
+			animation.directionBackwards = true;
+
+		}
+
+	},
+
+	setAnimationFPS: function ( name, fps ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.fps = fps;
+			animation.duration = ( animation.end - animation.start ) / animation.fps;
+
+		}
+
+	},
+
+	setAnimationDuration: function ( name, duration ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.duration = duration;
+			animation.fps = ( animation.end - animation.start ) / animation.duration;
+
+		}
+
+	},
+
+	setAnimationWeight: function ( name, weight ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.weight = weight;
+
+		}
+
+	},
+
+	setAnimationTime: function ( name, time ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.time = time;
+
+		}
+
+	},
+
+	getAnimationTime: function ( name ) {
+
+		var time = 0;
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			time = animation.time;
+
+		}
+
+		return time;
+
+	},
+
+	getAnimationDuration: function ( name ) {
+
+		var duration = - 1;
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			duration = animation.duration;
+
+		}
+
+		return duration;
+
+	},
+
+	playAnimation: function ( name ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.time = 0;
+			animation.active = true;
+
+		} else {
+
+			console.warn( "MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" );
+
+		}
+
+	},
+
+	stopAnimation: function ( name ) {
+
+		var animation = this.animationsMap[ name ];
+
+		if ( animation ) {
+
+			animation.active = false;
+
+		}
+
+	},
+
+	update: function ( delta ) {
+
+		for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
+
+			var animation = this.animationsList[ i ];
+
+			if ( ! animation.active ) continue;
+
+			var frameTime = animation.duration / animation.length;
+
+			animation.time += animation.direction * delta;
+
+			if ( animation.mirroredLoop ) {
+
+				if ( animation.time > animation.duration || animation.time < 0 ) {
+
+					animation.direction *= - 1;
+
+					if ( animation.time > animation.duration ) {
+
+						animation.time = animation.duration;
+						animation.directionBackwards = true;
+
+					}
+
+					if ( animation.time < 0 ) {
+
+						animation.time = 0;
+						animation.directionBackwards = false;
+
+					}
+
+				}
+
+			} else {
+
+				animation.time = animation.time % animation.duration;
+
+				if ( animation.time < 0 ) animation.time += animation.duration;
+
+			}
+
+			var keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
+			var weight = animation.weight;
+
+			if ( keyframe !== animation.currentFrame ) {
+
+				this.morphTargetInfluences[ animation.lastFrame ] = 0;
+				this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
+
+				this.morphTargetInfluences[ keyframe ] = 0;
+
+				animation.lastFrame = animation.currentFrame;
+				animation.currentFrame = keyframe;
+
+			}
+
+			var mix = ( animation.time % frameTime ) / frameTime;
+
+			if ( animation.directionBackwards ) mix = 1 - mix;
+
+			if ( animation.currentFrame !== animation.lastFrame ) {
+
+				this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
+				this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
+
+			} else {
+
+				this.morphTargetInfluences[ animation.currentFrame ] = weight;
+
+			}
+
+		}
+
+	}
+
+} );
+
+export { MorphBlendMesh };

+ 1 - 1
examples/webgl_loader_md2_control.html

@@ -28,7 +28,7 @@
 		<script src="js/controls/OrbitControls.js"></script>
 
 		<script src="js/loaders/MD2Loader.js"></script>
-		<script src="js/MorphBlendMesh.js"></script>
+		<script src="js/misc/MorphBlendMesh.js"></script>
 		<script src="js/MD2CharacterComplex.js"></script>
 		<script src="js/misc/Gyroscope.js"></script>
 

+ 1 - 0
utils/modularize.js

@@ -110,6 +110,7 @@ var files = [
 	{ path: 'misc/ConvexObjectBreaker.js', dependencies: [ { name: 'ConvexBufferGeometry', path: 'geometries/ConvexGeometry.js' } ], ignoreList: [ 'Matrix4' ] },
 	{ path: 'misc/Gyroscope.js', dependencies: [], ignoreList: [] },
 	{ path: 'misc/MD2Character.js', dependencies: [ { name: 'MD2Loader', path: 'loaders/MD2Loader.js' } ], ignoreList: [] },
+	{ path: 'misc/MorphBlendMesh.js', dependencies: [], ignoreList: [] },
 	{ path: 'misc/Ocean.js', dependencies: [ { name: 'OceanShaders', path: 'shaders/OceanShaders.js' } ], ignoreList: [] },
 
 	{ path: 'modifiers/ExplodeModifier.js', dependencies: [], ignoreList: [] },