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; }