Ejemplo n.º 1
0
MStatus
MannequinMoveManipulator::connectToDependNode(const MObject &dependNode) {
  MStatus status;
  MFnDependencyNode nodeFn(dependNode, &status);

  if (!status)
     return MS::kFailure;

  MPlug translatePlug = nodeFn.findPlug("translate", &status);

  if (!status)
     return MS::kFailure;

  int plugIndex = 0;
  status = connectPlugToValue(translatePlug, _translateIndex, plugIndex);

  if (!status)
     return MS::kFailure;

  MFnDagNode dagNodeFn(dependNode);
  MDagPath nodePath;
  dagNodeFn.getPath(nodePath);

  MTransformationMatrix m(nodePath.exclusiveMatrix());
  _parentXform = m;

  MTransformationMatrix n(nodePath.inclusiveMatrix());
  _childXform = n;

  finishAddingManips();
  return MPxManipulatorNode::connectToDependNode(dependNode);
}
Ejemplo n.º 2
0
MStatus ik2Bsolver::doSolve()
//
// This is the doSolve method which calls solveIK.
//
{
	MStatus stat;

	// Handle Group
	//
	MIkHandleGroup * handle_group = handleGroup();
	if (NULL == handle_group) {
		return MS::kFailure;
	}

	// Handle
	//
	// For single chain types of solvers, get the 0th handle.
	// Single chain solvers are solvers which act on one handle only, 
	// i.e. the	handle group for a single chain solver
	// has only one handle
	//
	MObject handle = handle_group->handle(0);
	MDagPath handlePath = MDagPath::getAPathTo(handle);
	MFnIkHandle handleFn(handlePath, &stat);

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

	// Mid Joint
	//
	effectorPath.pop();
	MFnIkJoint midJointFn(effectorPath);

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

	// Preferred angles
	//
	double startJointPrefAngle[3];
	double midJointPrefAngle[3];
	startJointFn.getPreferedAngle(startJointPrefAngle);
	midJointFn.getPreferedAngle(midJointPrefAngle);

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

	AwPoint handlePos = handleFn.rotatePivot(MSpace::kWorld);
	AwPoint effectorPos = effectorFn.rotatePivot(MSpace::kWorld);
	AwPoint midJointPos = midJointFn.rotatePivot(MSpace::kWorld);
	AwPoint startJointPos = startJointFn.rotatePivot(MSpace::kWorld);
	AwVector poleVector = poleVectorFromHandle(handlePath);
	poleVector *= handlePath.exclusiveMatrix();
	double twistValue = twistFromHandle(handlePath);
	
	AwQuaternion qStart, qMid;

	solveIK(startJointPos,
			midJointPos,
			effectorPos,
			handlePos,
			poleVector,
			twistValue,
			qStart,
			qMid);

	midJointFn.rotateBy(qMid, MSpace::kWorld);
	startJointFn.rotateBy(qStart, MSpace::kWorld);

	return MS::kSuccess;
}
Ejemplo n.º 3
0
MBoundingBox AbcWriteJob::getBoundingBox(double iFrame, const MMatrix & eMInvMat)
{
    MStatus status;
    MBoundingBox curBBox;

    if (iFrame == mFirstFrame)
    {
        // Set up bbox shape map in the first frame.
        // If we have a lot of transforms and shapes, we don't need to
        // iterate them for each frame.
        MItDag dagIter;
        for (dagIter.reset(mCurDag); !dagIter.isDone(); dagIter.next())
        {
            MObject object = dagIter.currentItem();
            MDagPath path;
            dagIter.getPath(path);

            // short-circuit if the selection flag is on but this node is not in the
            // active selection

            // MGlobal::isSelected(ob) doesn't work, because DG node and DAG node is
            // not the same even if they refer to the same MObject
            if (mArgs.useSelectionList && !mSList.hasItem(path))
            {
                dagIter.prune();
                continue;
            }

            MFnDagNode dagNode(path, &status);
            if (status == MS::kSuccess)
            {
                // check for riCurves flag for flattening all curve object to
                // one curve group
                MPlug riCurvesPlug = dagNode.findPlug("riCurves", &status);
                if ( status == MS::kSuccess && riCurvesPlug.asBool() == true)
                {
                    MBoundingBox box = dagNode.boundingBox();
                    box.transformUsing(path.exclusiveMatrix()*eMInvMat);
                    curBBox.expand(box);

                    // Prune this curve group
                    dagIter.prune();

                    // Save children paths
                    std::map< MDagPath, util::ShapeSet, util::cmpDag >::iterator iter =
                        mBBoxShapeMap.insert(std::make_pair(mCurDag, util::ShapeSet())).first;
                    if (iter != mBBoxShapeMap.end())
                        (*iter).second.insert(path);
                }
                else if (object.hasFn(MFn::kParticle)
                    || object.hasFn(MFn::kMesh)
                    || object.hasFn(MFn::kNurbsCurve)
                    || object.hasFn(MFn::kNurbsSurface) )
                {
                    if (util::isIntermediate(object))
                        continue;

                    MBoundingBox box = dagNode.boundingBox();
                    box.transformUsing(path.exclusiveMatrix()*eMInvMat);
                    curBBox.expand(box);

                    // Save children paths
                    std::map< MDagPath, util::ShapeSet, util::cmpDag >::iterator iter =
                        mBBoxShapeMap.insert(std::make_pair(mCurDag, util::ShapeSet())).first;
                    if (iter != mBBoxShapeMap.end())
                        (*iter).second.insert(path);
                }
            }
        }
    }
    else
    {
        // We have already find out all the shapes for the dag path.
        std::map< MDagPath, util::ShapeSet, util::cmpDag >::iterator iter =
            mBBoxShapeMap.find(mCurDag);
        if (iter != mBBoxShapeMap.end())
        {
            // Iterate through the saved paths to calculate the box.
            util::ShapeSet& paths = (*iter).second;
            for (util::ShapeSet::iterator pathIter = paths.begin();
                pathIter != paths.end(); pathIter++)
            {
                MFnDagNode dagNode(*pathIter, &status);
                if (status == MS::kSuccess)
                {
                    MBoundingBox box = dagNode.boundingBox();
                    box.transformUsing((*pathIter).exclusiveMatrix()*eMInvMat);
                    curBBox.expand(box);
                }
            }
        }
    }

    return curBBox;
}
Ejemplo n.º 4
0
/**
 * Insert a new node into the hash table.
 */
int liqRibHT::insert( MDagPath &path, double /*lframe*/, int sample,
                      ObjectType objType,
                      int CountID,
                      MMatrix *matrix,
                      const MString instanceStr,
                      int particleId )
{
	CM_TRACE_FUNC("liqRibHT::insert("<<path.fullPathName().asChar()<<",lframe,"
		<<sample<<","<<objType<<","<<CountID<<",matrix,"<<instanceStr.asChar()<<","<<particleId<<")");

  LIQDEBUGPRINTF( "-> inserting node into hash table\n" );
  MFnDagNode  fnDagNode( path );
  MStatus    returnStatus;

  objTypeVec.push_back( objType );

  MString nodeName = fnDagNode.fullPathName( &returnStatus );
  if ( objType == MRT_RibGen ) 
    nodeName += "RIBGEN";

  const char* name( nodeName.asChar() );

  ulong hc = hash( name ,CountID );

  RibHashVec.push_back( nodeName );
  LIQDEBUGPRINTF( "-> hashed node name: %s", name );
  LIQDEBUGPRINTF( " ID: %u\n", hc );

  liqRibNodePtr  node;
  /*node = find( path.node(), objType );*/
  node = find( nodeName, path, objType );
  liqRibNodePtr     newNode;
  liqRibNodePtr    instance;

  // If "node" is non-null then there's already a hash table entry at
  // this point
  //
  liqRibNodePtr tail;
  if( node ) 
  {
    while( node ) 
    {
      tail = node;

      // Break if we've already dealt with this DAG path
      // (and instance string - by default this is "", which
      //  will match for most objects - allowing us to deal
      //  with particle-instancing).
      //
      if ( path        == node->path() &&
           instanceStr == node->getInstanceStr() )
      {
        break;
      }

      if ( path.node() == node->path().node() ) 
      {
        // We have found another instance of the object we are object
        // looking for
        instance = node;
      }
      node = node->next;
    }
    if ( ( !node ) && ( instance ) ) 
    {
      // We have not found a node with a matching path, but we have found
      // one with a matching object, so we need to insert a new instance
      newNode = liqRibNodePtr( new liqRibNode( instance, instanceStr ) );
    }
  }
  if( !newNode ) 
  {
    // We have to make a new node
    if ( !node) 
    {
      node = liqRibNodePtr( new liqRibNode( liqRibNodePtr(), instanceStr) );
      if ( tail ) 
      {
        assert( !tail->next );
        tail->next = node;
        RibNodeMap.insert( RNMAP::value_type( hc, node ) );
      } 
      else 
        RibNodeMap.insert( RNMAP::value_type( hc, node ) );
    }
  } 
  else 
  {
    assert( !node );
    // Append new instance node onto tail of linked list
    node = newNode;
    if( tail ) 
    {
      assert( !tail->next );
      tail->next = node;
      RibNodeMap.insert( RNMAP::value_type( hc, node ) );
    } 
    else 
      RibNodeMap.insert( RNMAP::value_type( hc, node ) );
  }

  node->set( path, sample, objType, particleId );

  // If we were given a specific matrix to use (this only
  // happens when we've got particle-instancing.
  //
  if( matrix != NULL )
  {
    // Calculate the inclusive matrix for the instanced
    // object (as a product of the original object's
    // exclusive matrix - see Maya docs - and the given
    // matrix).
    //
    MMatrix inclusiveMatrix = path.exclusiveMatrix() * ( *matrix );
    node->object( sample )->setMatrix( 0, inclusiveMatrix );
  }

  // We can NOT support deformation blur on particle instancing,
  // since there's no way to guarantee that the objects are
  // topologically identical over the sample range.
  //
  if( instanceStr != "" )
    node->motion.deformationBlur = false;

  LIQDEBUGPRINTF( "-> finished inserting node into hash table\n" );
  return 0;
}
Ejemplo n.º 5
0
MStatus ik2Bsolver::doSolve()
//
// This is the doSolve method which calls solveIK.
//
{
        MStatus stat;

        // Handle Group
        //
        MIkHandleGroup * handle_group = handleGroup();
        if (NULL == handle_group) {
                return MS::kFailure;
        }

        // Handle
        //
        // For single chain types of solvers, get the 0th handle.
        // Single chain solvers are solvers which act on one handle only, 
        // i.e. the     handle group for a single chain solver
        // has only one handle
        //
        MObject handle = handle_group->handle(0);
        MDagPath handlePath = MDagPath::getAPathTo(handle);
        MFnIkHandle handleFn(handlePath, &stat);

        // Effector
        //
        MDagPath effectorPath;
        handleFn.getEffector(effectorPath);
        // MGlobal::displayInfo(effectorPath.fullPathName());
        MFnIkEffector effectorFn(effectorPath);

        // Mid Joint
        //
        effectorPath.pop();
        MFnIkJoint midJointFn(effectorPath);
        
        // End Joint
        //
        MDagPath endJointPath;
        bool hasEndJ = findFirstJointChild(effectorPath, endJointPath);
        // if(hasEndJ) MGlobal::displayInfo(endJointPath.fullPathName());
        
        MFnIkJoint endJointFn(endJointPath);
        
        // Start Joint
        //
        MDagPath startJointPath;
        handleFn.getStartJoint(startJointPath);
        MFnIkJoint startJointFn(startJointPath);

        // Preferred angles
        //
        double startJointPrefAngle[3];
        double midJointPrefAngle[3];
        startJointFn.getPreferedAngle(startJointPrefAngle);
        midJointFn.getPreferedAngle(midJointPrefAngle);

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

        MPoint handlePos = handleFn.rotatePivot(MSpace::kWorld);
        MPoint effectorPos = effectorFn.rotatePivot(MSpace::kWorld);
        MPoint midJointPos = midJointFn.rotatePivot(MSpace::kWorld);
        MPoint startJointPos = startJointFn.rotatePivot(MSpace::kWorld);
        MVector poleVector = poleVectorFromHandle(handlePath);
        poleVector *= handlePath.exclusiveMatrix();
        double twistValue = twistFromHandle(handlePath);
        
		MObject thisNode = thisMObject();
        
		MVector localEndJointT = endJointFn.getTranslation(MSpace::kTransform);
		MVector worldEndJointT = endJointFn.rotatePivot(MSpace::kWorld) - midJointPos;
		
		double scaling =  worldEndJointT.length() / ( localEndJointT.length() + 1e-6);
		
		// MGlobal::displayInfo(MString(" scaling ")+scaling);
		
        // get rest length
        //
        double restL1, restL2;
		MPlug(thisNode, arestLength1).getValue(restL1);
		MPlug(thisNode, arestLength2).getValue(restL2);
        // get soft distance
        //
        MPlug plug( thisNode, asoftDistance );
        double softD = 0.0;
        plug.getValue(softD);
        
        restL1 *= scaling;
        restL2 *= scaling;
        softD *= scaling;
		
		// get max stretching
		double maxStretching = 0.0;
		MPlug(thisNode, amaxStretching).getValue(maxStretching);
        
        MQuaternion qStart, qMid;
        double stretching = 0.0;
        solveIK(startJointPos,
                        midJointPos,
                        effectorPos,
                        handlePos,
                        poleVector,
                        twistValue,
                        qStart,
                        qMid,
                        softD,
						restL1, restL2,
						stretching);

        midJointFn.rotateBy(qMid, MSpace::kWorld);
        startJointFn.rotateBy(qStart, MSpace::kWorld);

		midJointFn.setTranslation(MVector(restL1 / scaling, 0.0, 0.0), MSpace::kTransform);
		endJointFn.setTranslation(MVector(restL2 / scaling, 0.0, 0.0), MSpace::kTransform);
			
		// if(stretching > maxStretching) stretching = maxStretching;
		if(maxStretching > 0.0) {
			MVector vstretch(stretching* 0.5 / scaling, 0.0, 0.0);
			midJointFn.translateBy(vstretch, MSpace::kTransform);
			endJointFn.translateBy(vstretch, MSpace::kTransform);
		}
        
        return MS::kSuccess;
}