Ejemplo n.º 1
0
        public static ProjectList LoadProjects()
        {
            var filePath = projectListFilePath;

            try
            {
                if (File.Exists(filePath))
                {
                    var jsonData = File.ReadAllText(filePath);
                    if (!string.IsNullOrEmpty(jsonData))
                    {
                        return(SceneSerialization.FromJson <ProjectList>(jsonData));
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return(new ProjectList());
        }
        static IEnumerator ImportDataRecording(this IUsesCloudStorage storageUser, string recordingPath,
                                               string recordingKey, string recordingName, string jsonText, Stack <RequestHandle> requests,
                                               Action <UnityObject> callback)
        {
            k_DataRecordings.Clear();
            k_NewAssets.Clear();

            var recording = SceneSerialization.FromJson <CompanionDataRecording>(jsonText);

            var recordingInfo = SessionRecordingUtils.CreateSessionRecordingAsset(recordingPath);
            var timeline      = recordingInfo.Timeline;

            recordingInfo.name            = recordingName + " Info";
            recordingInfo.CloudResourceId = recordingKey;

            var resourceCount = 0;

            if (recording.HasCameraPath)
            {
                resourceCount++;
                requests.Push(storageUser.DownloadCameraPath(recordingKey, (success, list) =>
                {
                    if (success && list != null && list.Count > 0)
                    {
                        k_CameraPoseRecorder.PoseEvents = list;
                        var dataRecording = k_CameraPoseRecorder.TryCreateDataRecording(timeline, k_NewAssets);
                        if (dataRecording != null)
                        {
                            k_DataRecordings.Add(dataRecording);
                        }
                    }

                    // ReSharper disable once AccessToModifiedClosure
                    resourceCount--;
                }));
            }

            if (recording.HasPlaneData)
            {
                resourceCount++;
                requests.Push(storageUser.DownloadPlaneData(recordingKey, (success, list) =>
                {
                    if (success && list != null && list.Count > 0)
                    {
                        k_PlaneFindingRecorder.PlaneEvents = list;
                        var dataRecording = k_PlaneFindingRecorder.TryCreateDataRecording(timeline, k_NewAssets);
                        if (dataRecording != null)
                        {
                            k_DataRecordings.Add(dataRecording);
                        }
                    }

                    resourceCount--;
                }));
            }

            if (recording.HasPointCloud)
            {
                resourceCount++;
                requests.Push(storageUser.DownloadPointCloud(recordingKey, (success, list) =>
                {
                    if (success && list != null && list.Count > 0)
                    {
                        k_PointCloudRecorder.PointCloudEvents = list;
                        var dataRecording = k_PointCloudRecorder.TryCreateDataRecording(timeline, k_NewAssets);
                        if (dataRecording != null)
                        {
                            k_DataRecordings.Add(dataRecording);
                        }
                    }

                    resourceCount--;
                }));
            }

            while (resourceCount > 0)
            {
                yield return(null);
            }

            foreach (var dataRecording in k_DataRecordings)
            {
                recordingInfo.AddDataRecording(dataRecording);
                dataRecording.name = dataRecording.GetType().Name;
                AssetDatabase.AddObjectToAsset(dataRecording, timeline);
            }

            foreach (var newAsset in k_NewAssets)
            {
                AssetDatabase.AddObjectToAsset(newAsset, timeline);
            }

            AssetDatabase.SaveAssets();
            ProjectWindowUtil.ShowCreatedAsset(timeline);

            k_DataRecordings.Clear();
            k_NewAssets.Clear();

            if (!recording.HasVideo)
            {
                FinalizeDataRecordingImport(timeline, recordingKey, recordingPath, callback);
                yield break;
            }

            var videoPath = EditorUtility.SaveFilePanelInProject(k_SaveVideoDialogTitle, recordingName, k_VideoExtension, string.Empty);

            if (string.IsNullOrEmpty(recordingPath))
            {
                FinalizeDataRecordingImport(timeline, recordingKey, recordingPath, callback);
                yield break;
            }

            // TODO: Progress bar
            requests.Push(storageUser.DownloadVideo(recordingKey, (success, path) =>
            {
                try
                {
                    AssetDatabase.StartAssetEditing();

                    if (File.Exists(path))
                    {
                        var destinationPath = Path.Combine(Directory.GetCurrentDirectory(), videoPath);
                        if (File.Exists(destinationPath))
                        {
                            File.Delete(destinationPath);
                        }

                        File.Move(path, destinationPath);
                    }
                    else
                    {
                        Debug.LogError($"Couldn't find temp video file at path {path}");
                    }
                }
                catch (IOException e)
                {
                    Debug.LogException(e);
                }
                finally
                {
                    AssetDatabase.StopAssetEditing();
                }

                AssetDatabase.Refresh();

                var videoClip                      = AssetDatabase.LoadAssetAtPath <VideoClip>(videoPath);
                var videoTrack                     = timeline.CreateTrack <MarsVideoPlayableTrack>(null, k_DefaultVideoTrackName);
                var timelineClip                   = videoTrack.CreateClip <MarsVideoPlayableAsset>();
                timelineClip.displayName           = videoClip.name;
                timelineClip.duration              = videoClip.length;
                var videoPlayableAsset             = (MarsVideoPlayableAsset)timelineClip.asset;
                videoPlayableAsset.VideoClip       = videoClip;
                videoPlayableAsset.FacingDirection = CameraFacingDirection.World;
                timeline.editorSettings.fps        = (float)videoClip.frameRate;

                var videoHalfHeight            = videoClip.height * 0.5f;
                var halfFOV                    = recording.fovRadians * 0.5f;
                videoPlayableAsset.FocalLength = videoHalfHeight / Mathf.Tan(halfFOV);

                videoPlayableAsset.ZRotation = recording.zRotation;
            }));

            FinalizeDataRecordingImport(timeline, recordingKey, recordingPath, callback);
        }
        static RequestHandle ImportMarker(this IUsesCloudStorage storageUser, string imagePath, string markerKey,
                                          string jsonText, Action <UnityObject> callback)
        {
            return(storageUser.DownloadMarkerImage(markerKey, (success, tempPath) =>
            {
                var destinationPath = Path.Combine(Directory.GetCurrentDirectory(), imagePath);
                try
                {
                    AssetDatabase.StartAssetEditing();

                    if (File.Exists(tempPath))
                    {
                        if (File.Exists(destinationPath))
                        {
                            File.Delete(destinationPath);
                        }

                        File.Move(tempPath, destinationPath);
                    }
                    else
                    {
                        Debug.LogError($"Couldn't find image file at path {tempPath}");
                    }
                }
                catch (IOException e)
                {
                    Debug.LogException(e);
                }
                finally
                {
                    AssetDatabase.StopAssetEditing();
                }

                // we need access to the created texture for the image before we can add it to a marker library
                AssetDatabase.Refresh();

                ApplyImageMarkerTextureImportSettings(imagePath);

                var marker = SceneSerialization.FromJson <Marker>(jsonText);

                // add the created marker to a marker library
                var markerTex = AssetDatabase.LoadAssetAtPath <Texture2D>(imagePath);
                var markerLibrary = SelectMarkerLibrary();
                Guid markerGuid;
                if (markerTex != null && markerLibrary != null)
                {
                    markerGuid = CompanionEditorAssetUtils.CreateMarkerInLibrary(markerLibrary, marker, markerTex);
                }

                // create a Proxy in the scene with a MarkerCondition looking for the marker's new guid
                var markerProxyObj = CreateMarkerProxy(marker, markerGuid);
                EditorGUIUtility.PingObject(markerProxyObj);


                var prefabSavePath = EditorUtility.SaveFilePanelInProject(k_SaveProxyTitle,
                                                                          string.Format(k_ProxyNameFormat, marker.name), k_PrefabExtension, k_SaveProxyMessage);

                // if user presses 'cancel' in the save prompt, no prefab will be saved
                if (!string.IsNullOrEmpty(prefabSavePath))
                {
                    // creation of prefab is outside the start/stop editing block so we can highlight the created asset
                    var createdPrefab = PrefabUtility.SaveAsPrefabAssetAndConnect(markerProxyObj, prefabSavePath, InteractionMode.AutomatedAction);
                    ProjectWindowUtil.ShowCreatedAsset(createdPrefab);
                    callback(createdPrefab);
                }

                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                var resourceSync = CompanionResourceSync.instance;
                CompanionMarkerUtils.SplitMarkerKey(markerKey, out _, out var cloudGuid);
                resourceSync.SetAssetGuid(AssetDatabase.AssetPathToGUID(prefabSavePath), cloudGuid);
            }));
        }
        static void ImportEnvironment(string environmentName, string jsonText, string path,
                                      GameObject simulatedPlanePrefab, Material simulatedPlaneMaterial, Post postPrefab, MeshFilter meshPrefab,
                                      GameObject simulatedLightingPrefab, Action <UnityObject> callback)
        {
            var environment = SceneSerialization.FromJson <Environment>(jsonText);
            var height      = environment.height;
            var vertices    = environment.vertices;
            var center      = Vector3.zero;
            var posts       = CollectionPool <List <Post>, Post> .GetCollection();

            var  count    = vertices.Count;
            Post previous = null;

            foreach (var vertex in vertices)
            {
                var post = UnityObject.Instantiate(postPrefab);
                posts.Add(post);
                center += vertex;
                var postTransform = post.transform;
                postTransform.position = vertex;
                post.SetTopSphereHeight(height);

                if (previous != null)
                {
                    previous.Setup();
                    var previousPosition = previous.transform.position;
                    previous.UpdateWall(vertex, previousPosition - vertex, height);
                }

                previous = post;
            }

            if (count != 0)
            {
                center /= count;
            }

            var prefabRoot = new GameObject(environmentName).transform;
            var floorPlan  = new GameObject("Floor Plan").transform;

            prefabRoot.position = center;
            floorPlan.SetParent(prefabRoot, false);
            foreach (var post in posts)
            {
                post.transform.SetParent(floorPlan, true);
                var wall = post.Wall;
                if (wall != null)
                {
                    wall.SetParent(floorPlan, true);
                }
            }

            var planesRoot = new GameObject("Planes").transform;

            planesRoot.SetParent(prefabRoot, false);
            foreach (var plane in environment.planes)
            {
                var synthesizedPlane = ((GameObject)PrefabUtility.InstantiatePrefab(simulatedPlanePrefab, planesRoot)).GetComponent <SynthesizedPlane>();
                synthesizedPlane.transform.SetWorldPose(plane.pose);
                synthesizedPlane.SetMRPlaneData(plane.vertices, plane.center, plane.extents);
                synthesizedPlane.transform.SetParent(planesRoot, true);
                var renderer = synthesizedPlane.GetComponentInChildren <Renderer>();
                renderer.AddMaterial(simulatedPlaneMaterial);
            }

            var meshCapture = environment.MeshCapture;

            if (meshCapture.Meshes.Count > 0)
            {
                var meshesRoot = new GameObject("Meshes").transform;
                meshesRoot.SetParent(prefabRoot, false);
                var meshPath = EditorUtility.SaveFilePanelInProject(k_SaveMeshDialogTitle, environmentName, "asset", string.Empty);
                var index    = 0;
                foreach (var segment in meshCapture.Meshes)
                {
                    var meshFilter = UnityObject.Instantiate(meshPrefab, meshesRoot);
                    var mesh       = new Mesh {
                        name = $"Mesh Segment {index}"
                    };
                    mesh.SetVertices(segment.Vertices);
                    mesh.SetIndices(segment.Indices, MeshTopology.Triangles, 0);
                    mesh.SetNormals(segment.Normals);
                    meshFilter.transform.SetWorldPose(segment.Pose);
                    meshFilter.sharedMesh = mesh;
                    if (index == 0)
                    {
                        AssetDatabase.CreateAsset(mesh, meshPath);
                        AssetDatabase.SetMainObject(mesh, meshPath);
                    }
                    else
                    {
                        AssetDatabase.AddObjectToAsset(mesh, meshPath);
                    }

                    index++;
                }

                AssetDatabase.SaveAssets();
            }

            var environmentBounds    = BoundsUtils.GetBounds(prefabRoot);
            var prefabRootGameObject = prefabRoot.gameObject;
            var environmentSettings  = prefabRootGameObject.AddComponent <MARSEnvironmentSettings>();
            var environmentInfo      = environmentSettings.EnvironmentInfo;

            environmentInfo.EnvironmentBounds = environmentBounds;
            center = environmentBounds.center;
            var extents = environmentBounds.extents * 0.9f; // Reduce offset to avoid sim starting pose warning

            environmentInfo.DefaultCameraPivot = center;
            var cameraPose = new Pose(center + extents, Quaternion.LookRotation(-extents));

            environmentInfo.DefaultCameraWorldPose = cameraPose;
            environmentInfo.DefaultCameraSize      = environmentBounds.size.magnitude;
            environmentSettings.SetSimulationStartingPose(cameraPose, false);
            environmentSettings.UpdatePrefabInfo();
            UnityObject.Instantiate(simulatedLightingPrefab, prefabRoot);

            var prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(prefabRootGameObject, path, InteractionMode.AutomatedAction);

            UnityObject.DestroyImmediate(prefabRootGameObject);
            AssetDatabase.SetLabels(prefab, new[] { MARSEnvironmentManager.EnvironmentLabel });
            ModuleLoaderCore.instance.GetModule <MARSEnvironmentManager>().UpdateSimulatedEnvironmentCandidates();
            callback(prefab);

            CollectionPool <List <Post>, Post> .RecycleCollection(posts);
        }