示例#1
0
		private void doSimpleSolver()
		//
		// Solve single joint in the x-y plane
		//
		// - first it calculates the angle between the handle and the end-effector.
		// - then it determines which way to rotate the joint.
		//
		{
			// Get the handle and create a function set for it
			//
			MIkHandleGroup handle_group = handleGroup;
			if (null == handle_group) {
				throw new System.InvalidOperationException("invalid handle group.");
			}

			MObject handle = handle_group.handle( 0 );
			MDagPath handlePath = MDagPath.getAPathTo( handle );
			MFnIkHandle fnHandle = new MFnIkHandle( handlePath );

			// Get the position of the end_effector
			//
			MDagPath end_effector = new MDagPath();
			fnHandle.getEffector(end_effector);
			MFnTransform tran = new MFnTransform( end_effector );
			MPoint effector_position = tran.rotatePivot( MSpace.Space.kWorld );

			// Get the position of the handle
			//
			MPoint handle_position = fnHandle.rotatePivot( MSpace.Space.kWorld );

			// Get the start joint position
			//
			MDagPath start_joint = new MDagPath();
			fnHandle.getStartJoint( start_joint );
			MFnTransform start_transform = new MFnTransform( start_joint );
			MPoint start_position = start_transform.rotatePivot( MSpace.Space.kWorld );

			// Calculate the rotation angle
			//
			MVector v1 = start_position.minus( effector_position );
			MVector v2 = start_position.minus( handle_position );
			double angle = v1.angle( v2 );

			// -------- Figure out which way to rotate --------
			//
			//  define two vectors U and V as follows
			//  U   =   EndEffector(E) - StartJoint(S)
			//  N   =   Normal to U passing through EndEffector
			//
			//  Clip handle_position to half-plane U to determine the region it
			//  lies in. Use the region to determine  the rotation direction.
			//
			//             U
			//             ^              Region      Rotation
			//             |  B           
			//            (E)---N            A          C-C-W
			//         A   |                 B           C-W
			//             |  B
			//             |
			//            (S)
			//
			double rot = 0.0;	// Rotation about Z-axis

			// U and N define a half-plane to clip the handle against
			//
			MVector U = effector_position.minus( start_position );
			U.normalize();

			// Get a normal to U
			//
			MVector zAxis = new MVector( 0.0, 0.0, 1.0 );
			MVector N = U.crossProduct( zAxis );	// Cross product
			N.normalize();

			// P is the handle position vector
			//
			MVector P = handle_position.minus( effector_position );

			// Determine the rotation direction
			//
			double PdotN = P[0]*N[0] + P[1]*N[1];
			if ( PdotN < 0 ) {
				// counter-clockwise
				rot = angle;
			} else {
				// clockwise
				rot = -1.0 * angle;
			}

			// get and set the Joint Angles 
			//
			MDoubleArray jointAngles = new MDoubleArray();
			getJointAngles( jointAngles );
			jointAngles.set( jointAngles[0] + rot, 0 );
			setJointAngles( jointAngles );
		}
示例#2
0
        public override void doSolve()
        {
            MIkHandleGroup handle_group = handleGroup;
            if (handle_group == null)
                throw new InvalidOperationException("Invalid handle group");

            MObject handle = handle_group.handle(0);
            MDagPath handlePath = MDagPath.getAPathTo(handle);
            MFnIkHandle handleFn = new MFnIkHandle(handlePath);

            //Effector
            //
            MDagPath effectorPath = new MDagPath();
            handleFn.getEffector(effectorPath);
            MFnIkEffector effectorFn = new MFnIkEffector(effectorPath);

            effectorPath.pop();
            MFnIkJoint midJoinFn = new MFnIkJoint(effectorPath);

            // Start Joint
            //
            MDagPath startJointPath = new MDagPath();
            handleFn.getStartJoint(startJointPath);
            MFnIkJoint startJointFn = new MFnIkJoint(startJointPath);

            // Preferred angles
            //
            double [] startJointPrefAngle = new double[3];
            double[]  midJointPrefAngle = new double[3];

            startJointFn.getPreferedAngle(startJointPrefAngle);
            midJoinFn.getPreferedAngle(midJointPrefAngle);

            // Set to preferred angles
            //
            startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder);

            midJoinFn.setRotation(midJointPrefAngle, midJoinFn.rotationOrder);

            MPoint handlePos = handleFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awHandlePos = new AwPoint(handlePos.x, handlePos.y, handlePos.z, handlePos.w);

            MPoint effectorPos = effectorFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awEffectorPos = new AwPoint(effectorPos.x, effectorPos.y, effectorPos.z, effectorPos.w);

            MPoint midJoinPos = midJoinFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awMidJoinPos = new AwPoint(midJoinPos.x, midJoinPos.y, midJoinPos.z, midJoinPos.w);

            MPoint startJointPos = startJointFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awStartJointPos = new AwPoint(startJointPos.x, startJointPos.y, startJointPos.z, startJointPos.w);

            AwVector poleVector = poleVectorFromHandle(handlePath);
            MMatrix m = handlePath.exclusiveMatrix;
            AwMatrix awM = new AwMatrix();
            awM.setMatrix(m);
            poleVector = poleVector.mulMatrix(awM);
            double twistValue = twistFromHandle(handlePath);

            AwQuaternion qStart = new AwQuaternion();
            AwQuaternion qMid = new AwQuaternion();

            solveIK(awStartJointPos, awMidJoinPos, awEffectorPos, awHandlePos,
                poleVector, twistValue, qStart, qMid);

            MQuaternion mid = new MQuaternion(qMid.x, qMid.y, qMid.z, qMid.w);
            MQuaternion start = new MQuaternion(qStart.x, qStart.y, qStart.z, qStart.w);

            midJoinFn.rotateBy(mid, MSpace.Space.kWorld);
            startJointFn.rotateBy(start, MSpace.Space.kWorld);

            return;
        }
示例#3
0
        public override void doSolve()
        {
            MIkHandleGroup handle_group = handleGroup;

            if (handle_group == null)
            {
                throw new InvalidOperationException("Invalid handle group");
            }

            MObject     handle     = handle_group.handle(0);
            MDagPath    handlePath = MDagPath.getAPathTo(handle);
            MFnIkHandle handleFn   = new MFnIkHandle(handlePath);

            //Effector
            //
            MDagPath effectorPath = new MDagPath();

            handleFn.getEffector(effectorPath);
            MFnIkEffector effectorFn = new MFnIkEffector(effectorPath);

            effectorPath.pop();
            MFnIkJoint midJoinFn = new MFnIkJoint(effectorPath);

            // Start Joint
            //
            MDagPath startJointPath = new MDagPath();

            handleFn.getStartJoint(startJointPath);
            MFnIkJoint startJointFn = new MFnIkJoint(startJointPath);

            // Preferred angles
            //
            double [] startJointPrefAngle = new double[3];
            double[]  midJointPrefAngle   = new double[3];

            startJointFn.getPreferedAngle(startJointPrefAngle);
            midJoinFn.getPreferedAngle(midJointPrefAngle);

            // Set to preferred angles
            //
            startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder);

            midJoinFn.setRotation(midJointPrefAngle, midJoinFn.rotationOrder);

            MPoint  handlePos   = handleFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awHandlePos = new AwPoint(handlePos.x, handlePos.y, handlePos.z, handlePos.w);

            MPoint  effectorPos   = effectorFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awEffectorPos = new AwPoint(effectorPos.x, effectorPos.y, effectorPos.z, effectorPos.w);

            MPoint  midJoinPos   = midJoinFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awMidJoinPos = new AwPoint(midJoinPos.x, midJoinPos.y, midJoinPos.z, midJoinPos.w);

            MPoint  startJointPos   = startJointFn.rotatePivot(MSpace.Space.kWorld);
            AwPoint awStartJointPos = new AwPoint(startJointPos.x, startJointPos.y, startJointPos.z, startJointPos.w);

            AwVector poleVector = poleVectorFromHandle(handlePath);
            MMatrix  m          = handlePath.exclusiveMatrix;
            AwMatrix awM        = new AwMatrix();

            awM.setMatrix(m);
            poleVector = poleVector.mulMatrix(awM);
            double twistValue = twistFromHandle(handlePath);

            AwQuaternion qStart = new AwQuaternion();
            AwQuaternion qMid   = new AwQuaternion();

            solveIK(awStartJointPos, awMidJoinPos, awEffectorPos, awHandlePos,
                    poleVector, twistValue, qStart, qMid);

            MQuaternion mid   = new MQuaternion(qMid.x, qMid.y, qMid.z, qMid.w);
            MQuaternion start = new MQuaternion(qStart.x, qStart.y, qStart.z, qStart.w);

            midJoinFn.rotateBy(mid, MSpace.Space.kWorld);
            startJointFn.rotateBy(start, MSpace.Space.kWorld);

            return;
        }
示例#4
0
        private void doSimpleSolver()
        //
        // Solve single joint in the x-y plane
        //
        // - first it calculates the angle between the handle and the end-effector.
        // - then it determines which way to rotate the joint.
        //
        {
            // Get the handle and create a function set for it
            //
            MIkHandleGroup handle_group = handleGroup;

            if (null == handle_group)
            {
                throw new System.InvalidOperationException("invalid handle group.");
            }

            MObject     handle     = handle_group.handle(0);
            MDagPath    handlePath = MDagPath.getAPathTo(handle);
            MFnIkHandle fnHandle   = new MFnIkHandle(handlePath);

            // Get the position of the end_effector
            //
            MDagPath end_effector = new MDagPath();

            fnHandle.getEffector(end_effector);
            MFnTransform tran = new MFnTransform(end_effector);
            MPoint       effector_position = tran.rotatePivot(MSpace.Space.kWorld);

            // Get the position of the handle
            //
            MPoint handle_position = fnHandle.rotatePivot(MSpace.Space.kWorld);

            // Get the start joint position
            //
            MDagPath start_joint = new MDagPath();

            fnHandle.getStartJoint(start_joint);
            MFnTransform start_transform = new MFnTransform(start_joint);
            MPoint       start_position  = start_transform.rotatePivot(MSpace.Space.kWorld);

            // Calculate the rotation angle
            //
            MVector v1    = start_position.minus(effector_position);
            MVector v2    = start_position.minus(handle_position);
            double  angle = v1.angle(v2);

            // -------- Figure out which way to rotate --------
            //
            //  define two vectors U and V as follows
            //  U   =   EndEffector(E) - StartJoint(S)
            //  N   =   Normal to U passing through EndEffector
            //
            //  Clip handle_position to half-plane U to determine the region it
            //  lies in. Use the region to determine  the rotation direction.
            //
            //             U
            //             ^              Region      Rotation
            //             |  B
            //            (E)---N            A          C-C-W
            //         A   |                 B           C-W
            //             |  B
            //             |
            //            (S)
            //
            double rot = 0.0;                   // Rotation about Z-axis

            // U and N define a half-plane to clip the handle against
            //
            MVector U = effector_position.minus(start_position);

            U.normalize();

            // Get a normal to U
            //
            MVector zAxis = new MVector(0.0, 0.0, 1.0);
            MVector N     = U.crossProduct(zAxis);              // Cross product

            N.normalize();

            // P is the handle position vector
            //
            MVector P = handle_position.minus(effector_position);

            // Determine the rotation direction
            //
            double PdotN = P[0] * N[0] + P[1] * N[1];

            if (PdotN < 0)
            {
                // counter-clockwise
                rot = angle;
            }
            else
            {
                // clockwise
                rot = -1.0 * angle;
            }

            // get and set the Joint Angles
            //
            MDoubleArray jointAngles = new MDoubleArray();

            getJointAngles(jointAngles);
            jointAngles.set(jointAngles[0] + rot, 0);
            setJointAngles(jointAngles);
        }