private static void addGeometriesInCamFrustumAndViewPortFromNode(Camera vpCamera, Camera[] cameras, Spatial scene, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) {
        if (scene.getCullHint() == Spatial.CullHint.Always) return;

        boolean inFrustum = false;
        for (int j = 0; j < cameras.length && inFrustum == false; j++) {
            Camera camera = cameras[j];
            int planeState = camera.getPlaneState();
            camera.setPlaneState(0);
            inFrustum = camera.contains(scene.getWorldBound()) != Camera.FrustumIntersect.Outside && scene.checkCulling(vpCamera);
            camera.setPlaneState(planeState);
        }
        if (inFrustum) {
            if (scene instanceof Node)
            {
                Node node = (Node)scene;
                for (Spatial child: node.getChildren()) {
                    addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, child, mode, outputGeometryList);
                }
            }
            else if (scene instanceof Geometry) {
                if (checkShadowMode(scene.getShadowMode(), mode) && !((Geometry)scene).isGrouped()) {
                    outputGeometryList.add((Geometry)scene);
                }
            }
        }
    }
Helper function to recursively collect the geometries for getLitGeometriesInViewPort function.

@param vpCamera the viewPort camera
@param cameras the camera array to check geometries against, representing the light viewspace
@param scene the Node to traverse or geometry to possibly add
@param outputGeometryList the output list of all geometries that are in the camera frustum
jme3-core/src/main/java/com/jme3/shadow/ShadowUtil.java