MStatus testNpassiveNode::compute(const MPlug &plug, MDataBlock &data)
{
    MStatus stat;
    if ( plug == currentState )
    { 
      // get old positions and numVerts
      // if num verts is different, reset topo and zero velocity
      // if num verts is the same, compute new velocity
        int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
                
        MFnMesh inputMesh(inMeshObj);       
        unsigned int numVerts = 0;
        numVerts = inputMesh.numVertices();
        unsigned int prevNumVerts;
        fNObject.getNumVertices(prevNumVerts);
        if(numVerts != prevNumVerts) {
                int numPolygons = inputMesh.numPolygons();
                int * faceVertCounts = new int[numPolygons];
                
        
                int facesArrayLength = 0;
                for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                faceVertCounts[ii] = verts.length();
                facesArrayLength += verts.length();
                }
                int * faces = new int[facesArrayLength];
                int currIndex = 0;
                for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                for(jj=0;jj<(int)verts.length();jj++) {
                    faces[currIndex++] = verts[jj];
                }
            }
                int numEdges = inputMesh.numEdges();
                int * edges = new int[2*numEdges];
                currIndex = 0;
                for(ii=0;ii<numEdges;ii++) {
                int2 edge;
                inputMesh.getEdgeVertices(ii,edge);
                edges[currIndex++] = edge[0];
                edges[currIndex++] = edge[1];
                }
                // When you are doing the initialization, the first call must to be setTopology().  All other
                // calls must come after this.
            fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
                delete[] faceVertCounts;
                delete[] faces;
                delete[] edges;        
                MFloatPointArray vertexArray;
                inputMesh.getPoints(vertexArray, MSpace::kWorld);
                fNObject.setPositions(vertexArray,true);
                MFloatPointArray velocitiesArray;
                velocitiesArray.setLength(numVerts);
                for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = 0.0f;
                velocitiesArray[ii].y = 0.0f;
                velocitiesArray[ii].z = 0.0f;
                velocitiesArray[ii].w = 0.0f;
            }
            fNObject.setVelocities(velocitiesArray);
        } else {
                MFloatPointArray vertexArray;
                MFloatPointArray prevVertexArray;
                inputMesh.getPoints(vertexArray, MSpace::kWorld);
                fNObject.getPositions(prevVertexArray);
            // you may want to get the playback rate for the dt
            // double dt = MAnimControl::playbackBy() \ 24.0;
            // or get the real dt by caching the last eval time
            double dt = 1.0/24.0;
                MFloatPointArray velocitiesArray;
                velocitiesArray.setLength(numVerts);
                for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = (float)( (vertexArray[ii].x - prevVertexArray[ii].x)/dt);
                velocitiesArray[ii].y = (float)( (vertexArray[ii].y - prevVertexArray[ii].y)/dt);
                velocitiesArray[ii].z = (float)( (vertexArray[ii].x - prevVertexArray[ii].z)/dt);
                velocitiesArray[ii].w = 0.0f;
            }
            fNObject.setVelocities(velocitiesArray);
            fNObject.setPositions(vertexArray,true);
        }
        // in real life, you'd get these attribute values each frame and set them
        fNObject.setThickness(0.1f);
        fNObject.setBounce(0.0f);
        fNObject.setFriction(0.1f);
        fNObject.setCollisionFlags(true, true, true);               
        MFnNObjectData outputData;
        MObject mayaNObjectData = outputData.create();
        outputData.setObject(mayaNObjectData);
        
        outputData.setObjectPtr(&fNObject);        
        outputData.setCached(false);
        MDataHandle currStateOutputHandle = data.outputValue(currentState);
        currStateOutputHandle.set(outputData.object());
      
    }
    if ( plug == startState )
    {
        int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
                
        MFnMesh inputMesh(inMeshObj);       
        int numPolygons = inputMesh.numPolygons();
            int * faceVertCounts = new int[numPolygons];
                
        
            int facesArrayLength = 0;
            for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                faceVertCounts[ii] = verts.length();
                facesArrayLength += verts.length();
            }
            int * faces = new int[facesArrayLength];
            int currIndex = 0;
            for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                for(jj=0;jj<(int)verts.length();jj++) {
                    faces[currIndex++] = verts[jj];
               }
           }
            int numEdges = inputMesh.numEdges();
            int * edges = new int[2*numEdges];
            currIndex = 0;
            for(ii=0;ii<numEdges;ii++) {
                int2 edge;
                inputMesh.getEdgeVertices(ii,edge);
                edges[currIndex++] = edge[0];
                edges[currIndex++] = edge[1];
            }
            // When you are doing the initialization, the first call must to be setTopology().  All other
            // calls must come after this.
            fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
            delete[] faceVertCounts;
            delete[] faces;
            delete[] edges;        
            unsigned int numVerts = 0;
            numVerts = inputMesh.numVertices();        
            MFloatPointArray vertexArray;
            inputMesh.getPoints(vertexArray, MSpace::kWorld);
            fNObject.setPositions(vertexArray,true);
            MFloatPointArray velocitiesArray;
            velocitiesArray.setLength(numVerts);
            for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = 0.0f;
                velocitiesArray[ii].y = 0.0f;
                velocitiesArray[ii].z = 0.0f;
                velocitiesArray[ii].w = 0.0f;
           }
           fNObject.setVelocities(velocitiesArray);
           fNObject.setThickness(0.1f);
            fNObject.setBounce(0.0f);
            fNObject.setFriction(0.1f);
            fNObject.setCollisionFlags(true, true, true);               
        
            MFnNObjectData outputData;
            MObject mayaNObjectData = outputData.create();
            outputData.setObject(mayaNObjectData);
        
            outputData.setObjectPtr(&fNObject);        
            outputData.setCached(false);
            MDataHandle startStateOutputHandle = data.outputValue(startState);
            startStateOutputHandle.set(outputData.object());
    }
    else {
        stat = MS::kUnknownParameter;
    }
    return stat;
}
Exemplo n.º 2
0
MStatus testNobjectNode::compute(const MPlug &plug, MDataBlock &data)
{
	MStatus stat;

	if ( plug == outputGeom )
	{
		MObject inMeshObj = data.inputValue(inputGeom).asMesh();
		
        cerr<<"pull on outputGeom\n";

		MFnMeshData meshDataFn;
        MFnMesh inputMesh(inMeshObj);
		MObject newMeshObj = meshDataFn.create();
		MFnMesh newMeshFn;
		newMeshFn.copy( inMeshObj, newMeshObj );        

        //get the value of the currentTime so it can correctly dirty the
        //startState, currentState.
        data.inputValue(currentTime).asTime();

		// pull on next state.  This will cause the solver to pull on either
        // the startState or the currentState, depending on the time of solve.
        // When we return the state to the solver, it will do the solve and update
        // The N Object data directly.
		MObject nextNObj = data.inputValue(nextState).data();
        MFloatPointArray pts;        

        //At this point the N Object's internal state should have been updated
        //by the solver.  Read it out and set the output mesh.
        fNObject.getPositions(pts);
        if(pts.length() == (unsigned int) inputMesh.numVertices()) {
            newMeshFn.setPoints(pts);
        }

		newMeshFn.setObject( newMeshObj );

		data.outputValue(outputGeom).set(newMeshObj);
		data.setClean(plug);

	}
	if ( plug == currentState )
	{               
        MFnNObjectData outputData;
        MObject mayaNObjectData = outputData.create();
        outputData.setObject(mayaNObjectData);
        
        outputData.setObjectPtr(&fNObject);        
        outputData.setCached(false);

        MDataHandle currStateOutputHandle = data.outputValue(currentState);
        currStateOutputHandle.set(outputData.object());
	  
        cerr<<"pull on currentState\n";
	}
	if ( plug == startState )
	{
	    int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
				
        MFnMesh inputMesh(inMeshObj);		

        int numPolygons = inputMesh.numPolygons();
        int * faceVertCounts = new int[numPolygons];
                
        
        int facesArrayLength = 0;
        for(ii=0;ii<numPolygons;ii++) {
            MIntArray verts;
            inputMesh.getPolygonVertices(ii,verts);
            faceVertCounts[ii] = verts.length();
            facesArrayLength += verts.length();
        }
        int * faces = new int[facesArrayLength];
        int currIndex = 0;
        for(ii=0;ii<numPolygons;ii++) {
            MIntArray verts;
            inputMesh.getPolygonVertices(ii,verts);
            for(jj=0;jj<(int)verts.length();jj++) {
                faces[currIndex++] = verts[jj];
            }
        }

        int numEdges = inputMesh.numEdges();
        int * edges = new int[2*numEdges];
        currIndex = 0;
        for(ii=0;ii<numEdges;ii++) {
            int2 edge;
            inputMesh.getEdgeVertices(ii,edge);
            edges[currIndex++] = edge[0];
            edges[currIndex++] = edge[1];
        }

        // When you are doing the initialization, the first call must to be setTopology().  All other
        // calls must come after this.
        fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
        delete[] faceVertCounts;
        delete[] faces;
        delete[] edges;        


        unsigned int numVerts = 0;
        numVerts = inputMesh.numVertices();        

        MFloatPointArray vertexArray;
        inputMesh.getPoints(vertexArray);
        fNObject.setPositions(vertexArray,true);

        MFloatPointArray velocitiesArray;
        velocitiesArray.setLength(numVerts);
        for(ii=0;ii<(int)numVerts;ii++) {
            velocitiesArray[ii].x = 0.0f;
            velocitiesArray[ii].y = 0.0f;
            velocitiesArray[ii].z = 0.0f;
            velocitiesArray[ii].w = 0.0f;
        }
        fNObject.setVelocities(velocitiesArray);
        fNObject.setThickness(0.05f);
        fNObject.setInverseMass(1.0f);
        fNObject.setBounce(0.0f);
        fNObject.setFriction(0.1f);
        fNObject.setDamping(0.0f);
        fNObject.setBendResistance(0.0f);
        fNObject.setMaxIterations(100);        
        fNObject.setMaxSelfCollisionIterations(100);
        fNObject.setStretchAndCompressionResistance(20.0f,10.0f);
        fNObject.setSelfCollisionFlags(false);
        fNObject.setCollisionFlags(true);        	    

        
        MFnNObjectData outputData;
        MObject mayaNObjectData = outputData.create();
        outputData.setObject(mayaNObjectData);
        
        outputData.setObjectPtr(&fNObject);        
        outputData.setCached(false);

        MDataHandle startStateOutputHandle = data.outputValue(startState);
        startStateOutputHandle.set(outputData.object());

        cerr<<"pull on startState\n";
	}
	else {
		stat = MS::kUnknownParameter;
	}
	return stat;
}