MStatus sweptEmitter::emitCountPerPoint ( const MPlug &plug, MDataBlock &block, int length, // length of emitCountPP MIntArray &emitCountPP // output: emitCount for each point ) // // Descriptions: // Compute emitCount for each point where new particles come from. // { MStatus status; int plugIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in emitCountPerPoint: when plug.logicalIndex.\n"); // Get rate and delta time. // double rate = rateValue( block ); MTime dt = deltaTimeValue( plugIndex, block ); // Compute emitCount for each point. // double dblCount = rate * dt.as( MTime::kSeconds ); int intCount = (int)dblCount; for( int i = 0; i < length; i++ ) { emitCountPP.append( intCount ); } return( MS::kSuccess ); }
// // Evaluate the curve at the given time. // double interpHalf::evaluate(const MTime &val) { // Interpolate the before and after values. double sec = val.as(MTime::kSeconds); double alpha = (sec-sTime) / range; return (1.0 - alpha) * beforeVal + alpha * afterVal; }
ConstObjectPtr SceneShape::readSceneShapeAttribute( const MDagPath &p, SceneInterface::Name attributeName ) { MDagPath dagPath; SceneShape *sceneShape = findScene( p, false, &dagPath ); if ( !sceneShape ) { return 0; } MFnDagNode fnChildDag( dagPath ); if( attributeName == LinkedScene::linkAttribute ) { if( !fnChildDag.isIntermediateObject() ) { return readSceneShapeLink(p); } } ConstSceneInterfacePtr scene = sceneShape->getSceneInterface(); if ( !scene ) { return 0; } MPlug timePlug = fnChildDag.findPlug( aTime ); MTime time; timePlug.getValue( time ); return scene->readAttribute( attributeName, time.as( MTime::kSeconds ) ); }
MObject animCube::createMesh(const MTime& time, MObject& outData, MStatus& stat) { int numVertices, frame; float cubeSize; MFloatPointArray points; MFnMesh meshFS; // Scale the cube on the frame number, wrap every 10 frames. frame = (int)time.as( MTime::kFilm ); if (frame == 0) frame = 1; cubeSize = 0.5f * (float)( frame % 10); const int numFaces = 6; numVertices = 8; const int numFaceConnects = 24; MFloatPoint vtx_1( -cubeSize, -cubeSize, -cubeSize ); MFloatPoint vtx_2( cubeSize, -cubeSize, -cubeSize ); MFloatPoint vtx_3( cubeSize, -cubeSize, cubeSize ); MFloatPoint vtx_4( -cubeSize, -cubeSize, cubeSize ); MFloatPoint vtx_5( -cubeSize, cubeSize, -cubeSize ); MFloatPoint vtx_6( -cubeSize, cubeSize, cubeSize ); MFloatPoint vtx_7( cubeSize, cubeSize, cubeSize ); MFloatPoint vtx_8( cubeSize, cubeSize, -cubeSize ); points.append( vtx_1 ); points.append( vtx_2 ); points.append( vtx_3 ); points.append( vtx_4 ); points.append( vtx_5 ); points.append( vtx_6 ); points.append( vtx_7 ); points.append( vtx_8 ); // Set up an array containing the number of vertices // for each of the 6 cube faces (4 verticies per face) // int face_counts[numFaces] = { 4, 4, 4, 4, 4, 4 }; MIntArray faceCounts( face_counts, numFaces ); // Set up and array to assign vertices from points to each face // int face_connects[ numFaceConnects ] = { 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 5, 0, 3, 5, 4, 0, 4, 7, 1, 1, 7, 6, 2 }; MIntArray faceConnects( face_connects, numFaceConnects ); MObject newMesh = meshFS.create(numVertices, numFaces, points, faceCounts, faceConnects, outData, &stat); return newMesh; }
static void restoreOldTime(MTime &start, MTime &end, MTime &curr, MTime &minT, MTime &maxT) { const double st = start.as(start.unit()), en = end.as(end.unit()), cu = curr.as(curr.unit()), mi = minT.as(minT.unit()), ma = maxT.as(maxT.unit()); MString inst = "playbackOptions -ast "; inst += st; inst += " -aet "; inst += en; inst += " -min "; inst += mi; inst += " -max "; inst += ma; inst += ";\ncurrentTime "; inst += cu; inst += ";"; MGlobal::executeCommand(inst); }
// ------------------------------------------- void AnimationHelper::generateSamplingFunction() { mSamplingTimes.clear(); // Avoid any potential precision accumulation problems by using the MTime class as an iterator MTime startT = animationStartTime(); MTime endT = animationEndTime(); for ( MTime currentT = startT; currentT <= endT; ++currentT ) { mSamplingTimes.push_back ( ( float ) currentT.as ( MTime::kSeconds ) ); } }
MObject AniMesh::readFrame(const MTime& time,MObject& outData,MStatus& stat) { MFloatPointArray points; MFnMesh meshFS; int frame = (int)time.as( MTime::kFilm ); if (frame == 0) frame = 1; vector<size_t> face_v; vector<double> points_v; char cfilename[256]; sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),frame); //sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0); string filename = string(cfilename); fstream fp; fp.open(filename,ios::in); if (fp) { ImportVrml2 (filename, face_v, points_v); }else{ sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0); string filename = string(cfilename); ImportVrml2(filename,face_v,points_v); } size_t numVertices = points_v.size()/3; size_t numFaces = face_v.size()/3; for(vector<double>::const_iterator it = points_v.begin();it != points_v.end();it+=3) { MFloatPoint vtx(*it,*(it+1),*(it+2)); points.append(vtx); } vector<int> face_count; for(int i=0;i<numFaces;i++) { face_count.push_back(3); } MIntArray faceCounts(&face_count[0],numFaces); vector<int> face_connects; face_connects.resize(face_v.size()); for(int i=0;i<face_v.size();++i) { face_connects[i] = face_v[i]; } MIntArray faceConnects( &face_connects[0], face_connects.size() ); MObject newMesh=meshFS.create(numVertices, numFaces,points, faceCounts, faceConnects,outData,&stat); return newMesh; }
ConstObjectPtr SceneShape::readSceneShapeObject( const MDagPath &p ) { SceneShape *sceneShape = findScene( p, true ); if ( !sceneShape ) { return 0; } MPlug pTime( sceneShape->thisMObject(), aTime ); MTime time; pTime.getValue( time ); double t = time.as( MTime::kSeconds ); return sceneShape->getSceneInterface()->readObject( t ); }
ConstObjectPtr SceneShape::readSceneShapeLink( const MDagPath &p ) { MDagPath dagPath; SceneShape *sceneShape = findScene( p, true, &dagPath ); if ( !sceneShape ) { throw Exception("readSceneShapeLink: Could not find SceneShape!"); } ConstSceneInterfacePtr scene = sceneShape->getSceneInterface(); if ( !scene ) { throw Exception( "Empty scene!"); } MFnDagNode fnChildDag( dagPath ); MStatus st; MPlug timePlug = fnChildDag.findPlug( aTime, &st ); if( !st ) { throw Exception( "Could not find 'time' plug in SceneShape!"); } // if time plug is connected to maya global time, then we assume there's no time remapping between the Maya scene and the loaded scene. MPlugArray array; timePlug.connectedTo( array, true, false, &st ); if( !st ) { throw Exception( "Could not find 'time' plug connections in SceneShape!"); } for ( unsigned int i = 0; i < array.length(); i++ ) { if ( array[i].name() == "time1.outTime" ) { /// connected to time, so no time remapping between maya scene and loaded scene. return LinkedScene::linkAttributeData( scene.get() ); } } /// couldn't find connection to maya time, so this node is mapping the time some other way. MTime time; timePlug.getValue( time ); return LinkedScene::linkAttributeData( scene.get(), time.as( MTime::kSeconds ) ); }
/** * Build the animation from a Maya generic animated Transform */ osg::ref_ptr<osg::AnimationPath> Transform::animatedTransform2AnimationPath(MObject &obj) { osg::ref_ptr<osg::AnimationPath> anim = new osg::AnimationPath(); MTime start = MAnimControl::animationStartTime(); MTime end = MAnimControl::animationEndTime(); for( MTime t = start ; t <= end ; t += Config::instance()->getAnimSampleBy() ) { // Set the right time in Maya timeline so all properties are updated MAnimControl::setCurrentTime(t); anim->insert(t.as(MTime::kSeconds), osg::AnimationPath::ControlPoint( getCPPosition(obj), getCPRotation(obj), getCPScale(obj) )); } return anim; }
// // 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; }
float convert( const MTime &from ) { return from.as( MTime::kSeconds ); }
void ParamList::parseArgs(const MArgList &args) { MStatus stat; // Parse arguments from command line for (unsigned int i = 0; i < args.length(); i++ ) { if ((MString("-all") == args.asString(i,&stat)) && (MS::kSuccess == stat)) exportAll = true; else if ((MString("-world") == args.asString(i,&stat)) && (MS::kSuccess == stat)) exportWorldCoords = true; else if ((MString("-mesh") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportMesh = true; meshFilename = args.asString(++i,&stat); } else if ((MString("-mat") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportMaterial = true; materialFilename = args.asString(++i,&stat); } else if ((MString("-matPrefix") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { matPrefix = args.asString(++i,&stat); } else if ((MString("-copyTex") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { copyTextures = true; texOutputDir = args.asString(++i,&stat); } else if ((MString("-lightOff") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { lightingOff = true; } else if ((MString("-skel") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportSkeleton = true; skeletonFilename = args.asString(++i,&stat); } else if ((MString("-anims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportAnims = true; } else if ((MString("-animCur") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportAnimCurves = true; animFilename = args.asString(++i,&stat); } else if ((MString("-cam") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportCameras = true; camerasFilename = args.asString(++i,&stat); } else if ((MString("-v") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportVBA = true; } else if ((MString("-n") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportVertNorm = true; } else if ((MString("-c") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportVertCol = true; } else if ((MString("-cw") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportVertCol = true; exportVertColWhite = true; } else if ((MString("-t") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportTexCoord = true; } else if ((MString("-camAnim") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportCamerasAnim = true; } else if ((MString("-meshbin") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportMeshBin = true; } else if ((MString("-skelbin") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportSkelBin = true; } else if ((MString("-particles") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { exportParticles = true; particlesFilename = args.asString(++i,&stat); } else if ((MString("-shared") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { useSharedGeom = true; } else if ((MString("-np") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { MString npType = args.asString(i,&stat); if (npType == "curFrame") neutralPoseType = NPT_CURFRAME; else if (npType == "bindPose") neutralPoseType = NPT_BINDPOSE; else if (npType == "frame") { neutralPoseType = NPT_FRAME; neutralPoseFrame = args.asInt(++i,&stat); } } else if ((MString("-clip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) { //get clip name MString clipName = args.asString(++i,&stat); //get clip range MString clipRangeType = args.asString(++i,&stat); double startTime, stopTime; if (clipRangeType == "startEnd") { startTime = args.asDouble(++i,&stat); stopTime = args.asDouble(++i,&stat); MString rangeUnits = args.asString(++i,&stat); if (rangeUnits == "frames") { //range specified in frames => convert to seconds MTime t1(startTime, MTime::uiUnit()); MTime t2(stopTime, MTime::uiUnit()); startTime = t1.as(MTime::kSeconds); stopTime = t2.as(MTime::kSeconds); } } else { //range specified by time slider MTime t1 = MAnimControl::minTime(); MTime t2 = MAnimControl::maxTime(); startTime = t1.as(MTime::kSeconds); stopTime = t2.as(MTime::kSeconds); } // get sample rate double rate; MString sampleRateType = args.asString(++i,&stat); if (sampleRateType == "sampleByFrames") { // rate specified in frames int intRate = args.asInt(++i,&stat); MTime t = MTime(intRate, MTime::uiUnit()); rate = t.as(MTime::kSeconds); } else { // rate specified in seconds rate = args.asDouble(++i,&stat); } //add clip info clipInfo clip; clip.name = clipName; clip.start = startTime; clip.stop = stopTime; clip.rate = rate; clipList.push_back(clip); std::cout << "clip " << clipName.asChar() << "\n"; std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; std::cout << "rate: " << rate << "\n"; std::cout << "-----------------\n"; } } /* // Read options from exporter window // Gather clips data // Read info about the clips we have to transform int numClips,exportClip,rangeType,rateType,rangeUnits; double startTime,stopTime,rate; MString clipName; //read number of clips MGlobal::executeCommand("eval \"$numClips+=0\"",numClips,false); //read clips data for (int i=1; i<=numClips; i++) { MString command = "checkBox -q -v ExportClip"; command += i; MGlobal::executeCommand(command,exportClip,false); if (exportClip) { //get clip name command = "textField -q -tx ClipName"; command += i; MGlobal::executeCommand(command,clipName,false); //get clip range command = "radioButtonGrp -q -sl ClipRangeRadio"; command += i; MGlobal::executeCommand(command,rangeType,false); if (rangeType == 1) { //range specified from user command = "floatField -q -v ClipRangeStart"; command += i; MGlobal::executeCommand(command,startTime,false); command = "floatField -q -v ClipRangeEnd"; command += i; MGlobal::executeCommand(command,stopTime,false); //get range units command = "radioButtonGrp -q -sl ClipRangeUnits"; command += i; MGlobal::executeCommand(command,rangeUnits,false); if (rangeUnits == 1) { //range specified in frames => convert to seconds MTime t1(startTime, MTime::uiUnit()); MTime t2(stopTime, MTime::uiUnit()); startTime = t1.as(MTime::kSeconds); stopTime = t2.as(MTime::kSeconds); } } else { //range specified by time slider MTime t1 = MAnimControl::minTime(); MTime t2 = MAnimControl::maxTime(); startTime = t1.as(MTime::kSeconds); stopTime = t2.as(MTime::kSeconds); } //get sample rate command = "radioButtonGrp -q -sl ClipRateType"; command += i; MGlobal::executeCommand(command,rateType,false); MTime t; switch (rateType) { case 1: //rate specified in frames command = "intField -q -v ClipRateFrames"; command += i; MGlobal::executeCommand(command,rate,false); t = MTime(rate, MTime::uiUnit()); rate = t.as(MTime::kSeconds); break; case 2: //rate specified in seconds command = "floatField -q -v ClipRateSeconds"; command += i; MGlobal::executeCommand(command,rate,false); break; default://rate not specified, get from time slider rate = -1; break; } //add clip info clipInfo clip; clip.name = clipName; clip.start = startTime; clip.stop = stopTime; clip.rate = rate; clipList.push_back(clip); std::cout << "clip " << clipName.asChar() << "\n"; std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; std::cout << "rate: " << rate << "\n"; std::cout << "-----------------\n"; } }*/ }
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock) { MStatus status; // update the frame number to be imported MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status); double speed = speedHandle.asDouble(); MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status); double offset = offsetHandle.asDouble(); MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status); MTime t = timeHandle.asTime(); double inputTime = t.as(MTime::kSeconds); double fps = getFPS(); // scale and offset inputTime. inputTime = computeAdjustedTime(inputTime, speed, offset/fps); // this should be done only once per file if (mFileInitialized == false) { mFileInitialized = true; MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr); MFileObject fileObject; fileObject.setRawFullName(dataHandle.asString()); MString fileName = fileObject.resolvedFullName(); // TODO, make sure the file name, or list of files create a valid // Alembic IArchive // initialize some flags for plug update mSubDInitialized = false; mPolyInitialized = false; // When an alembic cache will be imported at the first time using // AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be // mIncludeFilterString for later use. When we save a maya scene(.ma) // mIncludeFilterAttr will be saved. Then when we load the saved // .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr. MDataHandle includeFilterHandle = dataBlock.inputValue(mIncludeFilterAttr, &status); MString& includeFilterString = includeFilterHandle.asString(); if (mIncludeFilterString.length() > 0) { includeFilterHandle.set(mIncludeFilterString); dataBlock.setClean(mIncludeFilterAttr); } else if (includeFilterString.length() > 0) { mIncludeFilterString = includeFilterString; } MDataHandle excludeFilterHandle = dataBlock.inputValue(mExcludeFilterAttr, &status); MString& excludeFilterString = excludeFilterHandle.asString(); if (mExcludeFilterString.length() > 0) { excludeFilterHandle.set(mExcludeFilterString); dataBlock.setClean(mExcludeFilterAttr); } else if (excludeFilterString.length() > 0) { mExcludeFilterString = excludeFilterString; } MFnDependencyNode dep(thisMObject()); MPlug allSetsPlug = dep.findPlug("allColorSets"); CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(), MObject::kNullObj, CreateSceneVisitor::NONE, "", mIncludeFilterString, mExcludeFilterString); { mData.getFrameRange(mSequenceStartTime, mSequenceEndTime); MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr, &status); startFrameHandle.set(mSequenceStartTime*fps); MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr, &status); endFrameHandle.set(mSequenceEndTime*fps); } } // Retime MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status); short playType = cycleHandle.asShort(); inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime, playType); clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime); // update only when the time lapse is big enough if (fabs(inputTime - mCurTime) > 0.00001) { mOutRead = std::vector<bool>(mOutRead.size(), false); mCurTime = inputTime; } if (plug == mOutPropArrayAttr) { if (mOutRead[0]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[0] = true; unsigned int propSize = static_cast<unsigned int>(mData.mPropList.size()); if (propSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutPropArrayAttr, &status); unsigned int outHandleIndex = 0; MDataHandle outHandle; // for all of the nodes with sampled attributes for (unsigned int i = 0; i < propSize; i++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(); } else { continue; } if (mData.mPropList[i].mArray.valid()) { readProp(mCurTime, mData.mPropList[i].mArray, outHandle); } else if (mData.mPropList[i].mScalar.valid()) { // for visibility only if (mData.mPropList[i].mScalar.getName() == Alembic::AbcGeom::kVisibilityPropertyName) { Alembic::Util::int8_t visVal = 1; mData.mPropList[i].mScalar.get(&visVal, Alembic::Abc::ISampleSelector(mCurTime, Alembic::Abc::ISampleSelector::kNearIndex )); outHandle.setGenericBool(visVal != 0, false); } else { // for all scalar props readProp(mCurTime, mData.mPropList[i].mScalar, outHandle); } } outArrayHandle.next(); } outArrayHandle.setAllClean(); } } else if (plug == mOutTransOpArrayAttr ) { if (mOutRead[1]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[1] = true; unsigned int xformSize = static_cast<unsigned int>(mData.mXformList.size()); if (xformSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutTransOpArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr); MDataHandle outHandle; unsigned int outHandleIndex = 0; for (unsigned int i = 0; i < xformSize; i++) { std::vector<double> sampleList; if (mData.mIsComplexXform[i]) { readComplex(mCurTime, mData.mXformList[i], sampleList); } else { Alembic::AbcGeom::XformSample samp; read(mCurTime, mData.mXformList[i], sampleList, samp); } unsigned int sampleSize = (unsigned int)sampleList.size(); for (unsigned int j = 0; j < sampleSize; j++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(&status); } else continue; outArrayHandle.next(); outHandle.set(sampleList[j]); } } outArrayHandle.setAllClean(); } } else if (plug == mOutLocatorPosScaleArrayAttr ) { if (mOutRead[8]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[8] = true; unsigned int locSize = static_cast<unsigned int>(mData.mLocList.size()); if (locSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr); MDataHandle outHandle; unsigned int outHandleIndex = 0; for (unsigned int i = 0; i < locSize; i++) { std::vector< double > sampleList; read(mCurTime, mData.mLocList[i], sampleList); unsigned int sampleSize = (unsigned int)sampleList.size(); for (unsigned int j = 0; j < sampleSize; j++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(&status); } else continue; outArrayHandle.next(); outHandle.set(sampleList[j]); } } outArrayHandle.setAllClean(); } } else if (plug == mOutSubDArrayAttr) { if (mOutRead[2]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutSubDArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[2] = true; unsigned int subDSize = static_cast<unsigned int>(mData.mSubDList.size()); if (subDSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutSubDArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < subDSize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFnMesh fnMesh(obj); readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j], mSubDInitialized); outHandle.set(obj); } } mSubDInitialized = true; outArrayHandle.setAllClean(); } // for the case where we don't have any nodes, we want to make sure // to push out empty meshes on our connections, this can happen if // the input file was offlined, currently we only need to do this for // meshes as Nurbs, curves, and the other channels don't crash Maya else { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutSubDArrayAttr, &status); if (outArrayHandle.elementCount() > 0) { do { MDataHandle outHandle = outArrayHandle.outputValue(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFloatPointArray emptyVerts; MIntArray emptyCounts; MIntArray emptyConnects; MFnMesh emptyMesh; emptyMesh.create(0, 0, emptyVerts, emptyCounts, emptyConnects, obj); outHandle.set(obj); } } while (outArrayHandle.next() == MS::kSuccess); } mSubDInitialized = true; outArrayHandle.setAllClean(); } } else if (plug == mOutPolyArrayAttr) { if (mOutRead[3]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutPolyArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[3] = true; unsigned int polySize = static_cast<unsigned int>(mData.mPolyMeshList.size()); if (polySize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutPolyArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < polySize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFnMesh fnMesh(obj); readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j], mPolyInitialized); outHandle.set(obj); } } mPolyInitialized = true; outArrayHandle.setAllClean(); } // for the case where we don't have any nodes, we want to make sure // to push out empty meshes on our connections, this can happen if // the input file was offlined, currently we only need to do this for // meshes as Nurbs, curves, and the other channels don't crash Maya else { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutPolyArrayAttr, &status); if (outArrayHandle.elementCount() > 0) { do { MDataHandle outHandle = outArrayHandle.outputValue(&status); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFloatPointArray emptyVerts; MIntArray emptyCounts; MIntArray emptyConnects; MFnMesh emptyMesh; emptyMesh.create(0, 0, emptyVerts, emptyCounts, emptyConnects, obj); outHandle.set(obj); } } while (outArrayHandle.next() == MS::kSuccess); } mPolyInitialized = true; outArrayHandle.setAllClean(); } } else if (plug == mOutCameraArrayAttr) { if (mOutRead[4]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[4] = true; unsigned int cameraSize = static_cast<unsigned int>(mData.mCameraList.size()); if (cameraSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutCameraArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr); double angleConversion = 1.0; switch (MAngle::uiUnit()) { case MAngle::kRadians: angleConversion = 0.017453292519943295; break; case MAngle::kAngMinutes: angleConversion = 60.0; break; case MAngle::kAngSeconds: angleConversion = 3600.0; break; default: break; } MDataHandle outHandle; unsigned int index = 0; for (unsigned int cameraIndex = 0; cameraIndex < cameraSize; cameraIndex++) { Alembic::AbcGeom::ICamera & cam = mData.mCameraList[cameraIndex]; std::vector<double> array; read(mCurTime, cam, array); for (unsigned int dataIndex = 0; dataIndex < array.size(); dataIndex++, index++) { // skip over sparse elements if (index != outArrayHandle.elementIndex()) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); // not shutter angle index, so not an angle if (dataIndex != 11) { outHandle.set(array[dataIndex]); } else { outHandle.set(array[dataIndex] * angleConversion); } } // for the per camera data handles } // for each camera outArrayHandle.setAllClean(); } } else if (plug == mOutNurbsSurfaceArrayAttr) { if (mOutRead[5]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[5] = true; unsigned int nSurfaceSize = static_cast<unsigned int>(mData.mNurbsList.size()); if (nSurfaceSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < nSurfaceSize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) continue; outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kNurbsSurface)) { readNurbs(mCurTime, mData.mNurbsList[j], obj); outHandle.set(obj); } } outArrayHandle.setAllClean(); } } else if (plug == mOutNurbsCurveGrpArrayAttr) { if (mOutRead[6]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[6] = true; unsigned int nCurveGrpSize = static_cast<unsigned int>(mData.mCurvesList.size()); if (nCurveGrpSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status); MDataHandle outHandle; std::vector<MObject> curvesObj; for (unsigned int i = 0; i < nCurveGrpSize; ++i) { readCurves(mCurTime, mData.mCurvesList[i], mData.mNumCurves[i], curvesObj); } std::size_t numChild = curvesObj.size(); // not the best way to do this // only reading bunches of curves based on the connections would be // more efficient when there is a bunch of broken connections for (unsigned int i = 0; i < numChild; i++) { if (outArrayHandle.elementIndex() != i) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); status = outHandle.set(curvesObj[i]); } outArrayHandle.setAllClean(); } } else { return MS::kUnknownParameter; } dataBlock.setClean(plug); return status; }
MStatus sweptEmitter::compute(const MPlug& plug, MDataBlock& block) // // Descriptions: // Call emit emit method to generate new particles. // { MStatus status; // Determine if we are requesting the output plug for this emitter node. // if( !(plug == mOutput) ) return( MS::kUnknownParameter ); // Get the logical index of the element this plug refers to, // because the node can be emitting particles into more // than one particle shape. // int multiIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in plug.logicalIndex.\n"); // Get output data arrays (position, velocity, or parentId) // that the particle shape is holding from the previous frame. // MArrayDataHandle hOutArray = block.outputArrayValue(mOutput, &status); McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n"); // Create a builder to aid in the array construction efficiently. // MArrayDataBuilder bOutArray = hOutArray.builder( &status ); McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n"); // Get the appropriate data array that is being currently evaluated. // MDataHandle hOut = bOutArray.addElement(multiIndex, &status); McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n"); // Get the data and apply the function set. // MFnArrayAttrsData fnOutput; MObject dOutput = fnOutput.create ( &status ); McheckErr(status, "ERROR in fnOutput.create.\n"); // Check if the particle object has reached it's maximum, // hence is full. If it is full then just return with zero particles. // bool beenFull = isFullValue( multiIndex, block ); if( beenFull ) { return( MS::kSuccess ); } // Get deltaTime, currentTime and startTime. // If deltaTime <= 0.0, or currentTime <= startTime, // do not emit new pariticles and return. // MTime cT = currentTimeValue( block ); MTime sT = startTimeValue( multiIndex, block ); MTime dT = deltaTimeValue( multiIndex, block ); if( (cT <= sT) || (dT <= 0.0) ) { // We do not emit particles before the start time, // and do not emit particles when moving backwards in time. // // This code is necessary primarily the first time to // establish the new data arrays allocated, and since we have // already set the data array to length zero it does // not generate any new particles. // hOut.set( dOutput ); block.setClean( plug ); return( MS::kSuccess ); } // Get speed, direction vector, and inheritFactor attributes. // double speed = speedValue( block ); MVector dirV = directionVector( block ); double inheritFactor = inheritFactorValue( multiIndex, block ); // Get the position and velocity arrays to append new particle data. // MVectorArray fnOutPos = fnOutput.vectorArray("position", &status); MVectorArray fnOutVel = fnOutput.vectorArray("velocity", &status); // Convert deltaTime into seconds. // double dt = dT.as( MTime::kSeconds ); // Apply rotation to the direction vector MVector rotatedV = useRotation ( dirV ); // position, MVectorArray inPosAry; // velocity MVectorArray inVelAry; // emission rate MIntArray emitCountPP; // Get the swept geometry data // MObject thisObj = this->thisMObject(); MPlug sweptPlug( thisObj, mSweptGeometry ); if ( sweptPlug.isConnected() ) { MDataHandle sweptHandle = block.inputValue( mSweptGeometry ); // MObject sweptData = sweptHandle.asSweptGeometry(); MObject sweptData = sweptHandle.data(); MFnDynSweptGeometryData fnSweptData( sweptData ); // Curve emission // if (fnSweptData.lineCount() > 0) { int numLines = fnSweptData.lineCount(); for ( int i=0; i<numLines; i++ ) { inPosAry.clear(); inVelAry.clear(); emitCountPP.clear(); MDynSweptLine line = fnSweptData.sweptLine( i ); // ... process current line ... MVector p1 = line.vertex( 0 ); MVector p2 = line.vertex( 1 ); inPosAry.append( p1 ); inPosAry.append( p2 ); inVelAry.append( MVector( 0,0,0 ) ); inVelAry.append( MVector( 0,0,0 ) ); // emit Rate for two points on line emitCountPP.clear(); status = emitCountPerPoint( plug, block, 2, emitCountPP ); emit( inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel ); } } // Surface emission (nurb or polygon) // if (fnSweptData.triangleCount() > 0) { int numTriangles = fnSweptData.triangleCount(); for ( int i=0; i<numTriangles; i++ ) { inPosAry.clear(); inVelAry.clear(); emitCountPP.clear(); MDynSweptTriangle tri = fnSweptData.sweptTriangle( i ); // ... process current triangle ... MVector p1 = tri.vertex( 0 ); MVector p2 = tri.vertex( 1 ); MVector p3 = tri.vertex( 2 ); MVector center = p1 + p2 + p3; center /= 3.0; inPosAry.append( center ); inVelAry.append( MVector( 0,0,0 ) ); // emit Rate for two points on line emitCountPP.clear(); status = emitCountPerPoint( plug, block, 1, emitCountPP ); emit( inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel ); } } } // Update the data block with new dOutput and set plug clean. // hOut.set( dOutput ); block.setClean( plug ); return( MS::kSuccess ); }
MStatus NuiMayaDeviceGrabber::compute( const MPlug& plug, MDataBlock& datablock ) // // Description: // This method computes the value of the given output plug based // on the values of the input attributes. // // Arguments: // plug - the plug to compute // data - object that provides access to the attributes for this node // { assert(m_pCache); if(!m_pCache) return MS::kFailure; MStatus returnStatus; /* Get time */ MDataHandle timeData = datablock.inputValue( aTime, &returnStatus ); MCHECKERROR(returnStatus, "Error getting time data handle\n") MTime time = timeData.asTime(); //!< 30 frames per second int frame = (int)time.as( MTime::kNTSCFrame ) - 1;//Noted: The first frame in MAYA is 1; if(m_pDevice) { std::shared_ptr<NuiCompositeFrame> pFrame = m_pDevice->popFrame(); if(pFrame) { pFrame->m_depthFrame.SetMinDepth(getShortValue(aMinDepth)); pFrame->m_depthFrame.SetMaxDepth(getShortValue(aMaxDepth)); if(m_pSLAM /*&& m_pSLAM->m_tracker.isThreadOn()*/) { std::shared_ptr<NuiVisualFrame> pVisualFrame = std::make_shared<NuiVisualFrame>(); pVisualFrame->acquireFromCompositeFrame(pFrame.get()); m_pSLAM->m_tracker.pushbackFrame(pVisualFrame); pVisualFrame.reset(); } m_pCache->pushbackFrame(pFrame); pFrame.reset(); } } std::shared_ptr<NuiCompositeFrame> pCurrentFrame = m_pCache->getLatestFrame(); if ( plug == aOutputMappable ) { std::shared_ptr<NuiCLMappableData> clData(nullptr); MDataHandle outHandle = datablock.outputValue( aOutputMappable ); NuiMayaMappableData* clmData = static_cast<NuiMayaMappableData*>(outHandle.asPluginData()); if(!clmData) { // Create some user defined geometry data and access the // geometry so we can set it // MFnPluginData fnDataCreator; MTypeId tmpid( NuiMayaMappableData::id ); fnDataCreator.create( tmpid, &returnStatus ); MCHECKERROR( returnStatus, "compute : error creating mappableData") clmData = (NuiMayaMappableData*)fnDataCreator.data( &returnStatus ); MCHECKERROR( returnStatus, "compute : error gettin at proxy mappableData object") clData = std::shared_ptr<NuiCLMappableData>(new NuiCLMappableData()); clmData->setData(clData); returnStatus = outHandle.set( clmData ); MCHECKERROR( returnStatus, "compute : error gettin at proxy mappableData object") }
// return seconds per frame double util::spf() { static const MTime sec(1.0, MTime::kSeconds); return 1.0 / sec.as(MTime::uiUnit()); }
MObject ClothSimMayaPlugin::createMesh(const MTime& time, MObject& outData, MStatus& stat) { double t = time.as(MTime::kSeconds); if (t <= 1.0 / 24 && m_prevTime > 1.0/24) { m_simMesh.reset(0); } int nx = 60; int ny = 60; if (!m_simMesh.get()) { Eigen::VectorXf v((nx+1) * (ny+1) * 3); Eigen::VectorXf x((nx + 1) * (ny + 1) * 3); Eigen::VectorXf uv((nx + 1) * (ny + 1) * 2); for (int i = 0; i <= nx; ++i) { for (int j = 0; j <= ny; ++j) { int base = i + (nx+1) * j; uv[2 * base + 0] = (float)i / nx - 0.5f; uv[2 * base + 1] = (float)j / ny - 0.5f; x[3 * base + 0] = uv[2 * base + 0]; x[3 * base + 1] = 0; x[3 * base + 2] = uv[2 * base + 1]; v[3 * base + 0] = v[3 * base + 1] = v[3 * base + 2] = 0; } } std::vector<int> triangleInds; for (int i = 0; i < nx; ++i) { for (int j = 0; j < ny; ++j) { int base = i + (nx + 1) * j; triangleInds.push_back(base + 0); triangleInds.push_back(base + 1); triangleInds.push_back(base + (nx + 1)); triangleInds.push_back(base + 1); triangleInds.push_back(base + (nx + 2)); triangleInds.push_back(base + (nx + 1)); } } m_simMesh.reset( new ClothMesh<float>( x, v, uv, triangleInds, 0.01f, 1000000.0f, 1000000.0f, 0.01f, 1000.0f, 1000.0f, 1.0f ) ); } std::vector<int> constraintIndices; std::vector< Eigen::Matrix3f > constraintMatrices; Eigen::VectorXf constraintVelocityDeltas(m_simMesh->x().size()); constraintVelocityDeltas.setConstant(0); for (int i = 0; i <= nx; ++i) { for (int j = 0; j <= ny; ++j) { int idx = i + (nx + 1) * j; float x = (float)i / nx - 0.5f; float y = (float)j / ny - 0.5f; if (x * x + y * y < 0.3 * 0.3) { constraintIndices.push_back(idx); constraintMatrices.push_back(Eigen::Matrix3f::Zero()); } } } if (t > m_prevTime) { ConstrainedCGSolver<float> solver( constraintIndices, constraintMatrices, constraintVelocityDeltas, 0.01f, 400 ); GravityField<float> g( m_simMesh->m(), Eigen::Vector3f( 0,-9.8f, 0 ) ); std::vector< ForceField<float>* > forceFields; forceFields.push_back( &g ); try { std::cerr << "advance" << std::endl; m_simMesh->advance(forceFields, float(t - m_prevTime)*0.5f, solver); m_simMesh->advance(forceFields, float(t - m_prevTime)*0.5f, solver); std::cerr << "done" << std::endl; } catch (const std::exception &e) { std::cerr << e.what() << std::endl; stat = MStatus::kFailure; return MObject(); } catch (...) { std::cerr << "unknown exception" << std::endl; stat = MStatus::kFailure; return MObject(); } } m_prevTime = t; MFloatPointArray points; for (int i = 0; i < m_simMesh->x().size(); i += 3) { MFloatPoint p(m_simMesh->x()[i], m_simMesh->x()[i + 1], m_simMesh->x()[i + 2]); points.append(p); } MFnMesh meshFS; MIntArray faceCounts((int)m_simMesh->triangleIndices().size()/3, 3); MIntArray faceConnects; for (unsigned i = 0; i < m_simMesh->triangleIndices().size(); ++i) { faceConnects.append(m_simMesh->triangleIndices()[i]); } MObject newMesh = meshFS.create((int)m_simMesh->x().size() / 3, (int)m_simMesh->triangleIndices().size() / 3, points, faceCounts, faceConnects, outData, &stat); return newMesh; }
virtual void ExportProcedural( AtNode *node ) { // do basic node export ExportMatrix( node, 0 ); // AiNodeSetPtr( node, "shader", arnoldShader(node) ); AiNodeSetInt( node, "visibility", ComputeVisibility() ); MPlug plug = FindMayaObjectPlug( "receiveShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "receive_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiSelfShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "self_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiOpaque" ); if( !plug.isNull() ) { AiNodeSetBool( node, "opaque", plug.asBool() ); } // now set the procedural-specific parameters AiNodeSetBool( node, "load_at_init", true ); // just for now so that it can load the shaders at the right time MFnDagNode fnDagNode( m_dagPath ); MBoundingBox bound = fnDagNode.boundingBox(); AiNodeSetPnt( node, "min", bound.min().x-m_dispPadding, bound.min().y-m_dispPadding, bound.min().z-m_dispPadding ); AiNodeSetPnt( node, "max", bound.max().x+m_dispPadding, bound.max().y, bound.max().z+m_dispPadding ); const char *dsoPath = getenv( "ALEMBIC_ARNOLD_PROCEDURAL_PATH" ); AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "bb_AlembicArnoldProcedural.so" ); // Set the parameters for the procedural //abcFile path MString abcFile = fnDagNode.findPlug("cacheFileName").asString().expandEnvironmentVariablesAndTilde(); //object path MString objectPath = fnDagNode.findPlug("cacheGeomPath").asString(); //object pattern MString objectPattern = "*"; plug = FindMayaObjectPlug( "objectPattern" ); if (!plug.isNull() ) { if (plug.asString() != "") { objectPattern = plug.asString(); } } //object pattern MString excludePattern = ""; plug = FindMayaObjectPlug( "excludePattern" ); if (!plug.isNull() ) { if (plug.asString() != "") { excludePattern = plug.asString(); } } float shutterOpen = 0.0; plug = FindMayaObjectPlug( "shutterOpen" ); if (!plug.isNull() ) { shutterOpen = plug.asFloat(); } float shutterClose = 0.0; plug = FindMayaObjectPlug( "shutterClose" ); if (!plug.isNull() ) { shutterClose = plug.asFloat(); } float timeOffset = 0.0; plug = FindMayaObjectPlug( "timeOffset" ); if (!plug.isNull() ) { timeOffset = plug.asFloat(); } int subDIterations = 0; plug = FindMayaObjectPlug( "ai_subDIterations" ); if (!plug.isNull() ) { subDIterations = plug.asInt(); } MString nameprefix = ""; plug = FindMayaObjectPlug( "namePrefix" ); if (!plug.isNull() ) { nameprefix = plug.asString(); } // bool exportFaceIds = fnDagNode.findPlug("exportFaceIds").asBool(); bool makeInstance = true; // always on for now plug = FindMayaObjectPlug( "makeInstance" ); if (!plug.isNull() ) { makeInstance = plug.asBool(); } bool flipv = false; plug = FindMayaObjectPlug( "flipv" ); if (!plug.isNull() ) { flipv = plug.asBool(); } bool invertNormals = false; plug = FindMayaObjectPlug( "invertNormals" ); if (!plug.isNull() ) { invertNormals = plug.asBool(); } short i_subDUVSmoothing = 1; plug = FindMayaObjectPlug( "ai_subDUVSmoothing" ); if (!plug.isNull() ) { i_subDUVSmoothing = plug.asShort(); } MString subDUVSmoothing; switch (i_subDUVSmoothing) { case 0: subDUVSmoothing = "pin_corners"; break; case 1: subDUVSmoothing = "pin_borders"; break; case 2: subDUVSmoothing = "linear"; break; case 3: subDUVSmoothing = "smooth"; break; default : subDUVSmoothing = "pin_corners"; break; } MTime curTime = MAnimControl::currentTime(); // fnDagNode.findPlug("time").getValue( frame ); // MTime frameOffset; // fnDagNode.findPlug("timeOffset").getValue( frameOffset ); float time = curTime.as(MTime::kFilm)+timeOffset; MString argsString; if (objectPath != "|"){ argsString += "-objectpath "; // convert "|" to "/" argsString += MString(replace_all(objectPath,"|","/").c_str()); } if (objectPattern != "*"){ argsString += "-pattern "; argsString += objectPattern; } if (excludePattern != ""){ argsString += "-excludepattern "; argsString += excludePattern; } if (shutterOpen != 0.0){ argsString += " -shutteropen "; argsString += shutterOpen; } if (shutterClose != 0.0){ argsString += " -shutterclose "; argsString += shutterClose; } if (subDIterations != 0){ argsString += " -subditerations "; argsString += subDIterations; argsString += " -subduvsmoothing "; argsString += subDUVSmoothing; } if (makeInstance){ argsString += " -makeinstance "; } if (nameprefix != ""){ argsString += " -nameprefix "; argsString += nameprefix; } if (flipv){ argsString += " -flipv "; } if (invertNormals){ argsString += " -invertNormals "; } argsString += " -filename "; argsString += abcFile; argsString += " -frame "; argsString += time; if (m_displaced){ argsString += " -disp_map "; argsString += AiNodeGetName(m_dispNode); } AiNodeSetStr(node, "data", argsString.asChar()); ExportUserAttrs(node); // Export light linking per instance ExportLightLinking(node); }
MStatus NBuddyEMPSaverNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; if (plug == _outTrigger) { MDataHandle outputPathHdl = data.inputValue( _empOutputPath, &status ); NM_CheckMStatus( status, "Failed to get the output path handle"); MString outputPath = outputPathHdl.asString(); // Get the input time MDataHandle timeHdl = data.inputValue( _time, &status ); NM_CheckMStatus( status, "Failed to get time handle"); MTime time = timeHdl.asTime(); // Get the frame padding MDataHandle framePaddingHdl = data.inputValue( _framePadding, &status ); NM_CheckMStatus( status, "Failed to get the framePadding handle"); int numPad = framePaddingHdl.asInt(); // Get the frame padding MDataHandle timeStepHdl = data.inputValue( _timeStep, &status ); NM_CheckMStatus( status, "Failed to get the timeStep handle"); int timeStep = timeStepHdl.asInt(); // Get the time in frames int frameNr = (int)floor( time.as( time.uiUnit() ) ); //Create the writer, givin it the time index in seconds Nb::EmpWriter* writer = new Nb::EmpWriter( "", outputPath.asChar(), // absolute fullpath of emp frameNr, // frame timeStep, // timestep numPad, // zero-padding time.as( MTime::kSeconds ) // emp timestamp ); // Then get the inputBodies MArrayDataHandle inBodyArrayData = data.inputArrayValue( _inBodies, &status ); NM_CheckMStatus( status, "Failed to create get inBodyArrayData handle"); // Loop the input in the inBody multi plug unsigned int numBodies = inBodyArrayData.elementCount(); if ( numBodies > 0 ) { //Jump to the first element in the array inBodyArrayData.jumpToArrayElement(0); //Loop all the body inputs and add them to the empWriter for ( unsigned int i(0); i < numBodies; ++i) { MDataHandle bodyDataHnd = inBodyArrayData.inputValue( &status ); MFnPluginData dataFn(bodyDataHnd.data()); //Get naiad body from datatype naiadBodyData * bodyData = (naiadBodyData*)dataFn.data( &status ); if ( bodyData && bodyData->nBody() ) { //Add body to writer try{ Nb::String channels("*.*"); writer->write(bodyData->nBody(),channels); } catch(std::exception& e) { std::cerr << "NBuddyEMPSaverNode::compute() " << e.what() << std::endl; } } else std::cerr << "NBuddyEMPSaverNode::compute() :: No body in input " << inBodyArrayData.elementIndex() << std::endl; //Next body in the input multi inBodyArrayData.next(); } } try{ writer->close(); // Get rid of the writer object delete writer; } catch(std::exception& e) { std::cerr << "NBuddyEMPSaverNode::compute() " << e.what() << std::endl; } //Set the output to be clean indicating that we have saved out the file MDataHandle outTriggerHnd = data.outputValue( _outTrigger, &status ); outTriggerHnd.set(true); data.setClean( plug ); } return status; }
MStatus latticeNoiseNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus returnStatus; float noiseAmplitude; float noiseFreq; if( plug == output ) { // Get the lattice data from the input attribute. First get the // data object, and then use the lattice data function set to extract // the actual lattice. // // Get the data handle // MDataHandle inputData = data.inputValue( input, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice data handle\n" ); // Get the data object // MObject latticeData = inputData.data(); MFnLatticeData dataFn( latticeData ); // Get the actual geometry // MObject lattice = dataFn.lattice(); MFnLattice lattFn( lattice, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice geometry\n" ); // Do the same for the output lattice // MDataHandle outputData = data.outputValue( output, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice data handle\n" ); // Get the data object // latticeData = outputData.data(); if ( latticeData.isNull() ) { // The data object for this attribute has not been created yet, so // we'll create it // latticeData = dataFn.create(); } else { // Use the data object that is already there // dataFn.setObject( latticeData ); } // Get the actual geometry // MObject outLattice = dataFn.lattice(); MFnLattice outLattFn( outLattice, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice geometry\n" ); // Get the amplitude and frequency // MDataHandle ampData = data.inputValue( amplitude, &returnStatus ); McheckErr( returnStatus, "ERROR getting amplitude\n" ); noiseAmplitude = ampData.asFloat(); MDataHandle freqData = data.inputValue( frequency, &returnStatus ); McheckErr( returnStatus, "ERROR getting frequency\n" ); noiseFreq = freqData.asFloat(); // Get the time. // MDataHandle timeData = data.inputValue( time, &returnStatus ); McheckErr( returnStatus, "ERROR getting time data handle\n" ); MTime time = timeData.asTime(); float seconds = (float)time.as( MTime::kSeconds ); // Easiest way to modify frequency is by modifying the time // seconds = seconds * noiseFreq; // We have the information we need now. We'll apply noise to the // points upon the lattice // unsigned s, t, u; lattFn.getDivisions( s, t, u ); // match up the divisions in the lattices // outLattFn.setDivisions( s, t, u ); for ( unsigned i = 0; i < s; i++ ) { for ( unsigned j = 0; j < t; j++ ) { for ( unsigned k = 0; k < u; k++ ) { MPoint & point = lattFn.point( i, j, k ); MPoint & outPoint = outLattFn.point( i, j, k ); pnt noisePnt = noise::atPointAndTime( (float)point.x, (float)point.y, (float)point.z, seconds ); // Make noise between -1 and 1 instead of 0 and 1 // noisePnt.x = ( noisePnt.x * 2.0F ) - 1.0F; noisePnt.y = ( noisePnt.y * 2.0F ) - 1.0F; noisePnt.z = ( noisePnt.z * 2.0F ) - 1.0F; outPoint.x = point.x + ( noisePnt.x * noiseAmplitude ); outPoint.y = point.y + ( noisePnt.y * noiseAmplitude ); outPoint.z = point.z + ( noisePnt.z * noiseAmplitude ); } } } outputData.set( latticeData ); data.setClean(plug); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
/** * Build the animation from Maya MotionPath */ osg::ref_ptr<osg::AnimationPath> Transform::motionPath2AnimationPath(MObject &obj) { osg::ref_ptr<osg::AnimationPath> anim = new osg::AnimationPath(); // STEP 1. Get the animation curve from this MotionPath MFnMotionPath motion; MFnDependencyNode dn(obj); MPlugArray conns; dn.getConnections(conns); for(int i=0; i<conns.length(); i++){ MPlug conn = conns[i]; MPlugArray connectedTo; // Get the connections having this node as destination conn.connectedTo(connectedTo, true, false); for(int j=0; j<connectedTo.length(); j++){ MPlug origin = connectedTo[j]; MObject origin_node = origin.node(); if(origin_node.hasFn(MFn::kMotionPath)){ motion.setObject(origin_node); break; } } } MFnAnimCurve anim_curve; dn.setObject(motion.object()); dn.getConnections(conns); for(int i=0; i<conns.length(); i++){ MPlug conn = conns[i]; MPlugArray connectedTo; // Get the connections having this node as destination conn.connectedTo(connectedTo, true, false); for(int j=0; j<connectedTo.length(); j++){ MPlug origin = connectedTo[j]; MObject origin_node = origin.node(); if(origin_node.hasFn(MFn::kAnimCurve)){ anim_curve.setObject(origin_node); break; } } } // STEP 2 ... // STEP 3. Benefits! for(int i=0; i<anim_curve.numKeys(); i++){ MTime t = anim_curve.time(i); double time = t.as(MTime::kSeconds); MAnimControl::setCurrentTime(MTime(time,MTime::kSeconds)); anim->insert(time, osg::AnimationPath::ControlPoint( getCPPosition(obj), getCPRotation(obj), getCPScale(obj) )); } return anim; }
// ------------------------------------------- void AnimationHelper::setAnimationEndTime ( float _time ) { MTime time ( _time, MTime::kSeconds ); double t = time.as ( MTime::uiUnit() ); MGlobal::executeCommand ( MString ( "playbackOptions -" TEND " " ) + t ); }