Exemplo n.º 1
0
MStatus intersectCmd::doIt(const MArgList& args)

// Description:
// 		Determine if the ray from the spotlight intersects the mesh.
//		If it does, display the intersection points.

{
	MStatus stat = MStatus::kSuccess;

	if (args.length() != 2) 
	{
		MGlobal::displayError("Need 2 items!");
		return MStatus::kFailure;
	}

	MSelectionList activeList;
	int i;
	
	for ( i = 0; i < 2; i++)
	{
		MString strCurrSelection;
		stat = args.get(i, strCurrSelection);
		if (MStatus::kSuccess == stat) activeList.add(strCurrSelection);
	}

	MItSelectionList iter(activeList);
	MFnSpotLight fnLight;  
	MFnMesh fnMesh;
	MFnDagNode dagNod;
	MFnDependencyNode fnDN;

	float fX = 0;
	float fY = 0;
	float fZ = 0;

	for ( ; !iter.isDone(); iter.next() )
	{
		MObject tempObjectParent, tempObjectChild;
		iter.getDependNode(tempObjectParent);

		if (tempObjectParent.apiType() == MFn::kTransform)
		{
			dagNod.setObject(tempObjectParent);
			tempObjectChild = dagNod.child(0, &stat);
		}

		// check what type of object is selected
		if (tempObjectChild.apiType() == MFn::kSpotLight)
		{
			MDagPath pathToLight;
			MERR_CHK(MDagPath::getAPathTo(tempObjectParent, pathToLight), "Couldn't get a path to the spotlight");
			MERR_CHK(fnLight.setObject(pathToLight), "Failure on assigning light");
			
			stat = fnDN.setObject(tempObjectParent);

			MPlug pTempPlug = fnDN.findPlug("translateX", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fX);
			}

			pTempPlug = fnDN.findPlug("translateY", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fY);
			}

			pTempPlug = fnDN.findPlug("translateZ", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fZ);
			}	
		}
		else if (tempObjectChild.apiType() == MFn::kMesh)
		{
			MDagPath pathToMesh;
			MERR_CHK(MDagPath::getAPathTo(tempObjectChild, pathToMesh), "Couldn't get a path to the spotlight");
			MERR_CHK(fnMesh.setObject(pathToMesh), "Failure on assigning light");	
		}
		else
		{
			MGlobal::displayError("Need a spotlight and a mesh");
			return MStatus::kFailure;
		}
	}

	MFloatPoint fpSource(fX, fY, fZ);
	MFloatVector fvRayDir = fnLight.lightDirection(0, MSpace::kWorld, &stat);
	MFloatPoint hitPoint;
	
	MMeshIsectAccelParams mmAccelParams = fnMesh.autoUniformGridParams();
	
	float fHitRayParam, fHitBary1, fHitBary2;
	int nHitFace, nHitTriangle;

	// a large positive number is used here for the maxParam parameter
	bool bAnyIntersection = fnMesh.anyIntersection(fpSource, fvRayDir, NULL, NULL, false,				MSpace::kWorld, (float)9999, false, &mmAccelParams, hitPoint, &fHitRayParam, &nHitFace, &nHitTriangle, 		&fHitBary1, &fHitBary2, (float)1e-6, &stat);
	
	if (! bAnyIntersection) 
	{
		MGlobal::displayInfo("There were no intersection points detected");
		return stat;
	}

	MFloatPointArray hitPoints;
	MFloatArray faHitRayParams;
	MIntArray iaHitFaces;
	MIntArray iaHitTriangles;
	MFloatArray faHitBary1;
	MFloatArray faHitBary2;

	bool bAllIntersections = fnMesh.allIntersections(fpSource, fvRayDir, NULL, NULL, false, MSpace::kWorld, 9999, false, NULL, false, hitPoints, &faHitRayParams, &iaHitFaces, &iaHitTriangles, &faHitBary1, &faHitBary2, 0.000001f, &stat);
	
	if (! bAllIntersections)
	{
		MGlobal::displayInfo("Error getting all intersections");
		return stat;
	}
	
	// check how many intersections are found
	unsigned int nNumberHitPoints = hitPoints.length();

	if (! nNumberHitPoints)
	{
		MGlobal::displayInfo("No hit points detected");
		return MStatus::kSuccess;
	}

	// Intersection exists; display intersections as spheres
	MString strCommandString = "string $strBall[] = `polySphere -r 0.5`;";
	strCommandString += "$strBallName = $strBall[0];";

	float x = 0;
	float y = 0;
	float z = 0;

	for (i = 0; i < (int)nNumberHitPoints; i++)
	{
		// get the points
		x = hitPoints[i][0];
		y = hitPoints[i][1];
		z = hitPoints[i][2];

		// execute some MEL to create a small sphere
		strCommandString += "setAttr ($strBallName + \".tx\") ";
		strCommandString += x;
		strCommandString += ";";

		strCommandString += "setAttr ($strBallName + \".ty\") ";
		strCommandString += y;
		strCommandString += ";";

		strCommandString += "setAttr ($strBallName + \".tz\") ";
		strCommandString += z;
		strCommandString += ";";

		MGlobal::executeCommand(strCommandString);
	}

	return stat;
}