예제 #1
0
MStatus splineSolverNode::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.
//
{
    //Do Real Solve
    //
    MStatus stat;
    float curCurveLength = curveFn.length();
    MPlug crvLengPlug = fnHandle.findPlug("cvLen");
    double initCurveLength = crvLengPlug.asDouble();
    //Twist
    MPlug twistRamp = fnHandle.findPlug("twistRamp");
    MRampAttribute curveAttribute( twistRamp, &stat );
    MPlug startTwistPlug = fnHandle.findPlug("strtw");
    double startTwist = startTwistPlug.asDouble();
    MPlug endTwistPlug = fnHandle.findPlug("endtw");
    double endTwist = endTwistPlug.asDouble();
    //Scale Ramp
    MPlug scaleRamp = fnHandle.findPlug("scaleRamp");
    MRampAttribute curveScaleAttribute( scaleRamp, &stat );
    //Roll
    MPlug rollPlug = fnHandle.findPlug("roll");
    double roll = rollPlug.asDouble();
    MPlug strPlug = fnHandle.findPlug("str");
    float stretchRatio = strPlug.asDouble();
    float normCrvLength = curCurveLength / initCurveLength;
    double scale[3] = {1 +stretchRatio*(normCrvLength -1), 1, 1};
    //Get Anchor Position
    MPlug ancPosPlug = fnHandle.findPlug("ancp");
    double anchorPos = ancPosPlug.asDouble();
    MPlug jointsTotLengthPlug = fnHandle.findPlug("jsLen");
    double jointsTotalLength = jointsTotLengthPlug.asDouble();
    double difLengthCurveJoints = curCurveLength - (jointsTotalLength * scale[0]);
    float startLength = 0.0 + anchorPos*( difLengthCurveJoints );
    float parm = curveFn.findParamFromLength( startLength );
    MPoint pBaseJoint, pEndJoint;
    curveFn.getPointAtParam( parm, pBaseJoint );
    //get Init normal
    MPlug initNormalPlug = fnHandle.findPlug("norm");
    double nx = initNormalPlug.child(0).asDouble();
    double ny = initNormalPlug.child(1).asDouble();
    double nz = initNormalPlug.child(2).asDouble();
    MVector eyeUp( nx, ny, nz );
    //get Init Tangent
    MPlug initTangentPlug = fnHandle.findPlug("tang");
    double tx = initTangentPlug.child(0).asDouble();
    double ty = initTangentPlug.child(1).asDouble();
    double tz = initTangentPlug.child(2).asDouble();
    MVector eyeV( tx, ty, tz );

    MFnIkJoint j( joints[0] );
    j.setTranslation( MVector( pBaseJoint ), MSpace::kWorld );
    float jointRotPercent = 1.0/joints.size();
    float currJointRot = 0;
    float prevTwist = 0;
    double angle;
    //j.setScale(scale);
    for (int i = 0; i < joints.size(); i++)
    {
        MFnIkJoint j( joints[i]);
        pBaseJoint = j.rotatePivot(MSpace::kWorld);
        //Calculate Scale
        float scaleValue;
        curveScaleAttribute.getValueAtPosition(currJointRot, scaleValue, &stat);
        //if ( scale[0] >= 1 ) // Stretch
        scale[1] = 1 + scaleValue * ( 1 - scale[0] );
        /*
        else //Squash
        	scale[1] = 1 + scaleValue * ( 1.0 - scale[0] );
        */
        if (scale[1] < 0)
            scale[1] = 0;
        scale[2] = scale[1];
        j.setScale(scale);
        //j.setRotation( rot, j.rotationOrder()  );
        if( i == joints.size() - 1)
            //Effector Position
            pEndJoint = tran.rotatePivot(MSpace::kWorld);
        else
        {
            //get position of next joint
            MFnIkJoint j2( joints[i + 1]);
            pEndJoint = j2.rotatePivot(MSpace::kWorld);
        }
        MVector vBaseJoint(pBaseJoint[0]-pEndJoint[0], pBaseJoint[1]-pEndJoint[1], pBaseJoint[2]-pEndJoint[2]);
        startLength += vBaseJoint.length();
        MVector eyeAim(1.0,0.0,0.0);
        MPoint pFinalPos;
        float parm = curveFn.findParamFromLength( startLength );
        //Aim to final Pos
        curveFn.getPointAtParam( parm, pFinalPos, MSpace::kWorld );
        MVector eyeU(pBaseJoint[0]-pFinalPos[0], pBaseJoint[1]-pFinalPos[1], pBaseJoint[2]-pFinalPos[2]);
        eyeU.normalize();
        MVector eyeW( eyeU ^ eyeV );
        eyeW.normalize();
        eyeV = eyeW ^ eyeU;
        MQuaternion qU( -eyeAim, eyeU );

        MVector upRotated( eyeUp.rotateBy( qU ));
        angle = acos( upRotated*eyeV );

        //Calculate Twist
        {
            float twistValue;
            curveAttribute.getValueAtPosition(currJointRot, twistValue, &stat);
            double rotVal = (1-twistValue)*startTwist + twistValue*endTwist;
            angle += MAngle(rotVal, MAngle::kDegrees).asRadians();
            currJointRot += jointRotPercent;
        }
        //Calculate Roll
        angle += roll;

        MQuaternion qV(angle, eyeU);

        MQuaternion q(qU*qV);

        j.setRotation( q, MSpace::kWorld );
    }

    return MS::kSuccess;
}
예제 #2
0
MStatus splineSolverNode::preSolve()
{

    MStatus stat;
    setRotatePlane(false);
    setSingleChainOnly(true);
    setPositionOnly(false);
    //Get Handle
    MIkHandleGroup * handle_group = handleGroup();
    if (NULL == handle_group) {
        return MS::kFailure;
    }
    MObject handle = handle_group->handle( 0 );
    MDagPath handlePath = MDagPath::getAPathTo( handle );
    fnHandle.setObject( handlePath );
    //Get Curve
    MPlug inCurvePlug = fnHandle.findPlug( "inCurve" );
    MDataHandle curveHandle = inCurvePlug.asMDataHandle();
    MObject inputCurveObject = curveHandle.asNurbsCurveTransformed();
    curveFn.setObject( inputCurveObject );
    float initCurveLength = curveFn.length();
    MVector initNormal = curveFn.normal(0);
    MVector initTangent = curveFn.tangent(0);
    float stretchRatio = 1;
    // Get the position of the end_effector
    //
    MDagPath effectorPath;
    fnHandle.getEffector(effectorPath);
    tran.setObject( effectorPath );
    // Get the start joint position
    //
    MDagPath startJointPath;
    fnHandle.getStartJoint( startJointPath );
    joints.clear();
    //Get Joints
    while (true)
    {
        effectorPath.pop();
        joints.push_back( effectorPath );
        if (effectorPath == startJointPath)
            break;
    }
    std::reverse(joints.begin(), joints.end());
    if (!fnHandle.hasAttribute("str"))
    {
        //Add Custom Attributes to Handle
        MFnNumericAttribute fnAttr;
        MObject attr = fnAttr.create("stretchRatio", "str", MFnNumericData::kDouble, stretchRatio);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setMin(0);
        fnAttr.setMax(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("anchorPosition", "ancp", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setMin(0);
        fnAttr.setMax(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("curveLength", "cvLen", MFnNumericData::kDouble, initCurveLength);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("initNormal", "norm", MFnNumericData::k3Double);
        fnAttr.setDefault(initNormal.x, initNormal.y, initNormal.z);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("initTangent", "tang", MFnNumericData::k3Double);
        fnAttr.setDefault(initTangent.x, initTangent.y, initTangent.z);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("jointsLength", "jsLen", MFnNumericData::kDouble, getJointsTotalLenght());
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("startTwist", "strtw", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("endTwist", "endtw", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        MObject twistRamp = MRampAttribute::createCurveRamp("twistRamp", "twr");
        fnHandle.addAttribute(twistRamp, MFnDependencyNode::kLocalDynamicAttr);
        MObject scaleRamp = MRampAttribute::createCurveRamp("scaleRamp", "scr");
        fnHandle.addAttribute(scaleRamp, MFnDependencyNode::kLocalDynamicAttr);
    } else
    {
        MPlug strPlug = fnHandle.findPlug("str");
        stretchRatio = strPlug.asDouble();
    }

    return MS::kSuccess;
}