// invoked by Save-button
    public IEnumerator SaveButtonClicked()
    {
        // save scene
        string sFilePath = FileUtils.GetPersitentDataPath("SavedSceneSurfaces.json");
        bool   bSaved    = SaveArScene(sFilePath);

        // save image
        if (bSaved)
        {
            string sJpegPath = FileUtils.GetPersitentDataPath("SavedSceneImage.jpg");
            SaveScreenShot(sJpegPath);
        }

        yield return(null);

        // show result
        if (bSaved && sceneInfoText)
        {
            MultiARManager marManager = MultiARManager.Instance;
            sceneInfoText.text = "Saved " + (marManager ? marManager.GetTrackedSurfacesCount() : 0) +
                                 " surfaces (head:" + (int)startHeading + ") to file: " + sFilePath;

            // wait for some time
            yield return(new WaitForSeconds(10f));

            // clear the info
            sceneInfoText.text = "Slide to save the scene into local file.";
        }

        routineRunning = false;
    }
    // saves AR scene parameters and the detected surfaces
    public bool SaveArScene(string dataFilePath)
    {
        MultiARManager marManager = MultiARManager.Instance;

        if (!marManager || marManager.GetTrackedSurfacesCount() == 0)
        {
            return(false);
        }

        JsonArScene data = new JsonArScene();

        data.saverVer  = 1;
        data.sceneDesc = string.Empty;
        data.timestamp = marManager.GetTrackedSurfacesTimestamp();

        if (locationEnabled && Input.location.status == LocationServiceStatus.Running)
        {
            data.scenePos = new JsonScenePos();

            data.scenePos.lat = lastLoc.latitude;
            data.scenePos.lon = lastLoc.longitude;
            data.scenePos.alt = lastLoc.altitude;

            Vector3 latLonM = GeoUtils.LatLong2Meters(lastLoc.latitude, lastLoc.longitude, lastLoc.altitude);
            data.scenePos.latm = (long)((double)latLonM.x * 1000.0);
            data.scenePos.lonm = (long)((double)latLonM.y * 1000.0);
            data.scenePos.altm = (long)latLonM.z;
        }


        if (gyroEnabled)
        {
            data.sceneRot = new JsonSceneRot();

            data.sceneRot.gyroAtt = gyroAttitude.eulerAngles;
            data.sceneRot.gyroRot = gyroRotation.eulerAngles;
        }

        data.compHeading  = compHeading;
        data.startHeading = startHeading;
        Quaternion compStartRot = Quaternion.Euler(0f, startHeading, 0f);

        data.sceneCam        = new JsonSceneCam();
        data.sceneCam.camPos = compStartRot * camPosition;

        data.sceneCam.camRot = camRotation.eulerAngles + compStartRot.eulerAngles;
        data.sceneCam.camRot = Quaternion.Euler(data.sceneCam.camRot).eulerAngles;

        // surfaces
        data.surfaceSet              = new JsonSurfaceSet();
        data.surfaceSet.timestamp    = marManager.GetTrackedSurfacesTimestamp();
        data.surfaceSet.surfaceCount = marManager.GetTrackedSurfacesCount();
        data.surfaceSet.surfaces     = new JsonSurface[data.surfaceSet.surfaceCount];

        MultiARInterop.TrackedSurface[] trackedSurfaces = marManager.GetTrackedSurfaces(true);
        for (int i = 0; i < data.surfaceSet.surfaceCount; i++)
        {
            // transformed surfaces
            data.surfaceSet.surfaces[i] = new JsonSurface();

            Vector3 surfacePos = trackedSurfaces[i].position;
            data.surfaceSet.surfaces[i].position = compStartRot * surfacePos;

//			data.surfaceSet.surfaces[i].rotation = trackedSurfaces[i].rotation.eulerAngles;
            Vector3 surfaceRot = trackedSurfaces[i].rotation.eulerAngles + compStartRot.eulerAngles;
            data.surfaceSet.surfaces[i].rotation = Quaternion.Euler(surfaceRot).eulerAngles;

            data.surfaceSet.surfaces[i].bounds   = trackedSurfaces[i].bounds;
            data.surfaceSet.surfaces[i].vertices = trackedSurfaces[i].points;
            data.surfaceSet.surfaces[i].indices  = trackedSurfaces[i].triangles;
        }

        try
        {
            // save json
            string sJsonText = JsonUtility.ToJson(data, true);
            File.WriteAllText(dataFilePath, sJsonText);

            Debug.Log("AR-Scene (head: " + (int)data.startHeading + ") saved to: " + dataFilePath);

            return(true);
        }
        catch (System.Exception ex)
        {
            string sMessage = ex.Message + "\n" + ex.StackTrace;
            Debug.LogError(sMessage);
        }

        return(false);
    }