public void Save(string name, Optional <Image> preview) { IsSaving = true; MapWorker.BuilderMapController.MapHost += (map, isSuccessful, error) => { if (isSuccessful) { var mapMeta = new MapMeta(map, new List <MapMeta.PropInfo>()); MapMetaManager.Save(mapMeta); GUIPopup.EnqueueMessage("Map Generated", 3); GUIPopup.EnqueueMessage("Notice: map name can be changed on website," + Environment.NewLine + "while the SDK side will not get updated until map cache cleared and a re-download has been triggered.", 5); Saved = true; } else { GUIPopup.EnqueueMessage("Fail to generate Map" + (string.IsNullOrEmpty(error) ? "" : "\n error: " + error), 5); } IsSaving = false; }; try { MapWorker.BuilderMapController.Host(name, preview); } catch (Exception e) { GUIPopup.EnqueueMessage("Fail to host map: " + e.Message, 5); IsSaving = false; } }
private IEnumerator TakePhotoCreateTarget() { creating = true; yield return(new WaitForEndOfFrame()); if (!creating) { yield break; } Texture2D photo = new Texture2D(Screen.width / 2, Screen.height / 2, TextureFormat.RGB24, false); photo.ReadPixels(new Rect(Screen.width / 5, Screen.height / 5, Screen.width * 3 / 5, Screen.height * 3 / 6), 0, 0, false); photo.Apply(); byte[] data = photo.EncodeToJPG(80); Destroy(photo); string photoName = "photo" + DateTime.Now.Ticks + ".jpg"; string photoPath = Path.Combine(directory, photoName); File.WriteAllBytes(photoPath, data); CreateImageTarget(photoName, photoPath); GUIPopup.EnqueueMessage("Image saved to: " + directory + Environment.NewLine + "Image target generated: " + photoName, 3); }
private void AdjustVideoAndPlay() { if (!cube) { return; } var player = cube.GetComponent <UnityEngine.Video.VideoPlayer>(); player.transform.localScale = new Vector3(1, (float)Screen.height / Screen.width, 1); if (player.isPlaying) { player.Stop(); } player.url = FileUtil.PathToUrl(Application.persistentDataPath + "/" + filePath); player.Play(); // Unity bug: https://issuetracker.unity3d.com/issues/android-video-player-cannot-play-files-located-in-the-persistent-data-directory-on-android-10 // more info in this thread: https://forum.unity.com/threads/error-videoplayer-on-android.742451/ // We are not going to fix or workaround this bug here, the video playback is just a visual feedback for recording result but not a recording feature. You can still find your recorded videos in the directory. #if UNITY_ANDROID && !UNITY_EDITOR int sdkVersion = 0; using (var buildVersion = new AndroidJavaClass("android.os.Build$VERSION")) { sdkVersion = buildVersion.GetStatic <int>("SDK_INT"); } if (sdkVersion >= 29) { GUIPopup.EnqueueMessage("Video recorded may not play on cube due to Unity VideoPlayer bug on Android Q", 5); } #endif }
private void Awake() { cube = Instantiate(Cube); videoRecorder = FindObjectOfType <VideoRecorder>(); videoRecorder.FilePathType = WritablePathType.PersistentDataPath; videoRecorder.StatusUpdate += (status, msg) => { if (status == RecordStatus.OnStarted) { GUIPopup.EnqueueMessage("Recording start", 5); } if (status == RecordStatus.FailedToStart || status == RecordStatus.FileFailed || status == RecordStatus.LogError) { GUIPopup.EnqueueMessage("Recording Error: " + status + ", details: " + msg, 5); } Debug.Log("RecordStatus: " + status + ", details: " + msg); }; var launcher = "AllSamplesLauncher"; if (Application.CanStreamedLevelBeLoaded(launcher)) { var button = BackButton.GetComponent <Button>(); button.onClick.AddListener(() => { UnityEngine.SceneManagement.SceneManager.LoadScene(launcher); }); } else { BackButton.gameObject.SetActive(false); } }
private IEnumerator AliveChecker(string name) { yield return(new WaitForSeconds(2)); GUIPopup.EnqueueMessage(name + Environment.NewLine + "Looks like the above scene couldn't be loaded." + Environment.NewLine + "Please check if the scene has been added to the build settings." + Environment.NewLine + "To add a scene to the build settings use the menu File->Build Settings...", 10); }
private void Start() { var launcher = "AllSamplesLauncher"; if (Application.CanStreamedLevelBeLoaded(launcher)) { var button = BackButton.GetComponent <Button>(); button.onClick.AddListener(() => { UnityEngine.SceneManagement.SceneManager.LoadScene(launcher); }); } else { BackButton.gameObject.SetActive(false); } sparse = Session.GetComponentInChildren <SparseSpatialMapWorkerFrameFilter>(); vioCamera = Session.GetComponentInChildren <VIOCameraDeviceUnion>(); TouchControl.TurnOn(TouchControl.gameObject.transform, Camera.main, false, false, true, false); if (string.IsNullOrEmpty(MapController.MapManagerSource.ID) || string.IsNullOrEmpty(MapController.MapManagerSource.Name)) { throw new UIPopupException("Map ID or Name NOT set, please set MapManagerSource on: " + MapController + Environment.NewLine + "To create SpatialMap, use <SpatialMap_SparseSpatialMap> sample." + Environment.NewLine + "To get Map ID and Name, use EasyAR Develop Center (www.easyar.com) -> SpatialMap -> Database Details." + Environment.NewLine + "Map ID is used when loading, it can be used to share maps among devices.", 100); } MapController.MapLoad += (map, status, error) => { GUIPopup.EnqueueMessage("Load map {name = " + map.Name + ", id = " + map.ID + "} into " + sparse.name + Environment.NewLine + " => " + status + (string.IsNullOrEmpty(error) ? "" : " <" + error + ">"), status ? 3 : 5); if (!status) { return; } GUIPopup.EnqueueMessage("Notice: load map (only the first time each map) will trigger a download in this sample." + Environment.NewLine + "Statistical request count will be increased (more details on EasyAR website)." + Environment.NewLine + "Map cache is used after a successful download." + Environment.NewLine + "Map cache will be cleared if SparseSpatialMapManager.clear is called or app uninstalled.", 5); }; MapController.MapLocalized += () => { GUIPopup.EnqueueMessage("Localized map {name = " + MapController.MapInfo.Name + "}", 3); }; MapController.MapStopLocalize += () => { GUIPopup.EnqueueMessage("Stopped localize map {name = " + MapController.MapInfo.Name + "}", 3); }; sparse.Localizer.startLocalization(); }
private void Start() { player = GetComponent <UnityEngine.Video.VideoPlayer>(); player.source = VideoSource.Url; var path = Application.streamingAssetsPath + "/" + VideoInStreamingAssets; if (Application.platform == RuntimePlatform.Android) { path = Application.persistentDataPath + "/" + VideoInStreamingAssets; { // Workaround Unity bug: https://issuetracker.unity3d.com/issues/android-video-player-cannot-play-files-located-in-the-persistent-data-directory-on-android-10 // more info in this thread: https://forum.unity.com/threads/error-videoplayer-on-android.742451/ // If you are using Unity versions with this issue fixed, you can safely skip this code block int sdkVersion = 0; #if UNITY_ANDROID && !UNITY_EDITOR using (var buildVersion = new AndroidJavaClass("android.os.Build$VERSION")) { sdkVersion = buildVersion.GetStatic <int>("SDK_INT"); } #endif if (sdkVersion >= 29) { GUIPopup.EnqueueMessage("Use web video to workaround Unity VideoPlayer bug on Android Q\nthe video play may be slow", 5); path = "https://staticfile-cdn.sightp.com/easyar/video/" + Path.GetFileName(VideoInStreamingAssets); } } } // Note: Use the Unity VideoPlayer in your own way. // We use video file in StreamingAssets in the samples only to keep compatiblity. // Some versions of Unity will have strange behaviors if video in resources. if (Application.platform == RuntimePlatform.Android && !File.Exists(path) && !path.StartsWith("https://")) { StartCoroutine(FileUtil.LoadFile(VideoInStreamingAssets, PathType.StreamingAssets, (data) => { StartCoroutine(WriteFile(path, data)); })); } else { player.url = FileUtil.PathToUrl(path); ready = true; StatusChanged(); } }
private void Awake() { cube = Instantiate(Cube); videoRecorder = FindObjectOfType <VideoRecorder>(); videoRecorder.FilePathType = VideoRecorder.OutputPathType.PersistentDataPath; videoRecorder.StatusUpdate += (status, msg) => { if (status == RecordStatus.OnStarted) { GUIPopup.EnqueueMessage("Recording start", 5); } if (status == RecordStatus.FailedToStart || status == RecordStatus.FileFailed || status == RecordStatus.LogError) { GUIPopup.EnqueueMessage("Recording Error: " + status + ", details: " + msg, 5); } Debug.Log("RecordStatus: " + status + ", details: " + msg); }; }
public void NextCamera() { if (!cameraDevice || cameraDevice.Device == null) { return; } if (CameraDevice.cameraCount() == 0) { GUIPopup.EnqueueMessage("Camera unavailable", 3); cameraDevice.Close(); return; } var index = cameraDevice.Device.index(); index = (index + 1) % CameraDevice.cameraCount(); cameraDevice.CameraOpenMethod = VideoCameraDevice.CameraDeviceOpenMethod.DeviceIndex; cameraDevice.CameraIndex = index; GUIPopup.EnqueueMessage("Switch to camera index: " + index, 3); cameraDevice.Close(); cameraDevice.Open(); }
public void SampleStop() { if (!videoRecorder) { return; } if (videoRecorder.StopRecording()) { GUIPopup.EnqueueMessage("Recording finished, video saved to Unity Application.persistentDataPath" + Environment.NewLine + "Filename: " + filePath + Environment.NewLine + "PersistentDataPath: " + Application.persistentDataPath + Environment.NewLine + "You can change sample code if you prefer to record videos into system album", 8); AdjustVideoAndPlay(); } else { GUIPopup.EnqueueMessage("Recording failed", 5); } if (cameraRecorder) { cameraRecorder.Destroy(); } }
public void LoadMapMeta(SparseSpatialMapController mapControllerPrefab, bool particleShow) { if (!MapWorker || MapWorker.Localizer == null) { return; } if (Maps.Count > 1) { MapWorker.LocalizerConfig.LocalizationMode = LocalizationMode.KeepUpdate; } foreach (var m in Maps) { var meta = m.Meta; var controller = UnityEngine.Object.Instantiate(mapControllerPrefab); controller.SourceType = SparseSpatialMapController.DataSource.MapManager; controller.MapManagerSource = meta.Map; controller.MapWorker = MapWorker; controller.ShowPointCloud = particleShow; controller.MapLoad += (map, status, error) => { Debug.Log("\t定位中"); Debug.Log( "\t下载信息:" + "\t名称" + map.Name + "\tID" + map.ID + Environment.NewLine); CurrentMapLoad?.Invoke(m); GUIPopup.EnqueueMessage("Load map {name = " + map.Name + ", id = " + map.ID + "} into " + MapWorker.name + Environment.NewLine + " => " + status + (string.IsNullOrEmpty(error) ? "" : " <" + error + ">"), status ? 3 : 5); if (!status) { return; } GUIPopup.EnqueueMessage("Notice: By default (MainViewRecycleBinClearMapCacheOnly == false)," + Environment.NewLine + "load map will not trigger a download in this sample." + Environment.NewLine + "Map cache is used (SparseSpatialMapManager.clear not called alone)." + Environment.NewLine + "Statistical request count will not be increased (more details on EasyAR website).", 5); foreach (var propInfo in meta.Props) { GameObject prop = null; foreach (var templet in PropCollection.Instance.Templets) { if (templet.Object.name == propInfo.Name) { prop = UnityEngine.Object.Instantiate(templet.Object); break; } } if (!prop) { Debug.LogError("Missing prop templet: " + propInfo.Name); continue; } prop.transform.parent = controller.propsParent; prop.transform.localPosition = new UnityEngine.Vector3(propInfo.Position[0], propInfo.Position[1], propInfo.Position[2]); prop.transform.localRotation = new Quaternion(propInfo.Rotation[0], propInfo.Rotation[1], propInfo.Rotation[2], propInfo.Rotation[3]); prop.transform.localScale = new UnityEngine.Vector3(propInfo.Scale[0], propInfo.Scale[1], propInfo.Scale[2]); prop.name = propInfo.Name; m.Props.Add(prop); } }; controller.MapLocalized += () => { Debug.Log("\t定位成功 " + controller.MapManagerSource.Name); CurrentMapLocalized?.Invoke(m); GUIPopup.EnqueueMessage("Localized map {name = " + controller.MapInfo.Name + "}", 3); var parameter = controller.PointCloudParticleParameter; parameter.StartColor = new Color32(11, 205, 255, 255); controller.PointCloudParticleParameter = parameter; controller.propsParent.gameObject.SetActive(true); }; controller.MapStopLocalize += () => { CurrentMapStopLocalized?.Invoke(m); Debug.Log("\t定位结束 " + controller.MapManagerSource.Name); GUIPopup.EnqueueMessage("Stopped localize map {name = " + controller.MapInfo.Name + "}", 3); var parameter = controller.PointCloudParticleParameter; parameter.StartColor = new Color32(163, 236, 255, 255); controller.PointCloudParticleParameter = parameter; controller.propsParent.gameObject.SetActive(false); }; m.Controller = controller; } MapWorker.Localizer.startLocalization(); }
public void LoadMapMeta(SparseSpatialMapController mapControllerPrefab, bool particleShow) { if (!MapWorker || MapWorker.Localizer == null) { return; } if (Maps.Count > 1) { // This will take effect after the next MapWorker Start or OnEnable is called. // In this sample, we are sure about this according to the calling sequence. MapWorker.LocalizerConfig.LocalizationMode = LocalizationMode.KeepUpdate; } Debug.Log("Maps.Count: " + Maps.Count); foreach (var m in Maps) { var meta = m.Meta; var controller = UnityEngine.Object.Instantiate(mapControllerPrefab); controller.SourceType = SparseSpatialMapController.DataSource.MapManager; controller.MapManagerSource = meta.Map; controller.MapWorker = MapWorker; controller.ShowPointCloud = particleShow; controller.MapLoad += (map, status, error) => { GUIPopup.EnqueueMessage("Load map {name = " + map.Name + ", id = " + map.ID + "} into " + MapWorker.name + Environment.NewLine + " => " + status + (string.IsNullOrEmpty(error) ? "" : " <" + error + ">"), status ? 3 : 5); if (!status) { return; } GUIPopup.EnqueueMessage("Notice: By default (MainViewRecycleBinClearMapCacheOnly == false)," + Environment.NewLine + "load map will not trigger a download in this sample." + Environment.NewLine + "Map cache is used (SparseSpatialMapManager.clear not called alone)." + Environment.NewLine + "Statistical request count will not be increased (more details on EasyAR website).", 5); // prop info foreach (var propInfo in meta.Props) { GameObject prop = null; Debug.Log("propInfo.type: " + propInfo.type); switch (propInfo.type) { case MapMeta.PropType.Text: prop = UnityEngine.Object.Instantiate(Globals.instance.templetes[0]); var textTmp = prop.GetComponentInChildren <TextMesh>(); textTmp.text = propInfo.text; break; case MapMeta.PropType.Texture: prop = UnityEngine.Object.Instantiate(Globals.instance.templetes[1]); prop.GetComponent <UrlManager>().SetUrl(propInfo.infoUrl, propInfo.infoFileName, propInfo.type); break; case MapMeta.PropType.Video: break; case MapMeta.PropType.Model: break; case MapMeta.PropType.other: Debug.LogError("error: The PropType is other"); break; } if (!prop) { Debug.LogError("Missing prop templet: " + propInfo.Name); continue; } prop.transform.SetParent(controller.transform); prop.transform.localPosition = new UnityEngine.Vector3(propInfo.Position[0], propInfo.Position[1], propInfo.Position[2]); prop.transform.localRotation = new Quaternion(propInfo.Rotation[0], propInfo.Rotation[1], propInfo.Rotation[2], propInfo.Rotation[3]); prop.transform.localScale = new UnityEngine.Vector3(propInfo.Scale[0], propInfo.Scale[1], propInfo.Scale[2]); prop.name = propInfo.Name; // prop info m.Props.Add(prop); } }; controller.MapLocalized += () => { GUIPopup.EnqueueMessage("Localized map {name = " + controller.MapInfo.Name + "}", 3); var parameter = controller.PointCloudParticleParameter; parameter.StartColor = new Color32(11, 205, 255, 255); controller.PointCloudParticleParameter = parameter; }; controller.MapStopLocalize += () => { GUIPopup.EnqueueMessage("Stopped localize map {name = " + controller.MapInfo.Name + "}", 3); var parameter = controller.PointCloudParticleParameter; parameter.StartColor = new Color32(163, 236, 255, 255); controller.PointCloudParticleParameter = parameter; }; m.Controller = controller; } MapWorker.Localizer.startLocalization(); }