ARFoundation 扫描局部图显示模型

2020-07-20  本文已影响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();
    }
}
上一篇下一篇

猜你喜欢

热点阅读