瀏覽代碼

MMDLoader Grant Non-local Rotation Animation support

takahiro 9 年之前
父節點
當前提交
680daf81b9
共有 1 個文件被更改,包括 144 次插入14 次删除
  1. 144 14
      examples/js/loaders/MMDLoader.js

+ 144 - 14
examples/js/loaders/MMDLoader.js

@@ -29,7 +29,7 @@
  *  - light motion in vmd support.
  *  - SDEF support.
  *  - uv/material/bone morphing support.
- *  - supply skinning support.
+ *  - more precise grant skinning support.
  *  - shadow support.
  */
 
@@ -1122,8 +1122,19 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
 
 			if ( p.flag & 0x100 || p.flag & 0x200 ) {
 
-				p.supplyParentIndex = dv.getIndex( pmx.metadata.boneIndexSize );
-				p.supplyRatio = dv.getFloat32();
+				// Note: I don't think Grant is an appropriate name
+				//       but I found that some English translated MMD tools use this term
+				//       so I've named it Grant so far.
+				//       I'd rename to more appropriate name from Grant later.
+				var grant = {};
+
+				grant.isLocal = ( p.flag & 0x80 ) !== 0 ? true : false;
+				grant.affectRotation = ( p.flag & 0x100 ) !== 0 ? true : false;
+				grant.affectPosition = ( p.flag & 0x200 ) !== 0 ? true : false;
+				grant.parentIndex = dv.getIndex( pmx.metadata.boneIndexSize );
+				grant.ratio = dv.getFloat32();
+
+				p.grant = grant;
 
 			}
 
@@ -1878,6 +1889,44 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 	};
 
+	var initGrants = function () {
+
+		if ( model.metadata.format === 'pmd' ) {
+
+			return;
+
+		}
+
+		var grants = [];
+
+		for ( var i = 0; i < model.metadata.boneCount; i++ ) {
+
+			var b = model.bones[ i ];
+			var grant = b.grant;
+
+			if ( grant === undefined ) {
+
+				continue;
+
+			}
+
+			var param = {};
+
+			param.index = i;
+			param.parentIndex = grant.parentIndex;
+			param.ratio = grant.ratio;
+			param.isLocal = grant.isLocal;
+			param.affectRotation = grant.affectRotation;
+			param.affectPosition = grant.affectPosition;
+
+			grants.push( param );
+
+		}
+
+		geometry.grants = grants;
+
+	};
+
 	var initMorphs = function () {
 
 		function updateVertex ( params, index, v, ratio ) {
@@ -2578,6 +2627,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 	initFaces();
 	initBones();
 	initIKs();
+	initGrants();
 	initMorphs();
 	initMaterials();
 	initPhysics();
@@ -3924,6 +3974,66 @@ THREE.MMDAudioManager.prototype = {
 
 };
 
+THREE.MMDGrantSolver = function ( mesh ) {
+
+	this.mesh = mesh;
+
+};
+
+THREE.MMDGrantSolver.prototype = {
+
+	constructor: THREE.MMDGrantSolver,
+
+	update: function () {
+
+		var q = new THREE.Quaternion();
+
+		return function () {
+
+			for ( var i = 0; i < this.mesh.geometry.grants.length; i ++ ) {
+
+				var g = this.mesh.geometry.grants[ i ];
+				var b = this.mesh.skeleton.bones[ g.index ];
+				var pb = this.mesh.skeleton.bones[ g.parentIndex ];
+
+				if ( g.isLocal ) {
+
+					// TODO: implement
+					if ( g.affectPosition ) {
+
+					}
+
+					// TODO: implement
+					if ( g.affectRotation ) {
+
+					}
+
+				} else {
+
+					// TODO: implement
+					if ( g.affectPosition ) {
+
+					}
+
+					if ( g.affectRotation ) {
+
+						q.set( 0, 0, 0, 1 );
+						q.slerp( pb.quaternion, g.ratio );
+						b.quaternion.multiply( q );
+						b.updateMatrixWorld( true );
+
+					}
+
+				}
+
+			}
+
+		};
+
+	}()
+
+};
+
 THREE.MMDHelper = function ( renderer ) {
 
 	this.renderer = renderer;
@@ -3932,6 +4042,7 @@ THREE.MMDHelper = function ( renderer ) {
 
 	this.doAnimation = true;
 	this.doIk = true;
+	this.doGrant = true;
 	this.doPhysics = true;
 	this.doOutlineDrawing = true;
 	this.doCameraAnimation = true;
@@ -3965,6 +4076,7 @@ THREE.MMDHelper.prototype = {
 
 		mesh.mixer = null;
 		mesh.ikSolver = null;
+		mesh.grantSolver = null;
 		mesh.physics = null;
 		this.meshes.push( mesh );
 
@@ -4035,6 +4147,14 @@ THREE.MMDHelper.prototype = {
 
 			}
 
+			mesh.ikSolver = new THREE.CCDIKSolver( mesh );
+
+			if ( mesh.geometry.grants !== undefined ) {
+
+				mesh.grantSolver = new THREE.MMDGrantSolver( mesh );
+
+			}
+
 		}
 
 		if ( mesh.geometry.morphAnimations !== undefined ) {
@@ -4053,12 +4173,6 @@ THREE.MMDHelper.prototype = {
 
 		}
 
-		if ( mesh.geometry.animations !== undefined ) {
-
-			mesh.ikSolver = new THREE.CCDIKSolver( mesh );
-
-		}
-
 	},
 
 	setCameraAnimation: function ( camera ) {
@@ -4205,13 +4319,14 @@ THREE.MMDHelper.prototype = {
 
 		var mixer = mesh.mixer;
 		var ikSolver = mesh.ikSolver;
+		var grantSolver = mesh.grantSolver;
 		var physics = mesh.physics;
 
 		if ( mixer !== null && this.doAnimation === true ) {
 
 			mixer.update( delta );
 
-			// workaround until I make IK and Physics Animation plugin
+			// workaround until I make IK, Grant, and Physics Animation plugin
 			this.backupBones( mesh );
 
 		}
@@ -4222,6 +4337,12 @@ THREE.MMDHelper.prototype = {
 
 		}
 
+		if ( grantSolver !== null && this.doGrant === true ) {
+
+			grantSolver.update();
+
+		}
+
 		if ( physics !== null && this.doPhysics === true ) {
 
 			physics.update( delta );
@@ -4438,14 +4559,23 @@ THREE.MMDHelper.prototype = {
 
 		}
 
-		if ( params && params.preventIk === true ) {
+		if ( params === undefined || params.preventIk !== true ) {
 
-			return;
+			var solver = new THREE.CCDIKSolver( mesh );
+			solver.update();
 
 		}
 
-		var solver = new THREE.CCDIKSolver( mesh );
-		solver.update();
+		if ( params === undefined || params.preventGrant !== true ) {
+
+			if ( mesh.geometry.grants !== undefined ) {
+
+				var solver = new THREE.MMDGrantSolver( mesh );
+				solver.update();
+
+			}
+
+		}
 
 	},