I’ve been doing something similar in my depth of field tool, although I was getting all the meshes visible in the camera frustum. And these methods are now deprecated.
class MMeshDrawTraversal : public MDrawTraversal {
/* User-defined MDrawTraversal for filtering mesh objects. */
virtual bool filterNode(const MDagPath &traversalItem) {
bool prune = false;
// Check to only prune shapes, not transforms.
if (traversalItem.childCount() == 0) {
if (!traversalItem.hasFn(MFn::kMesh)) {
prune = true;
}
}
return prune;
}
};
and then you just iterate through them and add to an array:
MStatus DepthOfFieldContext::getMeshesInView(MDagPath &cameraPath, unsigned int &portWidth, unsigned int &portHeight) {
/* Gets all meshes that are visible in the given camera.
Args:
cameraPath (MDagPath &): path to a valid scene camera
portWidth (unsigned int): width of the viewport to cull against
portHeight (unsigned int): height of the viewport to cull against
Returns:
status code (MStatus): kSuccess if the operation was successful, kFailure if an
error occured during the operation
*/
MStatus status;
_meshesInView.clear();
MDrawTraversal *trav = new MMeshDrawTraversal;
trav->enableFiltering(true);
trav->setFrustum(cameraPath, portWidth, portHeight);
trav->traverse();
for (unsigned int i = 0; i < trav->numberOfItems(); i++) {
MDagPath dagPath;
trav->itemPath(i, dagPath);
_meshesInView.append(dagPath);
}
// Clean up pointer
delete trav; trav = NULL;
return MS::kSuccess;
}
lastly you have to screen raycast with screen to world in the closestIntersection method.
Check Chad’s Vernonn api series. You have to compare the lenghts of the hits from the camera and return the closest your self. Annoying i know.