IECore::ObjectPtr FromMayaTransformConverter::doConversion( const MDagPath &dagPath, IECore::ConstCompoundObjectPtr operands ) const { MTransformationMatrix transform; if( m_spaceParameter->getNumericValue()==Local ) { MFnTransform fnT( dagPath ); transform = fnT.transformation(); } else { unsigned instIndex = dagPath.instanceNumber(); MObject dagNode = dagPath.node(); MFnDependencyNode fnN( dagNode ); MPlug plug = fnN.findPlug( "worldMatrix" ); MPlug instPlug = plug.elementByLogicalIndex( instIndex ); MObject matrix; instPlug.getValue( matrix ); MFnMatrixData fnM( matrix ); transform = fnM.transformation(); if ( m_spaceParameter->getNumericValue() == Custom ) { // multiply world transform by the inverse of the custom space matrix. transform = transform.asMatrix() * IECore::convert< MMatrix, Imath::M44f >( operands->member< IECore::M44fData >("customSpace", true)->readable().inverse() ); } } if( m_zeroPivotsParameter->getTypedValue() ) { transform.setScalePivot( MPoint( 0, 0, 0 ), MSpace::kTransform, true ); transform.setRotatePivot( MPoint( 0, 0, 0 ), MSpace::kTransform, true ); } if( m_eulerFilterParameter->getTypedValue() && m_lastRotationValid ) { transform.rotateTo( transform.eulerRotation().closestSolution( m_lastRotation ) ); } m_lastRotation = transform.eulerRotation(); m_lastRotationValid = true; return new IECore::TransformationMatrixdData( IECore::convert<IECore::TransformationMatrixd, MTransformationMatrix>( transform ) ); }
/** Create a RIB compatible representation of a Maya polygon mesh. */ liqRibMeshData::liqRibMeshData( MObject mesh ) : numFaces( 0 ), numPoints ( 0 ), numNormals ( 0 ), nverts(), verts(), vertexParam(NULL), normalParam(NULL) { CM_TRACE_FUNC("liqRibMeshData::liqRibMeshData("<<MFnDagNode(mesh).fullPathName().asChar()<<")"); unsigned int i; unsigned int j; areaLight = false; LIQDEBUGPRINTF( "-> creating mesh\n" ); MFnMesh fnMesh( mesh ); objDagPath = fnMesh.dagPath(); MStatus astatus; name = fnMesh.name(); areaLight =( liquidGetPlugValue( fnMesh, "areaIntensity", areaIntensity, astatus ) == MS::kSuccess )? true : false ; if ( areaLight ) { MDagPath meshDagPath; meshDagPath = fnMesh.dagPath(); MTransformationMatrix worldMatrix = meshDagPath.inclusiveMatrix(); MMatrix worldMatrixM = worldMatrix.asMatrix(); worldMatrixM.get( transformationMatrix ); } numPoints = fnMesh.numVertices(); numNormals = fnMesh.numNormals(); // UV sets ------------------- // //const unsigned numSTs( fnMesh.numUVs() ); const unsigned numUVSets( fnMesh.numUVSets() ); MString currentUVSetName; MStringArray extraUVSetNames; fnMesh.getCurrentUVSetName( currentUVSetName ); { MStringArray UVSetNames; fnMesh.getUVSetNames( UVSetNames ); for ( unsigned i( 0 ); i<numUVSets; i++ ) if ( UVSetNames[i] != currentUVSetName ) extraUVSetNames.append( UVSetNames[i] ); } numFaces = fnMesh.numPolygons(); const unsigned numFaceVertices( fnMesh.numFaceVertices() ); if ( numPoints < 1 ) { // MGlobal::displayInfo( MString( "fnMesh: " ) + fnMesh.name() ); // cerr << "Liquid : Could not export degenerate mesh '"<< fnMesh.fullPathName( &astatus ).asChar() << "'" << endl << flush; return; } unsigned face = 0; unsigned faceVertex = 0; unsigned count; unsigned vertex; unsigned normal; float S; float T; MPoint point; liqTokenPointer pointsPointerPair; liqTokenPointer normalsPointerPair; liqTokenPointer pFaceVertexSPointer; liqTokenPointer pFaceVertexTPointer; // Allocate memory and tokens numFaces = numFaces; nverts = shared_array< liqInt >( new liqInt[ numFaces ] ); verts = shared_array< liqInt >( new liqInt[ numFaceVertices ] ); pointsPointerPair.set( "P", rPoint, numPoints ); pointsPointerPair.setDetailType( rVertex ); if ( numNormals == numPoints ) { normalsPointerPair.set( "N", rNormal, numPoints ); normalsPointerPair.setDetailType( rVertex ); } else { normalsPointerPair.set( "N", rNormal, numFaceVertices ); normalsPointerPair.setDetailType( rFaceVarying ); } // uv std::vector<liqTokenPointer> UVSetsArray; UVSetsArray.reserve( 1 + extraUVSetNames.length() ); liqTokenPointer currentUVSetUPtr; liqTokenPointer currentUVSetVPtr; liqTokenPointer currentUVSetNamePtr; liqTokenPointer extraUVSetsUPtr; liqTokenPointer extraUVSetsVPtr; liqTokenPointer extraUVSetsNamePtr; if(liqglo.liqglo_outputMeshAsRMSArrays) { currentUVSetUPtr.set( "s", rFloat, numFaceVertices ); currentUVSetUPtr.setDetailType( rFaceVarying ); currentUVSetVPtr.set( "t", rFloat, numFaceVertices ); currentUVSetVPtr.setDetailType( rFaceVarying ); currentUVSetNamePtr.set( "currentUVSet", rString, 1 ); currentUVSetNamePtr.setDetailType( rConstant ); if( numUVSets > 1 ) { extraUVSetsUPtr.set( "u_uvSet", rFloat, numFaceVertices, numUVSets-1 ); extraUVSetsUPtr.setDetailType( rFaceVarying ); extraUVSetsVPtr.set( "v_uvSet", rFloat, numFaceVertices, numUVSets-1 ); extraUVSetsVPtr.setDetailType( rFaceVarying ); extraUVSetsNamePtr.set( "extraUVSets", rString, numUVSets-1 ); extraUVSetsNamePtr.setDetailType( rConstant ); } } else { if ( numUVSets > 0 ) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( "st", rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( rFaceVarying ); UVSetsArray.push_back( pFaceVertexPointerPair ); for ( unsigned j( 0 ); j<extraUVSetNames.length(); j++) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( extraUVSetNames[j].asChar(), rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( rFaceVarying ); UVSetsArray.push_back( pFaceVertexPointerPair ); } if( liqglo.liqglo_outputMeshUVs ) { // Match MTOR, which also outputs face-varying STs as well for some reason - Paul // not anymore - Philippe pFaceVertexSPointer.set( "u", rFloat, numFaceVertices ); pFaceVertexSPointer.setDetailType( rFaceVarying ); pFaceVertexTPointer.set( "v", rFloat, numFaceVertices ); pFaceVertexTPointer.setDetailType( rFaceVarying ); } } } vertexParam = pointsPointerPair.getTokenFloatArray(); normalParam = normalsPointerPair.getTokenFloatArray(); // Read the mesh from Maya MFloatVectorArray normals; fnMesh.getNormals( normals ); for ( MItMeshPolygon polyIt ( mesh ); polyIt.isDone() == false; polyIt.next() ) { count = polyIt.polygonVertexCount(); nverts[face] = count; for( i=0; i<count; i++ ) // boucle sur les vertex de la face { vertex = polyIt.vertexIndex( i ); verts[faceVertex] = vertex; point = polyIt.point( i, MSpace::kObject ); pointsPointerPair.setTokenFloat( vertex, point.x, point.y, point.z ); normal = polyIt.normalIndex( i ); if( numNormals == numPoints ) normalsPointerPair.setTokenFloat( vertex, normals[normal].x, normals[normal].y, normals[normal].z ); else normalsPointerPair.setTokenFloat( faceVertex, normals[normal].x, normals[normal].y, normals[normal].z ); if( liqglo.liqglo_outputMeshAsRMSArrays ) { for( j=0; j<numUVSets; j++ ) { if(j==0) { MString uvSetName = currentUVSetName; // set uvSet name currentUVSetNamePtr.setTokenString( 0, currentUVSetName.asChar() ); // set uv values fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); currentUVSetUPtr.setTokenFloat( faceVertex, S ); currentUVSetVPtr.setTokenFloat( faceVertex, 1-T ); } else { MString uvSetName = extraUVSetNames[j-1]; // set uvSet name extraUVSetsNamePtr.setTokenString( j-1, extraUVSetNames[j-1].asChar() ); // set uv values fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); extraUVSetsUPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, S ); extraUVSetsVPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, 1-T ); } } } else { if ( numUVSets ) { for( j=0; j<numUVSets; j++ ) { MString uvSetName; if(j==0) { uvSetName = currentUVSetName; } else { uvSetName = extraUVSetNames[j-1]; } fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); UVSetsArray[j].setTokenFloat( faceVertex, 0, S ); UVSetsArray[j].setTokenFloat( faceVertex, 1, 1-T ); //printf("V%d %s : %f %f => %f %f \n", i, uvSetName.asChar(), S, T, S, 1-T); if( liqglo.liqglo_outputMeshUVs && j==0) { // Match MTOR, which always outputs face-varying STs as well for some reason - Paul pFaceVertexSPointer.setTokenFloat( faceVertex, S ); pFaceVertexTPointer.setTokenFloat( faceVertex, 1-T ); } } } } // printf( "[%d] faceVertex = %d vertex = %d\n", i, faceVertex, vertex ); ++faceVertex; } ++face; } // Add tokens to array and clean up after tokenPointerArray.push_back( pointsPointerPair ); tokenPointerArray.push_back( normalsPointerPair ); if(liqglo.liqglo_outputMeshAsRMSArrays) { tokenPointerArray.push_back( currentUVSetNamePtr ); tokenPointerArray.push_back( currentUVSetUPtr ); tokenPointerArray.push_back( currentUVSetVPtr ); if( numUVSets > 1 ) { tokenPointerArray.push_back( extraUVSetsNamePtr ); tokenPointerArray.push_back( extraUVSetsUPtr ); tokenPointerArray.push_back( extraUVSetsVPtr ); } } else { if( UVSetsArray.size() ) tokenPointerArray.insert( tokenPointerArray.end(), UVSetsArray.begin(), UVSetsArray.end() ); if( liqglo.liqglo_outputMeshUVs ) { tokenPointerArray.push_back( pFaceVertexSPointer ); tokenPointerArray.push_back( pFaceVertexTPointer ); } } addAdditionalSurfaceParameters( mesh ); }
void dagPoseInfo::printDagPoseInfo(MObject& dagPoseNode, unsigned index) // // Description: // Given a dagPose and an index corresponding to a joint, print out // the matrix info for the joint. // Return: // None. // { MFnDependencyNode nDagPose(dagPoseNode); fprintf(file,"%s\n",nDagPose.name().asChar()); // construct plugs for this joints world and local matrices // MObject aWorldMatrix = nDagPose.attribute("worldMatrix"); MPlug pWorldMatrix(dagPoseNode,aWorldMatrix); pWorldMatrix.selectAncestorLogicalIndex(index,aWorldMatrix); MObject aMatrix = nDagPose.attribute("xformMatrix"); MPlug pMatrix(dagPoseNode,aMatrix); pMatrix.selectAncestorLogicalIndex(index,aMatrix); // get and print the world matrix data // MObject worldMatrix, xformMatrix; MStatus status = pWorldMatrix.getValue(worldMatrix); if (MS::kSuccess != status) { displayError("Problem retrieving world matrix."); } else { bool foundMatrix = 0; MFnMatrixData dMatrix(worldMatrix); MMatrix wMatrix = dMatrix.matrix(&status); if (MS::kSuccess == status) { foundMatrix = 1; unsigned jj,kk; fprintf(file,"worldMatrix\n"); for (jj = 0; jj < 4; ++jj) { for (kk = 0; kk < 4; ++kk) { double val = wMatrix(jj,kk); fprintf(file,"%f ",val); } fprintf(file,"\n"); } } if (!foundMatrix) { displayError("Error getting world matrix data."); } } // get and print the local matrix data // status = pMatrix.getValue(xformMatrix); if (MS::kSuccess != status) { displayError("Problem retrieving xform matrix."); } else { bool foundMatrix = 0; MFnMatrixData dMatrix(xformMatrix); if (dMatrix.isTransformation()) { MTransformationMatrix xform = dMatrix.transformation(&status); if (MS::kSuccess == status) { foundMatrix = 1; MMatrix xformAsMatrix = xform.asMatrix(); unsigned jj,kk; fprintf(file,"matrix\n"); for (jj = 0; jj < 4; ++jj) { for (kk = 0; kk < 4; ++kk) { double val = xformAsMatrix(jj,kk); fprintf(file,"%f ",val); } fprintf(file,"\n"); } } } if (!foundMatrix) { displayError("Error getting local matrix data."); } } }
/*! * Description: Deform the point using the Sederberg-Parry FFD algorithm. * * Arguments: * block : the datablock of the node * iter : an iterator for the geometry to be deformed * m : matrix to transform the point into world space * multiIndex : the index of the geometry that we are deforming */ MStatus ffdPlanar::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& /*m*/, unsigned int multiIndex ) { MStatus status = MS::kSuccess; // Determine the displacement lattice points. MDataHandle row1Data = block.inputValue( latticeRow1, &status ); MCheckErr( status, "Error getting r1 data handle\n" ); MVector row1Vector = row1Data.asVector(); MDataHandle row2Data = block.inputValue( latticeRow2, &status ); MCheckErr( status, "Error getting r2 data handle\n" ); MVector row2Vector = row2Data.asVector(); MDataHandle row3Data = block.inputValue( latticeRow3, &status ); MCheckErr( status, "Error getting r3 data\n" ); MVector row3Vector = row3Data.asVector(); // Determine the envelope (this is a global scale factor for the deformer). MDataHandle envData = block.inputValue(envelope,&status); MCheckErr(status, "Error getting envelope data handle\n"); float env = envData.asFloat(); // Generate the FFD lattice. MVector lattice[FFD_LATTICE_POINTS_S][FFD_LATTICE_POINTS_T][FFD_LATTICE_POINTS_U] = { // Since dimensions known ahead of time, generate array now. { // x = 0 { MVector(0.f, row1Vector.x, 0.f), MVector(0.f, row1Vector.y, .5f), MVector(0.f, row1Vector.z, 1.f) }, // y = 0 }, { // x = 1 { MVector(.5f, row2Vector.x, 0.f), MVector(.5f, row2Vector.y, .5f), MVector(.5f, row2Vector.z, 1.f) }, // y = 0 }, { // x = 2 { MVector(1.f, row3Vector.x, 0.f), MVector(1.f, row3Vector.y, .5f), MVector(1.f, row3Vector.z, 1.f) }, // y = 0 } }; MBoundingBox boundingBox; status = getBoundingBox( block, multiIndex, boundingBox ); MCheckErr( status, "Error getting bounding box\n" ); MTransformationMatrix transform = getXyzToStuTransformation( boundingBox ); MMatrix transformMatrix = transform.asMatrix(); MMatrix inverseMatrix = transform.asMatrixInverse(); // Iterate through each point in the geometry. for ( ; !iter.isDone(); iter.next() ) { MPoint pt = iter.position(); MPoint ptStu = pt * transformMatrix; MPoint deformed = getDeformedPoint( ptStu, lattice ) * inverseMatrix; if ( env != 1.f ) { MVector diff = deformed - pt; deformed = pt + env * diff; } iter.setPosition( deformed ); } return status; }
MStatus SklWriter::dumpData() { MStatus status; MDagPath dag_path; MFnIkJoint fn_joint; // MItDag::kDepthFirst used to assure hierarchical order :) MItDag it_dag(MItDag::kDepthFirst, MFn::kJoint, &status); if (status != MStatus::kSuccess) FAILURE("SklWriter: MItDag::MItDag()"); int num_joints = 0; for (; !it_dag.isDone(); it_dag.next()) { SklBone bone; num_joints++; it_dag.getPath(dag_path); data_.joints.append(dag_path); fn_joint.setObject(dag_path); MString jointName = fn_joint.name(); strcpy_s(bone.name, SklBone::kNameLen, jointName.asChar()); MQuaternion rotation, axe; axe = fn_joint.rotateOrientation(MSpace::kTransform); fn_joint.getRotation(rotation, MSpace::kWorld); // since it's kWorld it will get orientation too. rotation = axe * rotation; // but care the devil in the details :) MVector translation = fn_joint.getTranslation(MSpace::kWorld); MTransformationMatrix transform; transform.setRotationQuaternion(rotation.x, rotation.y, rotation.z, rotation.w, MSpace::kWorld); transform.setTranslation(translation, MSpace::kWorld); MMatrix mat = transform.asMatrix(); for (int j = 0; j < 4; j++) for (int k = 0; k < 4; k++) bone.transform[j][k] = static_cast<float>(mat[j][k]); data_.bones.push_back(bone); } data_.num_bones = num_joints; // parenting bones for (int i = 0; i < num_joints; i++) { fn_joint.setObject(data_.joints[i]); if (fn_joint.parentCount() == 1 && fn_joint.parent(0).apiType() == MFn::kJoint) { MFnIkJoint fnParentJoint(fn_joint.parent(0)); fnParentJoint.getPath(dag_path); int j = 0; for (; j < num_joints; j++) { if (dag_path == data_.joints[j]) { data_.bones[i].parent = j; break; } } if (j == num_joints) FAILURE("SklWriter: parent is not upper in hierarchy ? .. oO"); } else { data_.bones[i].parent = -1; } } return MS::kSuccess; }
void AppleseedRenderer::defineLights() { MStatus stat; MFnDependencyNode rGlNode(getRenderGlobalsNode()); // first get the globals node and serach for a directional light connection MObject coronaGlobals = getRenderGlobalsNode(); std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; std::shared_ptr<MayaScene> mayaScene = MayaTo::getWorldPtr()->worldScenePtr; for (auto mobj : mayaScene->lightList) { std::shared_ptr<mtap_MayaObject> obj(std::static_pointer_cast<mtap_MayaObject>(mobj)); if (!obj->visible) continue; if (isSunLight(obj->mobject)) continue; asr::Assembly *lightAssembly = getCreateObjectAssembly(obj.get()); MFnDependencyNode depFn(obj->mobject); asf::auto_release_ptr<asr::Light> light; if (obj->mobject.hasFn(MFn::kPointLight)) { bool cast_indirect_light = getBoolAttr("mtap_cast_indirect_light", depFn, true); float importance_multiplier = getFloatAttr("mtap_importance_multiplier", depFn, 1.0f); MColor col = getColorAttr("color", depFn); float intensity = getFloatAttr("intensity", depFn, 1.0f); MString colorAttribute = obj->shortName + "_intensity"; defineColor(colorAttribute, col, intensity); int decay = getEnumInt("decayRate", depFn); light = asf::auto_release_ptr<asr::Light>( asr::PointLightFactory().create( obj->shortName.asChar(), asr::ParamArray() .insert("intensity", colorAttribute) .insert("intensity_multiplier", intensity) .insert("importance_multiplier", importance_multiplier) .insert("cast_indirect_light", cast_indirect_light) )); } if (obj->mobject.hasFn(MFn::kSpotLight)) { // redefinition because it is possible that this value is textured bool cast_indirect_light = getBoolAttr("mtap_cast_indirect_light", depFn, true); float importance_multiplier = getFloatAttr("mtap_importance_multiplier", depFn, 1.0f); MColor col = getColorAttr("color", depFn); float intensity = getFloatAttr("intensity", depFn, 1.0f); MString colorAttribute = obj->shortName + "_intensity"; defineColor(colorAttribute, col, intensity); Logging::debug(MString("Creating spotLight: ") + depFn.name()); float coneAngle = getDegree("coneAngle", depFn); float penumbraAngle = getDegree("penumbraAngle", depFn); float inner_angle = coneAngle; float outer_angle = coneAngle + penumbraAngle; light = asf::auto_release_ptr<asr::Light>( asr::SpotLightFactory().create( obj->shortName.asChar(), asr::ParamArray() .insert("radiance", colorAttribute) .insert("radiance_multiplier", intensity) .insert("inner_angle", inner_angle) .insert("outer_angle", outer_angle) .insert("importance_multiplier", importance_multiplier) .insert("cast_indirect_light", cast_indirect_light) )); } if (obj->mobject.hasFn(MFn::kDirectionalLight)) { bool cast_indirect_light = getBoolAttr("mtap_cast_indirect_light", depFn, true); float importance_multiplier = getFloatAttr("mtap_importance_multiplier", depFn, 1.0f); MVector lightDir(0, 0, -1); MVector lightDirTangent(1, 0, 0); MVector lightDirBiTangent(0, 1, 0); MColor col = getColorAttr("color", depFn); float intensity = getFloatAttr("intensity", depFn, 1.0f); MString colorAttribute = obj->shortName + "_intensity"; defineColor(colorAttribute, col, intensity); if( isSunLight(obj->mobject)) { //Logging::debug(MString("Found sunlight.")); //light = asf::auto_release_ptr<asr::Light>( // asr::SunLightFactory().create( // "sunLight", // asr::ParamArray() // .insert("environment_edf", "sky_edf") // .insert("turbidity", renderGlobals->sunTurbidity) // .insert("radiance_multiplier", renderGlobals->sunExitanceMultiplier * intensity / 30.0f) // )); }else{ light = asf::auto_release_ptr<asr::Light>( asr::DirectionalLightFactory().create( obj->shortName.asChar(), asr::ParamArray() .insert("irradiance", colorAttribute) .insert("irradiance_multiplier", intensity) .insert("importance_multiplier", importance_multiplier) .insert("cast_indirect_light", cast_indirect_light) )); } } if (obj->mobject.hasFn(MFn::kAreaLight)) { MString areaLightName = obj->fullNiceName; asf::auto_release_ptr<asr::MeshObject> plane = defineStandardPlane(); plane->set_name(areaLightName.asChar()); MayaObject *assemblyObject = getAssemblyMayaObject(obj.get()); asr::Assembly *ass = getCreateObjectAssembly(obj.get()); ass->objects().insert(asf::auto_release_ptr<asr::Object>(plane)); asr::MeshObject *meshPtr = (asr::MeshObject *)ass->objects().get_by_name(areaLightName.asChar()); MString objectInstanceName = getObjectInstanceName(obj.get()); MMatrix assemblyObjectMatrix = assemblyObject->dagPath.inclusiveMatrix(); // rotate the defalt up pointing standard plane by 90 degree to match the area light direction MTransformationMatrix tm; double rotate90Deg[3] = { -M_PI_2, 0, 0 }; tm.setRotation(rotate90Deg, MTransformationMatrix::kXYZ); MMatrix objectMatrix = tm.asMatrix(); MMatrix diffMatrix = objectMatrix;// *assemblyObjectMatrix; asf::Matrix4d appleMatrix; MMatrixToAMatrix(diffMatrix, appleMatrix); MString areaLightMaterialName = areaLightName + "_material"; MString physicalSurfaceName = areaLightName + "_physical_surface_shader"; MString areaLightColorName = areaLightName + "_color"; MString edfName = areaLightName + "_edf"; asr::ParamArray edfParams; MString lightColor = lightColorAsString(depFn); MColor color = getColorAttr("color", depFn); defineColor(areaLightColorName, color, getFloatAttr("intensity", depFn, 1.0f)); edfParams.insert("radiance", areaLightColorName.asChar()); //edfParams.insert("radiance_multiplier", getFloatAttr("intensity", depFn, 1.0f)); asf::auto_release_ptr<asr::EDF> edf = asr::DiffuseEDFFactory().create(edfName.asChar(), edfParams); ass->edfs().insert(edf); ass->surface_shaders().insert( asr::PhysicalSurfaceShaderFactory().create( physicalSurfaceName.asChar(), asr::ParamArray())); ass->materials().insert( asr::GenericMaterialFactory().create( areaLightMaterialName.asChar(), asr::ParamArray() .insert("surface_shader", physicalSurfaceName.asChar()) .insert("edf", edfName.asChar()))); asr::ParamArray objInstanceParamArray; addVisibilityFlags(obj, objInstanceParamArray); ass->object_instances().insert( asr::ObjectInstanceFactory::create( objectInstanceName.asChar(), objInstanceParamArray, meshPtr->get_name(), asf::Transformd::from_local_to_parent(appleMatrix), asf::StringDictionary() .insert("slot0", areaLightMaterialName.asChar()), asf::StringDictionary() .insert("slot0", "default"))); } if ( light.get() != nullptr) lightAssembly->lights().insert(light); } //std::shared_ptr<MayaObject> mlight = obj; //asf::Matrix4d appMatrix = asf::Matrix4d::identity(); //Logging::debug(MString("Creating light: ") + mlight->shortName); //MMatrix colMatrix = mlight->transformMatrices[0]; //this->MMatrixToAMatrix(colMatrix, appMatrix); //MFnLight lightFn(mlight->mobject, &stat); //if( !stat ) //{ // Logging::error(MString("Could not get light info from ") + mlight->shortName); // return; //} //float intensity = 1.0f; //getFloat(MString("intensity"), lightFn, intensity); //intensity *= 100 * this->renderGlobals->sceneScale; //// multiplier 30 was the default value in the example //MString colorAttribute = this->defineColor(lightFn, MString("color"), "srgb", 1.0f); //asf::auto_release_ptr<asr::Light> light; //if( mlight->mobject.hasFn(MFn::kSpotLight)) //{ // // redefinition because it is possible that this value is textured // colorAttribute = defineColorAttributeWithTexture(lightFn, MString("color"), 1.0f); // Logging::debug(MString("Creating spotLight: ") + lightFn.name()); // float coneAngle = 45.0f; // float penumbraAngle = 3.0f; // getFloat(MString("coneAngle"), lightFn, coneAngle); // getFloat(MString("penumbraAngle"), lightFn, penumbraAngle); // coneAngle = (float)RadToDeg(coneAngle); // penumbraAngle = (float)RadToDeg(penumbraAngle); // float inner_angle = coneAngle; // float outer_angle = coneAngle + penumbraAngle; // if( !update ) // { // light = asf::auto_release_ptr<asr::Light>( // asr::SpotLightFactory().create( // mlight->shortName.asChar(), // asr::ParamArray() // .insert("radiance", colorAttribute.asChar()) // .insert("radiance_multiplier", intensity) // .insert("inner_angle", inner_angle) // .insert("outer_angle", outer_angle) // )); // ass->lights().insert(light); // }else{ // asr::Light *pLight = ass->lights().get_by_name(obj->shortName.asChar()); // pLight->get_parameters().insert("radiance", colorAttribute.asChar()); // pLight->get_parameters().insert("radiance_multiplier", intensity); // pLight->get_parameters().insert("inner_angle", inner_angle); // pLight->get_parameters().insert("outer_angle", outer_angle); // } //} //if( mlight->mobject.hasFn(MFn::kDirectionalLight)) //{ // if( !update ) // { // if( this->isSunLight(mlight)) // { // Logging::debug(MString("Found sunlight.")); // light = asf::auto_release_ptr<asr::Light>( // asr::SunLightFactory().create( // "sunLight", // asr::ParamArray() // .insert("environment_edf", "sky_edf") // .insert("turbidity", renderGlobals->sunTurbidity) // .insert("radiance_multiplier", renderGlobals->sunExitanceMultiplier * intensity / 30.0f) // )); // }else{ // light = asf::auto_release_ptr<asr::Light>( // asr::DirectionalLightFactory().create( // mlight->shortName.asChar(), // asr::ParamArray() // .insert("radiance", colorAttribute.asChar()) // .insert("radiance_multiplier", intensity) // )); // } // ass->lights().insert(light); // // }else{ // asr::Light *pLight = ass->lights().get_by_name(obj->shortName.asChar()); // if( this->isSunLight(mlight)) // { // pLight->get_parameters().insert("environment_edf", "sky_edf"); // pLight->get_parameters().insert("turbidity", renderGlobals->sunTurbidity); // pLight->get_parameters().insert("radiance_multiplier", renderGlobals->sunExitanceMultiplier * intensity / 30.0f); // }else{ // pLight->get_parameters().insert("radiance", colorAttribute.asChar()); // pLight->get_parameters().insert("radiance_multiplier", intensity); // } // } //} //if( mlight->mobject.hasFn(MFn::kPointLight)) //{ // if( !update ) // { // light = asf::auto_release_ptr<asr::Light>( // asr::PointLightFactory().create( // mlight->shortName.asChar(), // asr::ParamArray() // .insert("radiance", colorAttribute.asChar()) // .insert("radiance_multiplier", intensity) // )); // ass->lights().insert(light); // }else{ // asr::Light *pLight = ass->lights().get_by_name(obj->shortName.asChar()); // pLight->get_parameters().insert("radiance", colorAttribute.asChar()); // pLight->get_parameters().insert("radiance_multiplier", intensity); // } //} }
/* static */ bool px_vp20Utils::RenderBoundingBox( const MBoundingBox& bounds, const GfVec4f& color, const MMatrix& worldViewMat, const MMatrix& projectionMat) { static const GfVec3f cubeLineVertices[24] = { // Vertical edges GfVec3f(-0.5f, -0.5f, 0.5f), GfVec3f(-0.5f, 0.5f, 0.5f), GfVec3f(0.5f, -0.5f, 0.5f), GfVec3f(0.5f, 0.5f, 0.5f), GfVec3f(0.5f, -0.5f, -0.5f), GfVec3f(0.5f, 0.5f, -0.5f), GfVec3f(-0.5f, -0.5f, -0.5f), GfVec3f(-0.5f, 0.5f, -0.5f), // Top face edges GfVec3f(-0.5f, 0.5f, 0.5f), GfVec3f(0.5f, 0.5f, 0.5f), GfVec3f(0.5f, 0.5f, 0.5f), GfVec3f(0.5f, 0.5f, -0.5f), GfVec3f(0.5f, 0.5f, -0.5f), GfVec3f(-0.5f, 0.5f, -0.5f), GfVec3f(-0.5f, 0.5f, -0.5f), GfVec3f(-0.5f, 0.5f, 0.5f), // Bottom face edges GfVec3f(-0.5f, -0.5f, 0.5f), GfVec3f(0.5f, -0.5f, 0.5f), GfVec3f(0.5f, -0.5f, 0.5f), GfVec3f(0.5f, -0.5f, -0.5f), GfVec3f(0.5f, -0.5f, -0.5f), GfVec3f(-0.5f, -0.5f, -0.5f), GfVec3f(-0.5f, -0.5f, -0.5f), GfVec3f(-0.5f, -0.5f, 0.5f), }; static const std::string vertexShaderSource( "#version 140\n" "\n" "in vec3 position;\n" "uniform mat4 mvpMatrix;\n" "\n" "void main()\n" "{\n" " gl_Position = vec4(position, 1.0) * mvpMatrix;\n" "}\n"); static const std::string fragmentShaderSource( "#version 140\n" "\n" "uniform vec4 color;\n" "out vec4 outColor;\n" "\n" "void main()\n" "{\n" " outColor = color;\n" "}\n"); PxrMayaGLSLProgram renderBoundsProgram; if (!renderBoundsProgram.CompileShader(GL_VERTEX_SHADER, vertexShaderSource)) { MGlobal::displayError("Failed to compile bounding box vertex shader"); return false; } if (!renderBoundsProgram.CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSource)) { MGlobal::displayError("Failed to compile bounding box fragment shader"); return false; } if (!renderBoundsProgram.Link()) { MGlobal::displayError("Failed to link bounding box render program"); return false; } if (!renderBoundsProgram.Validate()) { MGlobal::displayError("Failed to validate bounding box render program"); return false; } GLuint renderBoundsProgramId = renderBoundsProgram.GetProgramId(); glUseProgram(renderBoundsProgramId); // Populate an array buffer with the cube line vertices. GLuint cubeLinesVBO; glGenBuffers(1, &cubeLinesVBO); glBindBuffer(GL_ARRAY_BUFFER, cubeLinesVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeLineVertices), cubeLineVertices, GL_STATIC_DRAW); // Create a transformation matrix from the bounding box's center and // dimensions. MTransformationMatrix bboxTransformMatrix = MTransformationMatrix::identity; bboxTransformMatrix.setTranslation(bounds.center(), MSpace::kTransform); const double scales[3] = { bounds.width(), bounds.height(), bounds.depth() }; bboxTransformMatrix.setScale(scales, MSpace::kTransform); const MMatrix mvpMatrix = bboxTransformMatrix.asMatrix() * worldViewMat * projectionMat; GLfloat mvpMatrixArray[4][4]; mvpMatrix.get(mvpMatrixArray); // Populate the shader variables. GLuint mvpMatrixLocation = glGetUniformLocation(renderBoundsProgramId, "mvpMatrix"); glUniformMatrix4fv(mvpMatrixLocation, 1, GL_TRUE, &mvpMatrixArray[0][0]); GLuint colorLocation = glGetUniformLocation(renderBoundsProgramId, "color"); glUniform4fv(colorLocation, 1, color.data()); // Enable the position attribute and draw. glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_LINES, 0, sizeof(cubeLineVertices)); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &cubeLinesVBO); glUseProgram(0); return true; }
MStatus buildRotation::compute( const MPlug& plug, MDataBlock& data ) { MStatus returnStatus; if ((plug == rotate) || (plug.parent() == rotate) || (plug == rotateMatrix)) { MDataHandle upData = data.inputValue( up, &returnStatus ); McheckErr(returnStatus,"ERROR getting up vector data"); MDataHandle forwardData = data.inputValue( forward, &returnStatus ); McheckErr(returnStatus,"ERROR getting forward vector data"); MVector up = upData.asVector(); MVector forward = forwardData.asVector(); // Make sure that the up and forward vectors are orthogonal // if ( fabs( up * forward ) > EPSILON ) { // Non-zero dot product // MVector orthoVec = up ^ forward; MVector newForward = orthoVec ^ up; if ( forward * newForward < 0.0 ) { // Reverse the vector // newForward *= -1.0; } forward = newForward; } // Calculate the rotation required to align the y-axis with the up // vector // MTransformationMatrix firstRot; MVector rotAxis = MVector::yAxis ^ up; rotAxis.normalize(); firstRot.setToRotationAxis( rotAxis, MVector::yAxis.angle( up ) ); // Calculate the second rotation required to align the forward vector // MTransformationMatrix secondRot; MVector transformedForward = firstRot.asMatrix() * forward; transformedForward.normalize(); double angle = transformedForward.angle( MVector::zAxis ); if ( transformedForward.x < 0.0 ) { // Compensate for the fact that the angle method returns // the absolute value // angle *= -1.0; } secondRot.setToRotationAxis( up, angle ); // Get the requested rotation order // MDataHandle orderHandle = data.inputValue( rotateOrder ); short order = orderHandle.asShort(); MTransformationMatrix::RotationOrder rotOrder; switch ( order ) { case ROTATE_ORDER_XYZ: rotOrder = MTransformationMatrix::kXYZ; break; case ROTATE_ORDER_YZX: rotOrder = MTransformationMatrix::kYZX; break; case ROTATE_ORDER_ZXY: rotOrder = MTransformationMatrix::kZXY; break; case ROTATE_ORDER_XZY: rotOrder = MTransformationMatrix::kXZY; break; case ROTATE_ORDER_YXZ: rotOrder = MTransformationMatrix::kYXZ; break; case ROTATE_ORDER_ZYX: rotOrder = MTransformationMatrix::kZYX; break; default: rotOrder = MTransformationMatrix::kInvalid; break; } MTransformationMatrix result = firstRot.asMatrix() * secondRot.asMatrix(); result.reorderRotation( rotOrder ); double rotation[3]; result.getRotation( rotation, rotOrder, MSpace::kTransform ); MDataHandle outputRot = data.outputValue( rotate ); outputRot.set( rotation[0], rotation[1], rotation[2] ); outputRot.setClean(); MDataHandle outputMatrix = data.outputValue( rotateMatrix ); outputMatrix.set( result.asMatrix() ); outputMatrix.setClean(); } else return MS::kUnknownParameter; return MS::kSuccess; }
// COMPUTE ====================================== MStatus gear_rollSplineKine::compute(const MPlug& plug, MDataBlock& data) { MStatus returnStatus; // Error check if (plug != output) return MS::kUnknownParameter; // Get inputs matrices ------------------------------ // Inputs Parent MArrayDataHandle adh = data.inputArrayValue( ctlParent ); int count = adh.elementCount(); if (count < 1) return MS::kFailure; MMatrixArray inputsP(count); for (int i = 0 ; i < count ; i++){ adh.jumpToElement(i); inputsP[i] = adh.inputValue().asMatrix(); } // Inputs adh = data.inputArrayValue( inputs ); if (count != adh.elementCount()) return MS::kFailure; MMatrixArray inputs(count); for (int i = 0 ; i < count ; i++){ adh.jumpToElement(i); inputs[i] = adh.inputValue().asMatrix(); } adh = data.inputArrayValue( inputsRoll ); if (count != adh.elementCount()) return MS::kFailure; MDoubleArray roll(adh.elementCount()); for (int i = 0 ; i < count ; i++){ adh.jumpToElement(i); roll[i] = degrees2radians((double)adh.inputValue().asFloat()); } // Output Parent MDataHandle ha = data.inputValue( outputParent ); MMatrix outputParent = ha.asMatrix(); // Get inputs sliders ------------------------------- double in_u = (double)data.inputValue( u ).asFloat(); bool in_resample = data.inputValue( resample ).asBool(); int in_subdiv = data.inputValue( subdiv ).asShort(); bool in_absolute = data.inputValue( absolute ).asBool(); // Process ------------------------------------------ // Get roll, pos, tan, rot, scl MVectorArray pos(count); MVectorArray tan(count); MQuaternion *rot; rot = new MQuaternion[count]; MVectorArray scl(count); double threeDoubles[3]; for (int i = 0 ; i < count ; i++){ MTransformationMatrix tp(inputsP[i]); MTransformationMatrix t(inputs[i]); pos[i] = t.getTranslation(MSpace::kWorld); rot[i] = tp.rotation(); t.getScale(threeDoubles, MSpace::kWorld); scl[i] = MVector(threeDoubles[0], threeDoubles[1], threeDoubles[2]); tan[i] = MVector(threeDoubles[0] * 2.5, 0, 0).rotateBy(t.rotation()); } // Get step and indexes // We define between wich controlers the object is to be able to // calculate the bezier 4 points front this 2 objects double step = 1.0 / max( 1, count-1.0 ); int index1 = (int)min( count-2.0, in_u/step ); int index2 = index1+1; int index1temp = index1; int index2temp = index2; double v = (in_u - step * double(index1)) / step; double vtemp = v; // calculate the bezier MVector bezierPos; MVector xAxis, yAxis, zAxis; if(!in_resample){ // straight bezier solve MVectorArray results = bezier4point(pos[index1],tan[index1],pos[index2],tan[index2],v); bezierPos = results[0]; xAxis = results[1]; } else if(!in_absolute){ MVectorArray presample(in_subdiv); MVectorArray presampletan(in_subdiv); MDoubleArray samplelen(in_subdiv); double samplestep = 1.0 / double(in_subdiv-1); double sampleu = samplestep; presample[0] = pos[index1]; presampletan[0] = tan[index1]; MVector prevsample(presample[0]); MVector diff; samplelen[0] = 0; double overalllen = 0; MVectorArray results(2); for(long i=1;i<in_subdiv;i++,sampleu+=samplestep){ results = bezier4point(pos[index1],tan[index1],pos[index2],tan[index2],sampleu); presample[i] = results[0]; presampletan[i] = results[1]; diff = presample[i] - prevsample; overalllen += diff.length(); samplelen[i] = overalllen; prevsample = presample[i]; } // now as we have the sampleu = 0; for(long i=0;i<in_subdiv-1;i++,sampleu+=samplestep){ samplelen[i+1] = samplelen[i+1] / overalllen; if(v>=samplelen[i] && v <= samplelen[i+1]){ v = (v - samplelen[i]) / (samplelen[i+1] - samplelen[i]); bezierPos = linearInterpolate(presample[i],presample[i+1],v); xAxis = linearInterpolate(presampletan[i],presampletan[i+1],v); break; } } } else{ MVectorArray presample(in_subdiv); MVectorArray presampletan(in_subdiv); MDoubleArray samplelen(in_subdiv); double samplestep = 1.0 / double(in_subdiv-1); double sampleu = samplestep; presample[0] = pos[0]; presampletan[0] = tan[0]; MVector prevsample(presample[0]); MVector diff; samplelen[0] = 0; double overalllen = 0; MVectorArray results; for(long i=1;i<in_subdiv;i++,sampleu+=samplestep){ index1 = (int)min(count-2,sampleu / step); index2 = index1+1; v = (sampleu - step * double(index1)) / step; results = bezier4point(pos[index1],tan[index1],pos[index2],tan[index2],v); presample[i] = results[0]; presampletan[i] = results[1]; diff = presample[i] - prevsample; overalllen += diff.length(); samplelen[i] = overalllen; prevsample = presample[i]; } // now as we have the sampleu = 0; for(long i=0;i<in_subdiv-1;i++,sampleu+=samplestep){ samplelen[i+1] = samplelen[i+1] / overalllen; if(in_u>=samplelen[i] && in_u <= samplelen[i+1]){ in_u = (in_u - samplelen[i]) / (samplelen[i+1] - samplelen[i]); bezierPos = linearInterpolate(presample[i],presample[i+1],in_u); xAxis = linearInterpolate(presampletan[i],presampletan[i+1],in_u); break; } } } // compute the scaling (straight interpolation!) MVector scl1 = linearInterpolate(scl[index1temp], scl[index2temp],vtemp); // compute the rotation! MQuaternion q = slerp(rot[index1temp], rot[index2temp], vtemp); yAxis = MVector(0,1,0); yAxis = yAxis.rotateBy(q); // use directly or project the roll values! // print roll double a = linearInterpolate(roll[index1temp], roll[index2temp], vtemp); yAxis = yAxis.rotateBy( MQuaternion(xAxis.x * sin(a/2.0), xAxis.y * sin(a/2.0), xAxis.z * sin(a/2.0), cos(a/2.0))); zAxis = xAxis ^ yAxis; zAxis.normalize(); yAxis = zAxis ^ xAxis; yAxis.normalize(); // Output ------------------------------------------- MTransformationMatrix result; // translation result.setTranslation(bezierPos, MSpace::kWorld); // rotation q = getQuaternionFromAxes(xAxis,yAxis,zAxis); result.setRotationQuaternion(q.x, q.y, q.z, q.w); // scaling threeDoubles[0] = 1; threeDoubles[0] = scl1.y; threeDoubles[0] = scl1.z; result.setScale(threeDoubles, MSpace::kWorld); MDataHandle h = data.outputValue( output ); h.setMMatrix( result.asMatrix() * outputParent.inverse() ); data.setClean( plug ); return MS::kSuccess; }