示例#1
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;
        }
示例#2
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);
        }