美文网首页
ARFoundation 扫描局部图显示模型

ARFoundation 扫描局部图显示模型

作者: 玄策丶 | 来源:发表于2020-07-20 14:52 被阅读0次
    背景:

    AR项目开发时遇到的这个问题,即扫描的底图特别大,好几米×好几米的那种,只用一台手机或者Pad不可能扫描到底图的全部分,所以要实现只扫描底图的局部即可实现AR功能,并且模型位置准确。
    ps:EsayAR可以扫描局部。。。

    方法:

    1、将大图用PS分成了1×1米的N个小图。
    2、将小图全部放到ARFoundationReferenceImageLibrary中。名字123.。。


    1.png

    3、Anchor的预制体放N个锚点(排列与Library中小图的顺序相反,即小图切开的顺序是左上到右下,锚点的放置是右下到左上,小图第一张在左上,锚点第一个在右下。但对应名字是相同,你懂我意思吧=。=?我这儿切了18张小图,所以放18个锚点)


    2.png
    4、上代码(Jobe)
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.XR.ARSubsystems;
    using UnityEngine.XR.ARFoundation;
    using UnityEngine.UI;
    
    public class ImageController : MonoBehaviour
    {
        ARTrackedImageManager imageTrackManager;
    
        ARAnchorManager anchorManager;
    
        Vector3 vecpos,vecScl;
        Quaternion quarot;
    
        GameObject AnchorObj,AnchorChild,DayObj,NightObj;
        public GameObject DayButton, NightButton;
        public Slider ScaleControlSlider;
        bool isDay = true;
    
        public GameObject AnchorButton, TrackButton;
        GameObject[] AnchorPoint = new GameObject[18];
        bool IsAnchorCreat = false;
        bool IsBuildSource,isStartBuild;
    
        public GameObject UITishiObj,SaomiaoUI,Tishikuang;
    
        public GameObject CamObj;
        public List<GameObject> ImgTargetObj = new List<GameObject>();
        private List<float> ObjList;
        private Dictionary<float, GameObject> TargetDic;
        List<float> dis = new List<float>();
        float MinDis = 500;
    
        public Text text;
        // Start is called before the first frame update
        void Awake()
        {
            ManagerAudio.Instance.PlayBg(TypeAudio.Music.BeiJing01, true);
            imageTrackManager = GetComponent<ARTrackedImageManager>();
            anchorManager = GetComponent<ARAnchorManager>();
            TargetDic = new Dictionary<float, GameObject>();
            ObjList = new List<float>();
            UITishiObj.SetActive(false);
            SaomiaoUI.SetActive(true);
            Tishikuang.SetActive(false);
            DayObj = new GameObject();
            NightObj = new GameObject();
            AnchorObj = new GameObject();
            IsBuildSource = false;
            isStartBuild = true;
            DayButton.SetActive(false);
            NightButton.SetActive(true);
            NightButton.gameObject.GetComponent<Button>().interactable = false;
            AnchorButton.gameObject.GetComponent<Button>().interactable = false;
            ScaleControlSlider.gameObject.SetActive(false);
        }
    
        private void OnEnable()
        {
            imageTrackManager.trackedImagesChanged += OnTrackedImagesChanged;
            anchorManager.anchorsChanged += OnAnchorsChanged;
    
            
        }
    
        void OnDisable()
        {
            imageTrackManager.trackedImagesChanged -= OnTrackedImagesChanged;
            anchorManager.anchorsChanged -= OnAnchorsChanged;
    
        }
    
        void UpdateInfo(ARTrackedImage trackedImage)
        {
            //if (trackedImage.trackingState != TrackingState.None)
            //{
            //    vecpos = imageTrackManager.trackedImagePrefab.gameObject.transform.position;
            //    quarot = imageTrackManager.trackedImagePrefab.gameObject.transform.rotation;
            //}
        }
    
        void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
        {
            foreach (var item in eventArgs.added)
            {
                ImgTargetObj.Add(item.gameObject);
                if (!IsAnchorCreat)
                {
                    vecpos = item.transform.position;
                    quarot = item.transform.rotation;
                    AnchorObj = anchorManager.AddAnchor(new Pose(vecpos, quarot)).gameObject;
                    AnchorChild = AnchorObj.gameObject.transform.GetChild(18).gameObject;
                    AnchorPoint[0] = AnchorObj.gameObject.transform.GetChild(0).gameObject;
                    AnchorPoint[1] = AnchorObj.gameObject.transform.GetChild(1).gameObject;
                    AnchorPoint[2] = AnchorObj.gameObject.transform.GetChild(2).gameObject;
                    AnchorPoint[3] = AnchorObj.gameObject.transform.GetChild(3).gameObject;
                    AnchorPoint[4] = AnchorObj.gameObject.transform.GetChild(4).gameObject;
                    AnchorPoint[5] = AnchorObj.gameObject.transform.GetChild(5).gameObject;
                    AnchorPoint[6] = AnchorObj.gameObject.transform.GetChild(6).gameObject;
                    AnchorPoint[7] = AnchorObj.gameObject.transform.GetChild(7).gameObject;
                    AnchorPoint[8] = AnchorObj.gameObject.transform.GetChild(8).gameObject;
    AnchorPoint[9] = AnchorObj.gameObject.transform.GetChild(9).gameObject;
    AnchorPoint[10] = AnchorObj.gameObject.transform.GetChild(10).gameObject;
    AnchorPoint[11] = AnchorObj.gameObject.transform.GetChild(11).gameObject;
    AnchorPoint[12] = AnchorObj.gameObject.transform.GetChild(12).gameObject;
    AnchorPoint[13] = AnchorObj.gameObject.transform.GetChild(13).gameObject;
    AnchorPoint[14] = AnchorObj.gameObject.transform.GetChild(14).gameObject;
    AnchorPoint[15] = AnchorObj.gameObject.transform.GetChild(15).gameObject;
    AnchorPoint[16] = AnchorObj.gameObject.transform.GetChild(16).gameObject;
    AnchorPoint[17] = AnchorObj.gameObject.transform.GetChild(17).gameObject;
                    AnchorButton.gameObject.GetComponent<Button>().interactable = true;
                    UITishiObj.SetActive(true);
                    SaomiaoUI.SetActive(false);
                    ScaleControlSlider.gameObject.SetActive(true);
                    IsAnchorCreat = true;
                }
    
                //if(!IsBuildSource)
                //{
                //    AnchorChild.gameObject.transform.parent = AnchorPoint[int.Parse(item.referenceImage.name) - 1].transform;
                //    AnchorChild.gameObject.transform.localPosition = Vector3.zero;
                //}
            }
            foreach (var imgTarget in eventArgs.updated)
            {
                if(imgTarget.trackingState == TrackingState.Tracking)
                {
                    imgTarget.gameObject.SetActive(true);
                    vecpos = imgTarget.transform.position;
                    quarot = imgTarget.transform.rotation;
                    if (isStartBuild)
                    {
                        CountDistance();
                        //AnchorChild.gameObject.transform.parent = AnchorPoint[int.Parse(imgTarget.referenceImage.name) - 1].transform;
                        //AnchorChild.gameObject.transform.localPosition = Vector3.zero;
                        //AnchorObj.gameObject.transform.position = vecpos;
                        //AnchorObj.gameObject.transform.rotation = quarot;
                    }
                    else
                    {
                        if (!IsBuildSource)
                        {
                            CountDistance();
                            //AnchorChild.gameObject.transform.parent = AnchorPoint[int.Parse(imgTarget.referenceImage.name) - 1].transform;
                            //AnchorChild.gameObject.transform.localPosition = Vector3.zero;
                            //AnchorObj.gameObject.transform.position = vecpos;
                            //AnchorObj.gameObject.transform.rotation = quarot;
                        }else
                        {
                            AnchorObj.transform.position = AnchorPos;
                            AnchorObj.transform.rotation = AnchorQua;
                        }
                    }
                }
                else if (imgTarget.trackingState == TrackingState.Limited)
                {
                    imgTarget.gameObject.SetActive(false);
                }
                //vecScl = new Vector3(imgTarget.size.x,0.01f,imgTarget.size.y);
            }
        }
    
        void CountDistance()
        {
            for (int i = 0; i < ImgTargetObj.Count; i++)
            {
                float minDis;
                if (ImgTargetObj[i].activeInHierarchy)
                {
                    minDis = Vector3.Distance(CamObj.transform.position, ImgTargetObj[i].gameObject.transform.position);
                }
                else
                {
                    minDis = 500 + i;
                }
                if (!TargetDic.ContainsKey(minDis))
                {
                    dis.Add(minDis);
                }
                TargetDic.Add(dis[i], ImgTargetObj[i].gameObject);
            }
            dis.Sort();
            if (dis.Count != 0)
                MinDis = dis[0];
            GameObject obj;
            TargetDic.TryGetValue(MinDis, out obj);
            AnchorObj.transform.gameObject.transform.position = obj.gameObject.transform.position;
            AnchorObj.transform.gameObject.transform.rotation = obj.gameObject.transform.rotation;
            AnchorChild.transform.parent = AnchorPoint[int.Parse(obj.gameObject.GetComponent<ARTrackedImage>().referenceImage.name) - 1].gameObject.transform;
            AnchorChild.transform.localPosition = Vector3.zero;
            TargetDic.Clear();
            dis.Clear();
        }
    
        Vector3 AnchorPos;
        Quaternion AnchorQua;
    
        public void AddAnchorsFunc()
        {
            if(isStartBuild)
            {
                isStartBuild = false;
                
                //anchorManager.AddAnchor(new Pose(vecpos, quarot));
                foreach (var img in imageTrackManager.trackables)
                {
                    img.gameObject.transform.GetChild(0).gameObject.SetActive(false);
                    img.gameObject.SetActive(false);
                }
                
                UITishiObj.SetActive(false);
                Tishikuang.SetActive(true);
                AnchorPos = AnchorObj.transform.position;
                AnchorQua = AnchorObj.transform.rotation;
    
                IsBuildSource = true;
            }
            else
            {
                if(IsBuildSource)
                {
                    IsBuildSource = false;
    
                    foreach (var img in imageTrackManager.trackables)
                    {
                        img.gameObject.SetActive(true);
                    }
                    
                }
                else
                {
                    IsBuildSource = true;
    
                    AnchorPos = AnchorObj.transform.position;
                    AnchorQua = AnchorObj.transform.rotation;
                    foreach (var img in imageTrackManager.trackables)
                    {
                        img.gameObject.SetActive(false);
                    }
                    
                }
            }
        }
    
        void OnAnchorsChanged(ARAnchorsChangedEventArgs eventArgs)
        {
            foreach (var item in eventArgs.added)
            {
                //StartCoroutine(ScaleTweensControl());
                NightButton.gameObject.GetComponent<Button>().interactable = true;
                ScaleControlSlider.interactable = true;
                ScaleControlSlider.value = 0;
                DayObj = AnchorChild.gameObject.transform.GetChild(0).GetChild(0).GetChild(0).gameObject;
                NightObj = AnchorChild.gameObject.transform.GetChild(0).GetChild(0).GetChild(1).gameObject;
                //item.gameObject.transform.GetChild(0).GetChild(0).GetChild(2).transform.localScale = vecScl;
            }
    
            foreach (var anchorObj in eventArgs.updated)
            {
    
            }
        }
    
        IEnumerator ScaleTweensControl()
        {
            bool go = true;
            float addnum = 0.005f;
            yield return new WaitForEndOfFrame();
            while(go)
            {
                ScaleControlSlider.value += addnum;
                yield return new WaitForEndOfFrame();
                if(ScaleControlSlider.value >= 0.55f)
                {
                    go = false;
                }
                addnum += 0.0008f;
            }
            yield return new WaitForEndOfFrame();
        }
    
        public void DayNightChangeControll()
        {
            isDay = !isDay;
            DayButton.SetActive(!isDay);
            NightButton.SetActive(isDay);
            DayObj.SetActive(isDay);
            NightObj.SetActive(!isDay);
        }
    
        private void Update()
        {
            if (!IsBuildSource)
            {
                AnchorButton.SetActive(true);
                TrackButton.SetActive(false);
            }
            else
            {
                AnchorButton.SetActive(false);
                TrackButton.SetActive(true);
            }
            text.text = IsBuildSource.ToString();
            if (ScaleControlSlider.gameObject.activeInHierarchy && ScaleControlSlider.interactable == true)
            {
                AnchorChild.gameObject.transform.localScale = new Vector3(ScaleControlSlider.value + 1f, ScaleControlSlider.value + 1f, ScaleControlSlider.value + 1f);
            }
        }
    
        public void OnClickQuit()
        {
            Application.Quit();
        }
    }
    

    相关文章

      网友评论

          本文标题:ARFoundation 扫描局部图显示模型

          本文链接:https://www.haomeiwen.com/subject/tytykktx.html