void TestDeformer::__debugMeshInfo(const char* msg, MObject &meshMobj) { #ifdef _DEBUG MStatus status; MFnMesh fnMesh(meshMobj, &status); CHECK_MSTATUS(status); __debug("%s(), fnMesh.fullPathName=%s", msg, fnMesh.fullPathName().asChar()); __debug("%s(), fnMesh.name=%s", msg, fnMesh.name().asChar()); MDagPath path; CHECK_MSTATUS(fnMesh.getPath(path)); __debug("%s(), path=%s", msg, path.fullPathName().asChar()); MDagPath dagpath = fnMesh.dagPath(&status); CHECK_MSTATUS(status); __debug("%s(), dagpath=%s", msg, dagpath.fullPathName().asChar()); MFnDependencyNode fnDNode(meshMobj, &status); CHECK_MSTATUS(status);// __debug("%s(), name=%s", msg, fnDNode.name().asChar()); MFnDagNode fnDagNode(meshMobj, &status); CHECK_MSTATUS(status);// MDagPath path2; CHECK_MSTATUS(fnDagNode.getPath(path2));// __debug("%s(), path2=%s", msg, path2.fullPathName().asChar()); MDagPath dagpath2 = fnDagNode.dagPath(&status); CHECK_MSTATUS(status);// __debug("%s(), dagpath2=%s", msg, dagpath2.fullPathName().asChar()); #endif }
MStatus linearFrictionCmd::doIt(const MArgList& args) { MStatus stat; MArgDatabase argData(syntax(),args,&stat); if(argData.isFlagSet(lfFlag))argData.getFlagArgument(lfFlag,0,linearFriction); MSelectionList activeSelect; MGlobal::getActiveSelectionList(activeSelect); for(int i=0;i<activeSelect.length();i++) { MObject tNode; activeSelect.getDependNode(i,tNode); MFnDagNode fnDagNode(tNode); MObject pNode=fnDagNode.child(0); MFnDependencyNode fnNode(pNode); //MString name=fnNode1.name().asChar(); if(fnNode.typeId() == particleNode::typeId) { //get solver message attribute from particleNode MPlug(pNode, particleNode::linearFriction).setValue(linearFriction); } } return dgMod.doIt(); }
//- This function is responsible to make the connection (association) //- between manipulators and the affected attributes. When a node in a scene //- is selected and user click on “show manipulator tool”, //- this function is called with the selected node. //- Arguments: //- dependNode - the node which is selected MStatus arrowLocatorManip::connectToDependNode(const MObject &dependNode) { MStatus status = MStatus::kSuccess; //- Find the "windDirection" plug on the selected node, which is the custom //- locator node. MFnDependencyNode fnDepNode(dependNode); MPlug rotationPlug = fnDepNode.findPlug(MString("windDirection"),&status); //- Connect the "windDirection" plug with the base disc manip MFnDiscManip fnDisc(fDiscManip,&status); status = fnDisc.connectToAnglePlug(rotationPlug); //- Set up affecting relationship using conversion callback function //- We are using addPlugToManipConversionCallback so that whenever //- the custom locator moves, the dis manip moves with it. MFnDagNode fnDagNode(dependNode); fnDagNode.getPath(fNodePath); unsigned int centerPointIndex = fnDisc.centerIndex(&status); addPlugToManipConversionCallback(centerPointIndex,(plugToManipConversionCallback)&arrowLocatorManip::centerPointCallback); //- The following two functions are mandatory inside your //- connectToDependNode() function status = finishAddingManips(); status = MPxManipContainer::connectToDependNode(dependNode); return status; }
// ========== DtCameraGetPosition ========== // // SYNOPSIS // Return the camera position. // int DtCameraGetPosition( int cameraID, float* xTran, float* yTran, float* zTran ) { // Check for error. // if( (cameraID < 0) || (cameraID >= local->camera_ct ) ) { *xTran = 0.0; *yTran = 0.0; *zTran = 0.0; return( 0 ); } MStatus stat = MS::kSuccess; MFnDagNode fnDagNode( local->cameras[cameraID].transformNode, &stat ); MDagPath aPath; stat = fnDagNode.getPath( aPath ); // Get the global transformation matrix of the camera node. // MMatrix globalMatrix = aPath.inclusiveMatrix(); MFnCamera fnCamera( local->cameras[cameraID].cameraShapeNode, &stat ); MPoint eyePt; double eyePos[4]; if( MS::kSuccess == stat ) { eyePt = fnCamera.eyePoint( MSpace::kObject, &stat ); if( DtExt_Debug() & DEBUG_CAMERA ) { cerr << "eye point is at " << eyePt.x << " " << eyePt.y << " " << eyePt.z << endl; } eyePt *= globalMatrix; eyePt.get( eyePos ); } else { DtExt_Err( "Error in getting the camera function set\n" ); } // Return values: // *xTran = eyePos[0]; *yTran = eyePos[1]; *zTran = eyePos[2]; return( 1 ); } // DtCameraGetPosition //
MStatus pbdSolverCmd::redoIt() { //create solver node MStatus stat; MObject transform = dgMod.createNode("transform"); MObject solver= dgMod.createNode(pbdSolverNode::typeId, transform, &stat); //connect time attribute MPlug plgInTime(solver,pbdSolverNode::time); MItDependencyNodes dnTime(MFn::kTime); MObject time = dnTime.thisNode(); MPlug plgOutTime = MFnDependencyNode(time).findPlug("outTime", false); dgMod.connect(plgOutTime, plgInTime); //connect msattr MSelectionList activeSelect; MGlobal::getActiveSelectionList(activeSelect); int pnum = 0, mnum = 0; for(int i = 0;i < activeSelect.length(); ++i) { MObject tNode; activeSelect.getDependNode(i,tNode); MFnDagNode fnDagNode(tNode); MObject pNode=fnDagNode.child(0); MFnDependencyNode fnNode(pNode); //MString name=fnNode1.name().asChar(); if(fnNode.typeId() == OParticleNode::typeId) { //get solver message attribute from particleNode MPlug s_msg(pNode,OParticleNode::pbd_solver); //get particle message attribute from solverNode MPlug o_msg(solver,pbdSolverNode::orientedParticle); dgMod.connect(o_msg,s_msg); ++pnum; } else if(pNode.apiType()==MFn::kMesh) { MString name=MFnDependencyNode(pNode).name().asChar(); MPlug m_vs=fnNode.findPlug("ogc",false); MPlug s_vs(solver,pbdSolverNode::inMesh); dgMod.connect(m_vs,s_vs); ++mnum; } } if( pnum == 0 ) MGlobal::displayError(" No oriented particles are selected"); if( mnum == 0 ) MGlobal::displayError(" No mesh is selected"); MGlobal::displayInfo("PBD solver is created"); return dgMod.doIt(); }
MStatus ReferenceManager::getTopLevelReferenceNode(const MDagPath & dagPath, MObject & outReferenceNode) { MStatus status; MFnDagNode fnDagNode(dagPath, &status); if (!status) return status; bool isFromReferencedFile = fnDagNode.isFromReferencedFile(&status); if (!status) return status; if (!isFromReferencedFile) { // dagPath is not a reference return MS::kFailure; } // Get full dag path MString fullPathName; fullPathName = dagPath.fullPathName(&status); if (!status) return status; // Get nearest reference node MString RNPath; MString command = MString("referenceQuery -referenceNode ") + fullPathName; status = MGlobal::executeCommand(command, RNPath); if (!status) return status; MObject RN = DagHelper::getNode(RNPath); if (RN.isNull()) return MS::kFailure; MFnReference fnRN(RN, &status); if (!status) return status; // Get parent most reference node MObject parentRN = fnRN.parentReference(&status); if (!status) return status; while (!parentRN.isNull()) { RN = parentRN; status = fnRN.setObject(parentRN); if (!status) return status; parentRN = fnRN.parentReference(&status); if (!status) return status; } outReferenceNode = RN; return MS::kSuccess; }
// ========== DtCameraGetInterest ========== // // SYNOPSIS // Return the camera position. // int DtCameraGetInterest(int cameraID,float* xTran,float* yTran,float* zTran) { // check for error // if ( (cameraID < 0) || (cameraID >= local->camera_ct) ) { *xTran = 0.0; *yTran = 0.0; *zTran = 0.0; return(0); } // return values // MStatus stat = MS::kSuccess; MFnDagNode fnDagNode( local->cameras[cameraID].transformNode, &stat ); MDagPath aPath; stat = fnDagNode.getPath( aPath ); // Get the global transformation matrix of the camera node. // MMatrix globalMatrix = aPath.inclusiveMatrix(); MFnCamera fnCamera( local->cameras[cameraID].cameraShapeNode, &stat ); // Center of interest point: view node point. // MPoint coiPoint = fnCamera.centerOfInterestPoint( MSpace::kObject, &stat ); double coiPos[4]; if( DtExt_Debug() & DEBUG_CAMERA ) { coiPoint.get( coiPos ); cerr << "local center of interest( view point position ) is " << coiPos[0] << " " << coiPos[1] << " " << coiPos[2] << " " << coiPos[3] << endl; } coiPoint *= globalMatrix; coiPoint.get( coiPos ); *xTran = coiPos[0]; *yTran = coiPos[1]; *zTran = coiPos[2]; return(1); } // DtCameraGetInterest //
//update the passive rigid bodies by interpolation of the previous and current frame void dSolverNode::updatePassiveRigidBodies(MPlugArray &rbConnections, std::vector<xforms_t> &xforms, float t) { size_t pb = 0; for(size_t i = 0; i < rbConnections.length(); ++i) { MObject node = rbConnections[i].node(); MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == rigidBodyNode::typeId) { rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; continue; } MPlug plgMass(node, rigidBodyNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(!active) { //do linear interpolation for now rb->set_transform(xforms[pb].m_x0 + t * (xforms[pb].m_x1 - xforms[pb].m_x0), normalize(xforms[pb].m_q0 + t * (xforms[pb].m_q1 - xforms[pb].m_q0))); ++pb; } } else if(fnDagNode.typeId() == rigidBodyArrayNode::typeId) { rigidBodyArrayNode *rbNode = static_cast<rigidBodyArrayNode*>(fnDagNode.userNode()); std::vector<rigid_body_t::pointer>& rbs = rbNode->rigid_bodies(); if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; return; } MPlug plgMass(node, rigidBodyArrayNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(!active) { for(size_t j = 0; j < rbs.size(); ++j) { rbs[j]->set_transform(xforms[pb].m_x0 + t * (xforms[pb].m_x1 - xforms[pb].m_x0), normalize(xforms[pb].m_q0 + t * (xforms[pb].m_q1 - xforms[pb].m_q0))); ++pb; } } } } }
void SoftBodyNode::computeSoftBody(const MPlug &plug, MDataBlock &data) { // std::cout << "(SoftBodyNode::computeSoftBody) | "; MObject thisObject(thisMObject()); MPlug plgInputMesh(thisObject, inputMesh); MObject update; //force evaluation of the shape plgInputMesh.getValue(update); btAssert(plgInputMesh.isConnected()); MPlugArray connections; plgInputMesh.connectedTo(connections, true, false); // MFnDependencyNode fnNode(connections[0].node()); btAssert( connections.length() != 0); // std::cout << "(SoftBodyNode::computeSoftBody) Dependency node fn name: | " << fnNode.name() << std::endl; MFnMesh meshFn(connections[0].node()); MFnDagNode fnDagNode(thisObject); MFnTransform fnTransform(fnDagNode.parent(0)); MVector mtranslation = fnTransform.getTranslation(MSpace::kTransform); MQuaternion mrotation; fnTransform.getRotation(mrotation, MSpace::kObject); std::cout << "(SoftBodyNode::computeSoftBody) fnTranform: | " << fnTransform.name().asChar() << std::endl; std::cout << "(SoftBodyNode::computeSoftBody) fnTranform: | " << mtranslation.x << ", " << mtranslation.y << ", " << mtranslation.z << std::endl; solver_t::remove_soft_body(this->m_soft_body); std::vector<int> triVertIndices; std::vector<float> triVertCoords; createHelperMesh(meshFn, triVertIndices, triVertCoords, MSpace::kTransform); this->m_soft_body = solver_t::create_soft_body(triVertCoords, triVertIndices); solver_t::add_soft_body(this->m_soft_body, this->name().asChar()); // this->m_soft_body->set_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z), // quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); data.outputValue(ca_softBody).set(true); data.setClean(plug); }
MStatus boingRbCmd::setBulletVectorAttribute(MObject node, MString attr, MVector vec) { //MObject node = rbConnections[i].node(); MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == boingRBNode::typeId) { boingRBNode *rbNode = static_cast<boingRBNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); if (rb) { if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; return MS::kFailure; } MPlug plgMass(node, boingRBNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { if (attr=="velocity") { vec3f vel; vel = vec3f((float)vec.x,(float)vec.y,(float)vec.z); rb->set_linear_velocity(vel); } else if (attr=="position") { vec3f pos; quatf rot; rb->get_transform(pos, rot); pos = vec3f((float)vec.x,(float)vec.y,(float)vec.z); rb->set_transform(pos, rot); } else if (attr=="angularVelocity") { vec3f av; av = vec3f((float)vec.x,(float)vec.y,(float)vec.z); rb->set_angular_velocity(av); } } } } return MS::kSuccess; }
MVector boingRbCmd::getBulletVectorAttribute(MObject node, MString attr) { MVector vec; MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == boingRBNode::typeId) { boingRBNode *rbNode = static_cast<boingRBNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); if (rb) { if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; return vec; } MPlug plgMass(node, boingRBNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { if (attr=="velocity") { vec3f vel; rb->get_linear_velocity(vel); vec = MVector((double)vel[0], (double)vel[1], (double)vel[2]); } else if (attr=="position") { vec3f pos; quatf rot; rb->get_transform(pos, rot); vec = MVector((double)pos[0], (double)pos[1], (double)pos[2]); } else if (attr=="angularVelocity") { vec3f av; rb->get_angular_velocity(av); vec = MVector((double)av[0], (double)av[1], (double)av[2]); } } } } return vec; }
void nailConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data) { // std::cout << "nailConstraintNode::computeWorldMatrix" << std::endl; MObject thisObject(thisMObject()); MFnDagNode fnDagNode(thisObject); MObject update; MPlug(thisObject, ca_constraint).getValue(update); MPlug(thisObject, ca_constraintParam).getValue(update); MStatus status; MFnTransform fnParentTransform(fnDagNode.parent(0, &status)); MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status); // MQuaternion mrotation; // fnParentTransform.getRotation(mrotation, MSpace::kTransform); if(m_constraint) { vec3f world; m_constraint->get_world(world); if(world[0] != float(mtranslation.x) || world[1] != float(mtranslation.y) || world[2] != float(mtranslation.z)) { /* mat4x4f xform; m_constraint->rigid_body()->get_transform(xform); vec4f pivot = prod(trans(xform), vec4f(mtranslation.x, mtranslation.y, mtranslation.z, 1.0)); std::cout << "pivot (" << pivot[0] << "," << pivot[0] << "," << pivot[0] << ")" << std::endl; */ // std::cout << "mtranslation (" << mtranslation[0] << "," << mtranslation[0] << "," << mtranslation[0] << ")" << std::endl; m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2])); } } data.setClean(plug); }
TransformNode::TransformNode(MObject node) : ContainerNode(node) { _isSkeleton = false; _isMesh = false; MFnDependencyNode fnDependencyNode(node); MPlugArray plugArray; fnDependencyNode.getConnections(plugArray); for (int i = 0; i < plugArray.length(); i++) { MPlug& plug = plugArray[i]; bool isArray = plug.isArray(); MPlugArray connectedDstPlugins, connectedSrcPlugins; if (plug.connectedTo(connectedDstPlugins, true, false) == true) { for (int i = 0; i < connectedDstPlugins.length(); i++) { MPlug& plug = connectedDstPlugins[i]; MObject node = plug.node(); MFnDependencyNode fnPlugNode(node); MString name = fnPlugNode.name(); } } } MFnDagNode fnDagNode(node); int childCount = fnDagNode.childCount(); for (int i = 0; i < childCount; i++) { MObject child = fnDagNode.child(i); if (child.hasFn(MFn::kMesh)) { _isMesh = true; break; } else if (child.hasFn(MFn::kJoint)) { _isSkeleton = true; break; } } }
// ========== DtCameraGetOrientationQuaternion ========== // // SYNOPSIS // Return the camera orientation as a quaternion // This is far not optimal, but works // // Not implemented yet in Maya DT. // int DtCameraGetOrientationQuaternion( int cameraID, float* LXRot, float* LYRot, float* LZRot, float* LWRot ) { MStatus stat = MS::kSuccess; double Xrot, Yrot, Zrot, Wrot; *LXRot = 0.0; *LYRot = 0.0; *LZRot = 0.0; *LWRot = 0.0; // Check for error. // if( ( cameraID < 0 ) || ( cameraID >= local->camera_ct ) ) { return( 0 ); } MFnDagNode fnDagNode( local->cameras[cameraID].transformNode, &stat ); MDagPath aPath; stat = fnDagNode.getPath( aPath ); MFnTransform fnTransform( aPath, &stat ); fnTransform.getRotationQuaternion ( Xrot, Yrot, Zrot, Wrot, MSpace::kWorld); *LXRot = Xrot; *LYRot = Yrot; *LZRot = Zrot; *LWRot = Wrot; return 1; } // DtCameraGetOrientationQuaternion //
bool AbcWriteJob::checkInstance(MDagPath dag, MayaTransformWriterPtr iParent) { MFnDagNode fnDagNode(dag.node()); if (fnDagNode.isInstanced(false)) { MDagPathArray paths; fnDagNode.getAllPaths(paths); if (!(mCurDag == paths[0])) { MStringArray pathparts; paths[0].fullPathName().split('|', pathparts); Alembic::Abc::OObject rootobj = mRoot.getTop(); Alembic::Abc::OObject tmpobj(rootobj); std::string tmpstring; unsigned partscount = pathparts.length(); for (unsigned i(0); i < partscount; i++) { tmpstring = pathparts[i].asChar(); tmpobj = tmpobj.getChild(tmpstring); // for selections of non-root objects, the first parts of a dag will not be a child of mRoot // traverse hierarchy until valid matching child is found, break loop only if each part of dag is invalid if (!tmpobj.valid()) { if (i == (partscount - 1)) break; tmpobj = rootobj; } } if (tmpobj.valid()) { iParent->getObject().addChildInstance(tmpobj, fnDagNode.name().asChar()); return true; } } } return false; }
void SoftBodyNode::draw( M3dView & view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status ) { MObject thisObject(thisMObject()); update(); MFnDagNode fnDagNode(thisObject); MFnTransform fnTransform(fnDagNode.parent(0)); MVector mtranslation = fnTransform.getTranslation(MSpace::kTransform); view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); // glTranslatef(-mtranslation.x, -mtranslation.y, -mtranslation.z); // size of the soft-body "icon" const float LINE_OFFSET = 0.25f; if(m_soft_body) { // draw a simple cross glBegin(GL_LINES); glVertex3f( - LINE_OFFSET, 0.0, 0.0); glVertex3f( LINE_OFFSET, 0.0,0.0); glVertex3f(0.0, - LINE_OFFSET, 0.0); glVertex3f(0.0, LINE_OFFSET, 0.0); glVertex3f(0.0, 0.0, - LINE_OFFSET); glVertex3f(0.0, 0.0, LINE_OFFSET); // glTranslatef(-mtranslation.x, -mtranslation.y, -mtranslation.z); // this->m_soft_body->gl_draw(collision_shape_t::kDSWireframe); glEnd(); glPopMatrix(); } // end if m_soft_body glPopAttrib(); view.endGL(); }
MStatus boingRbCmd::createRigidBody(collision_shape_t::pointer collision_shape, MObject node, MString name, MVector vel, MVector pos, MVector rot) { //MGlobal::getActiveSelectionList(m_undoSelectionList); if (!name.length()) { name = "dRigidBody"; } double mscale[3] = {1,1,1}; MQuaternion mrotation = MEulerRotation(rot).asQuaternion(); //collision_shape_t::pointer collision_shape; if(!collision_shape) { //not connected to a collision shape, put a default one collision_shape = solver_t::create_sphere_shape(); } else { if ( rot == MVector::zero || pos == MVector::zero ) { MFnDagNode fnDagNode(node); //cout<<"node : "<<fnDagNode.partialPathName()<<endl; MFnTransform fnTransform(fnDagNode.parent(0)); //cout<<"MFnTransform node : "<<fnTransform.partialPathName()<<endl; pos = fnTransform.getTranslation(MSpace::kTransform); fnTransform.getRotation(mrotation, MSpace::kTransform); fnTransform.getScale(mscale); } } //cout<<"removing m_rigid_body"<<endl; //solver_t::remove_rigid_body(m_rigid_body); cout<<"register name : "<<name<<endl; shared_ptr<solver_impl_t> solv = solver_t::get_solver(); rigid_body_t::pointer m_rigid_body = solver_t::create_rigid_body(collision_shape); solver_t::add_rigid_body(m_rigid_body, name.asChar()); //cout<<"transform : "<<pos<<endl; //cout<<"rotation : "<<rot<<endl; //cout<<"velocity : "<<vel<<endl; //m_rigid_body->collision_shape()->set_user_pointer(name); //const rigid_body_impl_t* rb = static_cast<const rigid_body_impl_t*>(m_rigid_body.get()); const rigid_body_impl_t* rb = m_rigid_body->impl(); //rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(rb->get()); //rb->register_name(solv.get(),rbNode->name().asChar()); solv->register_name(rb, name.asChar()); m_rigid_body->set_transform(vec3f((float)pos.x, (float)pos.y, (float)pos.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2])); float mass = 1.f; //MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); /* float curMass = m_rigid_body->get_mass(); bool changedMassStatus= false; if ((curMass > 0.f) != (mass > 0.f)) { changedMassStatus = true; } if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); */ m_rigid_body->set_mass(mass); m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia()); //if (changedMassStatus) // solver_t::add_rigid_body(m_rigid_body, name.asChar()); //initialize those default values too float restitution = 0.3f; //MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution); m_rigid_body->set_restitution(restitution); float friction = 0.5f; //MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction); m_rigid_body->set_friction(friction); float linDamp = 0.f; //MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp); m_rigid_body->set_linear_damping(linDamp); float angDamp = 0.2f; //MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp); m_rigid_body->set_angular_damping(angDamp); //shared_ptr<solver_impl_t> solv = solver_t::get_solver(); //const char *namePtr = solv->m_nameMap.find(m_rigid_body); //const char* rbname = MySerializer::findNameForPointer(m_rigid_body); //cout<<"rbname = "<<namePtr<<endl; //solv.get()->dynamicsWorld(); return MS::kSuccess; }
collision_shape_t::pointer collisionShapeNode::createCompositeShape(const MPlug& plgInShape) { std::vector<collision_shape_t::pointer> childCollisionShapes; std::vector< vec3f> childPositions; std::vector< quatf> childOrientations; MPlugArray plgaConnectedTo; plgInShape.connectedTo(plgaConnectedTo, true, true); int numSelectedShapes = plgaConnectedTo.length(); if(numSelectedShapes > 0) { MObject node = plgaConnectedTo[0].node(); MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); int numChildren = dagPath.childCount(); if (node.hasFn(MFn::kTransform)) { MFnTransform trNode(dagPath); MVector mtranslation = trNode.getTranslation(MSpace::kTransform); MObject thisObject(thisMObject()); MFnDagNode fnDagNode(thisObject); MStatus status; MFnTransform fnParentTransform(fnDagNode.parent(0, &status)); mtranslation = trNode.getTranslation(MSpace::kPostTransform); mtranslation = fnParentTransform.getTranslation(MSpace::kTransform); const char* name = trNode.name().asChar(); printf("name = %s\n", name); for (int i=0;i<numChildren;i++) { MObject child = dagPath.child(i); if(child.hasFn(MFn::kMesh)) { return false; } if(child.hasFn(MFn::kTransform)) { MDagPath dagPath; MDagPath::getAPathTo(child, dagPath); MFnTransform trNode(dagPath); MVector mtranslation = trNode.getTranslation(MSpace::kTransform); mtranslation = trNode.getTranslation(MSpace::kPostTransform); MQuaternion mrotation; trNode.getRotation(mrotation, MSpace::kTransform); double mscale[3]; trNode.getScale(mscale); vec3f childPos((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z); quatf childOrn((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z); const char* name = trNode.name().asChar(); printf("name = %s\n", name); int numGrandChildren = dagPath.childCount(); { for (int i=0;i<numGrandChildren;i++) { MObject grandchild = dagPath.child(i); if(grandchild.hasFn(MFn::kMesh)) { collision_shape_t::pointer childShape = createCollisionShape(grandchild); if (childShape) { childCollisionShapes.push_back(childShape); childPositions.push_back(childPos); childOrientations.push_back(childOrn); } } } } } } } } if (childCollisionShapes.size()>0) { composite_shape_t::pointer composite = solver_t::create_composite_shape( &childCollisionShapes[0], &childPositions[0], &childOrientations[0], childCollisionShapes.size() ); return composite; } return 0; }
void sixdofConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data) { MObject thisObject(thisMObject()); MFnDagNode fnDagNode(thisObject); MObject update; MPlug(thisObject, ca_constraint).getValue(update); MPlug(thisObject, ca_constraintParam).getValue(update); MStatus status; MFnTransform fnParentTransform(fnDagNode.parent(0, &status)); double fixScale[3] = { 1., 1., 1. }; // lock scale fnParentTransform.setScale(fixScale); MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status); if(bSolverNode::isStartTime) { // allow to edit pivots MPlug plgRigidBodyA(thisObject, ia_rigidBodyA); MPlug plgRigidBodyB(thisObject, ia_rigidBodyB); MObject update; //force evaluation of the rigidBody plgRigidBodyA.getValue(update); if(plgRigidBodyA.isConnected()) { MPlugArray connections; plgRigidBodyA.connectedTo(connections, true, true); if(connections.length() != 0) { MFnDependencyNode fnNode(connections[0].node()); if(fnNode.typeId() == boingRBNode::typeId) { MObject rbAObj = fnNode.object(); boingRBNode *pRigidBodyNodeA = static_cast<boingRBNode*>(fnNode.userNode()); MPlug(rbAObj, pRigidBodyNodeA->worldMatrix).elementByLogicalIndex(0).getValue(update); } } } plgRigidBodyB.getValue(update); if(plgRigidBodyB.isConnected()) { MPlugArray connections; plgRigidBodyB.connectedTo(connections, true, true); if(connections.length() != 0) { MFnDependencyNode fnNode(connections[0].node()); if(fnNode.typeId() == boingRBNode::typeId) { MObject rbBObj = fnNode.object(); boingRBNode *pRigidBodyNodeB = static_cast<boingRBNode*>(fnNode.userNode()); MPlug(rbBObj, pRigidBodyNodeB->worldMatrix).elementByLogicalIndex(0).getValue(update); } } } if(m_constraint) { MQuaternion mrotation; fnParentTransform.getRotation(mrotation, MSpace::kTransform); bool doUpdatePivot = m_constraint->getPivotChanged(); if(!doUpdatePivot) { vec3f worldP; quatf worldR; m_constraint->get_world(worldP, worldR); float deltaPX = worldP[0] - float(mtranslation.x); float deltaPY = worldP[1] - float(mtranslation.y); float deltaPZ = worldP[2] - float(mtranslation.z); float deltaRX = (float)mrotation.x - worldR[1]; float deltaRY = (float)mrotation.y - worldR[2]; float deltaRZ = (float)mrotation.z - worldR[3]; float deltaRW = (float)mrotation.w - worldR[0]; float deltaSq = deltaPX * deltaPX + deltaPY * deltaPY + deltaPZ * deltaPZ + deltaRX * deltaRX + deltaRY * deltaRY + deltaRZ * deltaRZ + deltaRW * deltaRW; doUpdatePivot = (deltaSq > FLT_EPSILON); } if(doUpdatePivot) { m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2]), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); vec3f pivInA, pivInB; quatf rotInA, rotInB; m_constraint->get_frameA(pivInA, rotInA); m_constraint->get_frameB(pivInB, rotInB); MDataHandle hPivInA = data.outputValue(ia_pivotInA); float3 &ihPivInA = hPivInA.asFloat3(); MDataHandle hPivInB = data.outputValue(ia_pivotInB); float3 &ihPivInB = hPivInB.asFloat3(); for(int i = 0; i < 3; i++) { ihPivInA[i] = pivInA[i]; ihPivInB[i] = pivInB[i]; } MDataHandle hRotInA = data.outputValue(ia_rotationInA); float3 &hrotInA = hRotInA.asFloat3(); MQuaternion mrotA(rotInA[1], rotInA[2], rotInA[3], rotInA[0]); MEulerRotation newrotA(mrotA.asEulerRotation()); hrotInA[0] = rad2deg((float)newrotA.x); hrotInA[1] = rad2deg((float)newrotA.y); hrotInA[2] = rad2deg((float)newrotA.z); MDataHandle hRotInB = data.outputValue(ia_rotationInB); float3 &hrotInB = hRotInB.asFloat3(); MQuaternion mrotB(rotInB[1], rotInB[2], rotInB[3], rotInB[0]); MEulerRotation newrotB(mrotB.asEulerRotation()); hrotInB[0] = rad2deg((float)newrotB.x); hrotInB[1] = rad2deg((float)newrotB.y); hrotInB[2] = rad2deg((float)newrotB.z); m_constraint->setPivotChanged(false); m_constraint->get_local_frameA(m_PivInA, m_RotInA); m_constraint->get_local_frameB(m_PivInB, m_RotInB); } } } else { // if not start time, lock position and rotation if(m_constraint) { vec3f worldP; quatf worldR; m_constraint->get_world(worldP, worldR); fnParentTransform.setTranslation(MVector(worldP[0], worldP[1], worldP[2]), MSpace::kTransform); fnParentTransform.setRotation(MQuaternion(worldR[1], worldR[2], worldR[3], worldR[0])); } } m_initialized = true; data.setClean(plug); }
// ========== DtCameraGetUpPosition ========== // // SYNOPSIS // Return the camera Up position. // int DtCameraGetUpPosition( int cameraID, float* xTran, float* yTran, float* zTran ) { // Check for error. // if( (cameraID < 0) || (cameraID >= local->camera_ct ) ) { *xTran = 0.0; *yTran = 0.0; *zTran = 0.0; return( 0 ); } MStatus stat = MS::kSuccess; MFnDagNode fnDagNode( local->cameras[cameraID].transformNode, &stat ); MDagPath aPath; stat = fnDagNode.getPath( aPath ); // Get the global transformation matrix of the camera node. // MMatrix globalMatrix = aPath.inclusiveMatrix(); MFnCamera fnCamera( local->cameras[cameraID].cameraShapeNode, &stat ); MPoint eyePt; double eyePos[4]; double upPos[4]; if( MS::kSuccess == stat ) { eyePt = fnCamera.eyePoint( MSpace::kObject, &stat ); eyePt *= globalMatrix; eyePt.get( eyePos ); MVector upVec = fnCamera.upDirection( MSpace::kObject, &stat ); upVec *= globalMatrix; if( DtExt_Debug() & DEBUG_CAMERA ) { double up[3]; upVec.get( up ); cerr << "local up vector is " << up[0] << " " << up[1] << " " << up[2] << endl; } MPoint upPoint = eyePt + upVec; upPoint.get( upPos ); if( DtExt_Debug() & DEBUG_CAMERA ) { cerr << "global up point position is " << upPos[0] << " " << upPos[1] << " " << upPos[2] << " " << upPos[3] << endl; } } else { DtExt_Err( "Error in getting the camera function set\n" ); } *xTran = upPos[0]; *yTran = upPos[1]; *zTran = upPos[2]; return(1); }
//gather previous and current frame transformations for substep interpolation void dSolverNode::gatherPassiveTransforms(MPlugArray &rbConnections, std::vector<xforms_t> &xforms) { xforms.resize(0); xforms_t xform; for(size_t i = 0; i < rbConnections.length(); ++i) { MObject node = rbConnections[i].node(); MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == rigidBodyNode::typeId) { rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; continue; } MFnTransform fnTransform(fnDagNode.parent(0)); MPlug plgMass(node, rigidBodyNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(!active) { MQuaternion mquat; fnTransform.getRotation(mquat); MVector mpos(fnTransform.getTranslation(MSpace::kTransform)); rb->get_transform(xform.m_x0, xform.m_q0); xform.m_x1 = vec3f(mpos.x, mpos.y, mpos.z); xform.m_q1 = quatf(mquat.w, mquat.x, mquat.y, mquat.z); xforms.push_back(xform); } } else if(fnDagNode.typeId() == rigidBodyArrayNode::typeId) { rigidBodyArrayNode *rbNode = static_cast<rigidBodyArrayNode*>(fnDagNode.userNode()); std::vector<rigid_body_t::pointer>& rbs = rbNode->rigid_bodies(); if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; return; } MPlug plgMass(node, rigidBodyArrayNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(!active) { MPlug plgPosition(node, rigidBodyArrayNode::io_position); MPlug plgRotation(node, rigidBodyArrayNode::io_rotation); MPlug plgElement; for(size_t j = 0; j < rbs.size(); ++j) { rbs[j]->get_transform(xform.m_x0, xform.m_q0); plgElement = plgPosition.elementByLogicalIndex(j); plgElement.child(0).getValue(xform.m_x1[0]); plgElement.child(1).getValue(xform.m_x1[1]); plgElement.child(2).getValue(xform.m_x1[2]); vec3f rot; plgElement = plgRotation.elementByLogicalIndex(j); plgElement.child(0).getValue(rot[0]); plgElement.child(1).getValue(rot[1]); plgElement.child(2).getValue(rot[2]); MEulerRotation meuler(deg2rad(rot[0]), deg2rad(rot[1]), deg2rad(rot[2])); MQuaternion mquat = meuler.asQuaternion(); xform.m_q1 = quatf(mquat.w, mquat.x, mquat.y, mquat.z); xforms.push_back(xform); } } } } }
//apply fields in the scene from the rigid body void dSolverNode::applyFields(MPlugArray &rbConnections, float dt) { MVectorArray position; MVectorArray velocity; MDoubleArray mass; std::vector<rigid_body_t*> rigid_bodies; //gather active rigid bodies for(size_t i = 0; i < rbConnections.length(); ++i) { MObject node = rbConnections[i].node(); MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == rigidBodyNode::typeId) { rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); MPlug plgMass(node, rigidBodyNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { rigid_bodies.push_back(rb.get()); } } else if(fnDagNode.typeId() == rigidBodyArrayNode::typeId) { rigidBodyArrayNode *rbNode = static_cast<rigidBodyArrayNode*>(fnDagNode.userNode()); std::vector<rigid_body_t::pointer>& rbs = rbNode->rigid_bodies(); MPlug plgMass(node, rigidBodyArrayNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { for(size_t j = 0; j < rbs.size(); ++j) { rigid_bodies.push_back(rbs[j].get()); } } } } //clear forces and get the properties needed for field computation for(size_t i = 0; i < rigid_bodies.size(); ++i) { rigid_bodies[i]->clear_forces(); vec3f pos, vel; quatf rot; rigid_bodies[i]->get_transform(pos, rot); rigid_bodies[i]->get_linear_velocity(vel); position.append(MVector(pos[0], pos[1], pos[2])); velocity.append(MVector(vel[0], vel[1], vel[2])); //TODO mass.append(1.0); // } //apply the fields to the rigid bodies MVectorArray force; for(MItDag it(MItDag::kDepthFirst, MFn::kField); !it.isDone(); it.next()) { MFnField fnField(it.item()); fnField.getForceAtPoint(position, velocity, mass, force, dt); for(size_t i = 0; i < rigid_bodies.size(); ++i) { rigid_bodies[i]->apply_central_force(vec3f(force[i].x, force[i].y, force[i].z)); } } }
//update the scene after a simulation step void dSolverNode::updateActiveRigidBodies(MPlugArray &rbConnections) { //update the active rigid bodies to the new configuration for(size_t i = 0; i < rbConnections.length(); ++i) { MObject node = rbConnections[i].node(); MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == rigidBodyNode::typeId) { rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; continue; } MFnTransform fnTransform(fnDagNode.parent(0)); MPlug plgMass(node, rigidBodyNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { quatf rot; vec3f pos; rb->get_transform(pos, rot); fnTransform.setRotation(MQuaternion(rot[1], rot[2], rot[3], rot[0])); fnTransform.setTranslation(MVector(pos[0], pos[1], pos[2]), MSpace::kTransform); } } else if(fnDagNode.typeId() == rigidBodyArrayNode::typeId) { rigidBodyArrayNode *rbNode = static_cast<rigidBodyArrayNode*>(fnDagNode.userNode()); std::vector<rigid_body_t::pointer>& rbs = rbNode->rigid_bodies(); MPlug plgMass(node, rigidBodyArrayNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); //write the position and rotations if(active) { MPlug plgPosition(node, rigidBodyArrayNode::io_position); MPlug plgRotation(node, rigidBodyArrayNode::io_rotation); MPlug plgElement; for(size_t j = 0; j < rbs.size(); ++j) { vec3f pos; quatf rot; rbs[j]->get_transform(pos, rot); MEulerRotation meuler(MQuaternion(rot[1], rot[2], rot[3], rot[0]).asEulerRotation()); plgElement = plgPosition.elementByLogicalIndex(j); plgElement.child(0).setValue(pos[0]); plgElement.child(1).setValue(pos[1]); plgElement.child(2).setValue(pos[2]); plgElement = plgRotation.elementByLogicalIndex(j); plgElement.child(0).setValue(rad2deg(meuler.x)); plgElement.child(1).setValue(rad2deg(meuler.y)); plgElement.child(2).setValue(rad2deg(meuler.z)); } } //check if we have to output the rigid bodies to a file MPlug plgFileIO(node, rigidBodyArrayNode::ia_fileIO); bool doIO; plgFileIO.getValue(doIO); if(doIO) { dumpRigidBodyArray(node); } } } }
virtual void ExportProcedural( AtNode *node ) { // do basic node export ExportMatrix( node, 0 ); AtNode *shader = arnoldShader(); if( shader ) { AiNodeSetPtr( node, "shader", shader ); } 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() ); } // export any shading groups or displacement shaders which look like they // may be connected to procedural parameters. this ensures that maya shaders // the procedural will expect to find at rendertime will be exported to the // ass file (they otherwise might not be if they're not assigned to any objects). exportShadingInputs(); // now set the procedural-specific parameters MFnDagNode fnDagNode( m_dagPath ); MBoundingBox bound = fnDagNode.boundingBox(); AiNodeSetPnt( node, "min", bound.min().x, bound.min().y, bound.min().z ); AiNodeSetPnt( node, "max", bound.max().x, bound.max().y, bound.max().z ); const char *dsoPath = getenv( "IECOREARNOLD_PROCEDURAL_PATH" ); AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "ieProcedural.so" ); AiNodeDeclare( node, "className", "constant STRING" ); AiNodeDeclare( node, "classVersion", "constant INT" ); AiNodeDeclare( node, "parameterValues", "constant ARRAY STRING" ); // cast should be ok as we're registered to only work on procedural holders IECoreMaya::ProceduralHolder *pHolder = static_cast<IECoreMaya::ProceduralHolder *>( fnDagNode.userNode() ); std::string className; int classVersion; IECore::ParameterisedProceduralPtr procedural = pHolder->getProcedural( &className, &classVersion ); AiNodeSetStr( node, "className", className.c_str() ); AiNodeSetInt( node, "classVersion", classVersion ); IECorePython::ScopedGILLock gilLock; try { boost::python::object parser = IECoreMaya::PythonCmd::globalContext()["IECore"].attr( "ParameterParser" )(); boost::python::object serialised = parser.attr( "serialise" )( procedural->parameters() ); size_t numStrings = IECorePython::len( serialised ); AtArray *stringArray = AiArrayAllocate( numStrings, 1, AI_TYPE_STRING ); for( size_t i=0; i<numStrings; i++ ) { std::string s = boost::python::extract<std::string>( serialised[i] ); // hack to workaround ass parsing errors /// \todo Remove when we get the Arnold version that fixes this for( size_t c = 0; c<s.size(); c++ ) { if( s[c] == '#' ) { s[c] = '@'; } } AiArraySetStr( stringArray, i, s.c_str() ); } AiNodeSetArray( node, "parameterValues", stringArray ); } catch( boost::python::error_already_set ) { PyErr_Print(); } }
void dSolverNode::dumpRigidBodyArray(MObject &node) { // std::cout << "dSolverNode::dumpRigidBodyArray" << std::endl; MFnDagNode fnDagNode(node); rigidBodyArrayNode *rbaNode = static_cast<rigidBodyArrayNode*>(fnDagNode.userNode()); MPlug plgFiles(node, rigidBodyArrayNode::ia_fioFiles); // MPlug plgPositionAttribute(node, rigidBodyArrayNode::ia_fioPositionAttribute); // MPlug plgRotationAttribute(node, rigidBodyArrayNode::ia_fioRotationAttribute); MString mstr; plgFiles.getValue(mstr); std::string expr(mstr.asChar()); std::string base_path, extension; if(!expandFileExpression(expr, base_path, extension)) { std::cout << "dSolverNode::dumpRigidBodyArray: syntax error in file expression: " << std::endl << expr << std::endl; return; } if(extension != "pdb") { std::cout << "dSolverNode::dumpRigidBodyArray: only pdb files are supported" << std::endl; return; } std::string file_name = base_path + "." + extension; std::vector<rigid_body_t::pointer>& rbs = rbaNode->rigid_bodies(); pdb_io_t pdb_io; pdb_io.m_num_particles = rbs.size(); pdb_io.m_time = m_prevTime.value(); pdb_io.m_attributes.resize(3); //position pdb_io.m_attributes[0].m_num_elements = 1; pdb_io.m_attributes[0].m_name = ATTR_POSITION; pdb_io.m_attributes[0].m_type = pdb_io_t::kVector; pdb_io.m_attributes[0].m_vector_data.resize(rbs.size()); //rotation angle (in degrees) pdb_io.m_attributes[1].m_num_elements = 1; pdb_io.m_attributes[1].m_name = ATTR_IN_RANGLE; pdb_io.m_attributes[1].m_type = pdb_io_t::kReal; pdb_io.m_attributes[1].m_real_data.resize(rbs.size()); //rotation vector pdb_io.m_attributes[2].m_num_elements = 1; pdb_io.m_attributes[2].m_name = ATTR_IN_RAXIS; pdb_io.m_attributes[2].m_type = pdb_io_t::kVector; pdb_io.m_attributes[2].m_vector_data.resize(rbs.size()); for(size_t i = 0; i < rbs.size(); ++i) { vec3f pos; quatf rot; rbs[i]->get_transform(pos, rot); pdb_io.m_attributes[0].m_vector_data[i].x = pos[0]; pdb_io.m_attributes[0].m_vector_data[i].y = pos[1]; pdb_io.m_attributes[0].m_vector_data[i].z = pos[2]; // vec3f axis; float angle; q_to_axis_angle(rot, axis, angle); pdb_io.m_attributes[1].m_real_data[i] = rad2deg(angle); pdb_io.m_attributes[2].m_vector_data[i].x = axis[0]; pdb_io.m_attributes[2].m_vector_data[i].y = axis[1]; pdb_io.m_attributes[2].m_vector_data[i].z = axis[2]; } std::ofstream out(file_name.c_str()); pdb_io.write(out); }
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); }
void boing::createRigidBody() { //MGlobal::getActiveSelectionList(m_undoSelectionList); if (!name.length()) { name = "procBoingRb1"; } std::cout<<"name in boing::createRigidBody() "<<name<<endl; double mscale[3] = {1,1,1}; MQuaternion mrotation = MEulerRotation(m_initial_rotation).asQuaternion(); //collision_shape_t::pointer collision_shape; if(!m_collision_shape) { //not connected to a collision shape, put a default one m_collision_shape = solver_t::create_box_shape(); } else { if ( !node.isNull() ) { MFnDagNode fnDagNode(node); //cout<<"node : "<<fnDagNode.partialPathName()<<endl; MFnTransform fnTransform(fnDagNode.parent(0)); //cout<<"MFnTransform node : "<<fnTransform.partialPathName()<<endl; if ( m_initial_position == MVector::zero ) { m_initial_position = fnTransform.getTranslation(MSpace::kTransform); } if ( m_initial_rotation == MVector::zero ) { fnTransform.getRotation(mrotation, MSpace::kTransform); } fnTransform.getScale(mscale); } } shared_ptr<solver_impl_t> solv = solver_t::get_solver(); m_rigid_body = solver_t::create_rigid_body(m_collision_shape); m_rigid_body->set_transform(vec3f((float)m_initial_position.x, (float)m_initial_position.y, (float)m_initial_position.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->set_linear_velocity( vec3f((float)m_initial_velocity.x,(float)m_initial_velocity.y,(float)m_initial_velocity.z) ); m_rigid_body->set_angular_velocity( vec3f((float)m_initial_angularvelocity.x,(float)m_initial_angularvelocity.y,(float)m_initial_angularvelocity.z) ); m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2])); /* float mass = 1.f; m_rigid_body->set_mass(mass); m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia()); */ //float mass = 0.f; if (typeName == boingRBNode::typeName) { MPlug(node, boingRBNode::ia_mass).getValue(m_mass); } float curMass = m_rigid_body->get_mass(); bool changedMassStatus= false; if ((curMass > 0.f) != (m_mass > 0.f)) { changedMassStatus = true; } if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); m_rigid_body->set_mass(m_mass); m_rigid_body->set_inertia((float)m_mass * m_rigid_body->collision_shape()->local_inertia()); if (changedMassStatus) solver_t::add_rigid_body(m_rigid_body, name.asChar()); //initialize those default values too float restitution = 0.3f; //MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution); m_rigid_body->set_restitution(restitution); float friction = 0.5f; //MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction); m_rigid_body->set_friction(friction); float linDamp = 0.f; //MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp); m_rigid_body->set_linear_damping(linDamp); float angDamp = 0.2f; //MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp); m_rigid_body->set_angular_damping(angDamp); m_rigid_body->impl()->body()->setUserPointer((void*) this); }
bool preFrame( const MObject hairSystem, const double curTime, void **privateData ) { MStatus status; // If you need want to perform any preprocessing on your collision // objects pre-frame, do it here. One option for storing the pre- // processed data is on a typed attribute on the hairSystem node. // That data could be fetched and updated here. // // In our example, we'll just compute a bounding box here and NOT use // attribute storage. That is an exercise for the reader. // MFnDependencyNode fnHairSystem( hairSystem, &status ); CHECK_MSTATUS_AND_RETURN( status, false ); fprintf( stderr, "preFrame: calling hairSystem node=`%s', time=%g\n", fnHairSystem.name().asChar(), curTime ); MObjectArray cols; MIntArray logIdxs; CHECK_MSTATUS_AND_RETURN( MHairSystem::getCollisionObject( hairSystem, cols, logIdxs ), false ); int nobj = cols.length(); // Allocate private data. // This allows us to pre-process data on a pre-frame basis to avoid // calculating it per hair inside the collide() call. As noted earlier // we could allocate this in preFrame() and hang it off the hairSystem // node via a dynamic attribute. // Instead we'll allocate it here. // COLLISION_INFO *collisionInfo = (COLLISION_INFO *) malloc( sizeof( COLLISION_INFO ) ); collisionInfo->objs = (COLLISION_OBJ *) malloc( nobj * sizeof( COLLISION_OBJ ) ); collisionInfo->numObjs = nobj; // Create the private data that we'll make available to the collide // method. The data should actually be stored in a way that it can // be cleaned up (such as storing the pointer on the hairSystem node // using a dynamic attribute). As it stands right now, there is a // memory leak with this plug-in because the memory we're allocating // for the private data is never cleaned up. // // Note that when using the dynamic attribute approach, it is still // wise to set *privateData because this avoids the need to look up // the plug inside the collide() routine which is a high-traffic // method. // *privateData = (void *) collisionInfo; // Loop through the collision objects and pre-process, storing the // results in the collisionInfo structure. // int obj; for ( obj = 0; obj < nobj; ++obj ) { // Get the ith collision geometry we are connected to. // MObject colObj = cols[obj]; // Get the DAG path for the collision object so we can transform // the vertices to world space. // MFnDagNode fnDagNode( colObj, &status ); CHECK_MSTATUS_AND_RETURN( status, false ); MDagPath path; status = fnDagNode.getPath( path ); CHECK_MSTATUS_AND_RETURN( status, false ); MFnMesh fnMesh( path, &status ); if ( MS::kSuccess != status ) { fprintf( stderr, "%s:%d: collide was not passed a valid mesh shape\n", __FILE__, __LINE__ ); return( false ); } // Get the vertices of the object transformed to world space. // MFloatPointArray verts; status = fnMesh.getPoints( verts, MSpace::kWorld ); CHECK_MSTATUS_AND_RETURN( status, false ); // Compute the bounding box for the collision object. // As this is a quick and dirty demo, we'll just support collisions // between hair and the bbox. // double minx, miny, minz, maxx, maxy, maxz, x, y, z; minx = maxx = verts[0].x; miny = maxy = verts[0].y; minz = maxz = verts[0].z; int nv = verts.length(); int i; for ( i = 1; i < nv; ++i ) { x = verts[i].x; y = verts[i].y; z = verts[i].z; if ( x < minx ) { minx = x; } if ( y < miny ) { miny = y; } if ( z < minz ) { minz = z; } if ( x > maxx ) { maxx = x; } if ( y > maxy ) { maxy = y; } if ( z > maxz ) { maxz = z; } } // Store this precomputed informantion into our private data // structure. // collisionInfo->objs[obj].numVerts = nv; collisionInfo->objs[obj].minx = minx; collisionInfo->objs[obj].miny = miny; collisionInfo->objs[obj].minz = minz; collisionInfo->objs[obj].maxx = maxx; collisionInfo->objs[obj].maxy = maxy; collisionInfo->objs[obj].maxz = maxz; fprintf( stderr, "Inside preFrameInit, bbox=%g %g %g %g %g %g\n", minx,miny,minz,maxx,maxy,maxz); } return( true ); }
/* Rigid bodies are added to the solver here */ void rigidBodyNode::computeRigidBody(const MPlug& plug, MDataBlock& data) { MObject thisObject(thisMObject()); MPlug plgCollisionShape(thisObject, ia_collisionShape); MObject update; //force evaluation of the shape plgCollisionShape.getValue(update); // The following two variables are not actually used! vec3f prevCenter(0, 0, 0); quatf prevRotation(qidentity<float>()); if(m_rigid_body) { prevCenter = m_rigid_body->collision_shape()->center(); prevRotation = m_rigid_body->collision_shape()->rotation(); } collision_shape_t::pointer collision_shape; if(plgCollisionShape.isConnected()) { MPlugArray connections; plgCollisionShape.connectedTo(connections, true, true); if(connections.length() != 0) { MFnDependencyNode fnNode(connections[0].node()); if(fnNode.typeId() == collisionShapeNode::typeId) { collisionShapeNode *pCollisionShapeNode = static_cast<collisionShapeNode*>(fnNode.userNode()); collision_shape = pCollisionShapeNode->collisionShape(); } else { std::cout << "rigidBodyNode connected to a non-collision shape node!" << std::endl; } } } if(!collision_shape) { //not connected to a collision shape, put a default one collision_shape = solver_t::create_sphere_shape(); } solver_t::remove_rigid_body(m_rigid_body); m_rigid_body = solver_t::create_rigid_body(collision_shape); solver_t::add_rigid_body(m_rigid_body,name().asChar()); // once at creation/load time : get transform from Maya transform node MFnDagNode fnDagNode(thisObject); MFnTransform fnTransform(fnDagNode.parent(0)); MVector mtranslation = fnTransform.getTranslation(MSpace::kTransform); MQuaternion mrotation; fnTransform.getRotation(mrotation, MSpace::kTransform); double mscale[3]; fnTransform.getScale(mscale); m_rigid_body->set_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2])); float mass = 0.f; MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); float curMass = m_rigid_body->get_mass(); bool changedMassStatus= false; if ((curMass > 0.f) != (mass > 0.f)) { changedMassStatus = true; } if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); m_rigid_body->set_mass(mass); m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia()); if (changedMassStatus) solver_t::add_rigid_body(m_rigid_body, name().asChar()); //initialize those default values too float restitution = 0.f; MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution); m_rigid_body->set_restitution(restitution); float friction = 0.5f; MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction); m_rigid_body->set_friction(friction); float linDamp = 0.f; MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp); m_rigid_body->set_linear_damping(linDamp); float angDamp = 0.f; MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp); m_rigid_body->set_angular_damping(angDamp); /* //this is not necessary, initialize linear/angular velocity (spin) is already set at initRigidBodyArray in dSolverNode.cpp MPlug ilv(thisObject, rigidBodyNode::ia_initialVelocity); MDataHandle hInitLinVel= ilv.asMDataHandle(); float3 &initLinVel= hInitLinVel.asFloat3(); vec3f lv(initLinVel[0],initLinVel[1],initLinVel[2]); m_rigid_body->set_linear_velocity(lv); */ //?? the next line crashes Maya 2014. Note sure what it is supposed to achieve. // data.outputValue(ca_rigidBody).set(true); data.setClean(plug); }
void rigidBodyNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data) { if (!m_rigid_body) return; // std::cout << "rigidBodyNode::computeWorldMatrix" << std::endl; MObject thisObject(thisMObject()); MFnDagNode fnDagNode(thisObject); MObject update; MPlug(thisObject, ca_rigidBody).getValue(update); MPlug(thisObject, ca_rigidBodyParam).getValue(update); vec3f pos; quatf rot; MStatus status; MFnTransform fnParentTransform(fnDagNode.parent(0, &status)); double mscale[3]; fnParentTransform.getScale(mscale); m_rigid_body->get_transform(pos, rot); if(dSolverNode::isStartTime) { // allow to edit ptranslation and rotation MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status); MQuaternion mrotation; fnParentTransform.getRotation(mrotation, MSpace::kTransform); float deltaPX = (float)mtranslation.x - pos[0]; float deltaPY = (float)mtranslation.y - pos[1]; float deltaPZ = (float)mtranslation.z - pos[2]; float deltaRX = (float)mrotation.x - rot[1]; float deltaRY = (float)mrotation.y - rot[2]; float deltaRZ = (float)mrotation.z - rot[3]; float deltaRW = (float)mrotation.w - rot[0]; float deltaSq = deltaPX * deltaPX + deltaPY * deltaPY + deltaPZ * deltaPZ + deltaRX * deltaRX + deltaRY * deltaRY + deltaRZ * deltaRZ + deltaRW * deltaRW; if(deltaSq > FLT_EPSILON) { m_rigid_body->set_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->set_interpolation_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->update_constraint(); MDataHandle hInitPos = data.outputValue(ia_initialPosition); float3 &ihpos = hInitPos.asFloat3(); ihpos[0] = (float)mtranslation.x; ihpos[1] = (float)mtranslation.y; ihpos[2] = (float)mtranslation.z; MDataHandle hInitRot = data.outputValue(ia_initialRotation); float3 &ihrot = hInitRot.asFloat3(); MEulerRotation newrot(mrotation.asEulerRotation()); ihrot[0] = rad2deg((float)newrot.x); ihrot[1] = rad2deg((float)newrot.y); ihrot[2] = rad2deg((float)newrot.z); } } else { // if not start time, lock position and rotation for active rigid bodies float mass = 0.f; MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); if(mass > 0.f) { fnParentTransform.setTranslation(MVector(pos[0], pos[1], pos[2]), MSpace::kTransform); fnParentTransform.setRotation(MQuaternion(rot[1], rot[2], rot[3], rot[0])); } } float mass = 0.f; MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); float curMass = m_rigid_body->get_mass(); bool changedMassStatus= false; if ((curMass > 0.f) != (mass > 0.f)) { changedMassStatus = true; } if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); m_rigid_body->set_mass(mass); m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia()); if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); float restitution = 0.f; MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution); m_rigid_body->set_restitution(restitution); float friction = 0.5f; MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction); m_rigid_body->set_friction(friction); float linDamp = 0.f; MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp); m_rigid_body->set_linear_damping(linDamp); float angDamp = 0.f; MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp); m_rigid_body->set_angular_damping(angDamp); data.setClean(plug); //set the scale to the collision shape m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2])); }