Beispiel #1
0
MMatrix MotionSyn::syc()
{
	int subject =0;

	MMatrix stylemat(1,mFactors[2]->sizeCol());
	stylemat.copyRowRow(0,*mFactors[2],0);
	
	stylemat.scale(0.5);
	stylemat.axpyRowRow(0,*mFactors[2],1,0.5);
	std::cout << stylemat << std::endl;
	assert(mFactors.size() == 3);
	//assert(subject < mFactors[1]->sizeRow() && style < mFactors[2]->sizeRow());

	MMatrix mat(1,mFactors[1]->sizeCol() * mFactors[2]->sizeCol());

	for(size_t t = 0; t < mFactors[1]->sizeCol(); t++)
	{
		for(size_t k = 0; k < mFactors[2]->sizeCol(); k++)
		{
			double val = mFactors[1]->get(subject,t) * stylemat.get(0,k);
			mat.assign(val,t * stylemat.sizeCol() + k);
		}
	}

	MMatrix val = mGPM->predict(mat);
	double step  = val.get(0);
	int length = int(2*3.141592653589/step);

	std::vector<MMatrix> X(3);
	X[0].resize(length,2);
	X[1].resize(length, mFactors[1]->sizeCol());
	X[2].resize(length, mFactors[2]->sizeCol());

	for(int i = 0; i < length; i++)
	{
		X[0].assign(cos(double(i * step)), i, 0);
		X[0].assign(sin(double(i * step)), i, 1);
   		X[1].copyRowRow(i, *mFactors[1], subject);
		X[2].copyRowRow(i, stylemat, 0);
	}

	return meanPrediction(X,CVector3D<double>(0,mInitY.get(subject,1),0));
}
    //---------------------------------------------------
    // 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;
    }
Beispiel #3
0
void getUVFromConnectedTexturePlacementNode(MObject fileTextureNode, float inU, float inV, float& outU, float& outV)
{
	MObject texPlaceObj = getConnectedInNode(fileTextureNode, "uvCoord");
	outU = inU;
	outV = outV;
	if( texPlaceObj == MObject::kNullObj )
		return;

	double offsetU = 0.0;
	double offsetV = 0.0;

	MFnDependencyNode texPlaceNode(texPlaceObj);
	getDouble(MString("offsetU"), texPlaceNode, offsetU);
	getDouble(MString("offsetV"), texPlaceNode, offsetV);
	float repeatU = 1.0f, repeatV = 1.0f, rotateUV = 0.0f;
	getFloat("repeatU",  texPlaceNode, repeatU);
	getFloat("repeatV",  texPlaceNode, repeatV);
	getFloat("rotateUV",  texPlaceNode, rotateUV);

	MMatrix rotationMatrix;
	rotationMatrix.setToIdentity();
	rotationMatrix[0][0] =  cos(rotateUV) * repeatU;
	rotationMatrix[1][0] = -sin(rotateUV) * repeatU;
	rotationMatrix[0][1] =  sin(rotateUV) * repeatV;
	rotationMatrix[1][1] =  cos(rotateUV) * repeatV;

	MVector uv(inU - 0.5, inV - 0.5, 0.0);
	uv = uv * rotationMatrix;
	uv.x += 0.5;
	uv.y += 0.5;

	uv.x *= repeatU;
	uv.y *= repeatV;

	uv.x += offsetU;
	uv.y += offsetV;

	outU = uv.x;
	outV = uv.y;
}
Beispiel #4
0
void FujiRenderer::setTransform(mtfu_MayaObject *obj)
{
	if( obj->objectID == SI_BADID)
	{
		logger.error(MString("Object ") + obj->shortName + " has bad ID");
		return;
	}


	MMatrix rotMatrix;
	rotMatrix.setToIdentity();

	if( obj->mobject.hasFn(MFn::kAreaLight))
	{
		MTransformationMatrix tm(rotMatrix);
		double areaScale[3] = {2,2,2};
		tm.setScale(areaScale, MSpace::kWorld);
		MEulerRotation e(-90.0, 0.0, 0.0);
		tm.rotateBy(e, MSpace::kWorld);
		rotMatrix = tm.asMatrix();
	}
	
	MMatrix transformMatrix = rotMatrix * obj->dagPath.inclusiveMatrix();
	MTransformationMatrix objTMatrix(transformMatrix);
	double rot[3];
	double scale[3];

	MTransformationMatrix::RotationOrder rotOrder =  MTransformationMatrix::kXYZ;
	objTMatrix.getRotation(rot, rotOrder, MSpace::kWorld);
	MVector pos = objTMatrix.getTranslation(MSpace::kWorld);
	objTMatrix.getScale(scale, MSpace::kWorld);
	SiSetProperty3(obj->objectID, "translate", pos[0], pos[1], pos[2]);
	SiSetProperty3(obj->objectID, "rotate", RadToDeg(rot[0]), RadToDeg(rot[1]), RadToDeg(rot[2]));
	SiSetProperty3(obj->objectID, "scale", scale[0], scale[1], scale[2]);

	//logger.debug(MString("SetProperty3 ") + obj->shortName + " translate " + pos[0] + " " + pos[1] + " " + pos[2]);
	//logger.debug(MString("SetProperty3 ") + obj->shortName + " rotate " + RadToDeg(rot[0]) + " " + RadToDeg(rot[1]) + " " + RadToDeg(rot[2]));

}
Beispiel #5
0
void CylinderMesh::transform(MPointArray& points, MVectorArray& normals)
{
    MVector forward = mEnd - mStart;
    double s = forward.length();
    forward.normalize();

    MVector left = MVector(0,0,1)^forward;
    MVector up;
    if (left.length() < 0.0001)
    {
        up = forward^MVector(0,1,0);
        left = up^forward;
    }
    else
    {
        up = forward^left;
    }

    MMatrix mat;
    mat[0][0] = forward[0]; mat[0][1] = left[0]; mat[0][2] = up[0]; mat[0][3] = 0;
    mat[1][0] = forward[1];   mat[1][1] = left[1]; mat[1][2] = up[1]; mat[1][3] = 0;
    mat[2][0] = forward[2];   mat[2][1] = left[2]; mat[2][2] = up[2]; mat[2][3] = 0;
    mat[3][0] = 0;            mat[3][1] = 0;       mat[3][2] = 0;     mat[3][3] = 1;
    mat = mat.transpose();

    for (int i = 0; i < gPoints.length(); i++)
    {
        MPoint p = gPoints[i];
        p.x = p.x * s; // scale
        p = p * mat + mStart; // transform
        points.append(p);

        MVector n = gNormals[i] * mat;
        normals.append(n);
    }
}
Beispiel #6
0
void Kernel::computeKernel(MMatrix &K, const MMatrix &X, const MMatrix &X2) const
{
	assert(K.rowsMatch(X) && K.sizeCol() == X2.sizeRow());
 	
	for(size_t i = 0; i < K.sizeRow(); i++)
	{
		for(size_t j = 0; j < K.sizeCol(); j++)
		{
			K.assign(computeElement(X, i, X2, j), i, j);
		}
	}
}
Beispiel #7
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;
}
Beispiel #8
0
void Kernel::computeKernel(MMatrix &K, const MMatrix &X) const
{
	assert(K.rowsMatch(X) && K.isSquare());

	for(size_t i = 0; i < K.sizeRow(); i++)
	{
		for(size_t j = 0; j < i; j++)
		{
			double k = computeElement(X, i, X, j);
	 		K.assign(k,i,j);
			K.assign(k,j,i);
		}
		K.assign(computeDiagElement(X,i), i, i);
	}
	
}
Beispiel #9
0
void MotionSyn::toCircle(MMatrix & mat) const
{
	for (size_t i = 1; i < mSegments.size(); i++)
	{
		double theta = mFactors[0]->get(i-1, 0);
		double delta = mFactors[0]->get(i-1, 1);

		for (size_t j = mSegments[i-1]; j < mSegments[i]; j++)
		{
			double cosTheta = cos(theta + (j - mSegments[i-1]) * delta);
			double sinTheta = sin(theta + (j - mSegments[i-1]) * delta);

			mat.assign(cosTheta, j, 0);
			mat.assign(sinTheta, j, 1);

			//precompute for saving time
			//mGradTs[0]->assign(-sinTheta, j, 0);
			//mGradTs[0]->assign( cosTheta, j, 1);
			//mGradTs[1]->assign(-sinTheta*(j - mSegments[i-1]), j, 0);
			//mGradTs[1]->assign( cosTheta*(j - mSegments[i-1]), j, 1);
		}
	}
}
MStatus geometrySurfaceConstraint::compute( const MPlug& plug, MDataBlock& block )
{	
	MStatus returnStatus;
 
    if(plug == constraintTranslateX || plug == constraintTranslateY || plug == constraintTranslateZ) {
        if(!m_isInitd) {
// read rest position
            MDataHandle htgo = block.inputValue(targetRestP);
            double3 & tgo = htgo.asDouble3();
            MGlobal::displayInfo(MString("target rest p ")+tgo[0]+" "+tgo[1]+" "+tgo[2]);
            m_restPos = MPoint(tgo[0],tgo[1],tgo[2]);
			m_isInitd = true;
		}
		
		MArrayDataHandle targetArray = block.inputArrayValue( compoundTarget );
		const unsigned int targetArrayCount = targetArray.elementCount();
        MMatrix tm;
        tm.setToIdentity();
        unsigned int i;
		for ( i = 0; i < targetArrayCount; i++ ) {
            MDataHandle targetElement = targetArray.inputValue(&returnStatus);
            if(!returnStatus) {
                MGlobal::displayInfo("failed to get input value target element");
            }
            MDataHandle htm = targetElement.child(targetTransform);
            MFnMatrixData ftm(htm.data(), &returnStatus);
            if(!returnStatus) {
                MGlobal::displayInfo("failed to get matrix data");
            }
            tm = ftm.matrix();
            targetArray.next();
        }
		
		MDataHandle hparentInvMat = block.inputValue(constraintParentInverseMatrix);
		MMatrix parentInvMat = hparentInvMat.asMatrix();

// world position
        MPoint curPos(tm(3,0), tm(3,1), tm(3,2));
// offset in local space
		m_offsetToRest = m_restPos - curPos;
// object position in world space
		MPoint localP = m_offsetToRest * tm + curPos;
// in local space
		localP *= parentInvMat;

        MDataHandle hout;
        if(plug == constraintTranslateX) {
            hout = block.outputValue(constraintTranslateX);
			hout.set(localP.x);
        }
        else if(plug == constraintTranslateY) {
            hout = block.outputValue(constraintTranslateY);
			hout.set(localP.y);
        }
        else if(plug == constraintTranslateZ) {
            hout = block.outputValue(constraintTranslateZ);
			hout.set(localP.z);
        }
		
		//MPlug pgTx(thisMObject(), constraintTargetX);
		//pgTx.setValue(m_lastPos.x);
		//MPlug pgTy(thisMObject(), constraintTargetY);
		//pgTy.setValue(m_lastPos.y);
		//MPlug pgTz(thisMObject(), constraintTargetZ);
		//pgTz.setValue(m_lastPos.z);
		
		MPlug pgOx(thisMObject(), constraintObjectX);
		pgOx.setValue(m_offsetToRest.x);
		MPlug pgOy(thisMObject(), constraintObjectY);
		pgOy.setValue(m_offsetToRest.y);
		MPlug pgOz(thisMObject(), constraintObjectZ);
		pgOz.setValue(m_offsetToRest.z);
        
       // MFnNumericData nd;
		//MObject offsetData = nd.create( MFnNumericData::k3Double);
        //nd.setData3Double(m_lastPos.x, m_lastPos.y, m_lastPos.z);
        //MPlug pgTgo(thisMObject(), targetOffset);
        //pgTgo.setValue(offsetData); 
    }
	else
		return MS::kUnknownParameter;

	return MS::kSuccess;
}
Beispiel #11
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
}
Beispiel #12
0
//  ========== DtCameraGetMatrix ==========
//
//  SYNOPSIS
//	Return the camera transformation matrix. This matrix
// 	includes the camera rotation, translation, and scale
//	transforms. This function also sets the valid bits
//	for DT_CAMERA_POSITION and DT_CAMERA_ORIENTATION.
//	The matrix is in row-major order.
//
//  From PA DT:
//          Not implemented: returns a pointer to an identity matrix
//          under the OpenModel implementation.
//
//  For Maya DT:
//          This fuction returns the camera's global transformation matrix.
//
int DtCameraGetMatrix( int cameraID,
					   float** matrix )
{
	// static float mtx[4][4];
	static float globalMtx[4][4];
	static float localMtx[4][4]; 

    // Check for error.
    //
	if( ( cameraID < 0) || ( cameraID >= local->camera_ct ) )
	{
		*matrix = NULL;
		return( 0 );
	}

    // Set the valid flag.
    //
	// local->cameras[cameraID].valid_bits|=(DT_VALID_BIT_MASK&DT_CAMERA_MATRIX);

    // Get transformations.
    //
#if 0
	mtx[0][0]=1.0;mtx[0][1]=0.0;mtx[0][2]=0.0;mtx[0][3]=0.0;
	mtx[1][0]=0.0;mtx[1][1]=1.0;mtx[1][2]=0.0;mtx[1][3]=0.0;
	mtx[2][0]=0.0;mtx[2][1]=0.0;mtx[2][2]=1.0;mtx[2][3]=0.0;
	mtx[3][0]=0.0;mtx[3][1]=0.0;mtx[3][2]=0.0;mtx[3][3]=1.0;
#endif

	// Camera transformation matrix is set on the transform node.
	//	
	MStatus returnStatus = MS::kSuccess;
	MFnDagNode fnTransNode( local->cameras[cameraID].transformNode, &returnStatus );
	MDagPath dagPath;
	returnStatus = fnTransNode.getPath( dagPath );
	if( MS::kSuccess == returnStatus )
	{
		if( DtExt_Debug() & DEBUG_CAMERA )
		{
			cerr << "Got the dagPath\n";
			cerr << "length of the dagpath is " << dagPath.length() << endl;
		}
	}

	MFnDagNode fnDagPath( dagPath, &returnStatus );

	MMatrix localMatrix;
	MMatrix globalMatrix;

	localMatrix = fnTransNode.transformationMatrix ( &returnStatus );
	globalMatrix = dagPath.inclusiveMatrix();

	localMatrix.get( localMtx );
	globalMatrix.get( globalMtx );

	if( DtExt_Debug() & DEBUG_CAMERA )
	{
		int i = 0;
		int j = 0;

		cerr << "camera's global transformation matrix:\n";
		
		for( i = 0; i < 4; i++ )
		{
			for( j = 0; j < 4; j++ )
			{
				cerr << globalMtx[i][j] << " ";
			}
			cerr << endl;
		}	

		cerr << "camera's local transformation matrix:\n";

		for( i = 0; i < 4; i++ )
		{
			for( j = 0; j < 4; j++ )
			{
				cerr << localMtx[i][j] << " ";
			}
			cerr << endl;
		}	
	}

	// *matrix = (float*)&mtx;
	*matrix = (float*)&globalMtx;

	return(1);
}  // DtCameraGetMatrix //
MStatus viewRenderUserOperation::execute( const MHWRender::MDrawContext & drawContext )
{
	// Sample code to debug pass information
	static const bool debugPassInformation = false;
	if (debugPassInformation)
	{
		const MHWRender::MPassContext & passCtx = drawContext.getPassContext();
		const MString & passId = passCtx.passIdentifier();
		const MStringArray & passSem = passCtx.passSemantics();
		printf("viewRenderUserOperation: drawing in pass[%s], semantic[", passId.asChar());
		for (unsigned int i=0; i<passSem.length(); i++)
			printf(" %s", passSem[i].asChar());
		printf("\n");
	}

	// Example code to find the active override.
	// This is not necessary if the operations just keep a reference
	// to the override, but this demonstrates how this
	// contextual information can be extracted.
	//
	MHWRender::MRenderer *theRenderer = MHWRender::MRenderer::theRenderer();
	const MHWRender::MRenderOverride *overridePtr = NULL;
	if (theRenderer)
	{
		const MString & overrideName = theRenderer->activeRenderOverride();
		overridePtr = theRenderer->findRenderOverride( overrideName );
	}

	// Some sample code to debug lighting information in the MDrawContext
	//
	if (fDebugLightingInfo)
	{
		viewRenderOverrideUtilities::printDrawContextLightInfo( drawContext );
	}

	// Some sample code to debug other MDrawContext information
	//
	if (fDebugDrawContext)
	{
		MStatus status;
		MMatrix matrix = drawContext.getMatrix(MHWRender::MFrameContext::kWorldMtx, &status);
		double dest[4][4];
		status = matrix.get(dest);
		printf("World matrix is:\n");
		printf("\t%f, %f, %f, %f\n", dest[0][0], dest[0][1], dest[0][2], dest[0][3]);
		printf("\t%f, %f, %f, %f\n", dest[1][0], dest[1][1], dest[1][2], dest[1][3]);
		printf("\t%f, %f, %f, %f\n", dest[2][0], dest[2][1], dest[2][2], dest[2][3]);
		printf("\t%f, %f, %f, %f\n", dest[3][0], dest[3][1], dest[3][2], dest[3][3]);

		MDoubleArray viewDirection = drawContext.getTuple(MHWRender::MFrameContext::kViewDirection, &status);
		printf("Viewdirection is: %f, %f, %f\n", viewDirection[0], viewDirection[1], viewDirection[2]);

		MBoundingBox box = drawContext.getSceneBox(&status);
		printf("Screen box is:\n");
		printf("\twidth=%f, height=%f, depth=%f\n", box.width(), box.height(), box.depth());
		float center[4];
		box.center().get(center);
		printf("\tcenter=(%f, %f, %f, %f)\n", center[0], center[1], center[2], center[3]);


		int originX, originY, width, height;
		status = drawContext.getViewportDimensions(originX, originY, width, height);
		printf("Viewport dimension: center(%d, %d), width=%d, heigh=%d\n", originX, originY, width, height);
	}

	//  Draw some addition things for scene draw
	//
	M3dView mView;
	if (mPanelName.length() &&
		(M3dView::getM3dViewFromModelPanel(mPanelName, mView) == MStatus::kSuccess))
	{
		// Get the current viewport and scale it relative to that
		//
		int targetW, targetH;
		drawContext.getRenderTargetSize( targetW, targetH );

		if (fDrawLabel)
		{
			MString testString("Drawing with override: ");
			testString += overridePtr->name();
			MPoint pos(0.0,0.0,0.0);
			glColor3f( 1.0f, 1.0f, 1.0f );
			mView.drawText( testString, pos);
		}

		// Some user drawing of scene bounding boxes
		//
		if (fDrawBoundingBoxes)
		{
			MDagPath cameraPath;
			mView.getCamera( cameraPath);
			MCustomSceneDraw userDraw;
			userDraw.draw( cameraPath, targetW, targetH );
		}
	}
	return MStatus::kSuccess;
}
Beispiel #14
0
MStatus CXRayCameraExport::ExportCamera(const MFileObject& file)
{
	MDagPath            node; 
    MObject             component; 
    MSelectionList      list; 
    MFnDagNode          nodeFn; 
	MFnCamera			C;
	MStatus		st ;
    
	MGlobal::getActiveSelectionList( list ); 
    for ( u32 index = 0; index < list.length(); ++index ) 
    { 
        list.getDagPath			( index, node, component ); 
        nodeFn.setObject		( node ); 
		st = C.setObject		(node);
		if(st!=MStatus::kSuccess)
		{
			Msg		("Selected object is not a camera");
			return	MStatus::kInvalidParameter;
		}

    } 

	Msg("exporting camera named [%s]",	C.name().asChar());

	MTime				tmTemp,tmTemp2;
	MTime				tmQuant;

	// Remember the frame the scene was at so we can restore it later.
	MTime storedFrame	= MAnimControl::currentTime();
	MTime startFrame	= MAnimControl::minTime();
	MTime endFrame		= MAnimControl::maxTime();

	tmTemp.setUnit		(MTime::uiUnit());
	tmTemp2.setUnit		(MTime::uiUnit());
	tmQuant.setUnit		(MTime::uiUnit());
	tmQuant				= 10.0; //3 time in sec. temporary
	
	COMotion			M;
	M.SetParam			(0, (int)(endFrame-startFrame).as(MTime::uiUnit()), 30);
	
	Fvector				P,R;
	tmTemp				= startFrame;

	MObject cam_parent	= C.parent(0);
	MFnTransform		parentTransform(cam_parent);
	

	MDistance			dist;
	while(tmTemp <= endFrame)
	{
		MAnimControl::setCurrentTime( tmTemp );

		MMatrix parentMatrix	=	parentTransform.transformation().asMatrix();
		MMatrix					cv;
		cv.setToIdentity		();
		cv[2][2]				= -1.0;
		MMatrix					TM;
		TM						=  (cv*parentMatrix)*cv;
		TM						= cv*TM;
		parentMatrix			= TM;

		Msg				("frame[%d]",(int)tmTemp.as(MTime::uiUnit()));
		
		dist.setValue	(parentMatrix[3][0]);
		P.x				= (float)dist.asMeters();
		dist.setValue	(parentMatrix[3][1]);
		P.y				= (float)dist.asMeters();
		dist.setValue	(parentMatrix[3][2]);
		P.z				= (float)dist.asMeters();

		Msg				("P %3.3f,%3.3f,%3.3f",P.x,P.y,P.z);

		double			rot[3];
		MTransformationMatrix::RotationOrder rot_order = MTransformationMatrix::kXYZ;

		st 				= parentTransform.getRotation( rot, rot_order );
                             
		R.x				= -(float)rot[0];
		R.y				= -(float)rot[1];
		R.z				= -(float)rot[2];
//.		Msg				("rt %3.3f,%3.3f,%3.3f kWorld",R.x,R.y,R.z);

		tmTemp2			= tmTemp-startFrame;
		M.CreateKey		(float(tmTemp2.as(MTime::uiUnit()))/30.0f,P,R);

		if(tmTemp==endFrame)
			break;

		tmTemp			+= tmQuant;

		if(tmTemp>endFrame)
			tmTemp=endFrame;
	};


	MString 			fn_save_to = file.fullName();
	fn_save_to			+= ".anm";

	Msg("file full name [%s]", fn_save_to);
	M.SaveMotion		(fn_save_to.asChar());

	MAnimControl::setCurrentTime( storedFrame );

	return MS::kSuccess;
}
// write the frame ranges and statistic string on the root
// Also call the post callbacks
void AbcWriteJob::postCallback(double iFrame)
{
    std::string statsStr = "";

    addToString(statsStr, "SubDStaticNum", mStats.mSubDStaticNum);
    addToString(statsStr, "SubDAnimNum", mStats.mSubDAnimNum);
    addToString(statsStr, "SubDStaticCVs", mStats.mSubDStaticCVs);
    addToString(statsStr, "SubDAnimCVs", mStats.mSubDAnimCVs);
    addToString(statsStr, "SubDStaticFaces", mStats.mSubDStaticFaces);
    addToString(statsStr, "SubDAnimFaces", mStats.mSubDAnimFaces);

    addToString(statsStr, "PolyStaticNum", mStats.mPolyStaticNum);
    addToString(statsStr, "PolyAnimNum", mStats.mPolyAnimNum);
    addToString(statsStr, "PolyStaticCVs", mStats.mPolyStaticCVs);
    addToString(statsStr, "PolyAnimCVs", mStats.mPolyAnimCVs);
    addToString(statsStr, "PolyStaticFaces", mStats.mPolyStaticFaces);
    addToString(statsStr, "PolyAnimFaces", mStats.mPolyAnimFaces);

    addToString(statsStr, "CurveStaticNum", mStats.mCurveStaticNum);
    addToString(statsStr, "CurveStaticCurves", mStats.mCurveStaticCurves);
    addToString(statsStr, "CurveAnimNum", mStats.mCurveAnimNum);
    addToString(statsStr, "CurveAnimCurves", mStats.mCurveAnimCurves);
    addToString(statsStr, "CurveStaticCVs", mStats.mCurveStaticCVs);
    addToString(statsStr, "CurveAnimCVs", mStats.mCurveAnimCVs);

    addToString(statsStr, "PointStaticNum", mStats.mPointStaticNum);
    addToString(statsStr, "PointAnimNum", mStats.mPointAnimNum);
    addToString(statsStr, "PointStaticCVs", mStats.mPointStaticCVs);
    addToString(statsStr, "PointAnimCVs", mStats.mPointAnimCVs);

    addToString(statsStr, "NurbsStaticNum", mStats.mNurbsStaticNum);
    addToString(statsStr, "NurbsAnimNum", mStats.mNurbsAnimNum);
    addToString(statsStr, "NurbsStaticCVs", mStats.mNurbsStaticCVs);
    addToString(statsStr, "NurbsAnimCVs", mStats.mNurbsAnimCVs);

    addToString(statsStr, "TransStaticNum", mStats.mTransStaticNum);
    addToString(statsStr, "TransAnimNum", mStats.mTransAnimNum);

    addToString(statsStr, "LocatorStaticNum", mStats.mLocatorStaticNum);
    addToString(statsStr, "LocatorAnimNum", mStats.mLocatorAnimNum);

    addToString(statsStr, "CameraStaticNum", mStats.mCameraStaticNum);
    addToString(statsStr, "CameraAnimNum", mStats.mCameraAnimNum);

    if (statsStr.length() > 0)
    {
        Alembic::Abc::OStringProperty stats(mRoot.getTop().getProperties(),
            "statistics");
        stats.set(statsStr);
    }

    if (mTransTimeIndex != 0)
    {
        MString propName;
        propName += static_cast<int>(mTransTimeIndex);
        propName += ".samples";
        Alembic::Abc::OUInt32Property samp(mRoot.getTop().getProperties(),
            propName.asChar());
        samp.set(mTransSamples);
    }

    if (mShapeTimeIndex != 0 && mShapeTimeIndex != mTransTimeIndex)
    {
        MString propName;
        propName += static_cast<int>(mShapeTimeIndex);
        propName += ".samples";
        Alembic::Abc::OUInt32Property samp(mRoot.getTop().getProperties(),
            propName.asChar());
        samp.set(mShapeSamples);
    }

    MBoundingBox bbox;

    if (mArgs.melPostCallback.find("#BOUNDS#") != std::string::npos ||
        mArgs.pythonPostCallback.find("#BOUNDS#") != std::string::npos ||
        mArgs.melPostCallback.find("#BOUNDSARRAY#") != std::string::npos ||
        mArgs.pythonPostCallback.find("#BOUNDSARRAY#") != std::string::npos)
    {
        util::ShapeSet::const_iterator it = mArgs.dagPaths.begin();
        const util::ShapeSet::const_iterator end = mArgs.dagPaths.end();
        for (; it != end; it ++)
        {
            mCurDag = *it;

            MMatrix eMInvMat;
            if (mArgs.worldSpace)
            {
                eMInvMat.setToIdentity();
            }
            else
            {
                eMInvMat = mCurDag.exclusiveMatrixInverse();
            }

            bbox.expand(getBoundingBox(iFrame, eMInvMat));
        }
    }

    processCallback(mArgs.melPostCallback, true, iFrame, bbox);
    processCallback(mArgs.pythonPostCallback, false, iFrame, bbox);
}
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;
}
Beispiel #17
0
MMatrix MotionSyn::meanPrediction(const std::vector<MMatrix> &X ,CVector3D<double> initPos)
{
	std::vector<const MMatrix*> tempX;
	
	for(std::size_t t = 0; t < X.size(); t++)
		tempX.push_back(&X[t]);

	std::size_t motionLen = X[0].sizeRow();
	MMatrix Kx(motionLen, mNumData);
	mKernel->computeKernel(Kx, tempX, mFakeFactors);
	 
	MMatrix &Ymean = Kx * mInvK * mCentredY;
	
	for(std::size_t i = 0; i < Ymean.sizeCol(); i++)
	{
		Ymean.scaleCol(i, sqrt(mVarY.get(i)));
 	}

	MMatrix meanData;
	meanData.repmat(mMeanY, motionLen, 1);
 	
 	Ymean += meanData; 
 
	
	MMatrix motion(Ymean.sizeRow(), mInitY.sizeCol());
	motion.copyMMatrix(0, 0, Ymean, 0, Ymean.sizeRow(), 0, mInitY.sizeCol());
	
	//TODO
	motion.assign(initPos.x, 0, 0);
	motion.assign(initPos.y, 0, 1);
	motion.assign(initPos.z, 0, 2);
	 
	for (std::size_t i = 1; i < motionLen; i++)
	{
	/*	motion.assign(motion.get(i, 0), i, 0);
		motion.assign(motion.get(i, 1), i, 1);
		motion.assign(motion.get(i, 2), i, 2);*/

		motion.add(motion.get(i-1, 0), i, 0);
		motion.add(motion.get(i-1, 1), i, 1);
		motion.add(motion.get(i-1, 2), i, 2);
	}
  	
	mocapToEulerAngle(motion);
  
	for(std::size_t i = 3; i < motion.sizeCol(); i++)
	{
		motion.scaleCol(i, 180.0/M_PI);
 	}

	//for(std::size_t i = 0; i < motion.sizeRow(); i++)
	//{
	//	std::cout << motion.get(i,0) <<  " ,";
	//	std::cout << motion.get(i,1) <<  " ,";
	//	std::cout << motion.get(i,2) <<  " ,";
	//	std::cout << motion.get(i,3) <<  " ,";
	//	std::cout << motion.get(i,4) <<  " ,";
	//	std::cout << motion.get(i,5) <<  std::endl;
 //	}
	//
	return motion;
}
Beispiel #18
0
MMatrix MotionSyn::generate(std::size_t identity,vector<std::size_t> contents,std::size_t interval)
{
	std::size_t state_size = contents.size() * 2 - 1;
 	std::size_t length = interval * state_size;
	
	MMatrix motion(length,mInitY.sizeCol());
	
	std::vector<MMatrix> xStar(3);
	xStar[0].resize(length, 2);
	xStar[1].resize(length, mFactors[1]->sizeCol());
	xStar[2].resize(length, mFactors[2]->sizeCol());
 
	double current_state = 0;
	for (std::size_t i = 0; i < state_size; i++)
	{
		MMatrix kron(1,mFactors[1]->sizeCol() * mFactors[2]->sizeCol());
		if (i % 2 == 0)
		{
 			MMatrix mat1 = mFactors[1]->subMMatrix(identity, 0, 1, mFactors[1]->sizeCol());
			MMatrix mat2 = mFactors[2]->subMMatrix(contents[i/2], 0, 1, mFactors[2]->sizeCol());
 
			kron = mat1.kron(mat2);
 			MMatrix val = mGPM->predict(kron);

			double step = val.get(0);

			for (std::size_t t = 0; t < interval; t++)
			{
				xStar[0].assign(cos(current_state + double(t*step)), t + i * interval, 0);
				xStar[0].assign(sin(current_state + double(t*step)), t + i * interval, 1);
  				xStar[1].copyRowRow(t + i * interval, *mFactors[1], identity);
				xStar[2].copyRowRow(t + i * interval, *mFactors[2], contents[i/2]);
			}
			current_state += step * interval;
 		}
		else
		{
			for (std::size_t t = 0; t < interval; t++)
			{
				MMatrix linearIpconent(1,mFactors[2]->sizeCol());
				for (std::size_t k = 0; k < linearIpconent.sizeCol(); k++)
				{
					double val = (1 - double(t) / interval) * mFactors[2]->get(contents[(i-1)/2], k) 
								   + (double(t) / interval) * mFactors[2]->get(contents[(i+1)/2], k); 

					linearIpconent.assign(val, 0, k);
				}
		 
 				MMatrix mat = mFactors[1]->subMMatrix(identity, 0, 1, mFactors[1]->sizeCol());
				
				kron = mat.kron(linearIpconent);
 
				MMatrix val = mGPM->predict(kron);
				double step = val.get(0);

				current_state += step;

				xStar[0].assign(cos(current_state), t + i * interval, 0);
				xStar[0].assign(sin(current_state), t + i * interval, 1);

				xStar[1].copyRowRow(t + i * interval, *mFactors[1], identity);
				xStar[2].copyRowRow(t + i * interval, linearIpconent, 0);
			}
		}
	}
 	return meanPrediction(xStar,CVector3D<double>(0,mInitY.get(identity,1),0));
}
	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;
	}
Beispiel #20
0
void Kernel::getGradientX(std::vector<MMatrix*>&gX, const MMatrix &X,const MMatrix &X2,bool addG) const
{
	for(size_t t = 0; t < X.sizeRow(); t++)
		getGradientX(*gX[t],X,t,X2,addG);
}
Beispiel #21
0
MMatrix MotionSyn::synTrainsiton(const std::size_t identity, const std::size_t content1,const std::size_t content2,
								const std::size_t length, CVector3D<double> initPos, double &curState)
{
	std::vector<MMatrix> xStar(3);
  
	xStar[0].resize(length,2);
	xStar[1].resize(length, mFactors[1]->sizeCol());
	xStar[2].resize(length, mFactors[2]->sizeCol());
	
	MMatrix actor = mFactors[1]->subMMatrix(identity,0,1,mFactors[1]->sizeCol());

	/*std::vector<double> steps;
	double total = 0.0;
	for (std::size_t i = 0; i < length; i++)
	{
		MMatrix newContent(1,mFactors[2]->sizeCol());

		for(std::size_t t = 0; t < newContent.sizeCol(); t++)
		{
				double val =  (1 - double(t)/length) * mFactors[2]->get(content1,t) 
			  				  +		double(t)/length * mFactors[2]->get(content2,t);
				newContent.assign(val,t);
		}
		MMatrix kron = actor.kron(newContent);
		MMatrix val = mGPM->predict(kron);
		total += val.get(0);
		steps.push_back(val.get(0));
		xStar[1].copyRowRow(i,*mFactors[1],identity);
		xStar[2].copyRowRow(i,newContent,0);
	}
	total = 6.28 - total;
	for (std::size_t i = 0; i < length; i++)
	{
		total += steps[i];
		 xStar[0].assign(cos(6.28-steps[i]*(length-i)), i, 0);
		 xStar[0].assign(sin(6.28-steps[i]*(length-i)), i, 1);
	}*/
 
	for (std::size_t i = 0; i < length; i++)
	{
	 	if(i < 50)
		{
			MMatrix newContent(1,mFactors[2]->sizeCol());
			for(std::size_t t = 0; t < newContent.sizeCol(); t++)
			{
				double val =  (1 - double(t)/50) * mFactors[2]->get(content1,t) 
								+ double(t)/50 * mFactors[2]->get(content2,t);
				newContent.assign(val,t);
			}
	 		MMatrix kron = actor.kron(newContent);
			MMatrix val = mGPM->predict(kron);
			double step  = val.get(0);
			curState += step;
			xStar[2].copyRowRow(i,newContent,0);


		/*	MMatrix content = mFactors[2]->subMMatrix(content1,0,1,mFactors[2]->sizeCol());
			MMatrix kron = actor.kron(content);
			MMatrix val = mGPM->predict(kron);
			double step  = val.get(0);
			curState += step;
			xStar[2].copyRowRow(i,content,0);*/

 		}
		else
		{
			MMatrix content = mFactors[2]->subMMatrix(content2,0,1,mFactors[2]->sizeCol());
			MMatrix kron = actor.kron(content);
			MMatrix val = mGPM->predict(kron);
			double step  = val.get(0);
			curState += step;
			xStar[2].copyRowRow(i,content,0);
		}

		xStar[0].assign(cos(curState), i, 0);
		xStar[0].assign(sin(curState), i, 1);
		xStar[1].copyRowRow(i,*mFactors[1],identity);
		
	}
	return meanPrediction(xStar,initPos);
}
/** Create a RIB compatible representation of a Maya polygon mesh.
 */
liqRibMeshData::liqRibMeshData( MObject mesh )
: numFaces( 0 ),
  numPoints ( 0 ),
  numNormals ( 0 ),
  nverts(),
  verts(),
  vertexParam(NULL),
  normalParam(NULL)
{
	CM_TRACE_FUNC("liqRibMeshData::liqRibMeshData("<<MFnDagNode(mesh).fullPathName().asChar()<<")");

	unsigned int i;
	unsigned int j;
  areaLight = false;
  LIQDEBUGPRINTF( "-> creating mesh\n" );
  MFnMesh fnMesh( mesh );
  objDagPath = fnMesh.dagPath();
  MStatus astatus;
  
  name = fnMesh.name();
  areaLight =( liquidGetPlugValue( fnMesh, "areaIntensity", areaIntensity, astatus ) == MS::kSuccess )? true : false ; 

  if ( areaLight ) 
  {
    MDagPath meshDagPath;
    meshDagPath = fnMesh.dagPath();
    MTransformationMatrix worldMatrix = meshDagPath.inclusiveMatrix();
    MMatrix worldMatrixM = worldMatrix.asMatrix();
    worldMatrixM.get( transformationMatrix );
  }

  numPoints = fnMesh.numVertices();
  numNormals = fnMesh.numNormals();

  // UV sets -------------------
  //
  //const unsigned numSTs( fnMesh.numUVs() );
  const unsigned numUVSets( fnMesh.numUVSets() );
  MString currentUVSetName;
  MStringArray extraUVSetNames;
  fnMesh.getCurrentUVSetName( currentUVSetName );
  {
    MStringArray UVSetNames;
    fnMesh.getUVSetNames( UVSetNames );

    for ( unsigned i( 0 ); i<numUVSets; i++ ) 
      if ( UVSetNames[i] != currentUVSetName ) 
        extraUVSetNames.append( UVSetNames[i] );
  }

  numFaces = fnMesh.numPolygons();
  const unsigned numFaceVertices( fnMesh.numFaceVertices() );

	if ( numPoints < 1 )
	{
//		MGlobal::displayInfo( MString( "fnMesh: " ) + fnMesh.name() );
//		cerr << "Liquid : Could not export degenerate mesh '"<< fnMesh.fullPathName( &astatus ).asChar() << "'" << endl << flush;
		return;
	}

  unsigned face = 0;
  unsigned faceVertex = 0;
  unsigned count;
  unsigned vertex;
  unsigned normal;
  float S;
  float T;
  MPoint point;
  liqTokenPointer pointsPointerPair;
  liqTokenPointer normalsPointerPair;
  liqTokenPointer pFaceVertexSPointer;
  liqTokenPointer pFaceVertexTPointer;

  // Allocate memory and tokens
  numFaces = numFaces;
  nverts = shared_array< liqInt >( new liqInt[ numFaces ] );
  verts = shared_array< liqInt >( new liqInt[ numFaceVertices ] );

  pointsPointerPair.set( "P", rPoint, numPoints );
  pointsPointerPair.setDetailType( rVertex );

  if ( numNormals == numPoints ) 
  {
    normalsPointerPair.set( "N", rNormal, numPoints );
    normalsPointerPair.setDetailType( rVertex );
  } 
  else 
  {
    normalsPointerPair.set( "N", rNormal, numFaceVertices );
    normalsPointerPair.setDetailType( rFaceVarying );
  }
  	
  // uv
  std::vector<liqTokenPointer> UVSetsArray;
  UVSetsArray.reserve( 1 + extraUVSetNames.length() );

  liqTokenPointer currentUVSetUPtr;
  liqTokenPointer currentUVSetVPtr;
  liqTokenPointer currentUVSetNamePtr;
  liqTokenPointer extraUVSetsUPtr;
  liqTokenPointer extraUVSetsVPtr;
  liqTokenPointer extraUVSetsNamePtr;
  if(liqglo.liqglo_outputMeshAsRMSArrays)
  {
	  currentUVSetUPtr.set( "s", rFloat, numFaceVertices );
	  currentUVSetUPtr.setDetailType( rFaceVarying );

	  currentUVSetVPtr.set( "t", rFloat, numFaceVertices );
	  currentUVSetVPtr.setDetailType( rFaceVarying );

	  currentUVSetNamePtr.set( "currentUVSet", rString, 1 );
	  currentUVSetNamePtr.setDetailType( rConstant );

	  if( numUVSets > 1 )
	  {
		  extraUVSetsUPtr.set( "u_uvSet", rFloat, numFaceVertices, numUVSets-1 );
		  extraUVSetsUPtr.setDetailType( rFaceVarying );

		  extraUVSetsVPtr.set( "v_uvSet", rFloat, numFaceVertices, numUVSets-1 );
		  extraUVSetsVPtr.setDetailType( rFaceVarying );

		  extraUVSetsNamePtr.set( "extraUVSets", rString, numUVSets-1 );
		  extraUVSetsNamePtr.setDetailType( rConstant );
	  }
  }
  else
  {
	  if ( numUVSets > 0 ) 
	  {
		liqTokenPointer pFaceVertexPointerPair;

		pFaceVertexPointerPair.set( "st", rFloat, numFaceVertices, 2 );
		pFaceVertexPointerPair.setDetailType( rFaceVarying );

		UVSetsArray.push_back( pFaceVertexPointerPair );

		for ( unsigned j( 0 ); j<extraUVSetNames.length(); j++) 
		{
		  liqTokenPointer pFaceVertexPointerPair;

		  pFaceVertexPointerPair.set( extraUVSetNames[j].asChar(), rFloat, numFaceVertices, 2 );
		  pFaceVertexPointerPair.setDetailType( rFaceVarying );

		  UVSetsArray.push_back( pFaceVertexPointerPair );
		}

		if( liqglo.liqglo_outputMeshUVs ) 
		{
		  // Match MTOR, which also outputs face-varying STs as well for some reason - Paul
		  // not anymore - Philippe
		  pFaceVertexSPointer.set( "u", rFloat, numFaceVertices );
		  pFaceVertexSPointer.setDetailType( rFaceVarying );

		  pFaceVertexTPointer.set( "v", rFloat, numFaceVertices );
		  pFaceVertexTPointer.setDetailType( rFaceVarying );
		}
	  }
  }

  vertexParam = pointsPointerPair.getTokenFloatArray();
  normalParam = normalsPointerPair.getTokenFloatArray();

  // Read the mesh from Maya
  MFloatVectorArray normals;
  fnMesh.getNormals( normals );

  for ( MItMeshPolygon polyIt ( mesh ); polyIt.isDone() == false; polyIt.next() ) 
  {
    count = polyIt.polygonVertexCount();
    nverts[face] = count;
	for( i=0; i<count; i++ )    // boucle sur les vertex de la face
    {
      vertex = polyIt.vertexIndex( i );
      verts[faceVertex] = vertex;
      point = polyIt.point( i, MSpace::kObject );
      pointsPointerPair.setTokenFloat( vertex, point.x, point.y, point.z );
      normal = polyIt.normalIndex( i );

      if( numNormals == numPoints ) 
        normalsPointerPair.setTokenFloat( vertex, normals[normal].x, normals[normal].y, normals[normal].z );
      else 
        normalsPointerPair.setTokenFloat( faceVertex, normals[normal].x, normals[normal].y, normals[normal].z );

	  if( liqglo.liqglo_outputMeshAsRMSArrays )
	  {
		  for( j=0; j<numUVSets; j++ )
		  {
			  if(j==0)
			  {
				  MString uvSetName = currentUVSetName;
				  // set uvSet name
				  currentUVSetNamePtr.setTokenString( 0, currentUVSetName.asChar() );
				  // set uv values
				  fnMesh.getPolygonUV( face, i, S, T, &uvSetName );

				  currentUVSetUPtr.setTokenFloat( faceVertex, S );
				  currentUVSetVPtr.setTokenFloat( faceVertex, 1-T );
			  }
			  else
			  {
				  MString uvSetName = extraUVSetNames[j-1];
				  // set uvSet name
				  extraUVSetsNamePtr.setTokenString( j-1, extraUVSetNames[j-1].asChar() );
				  // set uv values
				  fnMesh.getPolygonUV( face, i, S, T, &uvSetName );
				  extraUVSetsUPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, S );
				  extraUVSetsVPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, 1-T );
			  }
		  }
	  }
	  else
	  {
		  if ( numUVSets ) 
		  {
			  for( j=0; j<numUVSets; j++ )
			  {
				  MString uvSetName;
				  if(j==0)
				  {
					  uvSetName = currentUVSetName;
				  }
				  else
				  {
					  uvSetName = extraUVSetNames[j-1];
				  }
				  fnMesh.getPolygonUV( face, i, S, T, &uvSetName );
				  UVSetsArray[j].setTokenFloat( faceVertex, 0, S );
				  UVSetsArray[j].setTokenFloat( faceVertex, 1, 1-T );
				  //printf("V%d  %s : %f %f  =>  %f %f \n", i, uvSetName.asChar(), S, T, S, 1-T);

				  if( liqglo.liqglo_outputMeshUVs && j==0)
				  {
					  // Match MTOR, which always outputs face-varying STs as well for some reason - Paul
					  pFaceVertexSPointer.setTokenFloat( faceVertex, S );
					  pFaceVertexTPointer.setTokenFloat( faceVertex, 1-T );
				  }
			  }
		  }
		}
      // printf( "[%d] faceVertex = %d  vertex = %d\n", i, faceVertex, vertex );

      ++faceVertex;
    }
    ++face;
  }
  // Add tokens to array and clean up after
  tokenPointerArray.push_back( pointsPointerPair );
  tokenPointerArray.push_back( normalsPointerPair );

  if(liqglo.liqglo_outputMeshAsRMSArrays)
  {
	  tokenPointerArray.push_back( currentUVSetNamePtr );
	  tokenPointerArray.push_back( currentUVSetUPtr );
	  tokenPointerArray.push_back( currentUVSetVPtr );
	  if( numUVSets > 1 )
	  {
		  tokenPointerArray.push_back( extraUVSetsNamePtr );
		  tokenPointerArray.push_back( extraUVSetsUPtr );
		  tokenPointerArray.push_back( extraUVSetsVPtr );
	  }
  }
  else
  {
	  if( UVSetsArray.size() ) 
		  tokenPointerArray.insert( tokenPointerArray.end(), UVSetsArray.begin(), UVSetsArray.end() );

	  if( liqglo.liqglo_outputMeshUVs ) 
	  {
		  tokenPointerArray.push_back( pFaceVertexSPointer );
		  tokenPointerArray.push_back( pFaceVertexTPointer );
	  }
  }

  addAdditionalSurfaceParameters( mesh );
}
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;
}
Beispiel #24
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;
}
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;
}
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 );
						}
					}
				}
			}
		}
	}
}
Beispiel #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;
}
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 );		
				}
			}
		}
	}
}
Beispiel #29
0
/* virtual */
MStatus cgfxVector::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MFnData::Type dataType = MFnData::kInvalid;
 
	if( plug == sWorldVector ||
		plug == sWorldVectorX ||
		plug == sWorldVectorY ||
		plug == sWorldVectorZ ||
		plug == sWorldVectorW)
	{
		// We do isDirection first simply because if there is an
		// error, the isDirection error is more legible than the
		// vector or matrix error.
		//
		MDataHandle dhIsDirection = data.inputValue(sIsDirection, &status);
		if (!status)
		{
			status.perror("cgfxVector: isDirection handle");
			return status;
		}

		dataType = dhIsDirection.type();

		MDataHandle dhVector = data.inputValue(sVector, &status);
		if (!status)
		{
			status.perror("cgfxVector: vector handle");
			return status;
		}

		dataType = dhVector.type();

		MMatrix matrix;

		MPlug matrixPlug(thisMObject(), sMatrix);
		if (matrixPlug.isNull())
		{
			OutputDebugString("matrixPlug is NULL!\n");
		}

		// TODO: Fix this kludge.
		//
		// We should not have to do this but for some reason, 
		// using data.inputValue() fails for the sMatrix attribute.
		// Instead, we get a plug to the attribute and then get
		// the value directly.
		//
		MObject oMatrix;

		matrixPlug.getValue(oMatrix);

		MFnMatrixData fndMatrix(oMatrix, &status);
		if (!status)
		{
			status.perror("cgfxVector: matrix data");
		}

		matrix= fndMatrix.matrix(&status);
		if (!status)
		{
			status.perror("cgfxVector: get matrix");
		}

#if 0
		// TODO: This is how we are supposed to do it.  (I think).
		//
		MDataHandle dhMatrix = data.inputValue(sMatrix, &status);
		if (!status)
		{
			status.perror("cgfxVector: matrix handle");
		}

		dataType = dhMatrix.type();

		oMatrix			= dhMatrix.data();
		MFnMatrixData fnMatrix(oMatrix, &status);
		if (!status)
		{
			status.perror("cgfxVector: matrix function set");
		}

		matrix = fnMatrix.matrix();
#endif /* 0 */

		bool	 isDirection	= dhIsDirection.asBool();
		double3& vector			= dhVector.asDouble3();

		double mat[4][4];
		matrix.get(mat);

		double ix, iy, iz, iw;	// Input vector
		float  ox, oy, oz, ow;	// Output vector

		ix = vector[0];
		iy = vector[1];
		iz = vector[2];
		iw = isDirection ? 0.0 : 1.0;

		ox = (float)(mat[0][0] * ix +
					 mat[1][0] * iy +
					 mat[2][0] * iz +
					 mat[3][0] * iw);

		oy = (float)(mat[0][1] * ix +
					 mat[1][1] * iy +
					 mat[2][1] * iz +
					 mat[3][1] * iw);

		oz = (float)(mat[0][2] * ix +
					 mat[1][2] * iy +
					 mat[2][2] * iz +
					 mat[3][2] * iw);

		ow = (float)(mat[0][3] * ix +
					 mat[1][3] * iy +
					 mat[2][3] * iz +
					 mat[3][3] * iw);

		MDataHandle dhWVector = data.outputValue(sWorldVector, &status);
		if (!status)
		{
			status.perror("cgfxVector: worldVector handle");
			return status;
		}

		MDataHandle dhWVectorW = data.outputValue(sWorldVectorW, &status);
		if (!status)
		{
			status.perror("cgfxVector: worldVectorW handle");
			return status;
		}

		dhWVector.set(ox, oy, oz);
		dhWVectorW.set(ow);
		data.setClean(sWorldVector);
		data.setClean(sWorldVectorW);
	}
	else
	{
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
Beispiel #30
0
//  ========== DtCameraGetOrientation ==========
//
//  SYNOPSIS
//	Return the camera orientation as x,y,z 
//	Euler angles.
//
int DtCameraGetOrientation(	int cameraID,
							float* xRot,
							float* yRot,
							float* zRot )
{

	float	LRotX, LRotY, LRotZ;

	double	LX = 0.0;
	double  LY = 0.0;
	double  LZ = 0.0;
	double	LXV = 0.0;
	double  LYV = 0.0;
	double  LZV = 0.0;
	double	LXUp = 0.0;
	double  LYUp = 0.0;
	double  LZUp = 0.0;

	MMatrix	LMatrix;

    // Check for error.
    //
	if( (cameraID<0) || (cameraID>=local->camera_ct) )
	{
		*xRot=0.0;
		*yRot=0.0;
		*zRot=0.0;
		return( 0 );
	}

	MStatus returnStatus = MS::kSuccess;
	MFnCamera fnCamera( local->cameras[cameraID].cameraShapeNode, &returnStatus );

	if( MS::kSuccess == returnStatus )
	{
		MPoint eyePt = fnCamera.eyePoint( MSpace::kObject, &returnStatus );

		LX = eyePt.x;
		LY = eyePt.y;
		LZ = eyePt.z;

		if( DtExt_Debug() & DEBUG_CAMERA )
		{
			cerr << "eye point is at " 
				 << LX << " " << LY << " " << LZ << endl;
		}
		
		MVector upDir = fnCamera.upDirection( MSpace::kObject, &returnStatus );
		if( DtExt_Debug() & DEBUG_CAMERA )
		{
			cerr << "up direction is " 
				 << upDir.x << " " << upDir.y << " " << upDir.z << endl;
		}

		LXUp = upDir.x;
		LYUp = upDir.y;
		LZUp = upDir.z;

		
		MVector viewDir = fnCamera.viewDirection( MSpace::kObject, &returnStatus );
		if( DtExt_Debug() & DEBUG_CAMERA )
		{
			cerr << "view direction is " 
				 << viewDir.x << " " << viewDir.y << " " << viewDir.z << endl;
		}	
		LXV = -viewDir.x;
		LYV = -viewDir.y;
		LZV = -viewDir.z;
	}
	else
	{
		DtExt_Err( "Error in getting the camera function set\n" );
		return 0;
	}


// If the up-vector is a null-vector (a problem), set it to 0,1,0

    if ( (LXUp == 0) && (LYUp == 0) && (LZUp == 0) )
    {
        LXUp=0.0;
        LYUp=1.0;
        LZUp=0.0;
    }   

// Compute camera orbital angles LXV, LYV, LZV: direction vector of the camera

    LRotX = DtGetAngle2D( LYV, sqrt(LXV*LXV + LZV*LZV) );
    LRotY = DtGetAngle2D(LZV, LXV);
    if ( LRotY < 0.0 ) LRotY += 360.0;
   
	
    LX=0.0;
	LY=1.0;
	LZ=0.0;   // Unit-length up-vector
    
//	Create the inverse camera rotation matrix and transform the 
//	default up-vector with it

	MVector	vec( LX, LY, LZ );
	vec.rotateBy( MVector::kXaxis, LRotX-90.0 );
	vec.rotateBy( MVector::kYaxis, LRotY );

	LX = vec.x;
	LY = vec.y;
	LZ = vec.z;

#if 0
    LMatrix  = LMatrix.rotateX((LRotX-90.0)*DEGREE_TO_RADIAN);
    LMatrix *= LMatrix.rotateY(LRotY*DEGREE_TO_RADIAN);
    LMatrix.transVector(LX,LY,LZ);
#endif

    LRotZ = acos((LXUp*LX + LYUp*LY + LZUp*LZ) / 
				sqrt(LXUp*LXUp + LYUp*LYUp + LZUp*LZUp)) * RADIAN_TO_DEGREE;

    *xRot = LRotX;
	*yRot = LRotY;
	*zRot = LRotZ;

	return(1);
}  // DtCameraGetOrientation //