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 );
}
Пример #3
0
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.");
        }
    }
}
Пример #4
0
/*!
 * 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;
}
Пример #5
0
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;
}
Пример #6
0
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);
	//	}
	//}
}
Пример #7
0
Файл: utils.cpp Проект: JT-a/USD
/* 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;
}
Пример #8
0
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;
}
Пример #9
0
// 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;
}