【Unity-学习-016】EasyAR4.0稀疏空间地图 扫描场景 客户端

本帖主要描写编辑场景的功能实现,以及一些需要注意的问题。跟上层贴有所关联,想要更多了解请移步链接

上一篇和上上篇写的  帖子太细了,觉得没有必要。之后主要描述代码。

加载场景就是将之前保存(到本地或网络)的那些 *.Meta 信息在场景开始时加载,然后动态去识别map,识别后 遍历 PropCollection ,然后加载生成游戏对象。

脚本上:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

using easyar;

using SpatialMap_SparseSpatialMap;

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class LoadMapController : MonoBehaviour
{
    //截图功能
    public RawImage PreviewImage;
    private Texture2D capturedImage;
    private VideoCameraDevice videoCamera;

    //MapSession 加载地图相关
    public SparseSpatialMapController mapTemp;
    private MapSession mapSession;
    private ARSession session;
    private SparseSpatialMapWorkerFrameFilter mapWorker;


    //手动加载
    //public List<Color32> color32s = new List<Color32>();
    //List<SparseSpatialMapController> MapControllers = new List<SparseSpatialMapController>();


    public AudioSource aS;

    private void Awake()
    {
#if UNITY_EDITOR
        GameObject.FindObjectOfType<VIOCameraDeviceUnion>().enabled = false;
#endif
        session = FindObjectOfType<ARSession>();
        mapWorker = FindObjectOfType<SparseSpatialMapWorkerFrameFilter>();
        videoCamera = session.GetComponentInChildren<VideoCameraDevice>();

    }


    private void Start()
    {

        mapSession = new MapSession(mapWorker, MapMetaManager.LoadAll());
        mapSession.LoadMapMeta(mapTemp, false);
        mapSession.CurrentMapLocalized += (MapData) =>
        {
            //识别出来后播放一段声音 提示用户已经加载出来了
            if (aS.isPlaying == false)
            {
                aS.PlayOneShot(aS.clip);
            }
        };
        videoCamera.DeviceOpened += () =>
        {
            if (videoCamera == null)
            {
                return;
            }
            videoCamera.FocusMode = CameraDeviceFocusMode.Continousauto;
        };

    }

    / <summary>
    / 手动加载 meta 信息   暂时没有用,此时使用的时 mapSession 来加载地图信息
    / </summary>
    //private string mapName;
    //private void LoadMeta(List<MapMeta> mapMetas)
    //{

    //    int i = 0;
    //    foreach (var item in mapMetas)
    //    {
    //        var tempController = Instantiate(mapTemp).GetComponent<SparseSpatialMapController>();

    //        tempController.SourceType = SparseSpatialMapController.DataSource.MapManager;
    //        tempController.MapManagerSource.ID = item.Map.ID;
    //        tempController.MapManagerSource.Name = item.Map.Name;
    //        tempController.MapWorker = mapWorker;

    //        tempController.MapLoad += (arg1, arg2, arg3) =>
    //        {
    //            Debug.Log("\t下载信息:" + (arg2 ? "成功" : "失败:" + arg3) + Environment.NewLine +
    //                "\t名称" + arg1.Name + Environment.NewLine +
    //                "\tID" + arg1.ID + Environment.NewLine);
    //            mapName = arg1.Name;
    //        };
    //        tempController.MapLocalized += () => { Debug.Log("\t定位成功: " + mapName); };
    //        tempController.MapStopLocalize += () => { Debug.Log("\t定位停止 " + mapName); };
    //        tempController.PointCloudParticleParameter.StartColor = color32s[i];
    //        MapControllers.Add(tempController);
    //        i++;
    //    }
    //    mapWorker.Localizer.startLocalization();
    //}



    public void BackMain()
    {
        SceneManager.LoadScene("MainMapScene");
    }


    public void OpenPoint(bool flag)
    {
        foreach (var item in mapSession.Maps)
        {
            item.Controller.ShowPointCloud = flag;
        }
    }

    private void DestroySession()
    {
        if (mapSession != null)
        {
            mapSession.Dispose();
            mapSession = null;
        }
    }

    private void OnDestroy()
    {
        DestroySession();
    }


    /// <summary>
    /// 截图
    /// </summary>
    public void Snapshot()
    {
        var oneShot = Camera.main.gameObject.AddComponent<OneShot>();
        oneShot.Shot(false, (texture) =>
        {
            if (capturedImage)
            {
                Destroy(capturedImage);
            }
            capturedImage = texture;
            PreviewImage.texture = capturedImage;
            Destroy(oneShot);
        });
    }

    /// <summary>
    /// 存储
    /// </summary>
    /// <param name="texture"></param>
    public void SavePic(RawImage texture)
    {

        Texture texture1 = texture.texture;
        Texture2D texture2D = new Texture2D(texture1.width, texture1.height, TextureFormat.RGBA32, false);
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture renderTexture = RenderTexture.GetTemporary(texture1.width, texture1.height, 32);
        Graphics.Blit(texture1, renderTexture);

        RenderTexture.active = renderTexture;
        texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        texture2D.Apply();

        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(renderTexture);

        string destination;
#if UNITY_EDITOR
        destination = Application.persistentDataPath + "/Screenshots";
#elif UNITY_ANDROID
        destination = "/mnt/sdcard/DCIM/Screenshots";
#endif

        if (!System.IO.Directory.Exists(destination))
        {
            System.IO.Directory.CreateDirectory(destination);
        }
        destination = destination + "/" + System.DateTime.Now.ToFileTime() + ".PNG";
        //保存文件  
        Debug.Log("路径:" + destination);
        File.WriteAllBytes(destination, texture2D.EncodeToPNG());
    }



}

软件开始,用 MapSession 通过 MapMetaManager.LoadAll() 加载所有的地图。然后注册识别后的回调。

private void Start()
    {
        mapSession = new MapSession(mapWorker, MapMetaManager.LoadAll());
        mapSession.LoadMapMeta(mapTemp, false);
        mapSession.CurrentMapLocalized += (MapData) =>
        {
            //识别出来后播放一段声音 提示用户已经加载出来了
            if (aS.isPlaying == false)
            {
                aS.PlayOneShot(aS.clip);
            }
        };
        videoCamera.DeviceOpened += () =>
        {
            if (videoCamera == null)
            {
                return;
            }
            videoCamera.FocusMode = CameraDeviceFocusMode.Continousauto;
        };
    }

场景实现原理:在识别到地图后,会动态生成一个 Assets/Prefabs/SparseSpatialMapItem.prefab ,每个地图对应一个SparseSpatialMapItem。

本场景的 PropCollection 要和编辑场景的 保持一致。

场景配置:

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThursdayGame

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值