updateOne( ik ) {

			const bones = this.mesh.skeleton.bones; // for reference overhead reduction in loop

			const math = Math;
			const effector = bones[ ik.effector ];
			const target = bones[ ik.target ]; // don't use getWorldPosition() here for the performance
			// because it calls updateMatrixWorld( true ) inside.

			_targetPos.setFromMatrixPosition( target.matrixWorld );

			const links = ik.links;
			const iteration = ik.iteration !== undefined ? ik.iteration : 1;

			for ( let i = 0; i < iteration; i ++ ) {

				let rotated = false;

				for ( let j = 0, jl = links.length; j < jl; j ++ ) {

					const link = bones[ links[ j ].index ]; // skip this link and following links.
					// this skip is used for MMD performance optimization.

					if ( links[ j ].enabled === false ) break;
					const limitation = links[ j ].limitation;
					const rotationMin = links[ j ].rotationMin;
					const rotationMax = links[ j ].rotationMax; // don't use getWorldPosition/Quaternion() here for the performance
					// because they call updateMatrixWorld( true ) inside.

					link.matrixWorld.decompose( _linkPos, _invLinkQ, _linkScale );

					_invLinkQ.invert();

					_effectorPos.setFromMatrixPosition( effector.matrixWorld ); // work in link world


					_effectorVec.subVectors( _effectorPos, _linkPos );

					_effectorVec.applyQuaternion( _invLinkQ );

					_effectorVec.normalize();

					_targetVec.subVectors( _targetPos, _linkPos );

					_targetVec.applyQuaternion( _invLinkQ );

					_targetVec.normalize();

					let angle = _targetVec.dot( _effectorVec );

					if ( angle > 1.0 ) {

						angle = 1.0;

					} else if ( angle < - 1.0 ) {

						angle = - 1.0;

					}

					angle = math.acos( angle ); // skip if changing angle is too small to prevent vibration of bone
					// Refer to http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js

					if ( angle < 1e-5 ) continue;

					if ( ik.minAngle !== undefined && angle < ik.minAngle ) {

						angle = ik.minAngle;

					}

					if ( ik.maxAngle !== undefined && angle > ik.maxAngle ) {

						angle = ik.maxAngle;

					}

					_axis.crossVectors( _effectorVec, _targetVec );

					_axis.normalize();

					_q.setFromAxisAngle( _axis, angle );

					link.quaternion.multiply( _q ); // TODO: re-consider the limitation specification

					if ( limitation !== undefined ) {

						let c = link.quaternion.w;
						if ( c > 1.0 ) c = 1.0;
						const c2 = math.sqrt( 1 - c * c );
						link.quaternion.set( limitation.x * c2, limitation.y * c2, limitation.z * c2, c );

					}

					if ( rotationMin !== undefined ) {

						link.rotation.setFromVector3( link.rotation.toVector3( _vector ).max( rotationMin ) );

					}

					if ( rotationMax !== undefined ) {

						link.rotation.setFromVector3( link.rotation.toVector3( _vector ).min( rotationMax ) );

					}

					link.updateMatrixWorld( true );
					rotated = true;

				}

				if ( ! rotated ) break;

			}

			return this;

		}
Update one IK bone

@param {Object} ik parameter
@return {CCDIKSolver}