MStatus SwirlDeformer::deform( MDataBlock& block, MItGeometry &iter,
												const MMatrix &localToWorld, unsigned int geomIndex )
{
MStatus stat;
	
MDataHandle envData = block.inputValue( envelope );
float env = envData.asFloat();	
if( env == 0.0 ) // Deformer has no effect
	return MS::kSuccess;

MDataHandle matData = block.inputValue( deformSpace );
MMatrix mat = matData.asMatrix();
MMatrix invMat = mat.inverse();

MDataHandle startDistHnd = block.inputValue( startDist );
double startDist = startDistHnd.asDouble();	

MDataHandle endDistHnd = block.inputValue( endDist );
double endDist = endDistHnd.asDouble();	

MPoint pt;
float weight;
double dist;
double ang;
double cosAng;
double sinAng;
double x;
double distFactor;
for( iter.reset(); !iter.isDone(); iter.next() ) 
	{
	weight = weightValue( block, geomIndex, iter.index() );
	if( weight == 0.0f )
		continue;

	pt = iter.position();
	pt *= invMat;

	dist = sqrt( pt.x * pt.x + pt.z * pt.z );
	if( dist < startDist || dist > endDist )
		continue;

	distFactor = 1 - ((dist - startDist) / (endDist - startDist));

	ang = distFactor * M_PI * 2.0 * env * weight;
	if( ang == 0.0 )
		continue;

	cosAng = cos( ang );
	sinAng = sin( ang );
	x = pt.x * cosAng - pt.z * sinAng;
	pt.z = pt.x * sinAng + pt.z * cosAng;
	pt.x = x;

	pt *= mat;
	
	iter.setPosition( pt );
	}

return stat;
}
Exemple #2
0
void ProxyViz::updateViewFrustum(MObject & thisNode)
{
	MPlug matplg(thisNode, acameraspace);
	MObject matobj;
	matplg.getValue(matobj);
	MFnMatrixData matdata(matobj);
    MMatrix cameramat = matdata.matrix(); 
	AHelper::ConvertToMatrix44F(*cameraSpaceR(), cameramat);
	AHelper::ConvertToMatrix44F(*cameraInvSpaceR(), cameramat.inverse() );
	float peye[3];
	peye[0] = cameramat.matrix[3][0];
	peye[1] = cameramat.matrix[3][1];
	peye[2] = cameramat.matrix[3][2];
	setEyePosition(peye);
	
	MPlug hfaplg(thisNode, ahapeture);
	float hfa = hfaplg.asFloat();
	MPlug vfaplg(thisNode, avapeture);
	float vfa = vfaplg.asFloat();
	MPlug flplg(thisNode, afocallength);
	float fl = flplg.asFloat();
	
    float farClip = -20.f;
    if(numPlants() > 0) getFarClipDepth(farClip, gridBoundingBox() );
    
    setFrustum(hfa, vfa, fl, -10.f, farClip );
	
	MPlug overscanPlug(thisNode, ainoverscan);
	setOverscan(overscanPlug.asDouble() );
}
    //---------------------------------------------------
    // Retrieve the bind pose for a controller/joint std::pair
    //
    MMatrix DagHelper::getBindPoseInverse ( const MObject& controller, const MObject& influence )
    {
        MStatus status;
        if ( controller.apiType() == MFn::kSkinClusterFilter )
        {
            MFnSkinCluster controllerFn ( controller );

            // Find the correct index for the pre-bind matrix
            uint index = controllerFn.indexForInfluenceObject ( MDagPath::getAPathTo ( influence ), &status );
            if ( status != MStatus::kSuccess ) return MMatrix::identity;

            MPlug preBindMatrixPlug = controllerFn.findPlug ( "bindPreMatrix", &status );
            preBindMatrixPlug = preBindMatrixPlug.elementByLogicalIndex ( index, &status );
            if ( status != MStatus::kSuccess ) return MMatrix::identity;

            // Get the plug's matrix
            MMatrix ret;
            if ( !DagHelper::getPlugValue ( preBindMatrixPlug, ret ) ) return MMatrix::identity;

            return ret;
        }

        else if ( controller.apiType() == MFn::kJointCluster )
        {
            MMatrix ret;
            DagHelper::getPlugValue ( influence, "bindPose", ret );
            return ret.inverse();
        }

        else return MMatrix::identity;
    }
MStatus transRotateCombineMatrix::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MDataHandle hOutputMatrix = data.outputValue( aOutputMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hOutputInverseMatrix = data.outputValue( aOutputInverseMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hTransMatrix = data.inputValue( aInputTransMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hRotateMatrix = data.inputValue( aInputRotateMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MMatrix transMatrix = hTransMatrix.asMatrix();
	MMatrix rotateMatrix = hRotateMatrix.asMatrix();

	double buildMatrix[4][4] = { rotateMatrix( 0,0 ), rotateMatrix( 0,1 ), rotateMatrix( 0,2 ), 0,
		                         rotateMatrix( 1,0 ), rotateMatrix( 1,1 ), rotateMatrix( 1,2 ), 0,
								 rotateMatrix( 2,0 ), rotateMatrix( 2,1 ), rotateMatrix( 2,2 ), 0,
								 transMatrix( 3,0 ),  transMatrix( 3,1 ),  transMatrix( 3,2 ),  1 };

	MMatrix buildMtx = buildMatrix;
	
	if( plug == aOutputMatrix )
		hOutputMatrix.set( buildMtx );
	if( plug == aOutputInverseMatrix )
		hOutputInverseMatrix.set( buildMtx.inverse() );

	data.setClean( plug );

	return status;
}
//------------------------------------------------------------------------------
//
void GLPickingSelect::processTriangles(
    const SubNode::Ptr rootNode,
    const double seconds,
    const size_t numTriangles,
    VBOProxy::VBOMode vboMode
)
{
    const unsigned int bufferSize = (unsigned int)std::min(numTriangles,size_t(100000));
    boost::shared_array<GLuint>buffer (new GLuint[bufferSize*4]);

    M3dView view = fSelectInfo.view();

    MMatrix projMatrix;
    view.projectionMatrix(projMatrix);
    MMatrix modelViewMatrix;
    view.modelViewMatrix(modelViewMatrix);

    unsigned int x, y, w, h;
    view.viewport(x, y, w, h);
    double viewportX = static_cast<int>(x);   // can be less than 0
    double viewportY = static_cast<int>(y);   // can be less than 0
    double viewportW = w;
    double viewportH = h;

    fSelectInfo.selectRect(x, y, w, h);
    double selectX = static_cast<int>(x);  // can be less than 0
    double selectY = static_cast<int>(y);  // can be less than 0
    double selectW = w;
    double selectH = h;

    MMatrix selectAdjustMatrix;
    selectAdjustMatrix[0][0] = viewportW / selectW;
    selectAdjustMatrix[1][1] = viewportH / selectH;
    selectAdjustMatrix[3][0] = ((viewportX + viewportW/2.0) - (selectX + selectW/2.0)) / 
        viewportW * 2.0 * selectAdjustMatrix[0][0];
    selectAdjustMatrix[3][1] = ((viewportY + viewportH/2.0) - (selectY + selectH/2.0)) /
        viewportH * 2.0 * selectAdjustMatrix[1][1];

    MMatrix localToPort = modelViewMatrix * projMatrix * selectAdjustMatrix;

    view.beginSelect(buffer.get(), bufferSize*4);
    view.pushName(0);
    {
        Frustum frustum(localToPort.inverse());
        MMatrix xform(modelViewMatrix);
        
        DrawShadedState state(frustum, seconds, vboMode);
        DrawShadedTraversal traveral(state, xform, false, Frustum::kUnknown);
        rootNode->accept(traveral);
    }
    view.popName();
    int nbPick = view.endSelect();

    if (nbPick > 0) {
        unsigned int Zdepth = closestElem(nbPick, buffer.get());    
        float depth = float(Zdepth)/MAX_HW_DEPTH_VALUE;
        fMinZ = std::min(depth,fMinZ);
    }
}
Exemple #6
0
MStatus
offset::deform( MDataBlock& block,
				MItGeometry& iter,
				const MMatrix& /*m*/,
				unsigned int multiIndex)
//
// Method: deform
//
// Description:   Deform the point with a squash algorithm
//
// Arguments:
//   block		: the datablock of the node
//	 iter		: an iterator for the geometry to be deformed
//   m    		: matrix to transform the point into world space
//	 multiIndex : the index of the geometry that we are deforming
//
//
{
	MStatus returnStatus;
	
	// Envelope data from the base class.
	// The envelope is simply a scale factor.
	//
	MDataHandle envData = block.inputValue(envelope, &returnStatus);
	if (MS::kSuccess != returnStatus) return returnStatus;
	float env = envData.asFloat();	

	// Get the matrix which is used to define the direction and scale
	// of the offset.
	//
	MDataHandle matData = block.inputValue(offsetMatrix, &returnStatus );
	if (MS::kSuccess != returnStatus) return returnStatus;
	MMatrix omat = matData.asMatrix();
	MMatrix omatinv = omat.inverse();

	// iterate through each point in the geometry
	//
	for ( ; !iter.isDone(); iter.next()) {
		MPoint pt = iter.position();
		pt *= omatinv;
		
		float weight = weightValue(block,multiIndex,iter.index());
		
		// offset algorithm
		//
		pt.y = pt.y + env*weight;
		//
		// end of offset algorithm

		pt *= omat;
		iter.setPosition(pt);
	}
	return returnStatus;
}
Exemple #7
0
MStatus MG_curve::compute(const MPlug& plug,MDataBlock& dataBlock)
	{

		if (plug==output)
		{
			
			//MStatus
			MStatus stat;


			//Point array for the curve
			MPointArray pointArray ;

			//Get data from inputs
			MDataHandle degreeH = dataBlock.inputValue(degree);
			int degreeValue = degreeH.asInt();

			MDataHandle tmH = dataBlock.inputValue(transformMatrix);
			MMatrix tm = tmH.asMatrix();


			MArrayDataHandle inputMatrixH = dataBlock.inputArrayValue(inputMatrix);
			inputMatrixH.jumpToArrayElement(0);
			//Loop to get matrix data and convert in points

			for (int unsigned i=0;i<inputMatrixH.elementCount();i++,inputMatrixH.next())
			{
				

				MMatrix currentMatrix = inputMatrixH.inputValue(&stat).asMatrix() ;
				
				//Compensate the locator matrix
				
				MMatrix fixedMatrix = currentMatrix*tm.inverse();
				MPoint matrixP (fixedMatrix[3][0],fixedMatrix[3][1],fixedMatrix[3][2]);
				pointArray.append(matrixP);
				
			}
			
		MFnNurbsCurve curveFn;
		MFnNurbsCurveData curveDataFn;
		MObject curveData= curveDataFn.create();

		curveFn.createWithEditPoints(pointArray,degreeValue,MFnNurbsCurve::kOpen,0,0,0,curveData,&stat);
		
		MDataHandle outputH = dataBlock.outputValue(output);
		outputH.set(curveData);
		outputH.setClean();

		}


		return MS::kSuccess;
	}
    //---------------------------------------------------
    // set the bind pose for a transform
    //
    MStatus DagHelper::setBindPoseInverse ( const MObject& node, const MMatrix& bindPoseInverse )
    {
        MStatus status;
        MFnDependencyNode dgFn ( node );
        MPlug bindPosePlug = dgFn.findPlug ( "bindPose", &status );
        if ( status != MS::kSuccess )
        {
            MGlobal::displayWarning ( MString ( "No bindPose found on node " ) + dgFn.name() );
            return status;
        }

        MFnMatrixData matrixFn;
        MObject val = matrixFn.create ( bindPoseInverse.inverse(), &status );
        MObject invval = matrixFn.create ( bindPoseInverse, &status );
        if ( status != MS::kSuccess )
        {
            MGlobal::displayWarning ( MString ( "Error setting bindPose on node " ) + dgFn.name() );
            return status;
        }

        // set the bind pose on the joint itself
        bindPosePlug.setValue ( val );

        // Now, perhaps more significantly, see if there's a
        // skinCluster using this bone and update its bind
        // pose (as the joint bind pose is not connected to
        // the skin - it's set at bind time from the joint's
        // current position, and our importer may not want to
        // disturb the current scene state just to put bones
        // in a bind position before creating skin clusters)
        MObject _node ( node );
        MItDependencyGraph it ( _node, MFn::kSkinClusterFilter );
        while ( !it.isDone() )
        {
            MPlug plug = it.thisPlug();
            unsigned int idx = plug.logicalIndex();
            MFnDependencyNode skinFn ( plug.node() );
            MPlug skinBindPosePlug = skinFn.findPlug ( "bindPreMatrix", &status );

            if ( status == MS::kSuccess )
            {
                // The skinCluster stores inverse inclusive matrix
                // so notice we use invval (the MObject created off
                // the inverse matrix here)
                skinBindPosePlug = skinBindPosePlug.elementByLogicalIndex ( idx );
                skinBindPosePlug.setValue ( invval );
            }

            it.next();
        }

        return status;
    }
Exemple #9
0
void writeTMatrixList( std::ofstream *outFile, std::vector<MMatrix>& transformMatrices, bool inverse, float scaleFactor)
{
	for( int matrixId = 0; matrixId < transformMatrices.size(); matrixId++)
	{
		MMatrix tm = transformMatrices[matrixId];
		if( inverse )
			tm = tm.inverse();

		if( matrixId == 0)
		{
			*outFile << "\t\tray_transform " << matrixToString(tm) << "\n"; // normal transform
		}
		else{
			*outFile << "\t\tray_mtransform " << matrixToString(tm) << "\n"; // motion transform
		}
	}
}
//------------------------------------------------------------------------------
//
void RasterSelect::processTriangles(
    const SubNode::Ptr rootNode,
    double seconds,
    size_t /* numTriangles */,
    VBOProxy::VBOMode vboMode
)
{
    M3dView view = fSelectInfo.view();

    MMatrix projMatrix;
    view.projectionMatrix(projMatrix);
    MMatrix modelViewMatrix;
    view.modelViewMatrix(modelViewMatrix);

    unsigned int x, y, w, h;
    view.viewport(x, y, w, h);
    double viewportX = static_cast<int>(x);   // can be less than 0
    double viewportY = static_cast<int>(y);   // can be less than 0
    double viewportW = w;
    double viewportH = h;

    fSelectInfo.selectRect(x, y, w, h);
    double selectX = static_cast<int>(x);  // can be less than 0
    double selectY = static_cast<int>(y);  // can be less than 0
    double selectW = w;
    double selectH = h;

    MMatrix selectAdjustMatrix;
    selectAdjustMatrix[0][0] = viewportW / selectW;
    selectAdjustMatrix[1][1] = viewportH / selectH;
    selectAdjustMatrix[3][0] = ((viewportX + viewportW/2.0) - (selectX + selectW/2.0)) / 
        viewportW * 2.0 * selectAdjustMatrix[0][0];
    selectAdjustMatrix[3][1] = ((viewportY + viewportH/2.0) - (selectY + selectH/2.0)) /
        viewportH * 2.0 * selectAdjustMatrix[1][1];

    MMatrix localToPort = modelViewMatrix * projMatrix * selectAdjustMatrix;

    {
        Frustum frustum(localToPort.inverse());
        MMatrix xform(modelViewMatrix);
        
        DrawShadedState state(frustum, seconds, vboMode);
        DrawShadedTraversal traveral(state, xform, false, Frustum::kUnknown);
        rootNode->accept(traveral);
    }
}
Exemple #11
0
// COMPUTE ======================================
MStatus gear_curveCns::deform( MDataBlock& data, MItGeometry& iter, const MMatrix &mat, unsigned int mIndex )
{
    MStatus returnStatus;

	MArrayDataHandle adh = data.inputArrayValue( inputs );
	int deformer_count = adh.elementCount( &returnStatus );

	// Process
	while (! iter.isDone()){
		if (iter.index() < deformer_count){
			adh.jumpToElement(iter.index());
			MTransformationMatrix m(adh.inputValue().asMatrix() * mat.inverse());
			MVector v = m.getTranslation(MSpace::kWorld, &returnStatus );
			MPoint pt(v);
			iter.setPosition(pt);
		}
		iter.next();
	}
 
    return MS::kSuccess;
}
void 
simpleFluidEmitter::surfaceFluidEmitter(
	MFnFluid& 		fluid,
	const MMatrix&	fluidWorldMatrix,
	int 			plugIndex,
	MDataBlock& 	block,
	double 			dt,
	double			conversion,
	double			dropoff
)
//==============================================================================
//
//	Method:	
//
//		simpleFluidEmitter::surfaceFluidEmitter
//
//	Description:
//
//		Emits fluid from one of a predefined set of volumes (cube, sphere,
//		cylinder, cone, torus).
//
//	Parameters:
//
//		fluid:				fluid into which we are emitting
//		fluidWorldMatrix:	object->world matrix for the fluid
//		plugIndex:			identifies which fluid connected to the emitter
//							we are emitting into
//		block:				datablock for the emitter, to retrieve attribute
//							values
//		dt:					time delta for this frame
//		conversion:			mapping from UI emission rates to internal units
//		dropoff:			specifies how much emission rate drops off as
//							the surface points move away from the centers
//							of the voxels in which they lie.
//
//	Notes:
//		
//		To associate an owner object with an emitter, use the
//		addDynamic MEL command, e.g. "addDynamic simpleFluidEmitter1 pPlane1".
//
//==============================================================================
{
	//	get relevant world matrices
	//
	MMatrix fluidInverseWorldMatrix = fluidWorldMatrix.inverse();
	
	//	get emission rates for density, fuel, heat, and emission color
	//	
	double densityEmit = fluidDensityEmission( block );
	double fuelEmit = fluidFuelEmission( block );
	double heatEmit = fluidHeatEmission( block );
	bool doEmitColor = fluidEmitColor( block );
	MColor emitColor = fluidColor( block );
	
	//	rate modulation based on frame time, user value conversion factor, and
	//	standard emitter "rate" value (not actually exposed in most fluid
	//	emitters, but there anyway).
	//
	double theRate = getRate(block) * dt * conversion;

	//	get voxel dimensions and sizes (object space)
	//
	double size[3];
	unsigned int res[3];
	fluid.getDimensions( size[0], size[1], size[2] );
	fluid.getResolution( res[0], res[1], res[2] );
		
	//	voxel sizes
	double dx = size[0] / res[0];
	double dy = size[1] / res[1];
	double dz = size[2] / res[2];
	
	//	voxel centers
	double Ox = -size[0]/2;
	double Oy = -size[1]/2;
	double Oz = -size[2]/2;	

	//	get the "swept geometry" data for the emitter surface.  This structure
	//	tracks the motion of each emitter triangle over the time interval
	//	for this simulation step.  We just use positions on the emitter
	//	surface at the end of the time step to do the emission.
	//
	MDataHandle sweptHandle = block.inputValue( mSweptGeometry );
	MObject sweptData = sweptHandle.data();
	MFnDynSweptGeometryData fnSweptData( sweptData );

	//	for "non-jittered" sampling, just reset the random state for each 
	//	triangle, which gives us a fixed set of samples all the time.
	//	Sure, they're still jittered, but they're all jittered the same,
	//	which makes them kinda uniform.
	//
	bool jitter = fluidJitter(block);
	if( !jitter )
	{
		resetRandomState( plugIndex, block );
	}

	if( fnSweptData.triangleCount() > 0 )
	{
		//	average voxel face area - use this as the canonical unit that
		//	receives the emission rate specified by the users.  Scale the
		//	rate for other triangles accordingly.
		//
		double vfArea = pow(dx*dy*dz, 2.0/3.0);
		
		//	very rudimentary support for textured emission rate and
		//	textured emission color.  We simply sample each texture once
		//	at the center of each emitter surface triangle.  This will 
		//	cause aliasing artifacts when these triangles are large.
		//
		MFnDependencyNode fnNode( thisMObject() );
		MObject rateTextureAttr = fnNode.attribute( "textureRate" );
		MObject colorTextureAttr = fnNode.attribute( "particleColor" );

		bool texturedRate = hasValidEmission2dTexture( rateTextureAttr );
		bool texturedColor = hasValidEmission2dTexture( colorTextureAttr );
		
		//	construct texture coordinates for each triangle center
		//	
		MDoubleArray uCoords, vCoords;
		if( texturedRate || texturedColor )
		{
			uCoords.setLength( fnSweptData.triangleCount() );
			vCoords.setLength( fnSweptData.triangleCount() );
			
			int t;
			for( t = 0; t < fnSweptData.triangleCount(); t++ )
			{
				MDynSweptTriangle tri = fnSweptData.sweptTriangle( t );
				MVector uv0 = tri.uvPoint(0);
				MVector uv1 = tri.uvPoint(1);
				MVector uv2 = tri.uvPoint(2);
				
				MVector uvMid = (uv0+uv1+uv2)/3.0;
				uCoords[t] = uvMid[0];
				vCoords[t] = uvMid[1];
			}
		}

		//	evaluate textured rate and color values at the triangle centers
		//
		MDoubleArray texturedRateValues;
		if( texturedRate )
		{
			texturedRateValues.setLength( uCoords.length() );
			evalEmission2dTexture( rateTextureAttr, uCoords, vCoords, NULL, &texturedRateValues );
		}
		
		MVectorArray texturedColorValues;
		if( texturedColor )
		{
			texturedColorValues.setLength( uCoords.length() );
			evalEmission2dTexture( colorTextureAttr, uCoords, vCoords, &texturedColorValues, NULL );
		}
		
		for( int t = 0; t < fnSweptData.triangleCount(); t++ )
		{
			//	calculate emission rate and color values for this triangle
			//
			double curTexturedRate = texturedRate ? texturedRateValues[t] : 1.0;
			MColor curTexturedColor;
			if( texturedColor )
			{
				MVector& curVec = texturedColorValues[t];
				curTexturedColor.r = (float)curVec[0];
				curTexturedColor.g = (float)curVec[1];
				curTexturedColor.b = (float)curVec[2];
				curTexturedColor.a = 1.0;
			}
			else
			{
				curTexturedColor = emitColor;
			}

			MDynSweptTriangle tri = fnSweptData.sweptTriangle( t );
			MVector v0 = tri.vertex(0);
			MVector v1 = tri.vertex(1);
			MVector v2 = tri.vertex(2);

			//	compute number of samples for this triangle based on area,
			//	with large triangles receiving approximately 1 sample for 
			//	each voxel that they intersect
			//
			double triArea = tri.area();
			int numSamples = (int)(triArea / vfArea);
			if( numSamples < 1 ) numSamples = 1;
			
			//	compute emission rate for the points on the triangle.
			//	Scale the canonical rate by the area ratio of this triangle
			//	to the average voxel size, then split it amongst all the samples.
			//
			double triRate = (theRate*(triArea/vfArea))/numSamples;
			
			triRate *= curTexturedRate;
			
			for( int j = 0; j < numSamples; j++ )
			{
				//	generate a random point on the triangle,
				//	map it into fluid local space
				//
				double r1 = randgen();
				double r2 = randgen();
				
				if( r1 + r2 > 1 )
				{
					r1 = 1-r1;
					r2 = 1-r2;
				}
				double r3 = 1 - (r1+r2);
				MPoint randPoint = r1*v0 + r2*v1 + r3*v2;
				randPoint *= fluidInverseWorldMatrix;
				
				//	figure out where the current point lies
				//
				::int3 coord;
				fluid.toGridIndex( randPoint, coord );
				
				if( (coord[0]<0) || (coord[1]<0) || (coord[2]<0) ||
					(coord[0]>=(int)res[0]) || (coord[1]>=(int)res[1]) || (coord[2]>=(int)res[2]) )
				{
					continue;
				}
				
				//	do some falloff based on how far from the voxel center 
				//	the current point lies
				//
				MPoint gridPoint;
				gridPoint.x = Ox + (coord[0]+0.5)*dx;
				gridPoint.y = Oy + (coord[1]+0.5)*dy;
				gridPoint.z = Oz + (coord[2]+0.5)*dz;
				
				MVector diff = gridPoint - randPoint;
				double distSquared = diff * diff;
				double distDrop = dropoff * distSquared;
				
				double newVal = triRate * exp( -distDrop );
		
				//	emit into the voxel
				//
				if( newVal != 0 )
				{
					fluid.emitIntoArrays( (float) newVal, coord[0], coord[1], coord[2], (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, curTexturedColor );		
				}
			}
		}
	}
}
void 
simpleFluidEmitter::volumeFluidEmitter(
	MFnFluid& 		fluid,
	const MMatrix&	fluidWorldMatrix,
	int 			plugIndex,
	MDataBlock& 	block,
	double 			dt,
	double			conversion,
	double			dropoff
)
//==============================================================================
//
//	Method:	
//
//		simpleFluidEmitter::volumeFluidEmitter
//
//	Description:
//
//		Emits fluid from points distributed over the surface of the 
//		emitter's owner object.
//
//	Parameters:
//
//		fluid:				fluid into which we are emitting
//		fluidWorldMatrix:	object->world matrix for the fluid
//		plugIndex:			identifies which fluid connected to the emitter
//							we are emitting into
//		block:				datablock for the emitter, to retrieve attribute
//							values
//		dt:					time delta for this frame
//		conversion:			mapping from UI emission rates to internal units
//		dropoff:			specifies how much emission rate drops off as
//							we move away from the local y-axis of the 
//							volume emitter shape.
//
//==============================================================================
{
	//	get emitter position and relevant matrices 
	//	
	MPoint emitterPos = getWorldPosition();
	MMatrix emitterWorldMatrix = getWorldMatrix();
	MMatrix fluidInverseWorldMatrix = fluidWorldMatrix.inverse();
	
	//	get emission rates for density, fuel, heat, and emission color
	//	
	double densityEmit = fluidDensityEmission( block );
	double fuelEmit = fluidFuelEmission( block );
	double heatEmit = fluidHeatEmission( block );
	bool doEmitColor = fluidEmitColor( block );
	MColor emitColor = fluidColor( block );
	
	//	rate modulation based on frame time, user value conversion factor, and
	//	standard emitter "rate" value (not actually exposed in most fluid
	//	emitters, but there anyway).
	//
	double theRate = getRate(block) * dt * conversion;
	
	//	get voxel dimensions and sizes (object space)
	//
	double size[3];
	unsigned int res[3];
	fluid.getDimensions( size[0], size[1], size[2] );
	fluid.getResolution( res[0], res[1], res[2] );

	//	voxel sizes
	double dx = size[0] / res[0];
	double dy = size[1] / res[1];
	double dz = size[2] / res[2];
	
	// 	voxel centers
	double Ox = -size[0]/2;
	double Oy = -size[1]/2;
	double Oz = -size[2]/2;	

	//	find the voxels that intersect the bounding box of the volume
	//	primitive associated with the emitter
	//
	MBoundingBox bbox;
	if( !volumePrimitiveBoundingBox( bbox ) )
	{
		//	shouldn't happen
		//
		return;
	}
	
	//	transform volume primitive into fluid space
	//
	bbox.transformUsing( emitterWorldMatrix );
	bbox.transformUsing( fluidInverseWorldMatrix );
	MPoint lowCorner = bbox.min();
	MPoint highCorner = bbox.max();

	//	get fluid voxel coord range of bounding box
	//
	::int3 lowCoords;
	::int3 highCoords;
	fluid.toGridIndex( lowCorner, lowCoords );
	fluid.toGridIndex( highCorner, highCoords );
	
	int i;
	for ( i = 0; i < 3; i++ )
	{
		if ( lowCoords[i] < 0 ) {
			lowCoords[i] = 0;
		} else if ( lowCoords[i] > ((int)res[i])-1 ) {
			lowCoords[i] = ((int)res[i])-1;
		}

		if ( highCoords[i] < 0 ) {
			highCoords[i] = 0;
		} else if ( highCoords[i] > ((int)res[i])-1 ) {
			highCoords[i] = ((int)res[i])-1;
		}
		
	}

	//	figure out the emitter size relative to the voxel size, and compute
	//	a per-voxel sampling rate that uses 1 sample/voxel for emitters that
	//	are >= 2 voxels big in all dimensions.  For smaller emitters, use up
	//	to 8 samples per voxel.
	//
	double emitterVoxelSize[3];
	emitterVoxelSize[0] = (highCorner[0]-lowCorner[0])/dx;
	emitterVoxelSize[1] = (highCorner[1]-lowCorner[1])/dy;
	emitterVoxelSize[2] = (highCorner[2]-lowCorner[2])/dz;
		
	double minVoxelSize = MIN(emitterVoxelSize[0],MIN(emitterVoxelSize[1],emitterVoxelSize[2]));
	if( minVoxelSize < 1.0 )
	{
		minVoxelSize = 1.0;
	}
	int maxSamples = 8;
	int numSamples = (int)(8.0/(minVoxelSize*minVoxelSize*minVoxelSize) + 0.5);
	if( numSamples < 1 ) numSamples = 1;
	if( numSamples > maxSamples ) numSamples = maxSamples;
	
	//	non-jittered, just use one sample in the voxel center.  Should replace
	//	with uniform sampling pattern.
	//
	bool jitter = fluidJitter(block);
	if( !jitter )
	{
		numSamples = 1;
	}
	
	//	for each voxel that could potentially intersect the volume emitter
	//	primitive, take some samples in the voxel.  For those inside the
	//	volume, compute their dropoff relative to the primitive's local y-axis,
	//	and emit an appropriate amount into the voxel.
	//
	for( i = lowCoords[0]; i <= highCoords[0]; i++ )
	{
		double x = Ox + (i+0.5)*dx;
			
		for( int j = lowCoords[1]; j < highCoords[1]; j++ )
		{
			double y = Oy + (j+0.5)*dy;

			for( int k = lowCoords[2]; k < highCoords[2]; k++ )
			{
				double z = Oz + (k+0.5)*dz;
				
				for ( int si = 0; si < numSamples; si++) {
					
					//	compute voxel sample point (object space)
					//
					double rx, ry, rz;
					if(jitter) {
						rx = x + dx*(randgen() - 0.5);
						ry = y + dy*(randgen() - 0.5);
						rz = z + dz*(randgen() - 0.5);
					} else {
						rx = x;
						ry = y;
						rz = z;
					}
					
					//	to world space
					MPoint pt( rx, ry, rz );
					pt *= fluidWorldMatrix;

					//	test to see if point is inside volume primitive
					//
					if( volumePrimitivePointInside( pt, emitterWorldMatrix ) )
					{
						//	compute dropoff
						//
						double dist = pt.distanceTo( emitterPos );
						double distDrop = dropoff * (dist*dist);
						double newVal = (theRate * exp( -distDrop )) / (double)numSamples;
						
						//	emit into arrays
						//
						if( newVal != 0.0 )
						{
							fluid.emitIntoArrays( (float) newVal, i, j, k, (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, emitColor );
						}
					}
				}
			}
		}
	}
}
MStatus sgHair_controlJoint::setGravityJointPositionWorld()
{
	MStatus status;

	m_mtxArrGravityAdd = m_mtxArrBase;

	if( m_weightGravity == 0 ) return MS::kSuccess;

	if( !m_bStaticRotation )
	{
		double minParam = m_paramGravity - m_rangeGravity;
		double maxParam = m_paramGravity;
		double divRate = maxParam - minParam;
		if( divRate == 0 ) divRate = 0.0001;

		if( minParam > m_mtxArrBase.length()-1 ) return MS::kSuccess;
		MDoubleArray dArrGravityWeights;
		dArrGravityWeights.setLength( m_mtxArrBase.length() );

		double beforeWeight = 1.0;
		for( int i= m_mtxArrBase.length()-1; i > minParam, i >= 0; i-- )
		{
			double paramRate = ( i - minParam ) / divRate;
			if( paramRate > 1 ) paramRate = 1.0;
			else if( paramRate < 0 ) paramRate = 0.0;
			double cuRate = beforeWeight - paramRate;
			if( cuRate < 0 ) cuRate = 0;
			dArrGravityWeights[i] = cuRate * m_weightGravity;
			beforeWeight = paramRate;
		}

		MMatrix mtxDefault;
		MMatrix mtxMult;

		for( int i= m_mtxArrBase.length()-1; i > minParam, i >= 0; i-- )
		{
			if( dArrGravityWeights[i] == 0 ) continue;
			double weight = dArrGravityWeights[i];

			mtxDefault( 3,0 ) = m_mtxArrBase[i]( 3,0 );
			mtxDefault( 3,1 ) = m_mtxArrBase[i]( 3,1 );
			mtxDefault( 3,2 ) = m_mtxArrBase[i]( 3,2 );

			mtxMult = getAngleWeightedMatrix( m_mtxGravityOffset, weight );
			mtxMult( 3,0 ) = m_mtxArrBase[i]( 3,0 );
			mtxMult( 3,1 ) = m_mtxArrBase[i]( 3,1 );
			mtxMult( 3,2 ) = m_mtxArrBase[i]( 3,2 );

			mtxMult = mtxDefault.inverse() * mtxMult;

			for( int j=i; j< m_mtxArrBase.length(); j++ )
			{
				m_mtxArrGravityAdd[j] *= mtxMult;
			}
		}
	}
	else
	{
		double minParam = m_paramGravity - m_rangeGravity;
		double maxParam = m_paramGravity;
		double divRate = maxParam - minParam;
		if( divRate == 0 ) divRate = 0.0001;

		MDoubleArray dArrGravityWeights;
		dArrGravityWeights.setLength( m_mtxArrBase.length() );

		double weight;
		for( int i= 0; i < m_mtxArrBase.length(); i++ )
		{
			if( i < minParam )weight=0;
			else weight = (i-minParam)/divRate;
			if( weight > 1 ) weight = 1;
			m_mtxArrGravityAdd[i] = m_mtxArrBase[i];

			double invWeight = 1-weight;
			MMatrix mtx = weight * m_mtxGravityOffset*m_mtxArrBase[i] + invWeight * m_mtxArrBase[i]; 

			cleanMatrix( mtx );

			m_mtxArrGravityAdd[i] = mtx;
			m_mtxArrGravityAdd[i]( 3,0 ) = m_mtxArrBase[i]( 3,0 );
			m_mtxArrGravityAdd[i]( 3,1 ) = m_mtxArrBase[i]( 3,1 );
			m_mtxArrGravityAdd[i]( 3,2 ) = m_mtxArrBase[i]( 3,2 );
		}
		cout << endl;
	}
	return MS::kSuccess;
}
Exemple #15
0
void TestDeformer::_deform_on_one_mesh(MDataBlock& data,
                                      MItGeometry& iter,
                                      const MMatrix& localToWorldMatrix,
                                      unsigned int mIndex,
                                      MObject &driver_mesh,
                                      const MDataHandle &envelopeHandle, MArrayDataHandle &vertMapArrayData, MPointArray &tempOutputPts)
{
    MStatus status;

    float env = envelopeHandle.asFloat();

    // use driver_meshVertIter to walk through the vertex of the current driver mesh
    MItMeshVertex driver_meshVertIter( driver_mesh, &status );
    CHECK_MSTATUS( status );

    int i = 0;
    iter.reset();
    while( !iter.isDone(&status) )
    {
        CHECK_MSTATUS( status );

        // get the weight
        float weight = weightValue( data, mIndex, iter.index() ); //painted weight
        float ww = weight * env;

        if ( fabs(ww) > FLT_EPSILON )//if ( ww != 0 )
        {
            __debug("%s(), vertMapArrayData.elementCount()=%d, iter.index()=%d",
                    __FUNCTION__, vertMapArrayData.elementCount(), iter.index());

            // get index_mapped to which the currrent vertex vI is mapped
            CHECK_MSTATUS(vertMapArrayData.jumpToElement(iter.index()));
            int index_mapped = vertMapArrayData.inputValue(&status).asInt();
            CHECK_MSTATUS( status );

            if( index_mapped >= 0 )
            {
                __debug("index_mapped=%d", index_mapped);

                int prevInt;
                CHECK_MSTATUS( driver_meshVertIter.setIndex(index_mapped, prevInt) );

                // vertex wrold position on driver mesh
                MPoint mappedPt = driver_meshVertIter.position( MSpace::kWorld, &status );
                CHECK_MSTATUS( status );
                // vertex wrold position on driven mesh
                MPoint iterPt = iter.position(MSpace::kObject, &status) * localToWorldMatrix;
                CHECK_MSTATUS( status );

                // use ww to interpolate between mappedPt and iterPt
                MPoint pt = iterPt + ((mappedPt - iterPt) * ww );
                pt = pt * localToWorldMatrix.inverse();

                /// put the deform points to tempOutputPts
                tempOutputPts[i] += pt;
            }
        }//if
        CHECK_MSTATUS(iter.next());
        ++i;
    }//while
}
Exemple #16
0
void MG_poseReader::draw( M3dView & view, const MDagPath & path, 
							 M3dView::DisplayStyle dispStyle,
							 M3dView::DisplayStatus status )
{ 
   
	
	MPlug sizeP (thisMObject(),size);
	double sizeV;
	sizeP.getValue(sizeV);

	MPlug poseMatrixP (thisMObject(),poseMatrix);
	MObject poseMatrixData;
	poseMatrixP.getValue(poseMatrixData);
	MFnMatrixData matrixFn(poseMatrixData);
	MMatrix poseMatrixV =matrixFn.matrix();

	MPlug readerMatrixP (thisMObject(),readerMatrix);
	MObject readerMatrixData;
	readerMatrixP.getValue(readerMatrixData);

	matrixFn.setObject(readerMatrixData);
	MMatrix readerMatrixV =matrixFn.matrix();

	MMatrix poseMatrixFix =poseMatrixV*readerMatrixV.inverse();

	MPlug aimAxisP  (thisMObject(),aimAxis);
	int aimAxisV;
	aimAxisP.getValue(aimAxisV);
	MVector aimBall;

	  
	MPlug readerOnOffP(thisMObject(),readerOnOff);
	MPlug axisOnOffP(thisMObject(),axisOnOff);
	MPlug poseOnOffP(thisMObject(),poseOnOff);

	double readerOnOffV;
	double axisOnOffV;
	double poseOnOffV;

	readerOnOffP.getValue(readerOnOffV);
	axisOnOffP.getValue(axisOnOffV);
	poseOnOffP.getValue(poseOnOffV);

	MPlug xPositiveP  (thisMObject(),xPositive);
	MPlug xNegativeP  (thisMObject(),xNegative);

	double xPositiveV;
	double xNegativeV;

	xPositiveP.getValue(xPositiveV);
	xNegativeP.getValue(xNegativeV);

	double xColor = xPositiveV;
	if (xPositiveV==0)
	{
		xColor=xNegativeV;

	}
	


	MPlug yPositiveP  (thisMObject(),yPositive);
	MPlug yNegativeP  (thisMObject(),yNegative);

	double yPositiveV;
	double yNegativeV;

	yPositiveP.getValue(yPositiveV);
	yNegativeP.getValue(yNegativeV);

	double yColor = yPositiveV;
	if (yPositiveV==0)
	{
		yColor=yNegativeV;

	}

	MPlug zPositiveP  (thisMObject(),zPositive);
	MPlug zNegativeP  (thisMObject(),zNegative);

	double zPositiveV;
	double zNegativeV;

	zPositiveP.getValue(zPositiveV);
	zNegativeP.getValue(zNegativeV);

	double zColor = zPositiveV;
	if (zPositiveV==0)
	{
		zColor=zNegativeV;

	}



		if (aimAxisV==0)
		{
			
			aimBall.x=poseMatrixFix[0][0];
			aimBall.y=poseMatrixFix[0][1];
			aimBall.z=poseMatrixFix[0][2];
		}
		else if (aimAxisV==1)
		{
			
			aimBall.x=poseMatrixFix[1][0];
			aimBall.y=poseMatrixFix[1][1];
			aimBall.z=poseMatrixFix[1][2];

		}else
		{
			
			aimBall.x=poseMatrixFix[2][0];
			aimBall.y=poseMatrixFix[2][1];
			aimBall.z=poseMatrixFix[2][2];
		}
	
      
	//*****************************************************************
	// Initialize opengl and draw
	//*****************************************************************
	view.beginGL();
	glPushAttrib( GL_ALL_ATTRIB_BITS );
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glLineWidth(2);
	if(status == M3dView::kLead)
		glColor4f(0.0,1.0,0.0,0.3f);
	else
		glColor4f(1.0,1.0,0.0,0.3f);





	MVector baseV(0,0,0);
	MVector xp(1*sizeV,0,0);
	MVector xm(-1*sizeV,0,0);
	MVector yp(0,1*sizeV,0);
	MVector ym(0,-1*sizeV,0);
	MVector zp(0,0,1*sizeV);
	MVector zm(0,0,-1*sizeV);



	double * red;
	red = new double[4];
	red[0]=1;
	red[1]=0;
	red[2]=0;
	red[3]=1;

	double * green;
	green = new double[4];
	green[0]=0;
	green[1]=1;
	green[2]=0;
	green[3]=1;

	double * blue;
	blue = new double[4];
	blue[0]=0;
	blue[1]=0;
	blue[2]=1;
	blue[3]=1;

	double * yellow;
	yellow = new double[4];
	yellow[0]=1;
	yellow[1]=1;
	yellow[2]=0.2;
	yellow[3]=0.3;



	if (readerOnOffV==1)
	{
	drawSphere(sizeV,20,20,baseV,yellow);
	}
	
	
	if  (axisOnOffV==1)
	{
	drawSphere(sizeV/7,15,15,xp,red);
	drawSphere(sizeV/7,15,15,xm,red); 
	drawSphere(sizeV/7,15,15,yp,green);
	drawSphere(sizeV/7,15,15,ym,green);
	drawSphere(sizeV/7,15,15,zp,blue);
	drawSphere(sizeV/7,15,15,zm,blue);
	}
	if (poseOnOffV==1)
	{
	  

	
	double* color = blendColor(xColor,yColor,zColor,1);

	drawSphere(sizeV/7,15,15,aimBall*sizeV,color);
	}

	glDisable(GL_BLEND);
	glPopAttrib();



}
    //---------------------------------------
    void MaterialExporter::setSetParam ( const cgfxShaderNode* shaderNodeCgfx, const cgfxAttrDef* attribute )
    {
        COLLADASW::StreamWriter* streamWriter = mDocumentExporter->getStreamWriter();
        String attributeName = attribute->fName.asChar();

        cgfxAttrDef::cgfxAttrType attributeType = attribute->fType;
        switch ( attributeType )
        {
        case cgfxAttrDef::kAttrTypeBool:
            {
                COLLADASW::SetParamBool setParam ( streamWriter );
                setParam.openParam ( attributeName );
                setParam.appendValues ( attribute->fNumericDef && attribute->fNumericDef[0] );
                setParam.closeParam ();
                break;
            }
        case cgfxAttrDef::kAttrTypeInt:
            {
                COLLADASW::SetParamInt setParam ( streamWriter );
                setParam.openParam ( attributeName );
                setParam.appendValues ( (int) attribute->fNumericDef[0] );
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeString:
            {
                COLLADASW::SetParamString setParam ( streamWriter );
                setParam.openParam ( attributeName );
                if ( attribute->fStringDef != NULL ) 
                    setParam.appendValues ( String ( attribute->fStringDef.asChar() ) );
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeFloat:
            {
                COLLADASW::SetParamFloat setParam ( streamWriter );
                setParam.openParam ( attributeName );
                if ( attribute->fNumericDef!=NULL /*&& attribute->fNumericDef[0]!=0*/ )  
                    setParam.appendValues ( attribute->fNumericDef[0] );
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeVector2:
            {
                COLLADASW::SetParamFloat2 setParam ( streamWriter );
                setParam.openParam ( attributeName );
                for ( int i=0; i<attribute->fSize; ++i )
                {
                    if ( attribute->fNumericDef!=NULL /*&& attribute->fNumericDef[i]!=0*/ )  
                    {
                        double val = attribute->fNumericDef[i];
                        setParam.appendValues( val );
                    }
                }
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeVector3:
        case cgfxAttrDef::kAttrTypeColor3:
            {
                COLLADASW::SetParamFloat3 setParam ( streamWriter );
                setParam.openParam ( attributeName );
                for ( int i=0; i<attribute->fSize; ++i )
                {
                    if ( attribute->fNumericDef!=NULL /*&& attribute->fNumericDef[i]!=0*/ )  
                    {
                        double val = attribute->fNumericDef[i];
                        setParam.appendValues( val );
                    }
                }
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeVector4:
        case cgfxAttrDef::kAttrTypeColor4:
            {
                COLLADASW::SetParamFloat4 setParam ( streamWriter );
                setParam.openParam ( attributeName );
                for ( int i=0; i<attribute->fSize; ++i )
                {
                    if ( attribute->fNumericDef!=NULL /*&& attribute->fNumericDef[i]!=0*/ )  
                    {
                        double val = attribute->fNumericDef[i];
                        setParam.appendValues( val );
                    }
                }
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeWorldDir:
        case cgfxAttrDef::kAttrTypeWorldPos:
            {
                // Read the value
                double tmp[4];
                for ( int i=0; i<attribute->fSize; ++i )
                {
                    tmp[i] = attribute->fNumericDef[i];
                }
                if (attribute->fSize == 3) tmp[3] = 1.0;

                // Find the coordinate space, and whether it is a point or a vector
                int base = cgfxAttrDef::kAttrTypeFirstPos;
                if (attribute->fType <= cgfxAttrDef::kAttrTypeLastDir) 
                    base = cgfxAttrDef::kAttrTypeFirstDir;
                int space = attribute->fType - base;

                // Compute the transform matrix
                MMatrix mat;
                switch (space)
                {
                    /* case 0:	object space, handled in view dependent method */
                case 1:	/* world space  - do nothing, identity */ break;
                    /* case 2: eye space, unsupported yet */
                    /* case 3: clip space, unsupported yet */
                    /* case 4: screen space, unsupported yet */
                }

                if ( base == cgfxAttrDef::kAttrTypeFirstPos )
                {
                    MPoint point(tmp[0], tmp[1], tmp[2], tmp[3]);
                    point *= mat;
                    tmp[0] = point.x;
                    tmp[1] = point.y;
                    tmp[2] = point.z;
                    tmp[3] = point.w;
                }
                else
                {
                    MVector vec(tmp[0], tmp[1], tmp[2]);
                    vec *= mat;
                    tmp[0] = vec.x;
                    tmp[1] = vec.y;
                    tmp[2] = vec.z;
                    tmp[3] = 1;
                }

                COLLADASW::SetParamFloat4 setParam ( streamWriter );
                setParam.openParam ( attributeName );
                setParam.appendValues( tmp[0], tmp[1], tmp[2], tmp[3] );
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeMatrix:
        case cgfxAttrDef::kAttrTypeWorldMatrix:
        case cgfxAttrDef::kAttrTypeViewMatrix:
        case cgfxAttrDef::kAttrTypeProjectionMatrix:
        case cgfxAttrDef::kAttrTypeWorldViewMatrix:
        case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
            {
                COLLADASW::SetParamFloat4x4 setParam ( streamWriter );
                setParam.openParam ( attributeName );

                MMatrix mayaMatrix;
                double* p = &mayaMatrix.matrix[0][0];
                for ( int k=0; k<attribute->fSize; ++k )
                {
                    p[k] = attribute->fNumericDef[k];
                }

                MMatrix wMatrix, vMatrix, pMatrix, sMatrix;
                MMatrix wvMatrix, wvpMatrix, wvpsMatrix;
                {
                    float tmp[4][4];

                    wMatrix.setToIdentity();

                    glGetFloatv(GL_MODELVIEW_MATRIX, &tmp[0][0]);
                    wvMatrix = MMatrix(tmp);

                    vMatrix = wMatrix.inverse() * wvMatrix;

                    glGetFloatv(GL_PROJECTION_MATRIX, &tmp[0][0]);
                    pMatrix = MMatrix(tmp);

                    wvpMatrix = wvMatrix * pMatrix;

                    float vpt[4];
                    float depth[2];

                    glGetFloatv(GL_VIEWPORT, vpt);
                    glGetFloatv(GL_DEPTH_RANGE, depth);

                    // Construct the NDC -> screen space matrix
                    //
                    float x0, y0, z0, w, h, d;

                    x0 = vpt[0];
                    y0 = vpt[1];
                    z0 = depth[0];
                    w  = vpt[2];
                    h  = vpt[3];
                    d  = depth[1] - z0;

                    // Make a reference to ease the typing
                    //
                    double* s = &sMatrix.matrix[0][0];

                    s[ 0] = w/2;	s[ 1] = 0.0;	s[ 2] = 0.0;	s[ 3] = 0.0;
                    s[ 4] = 0.0;	s[ 5] = h/2;	s[ 6] = 0.0;	s[ 7] = 0.0;
                    s[ 8] = 0.0;	s[ 9] = 0.0;	s[10] = d/2;	s[11] = 0.0;
                    s[12] = x0+w/2;	s[13] = y0+h/2;	s[14] = z0+d/2;	s[15] = 1.0;

                    wvpsMatrix = wvpMatrix * sMatrix;
                }		

                switch ( attribute->fType )
                {
                case cgfxAttrDef::kAttrTypeWorldMatrix:
                    mayaMatrix = wMatrix; break;
                case cgfxAttrDef::kAttrTypeViewMatrix:
                    mayaMatrix = vMatrix; break;
                case cgfxAttrDef::kAttrTypeProjectionMatrix:
                    mayaMatrix = pMatrix; break;
                case cgfxAttrDef::kAttrTypeWorldViewMatrix:
                    mayaMatrix = wvMatrix; break;
                case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                    mayaMatrix = wvpMatrix; break;
                default:
                    break;
                }

                if (attribute->fInvertMatrix)
                    mayaMatrix = mayaMatrix.inverse();

                if (!attribute->fTransposeMatrix)
                    mayaMatrix = mayaMatrix.transpose();

                double matrix[4][4];
                convertMayaMatrixToTransposedDouble4x4 ( matrix, mayaMatrix, getTolerance () );
                setParam.appendValues( matrix );
                setParam.closeParam();
                break;
            }
        case cgfxAttrDef::kAttrTypeColor1DTexture:
        case cgfxAttrDef::kAttrTypeColor2DTexture:
        case cgfxAttrDef::kAttrTypeColor3DTexture:
        case cgfxAttrDef::kAttrTypeColor2DRectTexture:
        case cgfxAttrDef::kAttrTypeNormalTexture:
        case cgfxAttrDef::kAttrTypeBumpTexture:
        case cgfxAttrDef::kAttrTypeCubeTexture:
        case cgfxAttrDef::kAttrTypeEnvTexture:
        case cgfxAttrDef::kAttrTypeNormalizationTexture:
            {
                CGparameter cgParameter = attribute->fParameterHandle;
                HwShaderExporter hwShaderExporter ( mDocumentExporter );
                hwShaderExporter.setShaderFxFileUri ( getShaderFxFileUri () );

                MObject shaderNode = shaderNodeCgfx->thisMObject();
                hwShaderExporter.exportSampler ( shaderNode, cgParameter, false );


                // -------------------------------
//                 String imageName = attribute->fStringDef.asChar();
// 
//                 MObject oNode = shaderNodeCgfx->thisMObject();
//                 MFnDependencyNode oNodeFn ( oNode );
//                 String oNodeName = oNodeFn.name().asChar(); // cgfxShader1
// 
//                 MPlug plug;
//                 if ( DagHelper::getPlugConnectedTo( oNode, attributeName, plug ) )
//                 {
//                     String plugName = plug.name().asChar(); // file1.outColor
//                     MObject textureNode = plug.node();
// 
//                     //COLLADASW::Surface::SurfaceType surfaceType;
//                     COLLADASW::Sampler::SamplerType samplerType;
//                     COLLADASW::ValueType::ColladaType samplerValueType;
// 
//                     switch ( attributeType )
//                     {
//                     case cgfxAttrDef::kAttrTypeColor1DTexture:
//                         //surfaceType = COLLADASW::Surface::SURFACE_TYPE_1D;
//                         samplerType = COLLADASW::Sampler::SAMPLER_TYPE_1D;
//                         samplerValueType = COLLADASW::ValueType::SAMPLER_1D;
//                         break;
//                     case cgfxAttrDef::kAttrTypeColor2DTexture:
//                     case cgfxAttrDef::kAttrTypeNormalTexture:
//                     case cgfxAttrDef::kAttrTypeBumpTexture:
//                         //surfaceType = COLLADASW::Surface::SURFACE_TYPE_2D;
//                         samplerType = COLLADASW::Sampler::SAMPLER_TYPE_2D;
//                         samplerValueType = COLLADASW::ValueType::SAMPLER_2D;
//                         break;
//                     case cgfxAttrDef::kAttrTypeColor3DTexture:
//                         //surfaceType = COLLADASW::Surface::SURFACE_TYPE_3D;
//                         samplerType = COLLADASW::Sampler::SAMPLER_TYPE_3D;
//                         samplerValueType = COLLADASW::ValueType::SAMPLER_3D;
//                         break;
//                     case cgfxAttrDef::kAttrTypeColor2DRectTexture:
//                         //surfaceType = COLLADASW::Surface::SURFACE_TYPE_RECT;
//                         samplerType = COLLADASW::Sampler::SAMPLER_TYPE_RECT;
//                         samplerValueType = COLLADASW::ValueType::SAMPLER_RECT;
//                         break;
//                     case cgfxAttrDef::kAttrTypeCubeTexture:
//                     case cgfxAttrDef::kAttrTypeEnvTexture:
//                     case cgfxAttrDef::kAttrTypeNormalizationTexture:
//                         //surfaceType = COLLADASW::Surface::SURFACE_TYPE_CUBE;
//                         samplerType = COLLADASW::Sampler::SAMPLER_TYPE_CUBE;
//                         samplerValueType = COLLADASW::ValueType::SAMPLER_CUBE;
//                         break;
//                     default:
//                         //surfaceType = COLLADASW::Surface::SURFACE_TYPE_UNTYPED;
//                         samplerType = COLLADASW::Sampler::SAMPLER_TYPE_UNSPECIFIED;
//                         samplerValueType = COLLADASW::ValueType::VALUE_TYPE_UNSPECIFIED;
//                     }
// 
//                     // Write the params elements
//                     setSetParamTexture ( attribute, textureNode, samplerType, samplerValueType );
//                }
            }
        }
    }
MStatus sphericalBlendShape::deform(MDataBlock& data, MItGeometry& itGeo, const MMatrix& mat, unsigned int geomIndex) 
{
	MStatus status = MS::kSuccess;

	float env = data.inputValue(envelope).asFloat();
	if (env <= 0.0f) {
		return MS::kSuccess;
	}

	MMatrix spaceMatrix = data.inputValue(aSpaceMatrix).asMatrix();
	short poleAxis		= data.inputValue(aPoleAxis).asShort();
	short seamAxis		= data.inputValue(aSeamAxis).asShort();
	short method		= data.inputValue(aMethod).asShort();
	MMatrix warpMatrix	= data.inputValue(aWarpMatrix).asMatrix();

	MTransformationMatrix warpTransMatrix(warpMatrix);
	MPoint warpPoint = warpTransMatrix.getTranslation(MSpace::kWorld);
	
	status = checkPoleAndSeam(poleAxis, seamAxis);
	CHECK_MSTATUS_AND_RETURN_IT(status);


	MMatrix invGeoMatrix   = mat.inverse();
	MMatrix invSpaceMatrix = spaceMatrix.inverse();

	MPointArray defPoints;
	MPoint* defPoint;
	MPoint inPoint, returnPoint;

	itGeo.allPositions(defPoints);
	unsigned int count = defPoints.length();

	unsigned int i;
	switch(method) {
		// XYZ to Spherical
	case 0:
		for (i=0; i<count; i++) {
			defPoint = &defPoints[i];
			inPoint = *defPoint;

			// bring the point into world space
			inPoint *= invGeoMatrix;
			// bring into local space of the input matrix
			inPoint *= invSpaceMatrix;

			cartesianToSpherical(inPoint, poleAxis, seamAxis, warpPoint, returnPoint);

			// bring the point back into world space
			returnPoint *= spaceMatrix;
			// bring the point back into local space
			returnPoint *= mat;
				
			lerp(*defPoint, returnPoint, env, *defPoint);
		}
		break;

	case 1:
		for (i=0; i<count; i++) {
			defPoint = &defPoints[i];
			inPoint = *defPoint;

			// bring the point into world space
			inPoint *= invGeoMatrix;
			// bring into local space of the input matrix
			inPoint *= invSpaceMatrix;

			sphericalToCartesian(inPoint, poleAxis, seamAxis, warpPoint, returnPoint);

			// bring the point back into world space
			returnPoint *= spaceMatrix;
			// bring the point back into local space
			returnPoint *= mat;
				
			lerp(*defPoint, returnPoint, env, *defPoint);
		}
		break;
	}

	itGeo.setAllPositions(defPoints);

	return MS::kSuccess;
}
MStatus probeDeformerARAPNode::deform( MDataBlock& data, MItGeometry& itGeo, const MMatrix &localToWorldMatrix, unsigned int mIndex )
{
	MObject thisNode = thisMObject();
    MStatus status;
    MThreadUtils::syncNumOpenMPThreads();    // for OpenMP
    
    bool worldMode = data.inputValue( aWorldMode ).asBool();
    bool areaWeighted = data.inputValue( aAreaWeighted ).asBool();
    short stiffnessMode = data.inputValue( aStiffness ).asShort();
    short blendMode = data.inputValue( aBlendMode ).asShort();
    short tetMode = data.inputValue( aTetMode ).asShort();
    short numIter = data.inputValue( aIteration ).asShort();
    short constraintMode = data.inputValue( aConstraintMode ).asShort();
    short visualisationMode = data.inputValue( aVisualisationMode ).asShort();
    mesh.transWeight = data.inputValue( aTransWeight ).asDouble();
    double constraintWeight = data.inputValue( aConstraintWeight ).asDouble();
    double normExponent = data.inputValue( aNormExponent ).asDouble();
    double visualisationMultiplier = data.inputValue(aVisualisationMultiplier).asDouble();
    MArrayDataHandle hMatrixArray = data.inputArrayValue(aMatrix);
    MArrayDataHandle hInitMatrixArray = data.inputArrayValue(aInitMatrix);
    // check connection
    if(hMatrixArray.elementCount() > hInitMatrixArray.elementCount() || hMatrixArray.elementCount() == 0 || blendMode == BM_OFF){
        return MS::kSuccess;
    }else if(hMatrixArray.elementCount() < hInitMatrixArray.elementCount()){
        std::set<int> indices;
        for(int i=0;i<hInitMatrixArray.elementCount();i++){
            hInitMatrixArray.jumpToArrayElement(i);
            indices.insert(hInitMatrixArray.elementIndex());
        }
        for(int i=0;i<hMatrixArray.elementCount();i++){
            hMatrixArray.jumpToArrayElement(i);
            indices.erase(hMatrixArray.elementIndex());
        }
        deleteAttr(data, aInitMatrix, indices);
        deleteAttr(data, aProbeConstraintRadius, indices);
        deleteAttr(data, aProbeWeight, indices);
    }
    bool isNumProbeChanged = (numPrb != hMatrixArray.elementCount());
    numPrb = hMatrixArray.elementCount();
    B.setNum(numPrb);
    // read matrices from probes
    std::vector<Matrix4d> initMatrix(numPrb), matrix(numPrb);
    readMatrixArray(hInitMatrixArray, initMatrix);
    readMatrixArray(hMatrixArray, matrix);
    // read vertex positions
    MPointArray Mpts;
    itGeo.allPositions(Mpts);
    int numPts = Mpts.length();
    
    // compute distance
    if(!data.isClean(aARAP) || !data.isClean(aComputeWeight) || isNumProbeChanged){
        // load points list
        if(worldMode){
            for(int j=0; j<numPts; j++ )
                Mpts[j] *= localToWorldMatrix;
        }
        pts.resize(numPts);
        for(int i=0;i<numPts;i++){
            pts[i] << Mpts[i].x, Mpts[i].y, Mpts[i].z;
        }
        // make tetrahedral structure
        getMeshData(data, input, inputGeom, mIndex, tetMode, pts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetMatrix, mesh.tetWeight);
        mesh.dim = removeDegenerate(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetMatrix);
        makeTetMatrix(tetMode, pts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetMatrix, mesh.tetWeight);
        makeTetCenterList(tetMode, pts, mesh.tetList, tetCenter);
        mesh.numTet = (int)mesh.tetList.size()/4;
        mesh.computeTetMatrixInverse();
        // initial probe position
        for(int i=0;i<numPrb;i++){
            B.centre[i] = transPart(initMatrix[i]);
        }
        // compute distance between probe and tetrahedra
        D.setNum(numPrb, numPts, mesh.numTet);
        D.computeDistTet(tetCenter, B.centre);
        D.findClosestTet();
        D.computeDistPts(pts, B.centre);
        D.findClosestPts();
        if(!areaWeighted){
            mesh.tetWeight.clear();
            mesh.tetWeight.resize(mesh.numTet,1.0);
        }
    }
    
    // (re)compute ARAP
    if(!data.isClean(aARAP) || isNumProbeChanged){
        // load painted weights
        if(stiffnessMode == SM_PAINT) {
            VectorXd ptsWeight(numPts);
            for (int i=0; !itGeo.isDone(); itGeo.next()){
                double w=weightValue(data, mIndex, itGeo.index());
                ptsWeight[i++] = (w>EPSILON) ? w : EPSILON;
            }
            makeTetWeightList(tetMode, mesh.tetList, faceList, edgeList, vertexList, ptsWeight, mesh.tetWeight);
        }else if(stiffnessMode == SM_LEARN) {
            std::vector<double> tetEnergy(mesh.numTet,0);
            MArrayDataHandle hSupervisedMesh = data.inputArrayValue(aSupervisedMesh);
            int numSupervisedMesh = hSupervisedMesh.elementCount();
            for(int j=0;j<numSupervisedMesh;j++){
                hSupervisedMesh.jumpToElement(j);
                MFnMesh ex_mesh(hSupervisedMesh.inputValue().asMesh());
                MPointArray Mspts;
                ex_mesh.getPoints( Mspts );
                if(numPts != Mspts.length()){
                    MGlobal::displayInfo("incompatible mesh");
                    return MS::kFailure;
                }
                std::vector<Vector3d> spts(numPts);
                for(int i=0;i<numPts;i++){
                    spts[i] << Mspts[i].x, Mspts[i].y, Mspts[i].z;
                }
                std::vector<double> dummy_weight;
                makeTetMatrix(tetMode, spts, mesh.tetList, faceList, edgeList, vertexList, Q, dummy_weight);
                Matrix3d S,R;
                for(int i=0;i<mesh.numTet;i++)  {
                    polarHigham((mesh.tetMatrixInverse[i]*Q[i]).block(0,0,3,3), S, R);
                    tetEnergy[i] += (S-Matrix3d::Identity()).squaredNorm();
                }
            }
            // compute weight (stiffness)
            double max_energy = *std::max_element(tetEnergy.begin(), tetEnergy.end());
            for(int i=0;i<mesh.numTet;i++)  {
                double w = 1.0 - tetEnergy[i]/(max_energy+EPSILON);
                mesh.tetWeight[i] *= w*w;
            }
        }

        // find constraint points
        constraint.resize(3*numPrb);
        for(int i=0;i<numPrb;i++){
            constraint[3*i] = T(i,mesh.tetList[4*D.closestTet[i]],constraintWeight);
            constraint[3*i+1] = T(i,mesh.tetList[4*D.closestTet[i]+1],constraintWeight);
            constraint[3*i+2] = T(i,mesh.tetList[4*D.closestTet[i]+2],constraintWeight);
        }
        if( constraintMode == CONSTRAINT_NEIGHBOUR ){
            std::vector<double> probeConstraintRadius(numPrb);
            MArrayDataHandle handle = data.inputArrayValue(aProbeConstraintRadius);
            if(handle.elementCount() != numPrb){
                MGlobal::displayInfo("# of Probes and probeConstraintRadius are different");
                return MS::kFailure;
            }
            for(int i=0;i<numPrb;i++){
                handle.jumpToArrayElement(i);
                probeConstraintRadius[i]=handle.inputValue().asDouble();
            }
            double constraintRadius = data.inputValue( aConstraintRadius ).asDouble();
            for(int i=0;i<numPrb;i++){
                double r = constraintRadius * probeConstraintRadius[i];
                for(int j=0;j<numPts;j++){
                    if(D.distPts[i][j]<r){
                        constraint.push_back(T(i,j,constraintWeight * pow((r-D.distPts[i][j])/r,normExponent)));
                    }
                }
            }
        }
        int numConstraint=constraint.size();
        mesh.constraintWeight.resize(numConstraint);
        mesh.constraintVal.resize(numConstraint,numPrb);
        for(int cur=0;cur<numConstraint;cur++){
            mesh.constraintWeight[cur] = std::make_pair(constraint[cur].col(), constraint[cur].value());
        }
        //
        isError = mesh.ARAPprecompute();
        status = data.setClean(aARAP);
    }        // END of ARAP precomputation
    
    if(isError>0){
        return MS::kFailure;
    }
    
    // probe weight computation
    if(!data.isClean(aComputeWeight) || isNumProbeChanged){
        // load probe weights
        MArrayDataHandle handle = data.inputArrayValue(aProbeWeight);
        if(handle.elementCount() != numPrb){
            MGlobal::displayInfo("# of Probes and probeWeight are different");
            isError = ERROR_ATTR;
            return MS::kFailure;
        }
        double effectRadius = data.inputValue( aEffectRadius ).asDouble();
        std::vector<double> probeWeight(numPrb), probeRadius(numPrb);
        for(int i=0;i<numPrb;i++){
            handle.jumpToArrayElement(i);
            probeWeight[i] = handle.inputValue().asDouble();
            probeRadius[i] = probeWeight[i] * effectRadius;
        }
        wr.resize(mesh.numTet);ws.resize(mesh.numTet);wl.resize(mesh.numTet);
        for(int j=0;j<mesh.numTet;j++){
            wr[j].resize(numPrb); ws[j].resize(numPrb); wl[j].resize(numPrb);
        }
        short weightMode = data.inputValue( aWeightMode ).asShort();
        if (weightMode == WM_INV_DISTANCE){
            for(int j=0;j<mesh.numTet;j++){
                double sum=0.0;
                std::vector<double> idist(numPrb);
                for (int i = 0; i<numPrb; i++){
                    idist[i] = probeRadius[i] / pow(D.distTet[i][j], normExponent);
                    sum += idist[i];
                }
                for (int i = 0; i<numPrb; i++){
                    wr[j][i] = ws[j][i] = wl[j][i] = sum > 0 ? idist[i] / sum : 0.0;
                }
            }
        }
        else if (weightMode == WM_CUTOFF_DISTANCE){
            for(int j=0;j<mesh.numTet;j++){
                for (int i = 0; i<numPrb; i++){
                    wr[j][i] = ws[j][i] = wl[j][i] = (D.distTet[i][j] > probeRadius[i])
                    ? 0 : pow((probeRadius[i] - D.distTet[i][j]) / probeRadius[i], normExponent);
                }
            }
        }else if (weightMode == WM_DRAW){
            float val;
            MRampAttribute rWeightCurveR( thisNode, aWeightCurveR, &status );
            MRampAttribute rWeightCurveS( thisNode, aWeightCurveS, &status );
            MRampAttribute rWeightCurveL( thisNode, aWeightCurveL, &status );
            for(int j=0;j<mesh.numTet;j++){
                for (int i = 0; i < numPrb; i++){
                    rWeightCurveR.getValueAtPosition(D.distTet[i][j] / probeRadius[i], val);
                    wr[j][i] = val;
                    rWeightCurveS.getValueAtPosition(D.distTet[i][j] / probeRadius[i], val);
                    ws[j][i] = val;
                    rWeightCurveL.getValueAtPosition(D.distTet[i][j] / probeRadius[i], val);
                    wl[j][i] = val;
                }
            }
        }else if(weightMode & WM_HARMONIC){
            Laplacian harmonicWeighting;
            makeFaceTet(data, input, inputGeom, mIndex, pts, harmonicWeighting.tetList, harmonicWeighting.tetMatrix, harmonicWeighting.tetWeight);
            harmonicWeighting.numTet = (int)harmonicWeighting.tetList.size()/4;
            std::vector<T> weightConstraint(numPrb);
            // the vertex closest to the probe is given probeWeight
            for(int i=0;i<numPrb;i++){
                weightConstraint[i]=T(i,D.closestPts[i],probeWeight[i]);
            }
            // vertices within effectRadius are given probeWeight
            if( data.inputValue( aNeighbourWeighting ).asBool() ){
                for(int i=0;i<numPrb;i++){
                    for(int j=0;j<numPts;j++){
                        if(D.distPts[i][j]<probeRadius[i]){
                            weightConstraint.push_back(T(i,j,probeWeight[i]));
                        }
                    }
                }
            }
            // set boundary condition for weight computation
            int numConstraint=weightConstraint.size();
            harmonicWeighting.constraintWeight.resize(numConstraint);
            harmonicWeighting.constraintVal.resize(numConstraint,numPrb);
            harmonicWeighting.constraintVal.setZero();
            for(int i=0;i<numConstraint;i++){
                harmonicWeighting.constraintVal(i,weightConstraint[i].row())=weightConstraint[i].value();
                harmonicWeighting.constraintWeight[i] = std::make_pair(weightConstraint[i].col(), weightConstraint[i].value());
            }
            // clear tetWeight
            if(!areaWeighted){
                harmonicWeighting.tetWeight.clear();
                harmonicWeighting.tetWeight.resize(harmonicWeighting.numTet,1.0);
            }
            // solve the laplace equation
            if( weightMode == WM_HARMONIC_ARAP){
                harmonicWeighting.computeTetMatrixInverse();
                harmonicWeighting.dim = numPts + harmonicWeighting.numTet;
                isError = harmonicWeighting.ARAPprecompute();
            }else if(weightMode == WM_HARMONIC_COTAN){
                harmonicWeighting.dim = numPts;
                isError = harmonicWeighting.cotanPrecompute();
            }
            if(isError>0) return MS::kFailure;
            std::vector< std::vector<double> > w_tet(numPrb);
            harmonicWeighting.harmonicSolve();
            for(int i=0;i<numPrb;i++){
                makeTetWeightList(tetMode, mesh.tetList, faceList, edgeList, vertexList, harmonicWeighting.Sol.col(i), w_tet[i]);
                for(int j=0;j<mesh.numTet; j++){
                    wr[j][i] = ws[j][i] = wl[j][i] = w_tet[i][j];
                }
            }
        }
        // normalise weights
        short normaliseWeightMode = data.inputValue( aNormaliseWeight ).asShort();
        for(int j=0;j<mesh.numTet;j++){
            D.normaliseWeight(normaliseWeightMode, wr[j]);
            D.normaliseWeight(normaliseWeightMode, ws[j]);
            D.normaliseWeight(normaliseWeightMode, wl[j]);
        }
        status = data.setClean(aComputeWeight);
    } // END of weight computation


    // setting up transformation matrix
    B.rotationConsistency = data.inputValue( aRotationConsistency ).asBool();
    bool frechetSum = data.inputValue( aFrechetSum ).asBool();
    blendedSE.resize(mesh.numTet); blendedR.resize(mesh.numTet); blendedS.resize(mesh.numTet); blendedL.resize(mesh.numTet);A.resize(mesh.numTet);
    for(int i=0;i<numPrb;i++){
        B.Aff[i]=initMatrix[i].inverse()*matrix[i];
    }
    B.parametrise(blendMode);
    

// prepare transform matrix for each simplex
#pragma omp parallel for
	for (int j = 0; j < mesh.numTet; j++){
		// blend matrix
		if (blendMode == BM_SRL){
			blendedS[j] = expSym(blendMat(B.logS, ws[j]));
			Vector3d l = blendMat(B.L, wl[j]);
            blendedR[j] = frechetSum ? frechetSO(B.R, wr[j]) : expSO(blendMat(B.logR, wr[j]));
			A[j] = pad(blendedS[j]*blendedR[j], l);
		}
		else if (blendMode == BM_SSE){
			blendedS[j] = expSym(blendMat(B.logS, ws[j]));
            blendedSE[j] = expSE(blendMat(B.logSE, wr[j]));
			A[j] = pad(blendedS[j], Vector3d::Zero()) * blendedSE[j];
		}
		else if (blendMode == BM_LOG3){
			blendedR[j] = blendMat(B.logGL, wr[j]).exp();
			Vector3d l = blendMat(B.L, wl[j]);
			A[j] = pad(blendedR[j], l);
		}
		else if (blendMode == BM_LOG4){
			A[j] = blendMat(B.logAff, wr[j]).exp();
		}
		else if (blendMode == BM_SQL){
			Vector4d q = blendQuat(B.quat, wr[j]);
			Vector3d l = blendMat(B.L, wl[j]);
			blendedS[j] = blendMatLin(B.S, ws[j]);
			Quaternion<double> RQ(q);
			blendedR[j] = RQ.matrix().transpose();
			A[j] = pad(blendedS[j]*blendedR[j], l);
		}
		else if (blendMode == BM_AFF){
			A[j] = blendMatLin(B.Aff, wr[j]);
		}
	}

    // compute target vertices position
    tetEnergy.resize(mesh.numTet);
    
    // set constraint
    int numConstraints = constraint.size();
    mesh.constraintVal.resize(numConstraints,3);
    RowVector4d cv;
    for(int cur=0;cur<numConstraints;cur++){
        cv = pad(pts[constraint[cur].col()]) * B.Aff[constraint[cur].row()];
        mesh.constraintVal(cur,0) = cv[0];
        mesh.constraintVal(cur,1) = cv[1];
        mesh.constraintVal(cur,2) = cv[2];
    }

    // iterate to determine vertices position
    for(int k=0;k<numIter;k++){
        // solve ARAP
        mesh.ARAPSolve(A);
        // set new vertices position
        new_pts.resize(numPts);
        for(int i=0;i<numPts;i++){
            new_pts[i][0]=mesh.Sol(i,0);
            new_pts[i][1]=mesh.Sol(i,1);
            new_pts[i][2]=mesh.Sol(i,2);
        }
        // if iteration continues
        if(k+1<numIter || visualisationMode == VM_ENERGY){
            std::vector<double> dummy_weight;
            makeTetMatrix(tetMode, new_pts, mesh.tetList, faceList, edgeList, vertexList, Q, dummy_weight);
            Matrix3d S,R,newS,newR;
            if(blendMode == BM_AFF || blendMode == BM_LOG4 || blendMode == BM_LOG3){
                for(int i=0;i<mesh.numTet;i++){
                    polarHigham(A[i].block(0,0,3,3), blendedS[i], blendedR[i]);
                }
            }
            #pragma omp parallel for
            for(int i=0;i<mesh.numTet;i++){
                polarHigham((mesh.tetMatrixInverse[i]*Q[i]).block(0,0,3,3), newS, newR);
                tetEnergy[i] = (newS-blendedS[i]).squaredNorm();
                A[i].block(0,0,3,3) = blendedS[i]*newR;
//                polarHigham((A[i].transpose()*PI[i]*Q[i]).block(0,0,3,3), newS, newR);
//                A[i].block(0,0,3,3) *= newR;
            }
        }
    }
    for(int i=0;i<numPts;i++){
        Mpts[i].x=mesh.Sol(i,0);
        Mpts[i].y=mesh.Sol(i,1);
        Mpts[i].z=mesh.Sol(i,2);
    }
    if(worldMode){
        for(int i=0;i<numPts;i++)
            Mpts[i] *= localToWorldMatrix.inverse();
    }
    itGeo.setAllPositions(Mpts);
    
    // set vertex colour
    if(visualisationMode != VM_OFF){
        std::vector<double> ptsColour(numPts, 0.0);
        if(visualisationMode == VM_ENERGY){
            makePtsWeightList(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, tetEnergy, ptsColour);
            for(int i=0;i<numPts;i++){
                ptsColour[i] *= visualisationMultiplier;
            }
        }else if(visualisationMode == VM_STIFFNESS){
            makePtsWeightList(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, mesh.tetWeight, ptsColour);
            double maxval = *std::max_element(ptsColour.begin(), ptsColour.end());
            for(int i=0;i<numPts;i++){
                ptsColour[i] = 1.0 - ptsColour[i]/maxval;
            }
        }else if(visualisationMode == VM_CONSTRAINT){
            for(int i=0;i<constraint.size();i++){
                ptsColour[constraint[i].col()] += constraint[i].value();
            }
        }else if(visualisationMode == VM_EFFECT){
            std:vector<double> wsum(mesh.numTet);
            for(int j=0;j<mesh.numTet;j++){
                //wsum[j] = std::accumulate(wr[j].begin(), wr[j].end(), 0.0);
                wsum[j]= visualisationMultiplier * wr[j][numPrb-1];
            }
            makePtsWeightList(tetMode, numPts, mesh.tetList, faceList, edgeList, vertexList, wsum, ptsColour);
        }
        visualise(data, outputGeom, ptsColour);
    }
    
    return MS::kSuccess;
}
Exemple #20
0
MStatus snapDeformer::deform(MDataBlock &data, MItGeometry &iter, const MMatrix &mat, unsigned int multiIndex) {
	MStatus stat;


    //lets see if we need to do anything
	MDataHandle DataHandle = data.inputValue(envelope, &stat);
	float env = DataHandle.asFloat();
	if (env == 0)
		return stat;
    DataHandle = data.inputValue(weight, &stat);
	const float weight = DataHandle.asFloat();
    if (weight == 0)
		return stat;
    
    env = (env*weight);


	//space target
	DataHandle = data.inputValue(space, &stat);
    int SpaceInt = DataHandle.asInt();

    //space source
	DataHandle = data.inputValue(spaceSource, &stat);
    int SpaceSourceInt = DataHandle.asInt();

    //pointlist
    MArrayDataHandle pointArrayHandle = data.inputArrayValue(pointList);


	//snapMesh
	MFnMesh	SnapMesh;
	DataHandle = data.inputValue(snapMesh, &stat);
    if (!stat)
        return Err(stat,"Can't get mesh to snap to");
    MObject SnapMeshObj = DataHandle.asMesh();
    SnapMesh.setObject(SnapMeshObj);
    MPointArray snapPoints;
    if (SpaceSourceInt==0)
        SnapMesh.getPoints(snapPoints, MSpace::kWorld);
    else
        SnapMesh.getPoints(snapPoints, MSpace::kObject);
    


    iter.reset();
    for ( ; !iter.isDone(); iter.next()) 	{
        //check for painted weights
        float currEnv = env * weightValue(data, multiIndex, iter.index());

        //get point to snap to
        unsigned int index;
        stat = pointArrayHandle.jumpToElement(iter.index());
        if (!stat)
            index = 0;
        else {
            DataHandle = pointArrayHandle.outputValue();
            index = DataHandle.asInt();
        }

        if (index != -1) {
            //calc point location
            MPoint currPoint;
            if (snapPoints.length() > index)
                currPoint = snapPoints[index];

            if (SpaceInt == 0)
                currPoint *= mat.inverse();

            if (currEnv !=1)
            {
                MPoint p = (currPoint- iter.position());
                currPoint = iter.position() + (p*currEnv);
            }


            //set point location
            iter.setPosition(currPoint);
        }
            
            
    }

    return stat;
}
MStatus CageDeformerNode::deform( MDataBlock& data, MItGeometry& itGeo, const MMatrix &localToWorldMatrix, unsigned int mIndex )
{
    /// main
    MStatus status;
    MThreadUtils::syncNumOpenMPThreads();    // for OpenMP
    // load cage mesh and other attributes
    MObject oCageMesh = data.inputValue( aCageMesh ).asMesh();
    short blendMode = data.inputValue(aBlendMode).asShort();
	bool rotationCosistency = data.inputValue( aRotationConsistency ).asBool();
	bool frechetSum = data.inputValue( aFrechetSum ).asBool();
    short newConstraintMode = data.inputValue(aConstraintMode).asShort();
    double newConstraintWeight = data.inputValue( aConstraintWeight ).asDouble();
    if ( oCageMesh.isNull() || blendMode == 99)
        return MS::kSuccess;
    short newCageMode = data.inputValue(aCageMode).asShort();
    MFnMesh fnCageMesh( oCageMesh, &status );
    CHECK_MSTATUS_AND_RETURN_IT( status );
    MPointArray cagePoints;
    fnCageMesh.getPoints( cagePoints,  MSpace::kWorld );
    // save initial cage state
    if (initCagePoints.length() != cagePoints.length()){
        initCageMesh = oCageMesh;
        initCagePoints=cagePoints;
    }
    // when cage mode is changed
    if(newCageMode != cageMode || newConstraintMode != constraintMode || newConstraintWeight != constraintWeight)
    {
        cageMode = newCageMode;
        constraintMode = newConstraintMode;
        constraintWeight = newConstraintWeight;
	    std::vector<double> tetWeight;
        // read target mesh data
        MArrayDataHandle hInput = data.outputArrayValue( input, &status );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        status = hInput.jumpToElement( mIndex );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        MObject oInputGeom = hInput.outputValue().child( inputGeom ).asMesh();
        MFnMesh inputMesh(oInputGeom);
        inputMesh.getPoints( pts );
		numPts=pts.length();
        for(int j=0; j<numPts; j++ )
            pts[j] *= localToWorldMatrix;
        MIntArray count;
        inputMesh.getTriangles( count, meshTriangles );
		numTet=meshTriangles.length()/3;
		std::vector<Matrix4d> P(numTet);
        tetCenter.resize(numTet);
        tetMatrixC(pts, meshTriangles, P, tetCenter);
        PI.resize(numTet);
		for(int i=0;i<numTet;i++)
			PI[i] = P[i].inverse();
        // prepare cage tetrahedra
        MFnMesh fnInitCageMesh( initCageMesh, &status );
        if(cageMode == 10 || cageMode == 11)  // face mode
        {
			if(cageMode == 10){       // triangulate faces by MAYA standard
                MIntArray count;
                fnInitCageMesh.getTriangles( count, triangles );
                tetWeight.resize(triangles.length()/3, 1.0f);
			}else if(cageMode ==11){  // trianglate faces with more than 3 edges in a symmetric way
				triangles.clear();
				MItMeshPolygon iter(initCageMesh);
				MIntArray tmp;
                MVector normal;
				tetWeight.reserve(4*iter.count());
                unsigned int l;
				for(unsigned int i=0; ! iter.isDone(); i++){
					iter.getVertices(tmp);
					l=tmp.length();
					if(l==3){
						tetWeight.push_back(1.0);
						triangles.append(tmp[0]);
						triangles.append(tmp[1]);
						triangles.append(tmp[2]);
					}else{
						for(unsigned int j=0;j<l;j++){
                            tetWeight.push_back((l-2.0)/l);
							triangles.append(tmp[j]);
							triangles.append(tmp[(j+1) % l]);
							triangles.append(tmp[(j+2) % l]);
						}
					}
					iter.next();
				}
            }
            // face mode compute init matrix
            numPrb=triangles.length()/3;
            initMatrix.resize(numPrb);
            tetMatrix(initCagePoints, triangles, cageMode, initMatrix);
            // compute weight
            w.resize(numTet);
            std::vector< std::vector<double> > idist(numTet);
            for(int j=0;j<numTet;j++){
                idist[j].resize(numPrb);
                w[j].resize(numPrb);
                double sidist = 0.0;
                for(int i=0;i<numPrb;i++){
                    idist[j][i] = tetWeight[i]/distPtTri(tetCenter[j],initMatrix[i]);
                    sidist += idist[j][i];
                }
                assert(sidist>0.0f);
                for(int i=0;i<numPrb;i++)
                    w[j][i] = idist[j][i] /sidist;
            }// face mode end
        }else if(cageMode == 0 || cageMode == 1){   // vertex mode
            triangles.clear();
            std::vector<int> tetCount(initCagePoints.length());
            MItMeshVertex iter(initCageMesh);
            for(int j=0; ! iter.isDone(); j++){
                MIntArray v;
                iter.getConnectedVertices(v);     // at each vertex, construct tetrahedra from connected edges
                int l=v.length();
                if(l==3){
                    if(isDegenerate(initCagePoints[j],initCagePoints[v[0]],initCagePoints[v[1]],initCagePoints[v[2]]) != 0){
                        tetCount[j]++;
                        triangles.append(j);
                        triangles.append(v[0]);
                        triangles.append(v[1]);
                        triangles.append(v[2]);
                    }
                }else{
                    for(int k=0;k<l;k++){
                        if(isDegenerate(initCagePoints[j],initCagePoints[v[k]],initCagePoints[v[(k+1) % l]],initCagePoints[v[(k+2) % l]]) != 0){
                            tetCount[j]++;
                            triangles.append(j);
                            triangles.append(v[k]);
                            triangles.append(v[(k+1) % l]);
                            triangles.append(v[(k+2) % l]);
                        }
                    }
                }
                iter.next();
            }
            numPrb=triangles.length()/4;
            initMatrix.resize(numPrb);
            tetMatrix(initCagePoints, triangles, cageMode, initMatrix);
            // vertex mode compute weight
            w.resize(numTet);
            std::vector< std::vector<double> > idist(numTet);
            tetWeight.resize(numPrb);
            for(int i=0;i<numPrb;i++)
                tetWeight[i]=1.0/(double)tetCount[triangles[4*i]];
            for(int j=0;j<numTet;j++){
                idist[j].resize(numPrb);
                w[j].resize(numPrb);
                double sidist = 0.0;
                for(int i=0;i<numPrb;i++){
                    Vector3d c(initCagePoints[triangles[4*i]].x,initCagePoints[triangles[4*i]].y,initCagePoints[triangles[4*i]].z);
                    idist[j][i] = tetWeight[i] / ((tetCenter[j]-c).squaredNorm());
                    sidist += idist[j][i];
                }
                assert(sidist>0.0f);
                for(int i=0;i<numPrb;i++)
                    w[j][i] = idist[j][i] /sidist;
            }
        }else if(cageMode == 5 || cageMode == 6 ){ // vertex averaged normal mode
            triangles.clear();
            std::vector<int> tetCount(initCagePoints.length());
            MItMeshVertex iter(initCageMesh);
            for(int j=0; ! iter.isDone(); j++){
                MIntArray v;
                iter.getConnectedVertices(v);
                int l=v.length();
                for(int k=0;k<l;k++){
                    tetCount[j]++;
                    triangles.append(j);
                    triangles.append(v[k]);
                    triangles.append(v[(k+1) % l]);
                }
                iter.next();
            }
            numPrb=triangles.length()/3;
            initMatrix.resize(numPrb);
            tetMatrix(initCagePoints, triangles, cageMode, initMatrix);
            // vertex mode compute weight
            w.resize(numTet);
            std::vector< std::vector<double> > idist(numTet);
            tetWeight.resize(numPrb);
            for(int i=0;i<numPrb;i++)
                tetWeight[i]=1.0/(double)tetCount[triangles[3*i]];
            for(int j=0;j<numTet;j++){
                idist[j].resize(numPrb);
                w[j].resize(numPrb);
                double sidist = 0.0;
                for(int i=0;i<numPrb;i++){
                    Vector3d c(initCagePoints[triangles[3*i]].x,initCagePoints[triangles[3*i]].y,initCagePoints[triangles[3*i]].z);
                    idist[j][i] = tetWeight[i] / ((tetCenter[j]-c).squaredNorm());
                    sidist += idist[j][i];
                }
                assert(sidist>0.0f);
                for(int i=0;i<numPrb;i++)
                    w[j][i] = idist[j][i] /sidist;
            }
        }// end of cage setup
        
        // find constraint points
        if(constraintMode == 1){
            numConstraint = numPrb;
        }else{
            numConstraint = 1;    // at least one constraint is necessary to determine global translation
        }
        constraintTet.resize(numConstraint);
        constraintVector.resize(numConstraint);
        // for each cage tetrahedra, constraint the point on the mesh with largest weight
        for(int i=0;i<numConstraint;i++){
            constraintTet[i] = 0;
            for(int j=1;j<numTet;j++){
                if(w[j][i] > w[constraintTet[i]][i]){
                    constraintTet[i] = j;
                }
            }
            constraintVector[i] << tetCenter[constraintTet[i]](0), tetCenter[constraintTet[i]](1), tetCenter[constraintTet[i]](2), 1.0;
        }
        // precompute arap solver
        arapHI(PI, meshTriangles);
    }
    // compute deformation
    if( ! rotationCosistency || numPrb != prevNs.size()){        // clear previous rotation
        prevThetas.clear();
        prevThetas.resize(numPrb, 0.0);
        prevNs.clear();
        prevNs.resize(numPrb, Vector3d::Zero());
    }
    //  find affine transformations for tetrahedra
    std::vector<Matrix4d> cageMatrix(numPrb), SE(numPrb), logSE(numPrb),logAff(numPrb),aff(numPrb);
    std::vector<Matrix3d> logR(numPrb),R(numPrb),logS(numPrb),logGL(numPrb);
    std::vector<Vector3d> L(numPrb);
    std::vector<Vector4d> quat(numPrb);
    tetMatrix(cagePoints, triangles, cageMode, cageMatrix);
    for(int i=0; i<numPrb; i++)
        aff[i]=initMatrix[i].inverse()*cageMatrix[i];
    // compute parametrisation
    if(blendMode == 0 || blendMode == 1 || blendMode == 5)  // polarexp or quaternion
    {
        for(unsigned int i=0;i<numPrb;i++){
            parametriseGL(aff[i].block(0,0,3,3), logS[i] ,R[i]);
            L[i] = transPart(aff[i]);
            if(blendMode == 0){  // Rotational log
                logR[i]=logSOc(R[i], prevThetas[i], prevNs[i]);
            }else if(blendMode == 1){ // Eucledian log
                SE[i]=affine(R[i], L[i]);
                logSE[i]=logSEc(SE[i], prevThetas[i], prevNs[i]);
            }else if(blendMode == 5){ // quaternion
                Quaternion<double> Q(R[i].transpose());
                quat[i] << Q.x(), Q.y(), Q.z(), Q.w();
            }
        }
    }else if(blendMode == 2){    //logmatrix3
        for(unsigned int i=0;i<numPrb;i++){
            logGL[i] = aff[i].block(0,0,3,3).log();
            L[i] = transPart(aff[i]);
        }
    }else if(blendMode == 3){   // logmatrix4
        for(unsigned int i=0;i<numPrb;i++){
            logAff[i] = aff[i].log();
        }
    }
    // compute blended matrices
#pragma omp parallel for
    std::vector<Matrix4d> At(numTet);
    for(int j=0; j<numTet; j++ ){
        if(blendMode==0){
            Matrix3d RR=Matrix3d::Zero();
            Matrix3d SS=Matrix3d::Zero();
            Vector3d l=Vector3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                RR += w[j][i] * logR[i];
                SS += w[j][i] * logS[i];
                l += w[j][i] * L[i];
            }
            SS = expSym(SS);
            if(frechetSum){
                RR = frechetSO(R, w[j]);
            }else{
                RR = expSO(RR);
            }
            At[j] = affine(SS*RR, l);
        }else if(blendMode==1){    // rigid transformation
            Matrix4d EE=Matrix4d::Zero();
            Matrix3d SS=Matrix3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                EE +=  w[j][i] * logSE[i];
                SS +=  w[j][i] * logS[i];
            }
            if(frechetSum){
                EE = frechetSE(SE, w[j]);
            }else{
                EE = expSE(EE);
            }
            At[j] = affine(expSym(SS),Vector3d::Zero())*EE;
        }else if(blendMode == 2){    //logmatrix3
            Matrix3d G=Matrix3d::Zero();
            Vector3d l=Vector3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                G +=  w[j][i] * logGL[i];
                l += w[j][i] * L[i];
            }
            At[j] = affine(G.exp(), l);
        }else if(blendMode == 3){   // logmatrix4
            Matrix4d A=Matrix4d::Zero();
            for(unsigned int i=0; i<numPrb; i++)
                A +=  w[j][i] * logAff[i];
            At[j] = A.exp();
        }else if(blendMode == 5){ // quaternion
            Vector4d q=Vector4d::Zero();
            Matrix3d SS=Matrix3d::Zero();
            Vector3d l=Vector3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                q += w[j][i] * quat[i];
                SS += w[j][i] * logS[i];
                l += w[j][i] * L[i];
            }
            SS = expSym(SS);
            Quaternion<double> Q(q);
            Matrix3d RR = Q.matrix().transpose();
            At[j] = affine(SS*RR, l);
        }else if(blendMode==10){
            At[j] = Matrix4d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                At[j] += w[j][i] * aff[i];
            }
        }
    }
    
    // compute target vertices position
    MatrixXd G=MatrixXd::Zero(numTet+numPts,3);
    arapG(At, PI, meshTriangles, aff, G);
    MatrixXd Sol = solver.solve(G);
    for(unsigned int i=0;i<numPts;i++){
        pts[i].x=Sol(i,0);
        pts[i].y=Sol(i,1);
        pts[i].z=Sol(i,2);
        pts[i] *= localToWorldMatrix.inverse();
    }
    itGeo.setAllPositions(pts);
    return MS::kSuccess;
}
Exemple #22
0
MStatus puttyNode::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& worldMatrix, unsigned int multiIndex)
{
//	MGlobal::displayInfo("deform");
    MStatus status = MS::kSuccess;

    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // get inputs
    //
	
	// get the node ready flag
	MDataHandle dh = block.inputValue(aScriptSourced,&status);
	SYS_ERROR_CHECK(status, "Error getting aScriptSourced data handle\n");
	bool scriptSourced = dh.asBool();
	if (!scriptSourced)
		return MS::kSuccess;


	dh = block.inputValue(aNodeReady,&status);
	SYS_ERROR_CHECK(status, "Error getting node ready data handle\n");
	bool nodeReady = dh.asBool();

	// if it's not ready, don't do anything
	if (!nodeReady)
		return MS::kSuccess;

    dh = block.inputValue(aDefSpace,&status);
    SYS_ERROR_CHECK(status, "Error getting defSpace data handle\n");
    short defSpace = dh.asShort();
    
    dh = block.inputValue(aDefWeights,&status);
    SYS_ERROR_CHECK(status, "Error getting defWeights data handle\n");
    short defWeights = dh.asShort();
 
    dh = block.inputValue(aDefEnvelope,&status);
    SYS_ERROR_CHECK(status, "Error getting defEnvelope data handle\n");
    short defEnvelope = dh.asShort();
    

    
    // get the command
    dh = block.inputValue(aCmdBaseName,&status);
    SYS_ERROR_CHECK(status, "Error getting aCmdBaseName  handle\n");    
    MString script =  dh.asString(); 
        
 /*   if (script == "")
    {
        status = MS::kFailure;
        USER_ERROR_CHECK(status, "no script provided!\n");    
    }
   */ 
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // build mel cmd string
    //
    
    // check if it's a valid cmd
        
   
    // get the envelope
    //
    double env = 1;
    
    if (defEnvelope == MSD_ENVELOPE_AUTO)
    {
        dh = block.inputValue(envelope,&status);
    	SYS_ERROR_CHECK(status, "Error getting envelope data handle\n");	
	    env = double(dh.asFloat());	
        
        // early stop 'cause there is nothing more to do
        if (env == 0.0)
            return MS::kSuccess;
    }
    
    // get the points, transform them into the right space if needed
    //
    int count = iter.count();
    MVectorArray points(count);
    for ( ; !iter.isDone(); iter.next()) 
        points[iter.index()] = iter.position();
        
    if ( defSpace == MSD_SPACE_WORLD )
    {
        for (int i = 0;i<count;i++)
            points[i] = MPoint(points[i]) * worldMatrix;
    }
    
    
    // get the weights
    //
    MDoubleArray weights;
    if ( defWeights == MSD_WEIGHTS_AUTO)
    {
        weights.setLength(count);
        
        for (int i = 0;i<count;i++)
            weights[i]  = weightValue(block,multiIndex,i);
        
    }


    // get the object name and type
    // get the input geometry, traverse through the data handles    
    MArrayDataHandle adh = block.outputArrayValue( input, &status );
    SYS_ERROR_CHECK(status,"error getting input array data handle.\n");

    status = adh.jumpToElement( multiIndex );
    SYS_ERROR_CHECK(status, "input jumpToElement failed.\n");

    // compound data 
    MDataHandle cdh = adh.inputValue( &status );
    SYS_ERROR_CHECK(status, "error getting input inputValue\n");
   
    // input geometry child
    dh = cdh.child( inputGeom );
    MObject dInputGeometry = dh.data();
   
    // get the type      
    MString geometryType = dInputGeometry.apiTypeStr();

    // get the name    
//    MFnDagNode dagFn( dInputGeometry, &status);
//    SYS_ERROR_CHECK(status, "error converting geometry obj to dag node\n");
   
//    MString geometryName = dagFn.fullPathName(&status);
//    SYS_ERROR_CHECK(status, "error getting full path name \n");

//    MString geometryType = "";
//    MString geometryName = "";
    
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //  
    //  set the current values on the temp plugs for the script to be picked up
    //
    
    // the position
    MObject thisNode = thisMObject();
    
    MPlug currPlug(thisNode,aCurrPosition);
    MFnVectorArrayData vecD;
    MObject currObj = vecD.create(points,&status);
    currPlug.setValue(currObj);
    SYS_ERROR_CHECK(status, "error setting currPosPlug value\n");
    
    // the weights
    currPlug =MPlug(thisNode,aCurrWeight);
    MFnDoubleArrayData dblD;
    currObj = dblD.create(weights,&status);
    currPlug.setValue(currObj);
    SYS_ERROR_CHECK(status, "error setting currWeightsPlug value\n");
    
    // world matrix
    currPlug =MPlug(thisNode,aCurrWorldMatrix);
    MFnMatrixData matD;
    currObj = matD.create(worldMatrix,&status);
    currPlug.setValue(currObj);
    SYS_ERROR_CHECK(status, "error setting currWorldMatrixPlug value\n");

    // the multi index
    currPlug =MPlug(thisNode,aCurrMultiIndex);
    currPlug.setValue(int(multiIndex));
    SYS_ERROR_CHECK(status, "error setting currMultiIndexPlug value\n");
    
    // geometry name/type
//    currPlug =MPlug(thisNode,aCurrGeometryName);
//    currPlug.setValue(geometryName);
//    SYS_ERROR_CHECK(status, "error setting aCurrGeometryName value\n");

    currPlug =MPlug(thisNode,aCurrGeometryType);
    currPlug.setValue(geometryType);
    SYS_ERROR_CHECK(status, "error setting aCurrGeometryType value\n");

   
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // execute the mel script
    //
    MString melCmd = script+"(\"" +name()+"\","+count+")";
    
    MCommandResult melResult;
    status = MGlobal::executeCommand(melCmd,melResult);
	
	// if the command did not work, then try to resource the script
	// (might have been that we were in a fresh scene and nothing was ready yet
	if (status != MS::kSuccess)
	{
		dh = block.inputValue(aScript,&status);
	    SYS_ERROR_CHECK(status, "Error getting aCmdBaseName  handle\n");    
		MString scriptFile =  dh.asString(); 	

		// try to source the script
		MString cmd = "source \"" + scriptFile+"\"";
			
		MCommandResult melResult;
		status = MGlobal::executeCommand(cmd,melResult);
		// if successfull, retry the command 
		if (!status.error())
		{
			status = MGlobal::executeCommand(melCmd,melResult);
		}
	}

	USER_ERROR_CHECK(status, "Error executing mel command, please check the function you provided is valid, error free and has the appropriate parameters!");

    // check the result type
    if ((melResult.resultType()) != (MCommandResult::kDoubleArray))
    {
        USER_ERROR_CHECK(MS::kFailure, "result of mel command has wrong type, should be doubleArray (which will be interpreted as vectorArray)!");
    }
    
    // get the result as a double array
    MDoubleArray newP;  
    status = melResult.getResult(newP);
    USER_ERROR_CHECK(status, "Error getting result of mel command!");
    
    int newCount = newP.length()/3;
    // size check
    if (newCount != count)
    {
        USER_ERROR_CHECK(MS::kFailure, "the size of the result does not match the size of the input!");
    }

    // convert the double array into a vector array
    MPointArray newPoints(newCount);
    
    for(int i=0;i<newCount;i++)
        newPoints[i]=MPoint(newP[i*3],newP[i*3+1],newP[i*3+2]);
    
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // interprete and apply the result
    //


  
    // do the envelope and weights   
    if ((defEnvelope == MSD_ENVELOPE_AUTO)||((defWeights == MSD_WEIGHTS_AUTO)))
    {
        MDoubleArray envPP(count, env);
    
        if (defWeights == MSD_WEIGHTS_AUTO)
        { 
            for (int i = 0;i<count;i++)
                envPP[i] *= weights[i];
        }

        // linear interpolation between old and new points
        for (int i = 0;i<count;i++)
            newPoints[i] = (points[i] * (1-envPP[i])) + (newPoints[i] * envPP[i]);
    }


    // retransform the result if it was in world space
    if ( defSpace == MSD_SPACE_WORLD )
    {
        MMatrix worldMatrixInv = worldMatrix.inverse();
        
        for (int i = 0;i<count;i++)
            newPoints[i] *= worldMatrixInv;
    }
 
 
    // set the points    
    iter.reset();
  	for ( ; !iter.isDone(); iter.next()) 
     	iter.setPosition(newPoints[iter.index()]);    

    return status;
}
Exemple #23
0
void MG_poseReader::drawArrowMatrix(const int aimAxis,const double arrowSizeV,const MMatrix poseM ,const MMatrix readerM)
 {

	
	 MVector tipV,corner1V,corner2V,corner3V,corner4V;
	 MMatrix tipM,corner1M,corner2M,corner3M,corner4M,baseM;
	 baseM.setToIdentity();
	 baseM*=poseM;
	 baseM*=readerM.inverse();
	 switch ( aimAxis )
			{

				case 0:
					if (aimAxis==0)
					{
						
						tipV.x=1*arrowSizeV;
						tipV.y=0.0;
						tipV.z=0.0;
						tipM=fromVecToMatrix(tipV);
						tipM*=poseM;
						tipM*=readerM.inverse();

						corner1V.x=0.9*arrowSizeV;
						corner1V.y=0.05*arrowSizeV;
						corner1V.z=-0.05*arrowSizeV;
						corner1M=fromVecToMatrix(corner1V);
						corner1M*=poseM;
						corner1M*=readerM.inverse();

						

						corner2V.x=0.9*arrowSizeV;
						corner2V.y=0.05*arrowSizeV;
						corner2V.z=0.05*arrowSizeV;
						corner2M=fromVecToMatrix(corner2V);
						corner2M*=poseM;
						corner2M*=readerM.inverse();


						corner3V.x=0.9*arrowSizeV;
						corner3V.y=-0.05*arrowSizeV;
						corner3V.z=0.05*arrowSizeV;
						corner3M=fromVecToMatrix(corner3V);
						corner3M*=poseM;
						corner3M*=readerM.inverse();


						corner4V.x=0.9*arrowSizeV;
						corner4V.y=-0.05*arrowSizeV;
						corner4V.z=-0.05*arrowSizeV;
						corner4M=fromVecToMatrix(corner4V);
						corner4M*=poseM;
						corner4M*=readerM.inverse();

						
					}
				case 1:
					if (aimAxis==1)
					{
						tipV.y=1*arrowSizeV;
						tipV.x=0.0;
						tipV.z=0.0;
						tipM=fromVecToMatrix(tipV);
						tipM*=poseM;
						tipM*=readerM.inverse();

						corner1V.y=0.9*arrowSizeV;
						corner1V.x=0.05*arrowSizeV;
						corner1V.z=-0.05*arrowSizeV;
						corner1M=fromVecToMatrix(corner1V);
						corner1M*=poseM;
						
						corner1M*=readerM.inverse();

						

						corner2V.y=0.9*arrowSizeV;
						corner2V.x=0.05*arrowSizeV;
						corner2V.z=0.05*arrowSizeV;
						corner2M=fromVecToMatrix(corner2V);
						corner2M*=poseM;
						corner2M*=readerM.inverse();


						corner3V.y=0.9*arrowSizeV;
						corner3V.x=-0.05*arrowSizeV;
						corner3V.z=0.05*arrowSizeV;
						corner3M=fromVecToMatrix(corner3V);
						corner3M*=poseM;
						corner3M*=readerM.inverse();


						corner4V.y=0.9*arrowSizeV;
						corner4V.x=-0.05*arrowSizeV;
						corner4V.z=-0.05*arrowSizeV;
						corner4M=fromVecToMatrix(corner4V);
						corner4M*=poseM;
						corner4M*=readerM.inverse();

					}

				case 2:
					if (aimAxis==2)
					{
						tipV.z=1*arrowSizeV;
						tipV.x=0.0;
						tipV.y=0.0;
						tipM=fromVecToMatrix(tipV);
						tipM*=poseM;
						tipM*=readerM.inverse();

						corner1V.z=0.9*arrowSizeV;
						corner1V.x=0.05*arrowSizeV;
						corner1V.y=-0.05*arrowSizeV;
						corner1M=fromVecToMatrix(corner1V);
						corner1M*=poseM;
						
						corner1M*=readerM.inverse();

						

						corner2V.z=0.9*arrowSizeV;
						corner2V.x=0.05*arrowSizeV;
						corner2V.y=0.05*arrowSizeV;
						corner2M=fromVecToMatrix(corner2V);
						corner2M*=poseM;
						corner2M*=readerM.inverse();


						corner3V.z=0.9*arrowSizeV;
						corner3V.x=-0.05*arrowSizeV;
						corner3V.y=0.05*arrowSizeV;
						corner3M=fromVecToMatrix(corner3V);
						corner3M*=poseM;
						corner3M*=readerM.inverse();


						corner4V.z=0.9*arrowSizeV;
						corner4V.x=-0.05*arrowSizeV;
						corner4V.y=-0.05*arrowSizeV;
						corner4M=fromVecToMatrix(corner4V);
						corner4M*=poseM;
						corner4M*=readerM.inverse();

					}


			}

	glBegin(GL_LINES);
		
		glVertex3d(baseM[3][0],baseM[3][1],baseM[3][2]);
		glVertex3d(tipM[3][0],tipM[3][1],tipM[3][2]);


	glEnd();


	glBegin(GL_TRIANGLES);
		glVertex3d(corner1M[3][0],corner1M[3][1],corner1M[3][2]);
		glVertex3d(corner2M[3][0],corner2M[3][1],corner2M[3][2]);
		glVertex3d(tipM[3][0],tipM[3][1],tipM[3][2]);

	glEnd();


	glBegin(GL_TRIANGLES);
		glVertex3d(corner3M[3][0],corner3M[3][1],corner3M[3][2]);
		glVertex3d(corner2M[3][0],corner2M[3][1],corner2M[3][2]);
		glVertex3d(tipM[3][0],tipM[3][1],tipM[3][2]);

	glEnd();


	glBegin(GL_TRIANGLES);
		glVertex3d(corner3M[3][0],corner3M[3][1],corner3M[3][2]);
		glVertex3d(corner4M[3][0],corner4M[3][1],corner4M[3][2]);
		glVertex3d(tipM[3][0],tipM[3][1],tipM[3][2]);

	glEnd();


	glBegin(GL_TRIANGLES);
		glVertex3d(corner1M[3][0],corner1M[3][1],corner1M[3][2]);
		glVertex3d(corner4M[3][0],corner4M[3][1],corner4M[3][2]);
		glVertex3d(tipM[3][0],tipM[3][1],tipM[3][2]);

	glEnd();

	


 }
MStatus sgCurveEditBrush_context::editCurve( MDagPath dagPathCurve,
		int beforeX, int beforeY, int currentX, int currentY, float radius, 
		const MDoubleArray& dArrLength, MPointArray &points )
{
	MStatus status;

	if( radius < 0 ) return MS::kSuccess;

	MDagPath dagPathCam;
	M3dView view = M3dView::active3dView( &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	view.getCamera( dagPathCam );

	MPoint  camPos = dagPathCam.inclusiveMatrix()[3];
	MVector vCamUp  = dagPathCam.inclusiveMatrix()[1];
	vCamUp.normalize();

	radius *= .05;

	MPoint nearClipBefore;
	MPoint farClipBefore;
	view.viewToWorld( beforeX, beforeY, nearClipBefore, farClipBefore );

	MVector rayBefore  = nearClipBefore - camPos;
	rayBefore.normalize();
	rayBefore *= 20;
	MPoint  posBefore = rayBefore + camPos;

	MPoint nearClipCurrent;
	MPoint farClipCurrent;
	view.viewToWorld( currentX, currentY, nearClipCurrent, farClipCurrent );

	MVector rayCurrent = nearClipCurrent - camPos;
	rayCurrent.normalize();
	rayCurrent *= 20;
	MPoint  posCurrent = rayCurrent + camPos;

	MVector vMove = posCurrent - posBefore;

	MMatrix mtxCurve = dagPathCurve.inclusiveMatrix();
	MFnNurbsCurve fnCurve( dagPathCurve );

	fnCurve.getCVs( points );

	for( int i=0; i< points.length(); i++ )
	{
		points[i] *= mtxCurve;
	}

	for( int i=1; i< points.length(); i++ )
	{
		MPoint cuPoint = points[i];
		MVector vPoint = cuPoint - camPos;

		MVector projV = ( vPoint * rayBefore )/( pow( rayBefore.length(), 2 ) )* rayBefore;
		MVector vertical = vPoint - projV;
		
		float radiusForPoint = vertical.length() / projV.length();

		if( radius < radiusForPoint )
			continue;
		MPoint parentPoint = points[i-1];

		MVector vCurveDirection = cuPoint - parentPoint;
		double vDirLength = vCurveDirection.length();

		MVector vEditDirection = vCurveDirection + vMove/rayBefore.length()*projV.length();

		double dotEdit = vCurveDirection.normal() * vEditDirection.normal();
		if( dotEdit < 0 ) continue;
		vEditDirection = vEditDirection * dotEdit + vCurveDirection*( 1-dotEdit );

		MVector vEditLength = vEditDirection / vEditDirection.length() * vCurveDirection.length();

		MVector vEdit = (vEditLength - vCurveDirection) * pow((double)(1-radiusForPoint/radius), 1 );
		points[i] += vEdit;

		for( int j=i+1; j< points.length(); j++ )
		{
			MPoint beforePoint = points[j];
			MPoint pPoint = points[j-1];
			MPoint beforePPoint = pPoint - vEdit;

			MVector vBefore = points[j] - beforePPoint;
			MVector vAfter  = points[j] - pPoint;
			MVector vCurrent = vAfter.normal() * dArrLength[j];
			
			points[j] = vCurrent + pPoint;

			vEdit = points[j] - beforePoint;
		}
	}

	MMatrix invMtxCurve = mtxCurve.inverse();
	for( int i=0; i< points.length(); i++ )
	{
		points[i] *= invMtxCurve;
	}

	fnCurve.setCVs( points );
	fnCurve.updateCurve();

	return MS::kSuccess;
}
Exemple #25
0
//#include "d3dx10.h"
//#pragma comment(lib, "d3dx10.lib")
void skeleton::loadKeyframe(joint& j,int time,keyframeTranslation& translation,keyframeRotation& rotation,keyframeScale& scale)
{
	MVector position;

	int parentIdx = j.parentIndex;
int DEBUG_TIME = 7;
	MMatrix matrix;
	{
		matrix = j.jointDag.inclusiveMatrix();
		MFnIkJoint jn(j.jointDag);
		if(jn.name() == "L_toe2")
		{
			char str[256];
			sprintf(str,"%5.5f,%5.5f,%5.5f\n\n",matrix[3][0],matrix[3][1],matrix[3][2]);
			OutputDebugString(str);
		}
		if(time == DEBUG_TIME)
		{
			MFnIkJoint jn(j.jointDag);
			if(jn.name() == "L_knee")
			{
				char str[256];
				sprintf(str,"%5.5f,%5.5f,%5.5f,%5.5f\n%5.5f,%5.5f,%5.5f,%5.5f\n%5.5f,%5.5f,%5.5f,%5.5f\n%5.5f,%5.5f,%5.5f,%5.5f\n\n",
					matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
					matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
					matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
					matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);
				//sprintf(str,"%5.5f,%5.5f,%5.5f\n\n",matrix[3][0],matrix[3][1],matrix[3][2]);
				OutputDebugString(str);
//				breakable;
			}
		}

		//printMatrix(matrix);
		MMatrix worldMatrix = j.worldMatrix;
		//printMatrix(worldMatrix);

		MMatrix invWorldMatrix = worldMatrix.inverse();
		//matrix = invWorldMatrix * matrix;

		//MTransformationMatrix mtm = matrix;
		//double q_x,q_y,q_z,q_w;
		//mtm.getRotationQuaternion(q_x,q_y,q_z,q_w);
		//double s_xyz[3];
		//mtm.getScale(s_xyz,MSpace::kWorld);
		//MVector t_xyz = mtm.getTranslation(MSpace::kWorld);

		//D3DXMATRIX d3dM(matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
		//	matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
		//	matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
		//	matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);

		//D3DXVECTOR3 d3dS,d3dT;
		//D3DXQUATERNION d3dQ;
		//HRESULT hr = D3DXMatrixDecompose(&d3dS,&d3dQ,&d3dT,&d3dM);

		//MMatrix matrixT = worldMatrix * matrix;


		//float t[3],q[4],s[3];
		//extractTranMatrix(matrix,t,q,s);

		//Vector3 t1(t[0],t[1],t[2]);
		//Quaternion q1(q_x,q_y,q_z,q_w);//q[0],q[1],q[2],q[3]);
		//Vector3 s1(s[0],s[1],s[2]);
		//Matrix4 m;
		//m.transform(t1,s1,q1);

		//printMatrix(matrix);

		if(j.parentIndex >= 0)
		{
			MMatrix pMatrix = m_joints[parentIdx].jointDag.inclusiveMatrix();
			//printMatrix(pMatrix);
			MMatrix pWorldMatrix = m_joints[parentIdx].worldMatrix;
			//printMatrix(pWorldMatrix);
			MMatrix invpWorldMatrix = pWorldMatrix.inverse();
			//pMatrix = invpWorldMatrix * pMatrix;
			//printMatrix(pMatrix);

			MMatrix pInvMatrix = pMatrix.inverse();
			matrix = matrix * pInvMatrix;
			//printMatrix(matrix);
		}
	}
	if(time == DEBUG_TIME)
	{
		MFnIkJoint jn(j.jointDag);
		if(jn.name() == "L_knee")
		{
			char str[256];
			sprintf(str,"%5.5f,%5.5f,%5.5f,%5.5f\n%5.5f,%5.5f,%5.5f,%5.5f\n%5.5f,%5.5f,%5.5f,%5.5f\n%5.5f,%5.5f,%5.5f,%5.5f\n\n",
				matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
				matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
				matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
				matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);
			OutputDebugString(str);
//			breakable;
		}
	}
	{
		MMatrix matrix	= j.jointDag.inclusiveMatrix() * j.jointDag.exclusiveMatrixInverse();
		//printMatrix(matrix);
		MMatrix worldMatrix = j.localMatrix;
		//printMatrix(worldMatrix);

		MMatrix invWorldMatrix = worldMatrix.inverse();
		matrix = matrix * invWorldMatrix;
		if(j.parentIndex >= 0)
		{
			matrix = matrix * m_joints[j.parentIndex].localMatrix;
		}
		//printMatrix(matrix);
	}

	extractTranMatrix(matrix,translation.v,rotation.q,scale.v);
	if(time >= DEBUG_TIME)
	{
		MFnIkJoint jn(j.jointDag);
		if(jn.name() == "L_leg")
		{
			char str[256];
			sprintf(str,"%5.5f,%5.5f,%5.5f\n\n",translation.v[0],translation.v[1],translation.v[2]);
			OutputDebugString(str);
			sprintf(str,"%5.5f,%5.5f,%5.5f,%5.5f\n\n",rotation.q[0],rotation.q[1],rotation.q[2],rotation.q[3]);
			OutputDebugString(str);
			sprintf(str,"%5.5f,%5.5f,%5.5f\n\n",scale.v[0],scale.v[1],scale.v[2]);
			OutputDebugString(str);

			/*D3DXMATRIX d3dM(matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
				matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
				matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
				matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);

			D3DXVECTOR3 d3dS,d3dT;
			D3DXQUATERNION d3dQ;
			HRESULT hr = D3DXMatrixDecompose(&d3dS,&d3dQ,&d3dT,&d3dM);
			hr = hr;*/

			//rotation.q[0] = -rotation.q[0];
			//rotation.q[1] = -rotation.q[1];
			//rotation.q[2] = -rotation.q[2];
			//rotation.q[3] = -rotation.q[3];
		}
	}

	/*D3DXQUATERNION q1 = D3DXQUATERNION(0.14122,0.09228,-0.82219,0.54365);
	D3DXQUATERNION q2 = D3DXQUATERNION(-0.13556,-0.09684,0.85495,-0.49124);
	D3DXQUATERNION q3;
	D3DXQuaternionSlerp(&q3,&q1,&q2,1-0.63636363);*/
	translation.time = time;
	rotation.time = time;
	scale.time = time;
}
MStatus   clusterControledCurve::compute( const MPlug& plug, MDataBlock& data )
{
	//MFnDependencyNode thisNode( thisMObject() );
	//cout << thisNode.name() << ", start" << endl;

	MStatus status;

	MDataHandle hInputCurve = data.inputValue( aInputCurve, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputCurveMatrix = data.inputValue( aInputCurveMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hOutputCurve = data.outputValue( aOutputCurve, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MArrayDataHandle hArrBindPreMatrix = data.inputArrayValue( aBindPreMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MArrayDataHandle hArrMatrix = data.inputArrayValue( aMatrix, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MArrayDataHandle hArrWeightList = data.inputArrayValue( aWeightList, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MDataHandle hUpdate = data.inputValue( aUpdate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MObject oInputCurve = hInputCurve.asNurbsCurve();

	int bindPreMatrixLength = hArrBindPreMatrix.elementCount();
	int matrixLength = hArrMatrix.elementCount();

	MFnNurbsCurve fnInputCurve = oInputCurve;
	int numCVs = fnInputCurve.numCVs();
	int weightListLength = hArrWeightList.elementCount();

	if( weightListLength > 100 )
	{
		cout << "WeightList Count Error : " << weightListLength << endl;
		return MS::kFailure;
	}

	MPointArray inputCvPoints;
	MPointArray outputCvPoints;

	fnInputCurve.getCVs( inputCvPoints );
	outputCvPoints.setLength( numCVs );

	MMatrix matrix;
	MMatrix inputCurveMatrix = hInputCurveMatrix.asMatrix();
	MMatrix inputCurveMatrixInverse = inputCurveMatrix.inverse();

	if( requireUpdate )
	CHECK_MSTATUS_AND_RETURN_IT( updateBindPreMatrix( oInputCurve, inputCurveMatrixInverse,
				                                      hArrMatrix, hArrBindPreMatrix, hUpdate.asBool() ) );

	for( int i=0; i< numCVs; i++ )
	{
		inputCvPoints[i] *= inputCurveMatrix;
	}

	for( int i=0; i< numCVs; i++ )
	{
		outputCvPoints[i] = MPoint( 0,0,0 );
		double weight;

		for( int j=0; j< matrixLength; j++ )
		{
			weight = setWeights[i][j];

			hArrMatrix.jumpToElement( j );
			matrix = hArrMatrix.inputValue().asMatrix();
			outputCvPoints[i] += inputCvPoints[i]*bindPreMatrix[j]*matrix*weight;
		}
	}

	for( int i=0; i< numCVs; i++ )
	{
		outputCvPoints[i] *= inputCurveMatrixInverse;
	}

	MFnNurbsCurveData outputCurveData;
	MObject oOutputCurve = outputCurveData.create();

	fnInputCurve.copy( oInputCurve, oOutputCurve );

	MFnNurbsCurve fnOutputCurve( oOutputCurve, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	fnOutputCurve.setCVs( outputCvPoints );

	hOutputCurve.set( oOutputCurve );

	data.setClean( plug );

	//cout << thisNode.name() << ", end" << endl;

	return status;
}
Exemple #27
0
//
//      Deform computation
//
MStatus jhMeshBlur::deform( MDataBlock& block,MItGeometry& iter,const MMatrix& m,unsigned int multiIndex)
{
    MStatus returnStatus;

    // Envelope
    float envData = block.inputValue(envelope, &returnStatus).asFloat();
	CHECK_MSTATUS(returnStatus);

    if(envData == 0)
		return MS::kFailure;

    /*
     VARIABLES
     */
    //float factor = block.inputValue(aShapeFactor, &returnStatus).asFloat();
    float fStrength = block.inputValue(aStrength, &returnStatus).asFloat();
	CHECK_MSTATUS(returnStatus);
	
	if (fStrength == 0)
		return MS::kFailure;
	
    float fThreshold = block.inputValue(aTreshhold, &returnStatus).asFloat();
	CHECK_MSTATUS(returnStatus);
    float fW = 0.0f; // weight
    float fDistance;
    fStrength *= envData;

    double dKracht = block.inputValue(aInterpPower, &returnStatus).asDouble();
	CHECK_MSTATUS(returnStatus);
    double dDotProduct;  // Dotproduct of the point

    bool bTweakblur = block.inputValue(aTweakBlur, &returnStatus).asBool();
	CHECK_MSTATUS(returnStatus);
	
    bool bQuad = block.inputValue(aQuadInterp, &returnStatus).asBool();
	CHECK_MSTATUS(returnStatus);
	
	MTime inTime = block.inputValue(aTime).asTime();
    int nTijd = (int)inTime.as(MTime::kFilm);


    MFloatVectorArray currentNormals;   // normals of mesh
    MFnPointArrayData fnPoints;         // help converting to MPointArrays
    MFloatVector dirVector;             // direction vector of the point
    MFloatVector normal;                // normal of the point
    MPointArray savedPoints;            // save all point before edited
    MMatrix matInv = m.inverse();       // inversed matrix
    MPoint ptA;                         // current point (iter mesh)
    MPoint ptB;                         // previous point (iter mesh)
    MPoint ptC;                         // mesh before previous point (iter mesh)

    // get node, use node to get inputGeom, use inputGeom to get mesh data, use mesh data to get normal data
    MFnDependencyNode nodeFn(this->thisMObject());

    MPlug inGeomPlug(nodeFn.findPlug(this->inputGeom,true));
    MObject inputObject(inGeomPlug.asMObject());
    MFnMesh inMesh(inputObject);

    inMesh.getVertexNormals(true, currentNormals);

    // get the previous mesh data
    MPlug oldMeshPlug = nodeFn.findPlug(MString("oldMesh"));
    MPlug oldMeshPositionsAPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 0);
    MPlug oldMeshPositionsBPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 1);
    MPlug oldMeshPositionsCPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 2); // cache for tweak mode
    MPlug oldMeshPositionsDPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 3); // cache for tweak mode

    // convert to MPointArrays
    MObject objOldMeshA;
    MObject objOldMeshB;
    MObject objOldMeshC; // cache
    MObject objOldMeshD; // cache

    oldMeshPositionsAPlug.getValue(objOldMeshA);
    oldMeshPositionsBPlug.getValue(objOldMeshB);
    oldMeshPositionsCPlug.getValue(objOldMeshC); // cache
    oldMeshPositionsDPlug.getValue(objOldMeshD); // cache

    fnPoints.setObject(objOldMeshA);
    MPointArray oldMeshPositionsA = fnPoints.array();
    
    fnPoints.setObject(objOldMeshB);
    MPointArray oldMeshPositionsB = fnPoints.array();
    
    fnPoints.setObject(objOldMeshC);
    MPointArray oldMeshPositionsC = fnPoints.array(); // cache
    
    fnPoints.setObject(objOldMeshD);
    MPointArray oldMeshPositionsD = fnPoints.array(); // cache

    
    
    // If mesh position variables are empty,fill them with default values
    if(oldMeshPositionsA.length() == 0 || nTijd <= 1){
        iter.allPositions(oldMeshPositionsA);

        for(int i=0; i < oldMeshPositionsA.length(); i++)
        {
            // convert to world
            oldMeshPositionsA[i] = oldMeshPositionsA[i] * m;
        }
		
        oldMeshPositionsB.copy(oldMeshPositionsA);
        oldMeshPositionsC.copy(oldMeshPositionsA); // cache
        oldMeshPositionsD.copy(oldMeshPositionsA); // cache
    }
	
	// get back old date again
	if (bTweakblur == true) { // restore cache
		oldMeshPositionsA.copy(oldMeshPositionsC);
		oldMeshPositionsB.copy(oldMeshPositionsD);
	}
    
    
    iter.allPositions(savedPoints);
    for(int i=0; i < savedPoints.length(); i++)
    {
        // convert points to world points
        savedPoints[i] = savedPoints[i] * m;
    }

    // Actual Iteration through points
    for (; !iter.isDone(); iter.next()){
        // get current position
        ptA = iter.position();
        // get old positions
        ptB = oldMeshPositionsA[iter.index()] * matInv;
        ptC = oldMeshPositionsB[iter.index()] * matInv;

        fDistance = ptA.distanceTo(ptB);
        fW = weightValue(block,multiIndex,iter.index());


        if (fDistance * (fStrength*fW) < fThreshold && fThreshold > 0){
            iter.setPosition(ptA);
        } else {
            // aim/direction vector to calculate strength
            dirVector = (ptA - ptB); // (per punt)
            dirVector.normalize();

            normal = currentNormals[iter.index()];

            dDotProduct = normal.x * dirVector.x + normal.y * dirVector.y + normal.z * dirVector.z;

            
            if(bQuad == true){
                MVector vecA(((ptB - ptC) + (ptA - ptB)) / 2);
                vecA.normalize();

                MPoint hiddenPt(ptB + (vecA * fDistance) * dKracht);
                ptA = quadInterpBetween(ptB, hiddenPt, ptA, (1 - fStrength * fW) + (linearInterp(dDotProduct, -1, 1) * (fStrength * fW) ) );
            } else {
                MPoint halfway = (ptA - ptB) * 0.5;
                MPoint offset = halfway * dDotProduct * (fStrength*fW);
                ptA = ptA - ((halfway * (fStrength*fW)) - offset); // + (offset * strength);
            }
            // set new value

            iter.setPosition(ptA);
        }
    }
    if(bTweakblur == false){
        oldMeshPositionsD.copy(oldMeshPositionsB);
        oldMeshPositionsC.copy(oldMeshPositionsA);
        oldMeshPositionsB.copy(oldMeshPositionsA);
        oldMeshPositionsA.copy(savedPoints);

        // Save back to plugs
        objOldMeshA = fnPoints.create(oldMeshPositionsA);
        objOldMeshB = fnPoints.create(oldMeshPositionsB);
        objOldMeshC = fnPoints.create(oldMeshPositionsC);
        objOldMeshD = fnPoints.create(oldMeshPositionsD);
		
        oldMeshPositionsAPlug.setValue(objOldMeshA);
        oldMeshPositionsBPlug.setValue(objOldMeshB);
        oldMeshPositionsCPlug.setValue(objOldMeshC);
        oldMeshPositionsDPlug.setValue(objOldMeshD);
    }
    
    return returnStatus;
}
	bool gpuCacheIsectUtil::getClosestPointOnTri(const MPoint &toThisPoint, const MPoint &pt1, const MPoint &pt2, const MPoint &pt3, MPoint &theClosestPoint, double &currDist) 
	{
		double		sum, a, b, c, len, dist;
		MMatrix mat;
		mat.setToIdentity();
		mat[2][0] = mat[2][1] = mat[2][2] = 1.;

		MVector v = toThisPoint - pt1;
		MVector v12 = pt2 - pt1;
		MVector v13 = pt3 - pt1;
		MVector norm = v12 ^ v13;
		len = norm * norm;
		if (len < 1.175494351e-38F) return false;
		len = ( norm * v ) / len;

		MPoint pnt = toThisPoint - len * norm;

		// Do a quick test first
		if (pnt.distanceTo(toThisPoint) >= currDist)
			return false;

		int i, j;				// Find best plane to project to
		if (fabs(norm[0]) > fabs(norm[1]))
		{
			if (fabs(norm[0]) > fabs(norm[2]))
			{
				i = 1; j = 2;
			}
			else
			{
				i = 0; j = 1;
			}
		}
		else
		{
			if (fabs(norm[1]) > fabs(norm[2]))
			{
				i = 0; j = 2;
				// i = 2; j = 0;
			}
			else
			{
				i = 0; j = 1;
			}
		}

		mat[0][0] = pt1[i]; mat[0][1] = pt2[i]; mat[0][2] = pt3[i]; 
		mat[1][0] = pt1[j]; mat[1][1] = pt2[j]; mat[1][2] = pt3[j]; 

		MMatrix	matInv = mat.inverse();
		MPoint abc(pnt[i], pnt[j], 1, 0);

		abc = matInv * abc;
		// Now abc is the barycentric coordinates of pnt
		// clip to inside triangle

		if (abc[0]<0) { // a < 0
			if (abc[1]<0) { // b < 0
				a = b = 0;
				c = 1;
			} else if (abc[2]<0) { // c < 0
				a = c = 0;
				b = 1;
			} else {
				a = 0;
				// c = BP dot BC / BC square;
				MVector v23 = pt3 - pt2; // BC
				MVector vp =  toThisPoint - pt2;  // BP

				c = ( vp * v23 ) / ( v23[0]*v23[0] + v23[1]*v23[1] + v23[2]*v23[2] );
				if (c<0) c = 0; else if (c>1) c = 1;
				b = 1 - c;
			}
		} else if (abc[1]<0) { // b < 0
			if (abc[2]<0) { // c < 0
				b = c = 0;
				a = 1;
				//} else if (abc[0]<0) { // a < 0
				//	b = a = 0;	// commented-code for optimization
				//	c = 1;		// leaving it in for readability (cyclic variations)
			} else {
				b = 0;
				// a = CP dot CA / CA square;
				MVector v31 = pt1 - pt3; // CA
				MVector vp =  toThisPoint - pt3;  // CP

				a = ( vp * v31 ) / ( v31[0]*v31[0] + v31[1]*v31[1] +v31[2]*v31[2] );
				if (a<0) a = 0; else if (a>1) a = 1;
				c = 1 - a;
			} 
		} else if (abc[2]<0) { // c < 0
			//if (abc[1]<0) { // b < 0
			//	c = b = 0;
			//	a = 1;
			//} else if (abc[0]<0) { // a < 0
			//	c = a = 0;
			//	b = 1;	// commented-code for optimization
			//} else {	// leaving it in for readability (cyclic variations)
			c = 0;
			// b = AP dot AB / AB square;
			//DIFF(v23, pt3, pt2); // AB
			MVector vp =  toThisPoint - pt1;  // AP

			b = ( vp * v12 ) / ( v12[0]*v12[0] + v12[1]*v12[1] + v12[2]*v12[2] );
			if (b<0) b = 0; else if (b>1) b = 1;
			a = 1 - b;
			//}
		} else {
			if (abc[0]>0) a = abc[0]; else a = 0;
			if (abc[1]>0) b = abc[1]; else b = 0;
			if (abc[2]>0) c = abc[2]; else c = 0;
		}
		sum = a+b+c;
		a /= sum ; b /= sum ; c /= sum ; 
		pnt = a * pt1 + b * pt2 + c * pt3;
		dist = pnt.distanceTo(toThisPoint);
		if ( dist < currDist)
		{			
			// Now it's really closer, keep it
			currDist = dist;
			theClosestPoint = pnt;
			return true;
		}
		return false;
	}
Exemple #29
0
// COMPUTE ======================================
MStatus gear_slideCurve2::deform( MDataBlock& data, MItGeometry& iter, const MMatrix &mat, unsigned int mIndex )
{
    MStatus returnStatus;
	
    // Inputs ---------------------------------------------------------
    // Input NurbsCurve
	// Curve
	MFnNurbsCurve crv( data.inputValue( master_crv ).asNurbsCurve() );
    MMatrix m = data.inputValue(master_mat).asMatrix();
        
    // Input Sliders
    double in_sl = (double)data.inputValue(slave_length).asFloat();
    double in_ml = (double)data.inputValue(master_length).asFloat();
    double in_position = (double)data.inputValue(position).asFloat();
    double in_maxstretch = (double)data.inputValue(maxstretch).asFloat();
	double in_maxsquash = (double)data.inputValue(maxsquash).asFloat();
    double in_softness = (double)data.inputValue(softness).asFloat();
	
    // Init -----------------------------------------------------------
    double mstCrvLength = crv.length();

    int slvPointCount = iter.exactCount(); // Can we use .count() ? 
    int mstPointCount = crv.numCVs();
	
    // Stretch --------------------------------------------------------
	double expo = 1;
    if ((mstCrvLength > in_ml) && (in_maxstretch > 1)){
        if (in_softness != 0){
            double stretch = (mstCrvLength - in_ml) / (in_sl * in_maxstretch);
            expo = 1 - exp(-(stretch) / in_softness);
		}

        double ext = min(in_sl * (in_maxstretch - 1) * expo, mstCrvLength - in_ml);

        in_sl += ext;
	}
    else if ((mstCrvLength < in_ml) && (in_maxsquash < 1)){
        if (in_softness != 0){
            double squash = (in_ml - mstCrvLength) / (in_sl * in_maxsquash);
            expo = 1 - exp(-(squash) / in_softness);
		}

        double ext = min(in_sl * (1 - in_maxsquash) * expo, in_ml - mstCrvLength);

        in_sl -= ext;
	}
		
    // Position --------------------------------------------------------
    double size = in_sl / mstCrvLength;
    double sizeLeft = 1 - size;

    double start = in_position * sizeLeft;
    double end = start + size;

	double tStart, tEnd;
	crv.getKnotDomain(tStart, tEnd);
	
    // Process --------------------------------------------------------
    double step = (end - start) / (slvPointCount - 1.0);
    MPoint pt;
	MVector tan;
    while (! iter.isDone()){
        double perc = start + (iter.index() * step);

        double u = crv.findParamFromLength(perc * mstCrvLength);

        if ((0 <= perc) && (perc <= 1))
            crv.getPointAtParam(u, pt, MSpace::kWorld);
        else{
			double overPerc;
            if (perc < 0){
                overPerc = perc;
                crv.getPointAtParam(0, pt, MSpace::kWorld);
                tan = crv.tangent(0);
			}
            else{
                overPerc = perc - 1;
                crv.getPointAtParam(mstPointCount-3.0, pt, MSpace::kWorld);
                tan = crv.tangent(mstPointCount-3.0);

            tan.normalize();
            tan *= mstCrvLength * overPerc;

            pt += tan;
			}
		}

        pt *= mat.inverse();
        pt *= m;
        iter.setPosition(pt);
        iter.next();
	}
 
    return MS::kSuccess;
}
Exemple #30
0
MStatus dgTransform::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MDataHandle hTranslate = data.inputValue( aTranslate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hRotate    = data.inputValue( aRotate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hScale     = data.inputValue( aScale, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hShear     = data.inputValue( aShear, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hJointOrient     = data.inputValue( aJointOrient, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MDataHandle hInputTranslate = data.inputValue( aInputTranslate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputRotate    = data.inputValue( aInputRotate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputScale     = data.inputValue( aInputScale, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputShear     = data.inputValue( aInputShear, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );


	MPxTransformationMatrix inputMpxTrMtx;
	MEulerRotation inputEulerRot( hInputRotate.asVector() );

	inputMpxTrMtx.translateTo( hInputTranslate.asVector() );
	inputMpxTrMtx.rotateTo( inputEulerRot );
	inputMpxTrMtx.scaleTo( hInputScale.asVector() );
	inputMpxTrMtx.shearTo( hInputShear.asVector() );


	MMatrix parentMatrix = inputMpxTrMtx.asMatrix();


	MPxTransformationMatrix mpxTrMtx;
	MEulerRotation eulerRot( hRotate.asVector() );
	MEulerRotation joEulerRot( hJointOrient.asVector() );

	mpxTrMtx.translateTo( hTranslate.asVector() );
	mpxTrMtx.rotateTo( eulerRot );
	mpxTrMtx.rotateBy( joEulerRot );
	mpxTrMtx.scaleTo( hScale.asVector() );
	mpxTrMtx.shearTo( hShear.asVector() );

	if( plug == aMatrix )
	{
		//cout <<"matrix"<<endl;
		MDataHandle hMatrix = data.outputValue( aMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hMatrix.setMMatrix( mpxTrMtx.asMatrix() );
	}

	if( plug == aInverseMatrix )
	{
		//cout <<"inverseMatrix"<<endl;
		MDataHandle hInverseMatrix = data.outputValue( aInverseMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hInverseMatrix.setMMatrix( mpxTrMtx.asMatrix().inverse() );
	}

	if( plug == aWorldMatrix || plug == aWorldInverseMatrix )
	{
		MMatrix worldMatrix = mpxTrMtx.asMatrix()*parentMatrix;
		if( plug == aWorldMatrix )
		{
			//cout <<"worldMatrix"<<endl;
			MDataHandle hWorldMatrix = data.outputValue( aWorldMatrix, &status );
			CHECK_MSTATUS_AND_RETURN_IT( status );
			hWorldMatrix.setMMatrix( worldMatrix );
		}

		if( plug == aWorldInverseMatrix )
		{
			//cout <<"worldInverseMatrix"<<endl;
			MDataHandle hWorldInverseMatrix = data.outputValue( aWorldInverseMatrix, &status );
			CHECK_MSTATUS_AND_RETURN_IT( status );
			hWorldInverseMatrix.setMMatrix( worldMatrix.inverse() );
		}
	}

	if( plug == aParentMatrix )
	{
		//cout <<"parentMatrix"<<endl;
		MDataHandle hParentMatrix = data.outputValue( aParentMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hParentMatrix.setMMatrix( parentMatrix );
	}

	if( plug == aParentInverseMatrix )
	{
		//cout <<"parentInverseMatrix"<<endl;
		MDataHandle hParentInverseMatrix = data.outputValue( aParentInverseMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hParentInverseMatrix.setMMatrix( parentMatrix.inverse() );
	}

	data.setClean( plug );

	return status;
}