分享

unity3d 尝试 基于地理定位的 增强现实

 南氏珍藏 2016-03-13

首先说,这个尝试失败,属于死在去医院的路上那种。


基于地理定位的增强现实,AR全息实景,是一种高大上的说法,说直白点就是山寨类似随便走这样的应用。

打开应用,搜索周边信息,然后再把信息叠加在摄像头拍摄到的内容上面。



思路:用手机移动来控制unity中的camrea,将摄像头拍摄到的内容作为背景。获取地理信息,将信息转化成文字添加到unity的世界中。


1、用手机移动控制unity中的camrea。

这段代码中unity的论坛中找到,但是时间很久远,改了下发现能用。

http://forum./threads/sharing-gyroscope-controlled-camera-on-iphone-4.98828/

[csharp] view plain copy
在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class CameraManager : MonoBehaviour {  
  5.   
  6.   
  7.   
  8.     private bool gyroBool;  
  9.     private Gyroscope gyro;  
  10.     private Quaternion rotFix;  
  11.   
  12.     public void Start ()  
  13.     {  
  14.         Transform currentParent = transform.parent;  
  15.         GameObject camParent = new GameObject ("GyroCamParent");  
  16.         camParent.transform.position = transform.position;  
  17.         transform.parent = camParent.transform;  
  18.         GameObject camGrandparent = new GameObject ("GyroCamGrandParent");  
  19.         camGrandparent.transform.position = transform.position;  
  20.         camParent.transform.parent = camGrandparent.transform;  
  21.         camGrandparent.transform.parent = currentParent;  
  22.   
  23.         gyroBool = SystemInfo.supportsGyroscope;  
  24.   
  25.         if (gyroBool) {  
  26.   
  27.             gyro = Input.gyro;  
  28.             gyro.enabled = true;  
  29.   
  30.             if (Screen.orientation == ScreenOrientation.LandscapeLeft) {  
  31.                 camParent.transform.eulerAngles = new Vector3 (90, 90, 0);  
  32.             } else if (Screen.orientation == ScreenOrientation.Portrait) {  
  33.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);  
  34.             } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {  
  35.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);  
  36.             } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {  
  37.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);  
  38.             } else {  
  39.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);  
  40.             }  
  41.   
  42.             if (Screen.orientation == ScreenOrientation.LandscapeLeft) {  
  43.                 rotFix = new Quaternion (0, 0,0.7071f,0.7071f);  
  44.             } else if (Screen.orientation == ScreenOrientation.Portrait) {  
  45.                 rotFix = new Quaternion (0, 0, 1, 0);  
  46.             } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {  
  47.                 rotFix = new Quaternion (0, 0, 1, 0);  
  48.             } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {  
  49.                 rotFix = new Quaternion (0, 0, 1, 0);  
  50.             } else {  
  51.                 rotFix = new Quaternion (0, 0, 1, 0);  
  52.             }  
  53.   
  54.             //Screen.sleepTimeout = 0;  
  55.         } else {  
  56.             #if UNITY_EDITOR  
  57.             print("NO GYRO");  
  58.             #endif  
  59.         }  
  60.     }  
  61.   
  62.     public void Update ()  
  63.     {  
  64.         if (gyroBool) {  
  65.             Quaternion quatMap;  
  66.             #if UNITY_IOS  
  67.             quatMap = gyro.attitude;  
  68.             #elif UNITY_ANDROID  
  69.             quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);  
  70.             #endif  
  71.             transform.localRotation = quatMap * rotFix;  
  72.         }  
  73.     }  
  74. }  


2、背景摄像头显示摄像机内容

摄像头的内容可以显示在guitexure上也可以显示在plan上,但是在guitexrue上显示的时候,方向转了90度,最后只好显示在plan上。

[csharp] view plain copy
在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class WebCamManager : MonoBehaviour {  
  5.   
  6.     // Use this for initialization  
  7.     void Start () {  
  8.   
  9.         WebCamTexture webcamTexture = new WebCamTexture ();  
  10.   
  11.         //如果有后置摄像头,调用后置摄像头  
  12.         for (int i = 0; i < WebCamTexture.devices.Length; i++) {  
  13.             if (!WebCamTexture.devices [i].isFrontFacing) {  
  14.                 webcamTexture.deviceName = WebCamTexture.devices [i].name;  
  15.                 break;  
  16.             }  
  17.         }  
  18.   
  19.         Renderer renderer = GetComponent<Renderer>();    
  20.         renderer.material.mainTexture = webcamTexture;    
  21.         webcamTexture.Play();    
  22.     }  
  23. }  


3、调用高德地图的地理定位和搜索附近

详细内容请看我之前的博客

http://blog.csdn.net/wuyt2008/article/details/50774017

http://blog.csdn.net/wuyt2008/article/details/50789423


4、当搜索到内容以后,将名称信息添加到unity的世界里。

[csharp] view plain copy
在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using UnityEngine.UI;  
  5.   
  6. public class ARMange : MonoBehaviour {  
  7.   
  8.     public List<PlaceInfo> places = new List<PlaceInfo>();  
  9.     public GameObject perfab;  
  10.     public PlaceInfo location = new PlaceInfo ();  
  11.   
  12.     public void ShowPlaces(){  
  13.         ClearPlace ();  
  14.   
  15.         for (int i = 0; i < places.Count; i++) {  
  16.   
  17.             GameObject newPlace = Instantiate<GameObject> (perfab);  
  18.             newPlace.transform.parent = this.transform;  
  19.   
  20.             double posZ = places [i].Latitude - location.Latitude;  
  21.             double posX = places [i].Longitude - location.Longitude;  
  22.   
  23.             float z = 0;  
  24.             float x = 0;  
  25.             float y = 0;  
  26.   
  27.             if (posZ > 0) {  
  28.                 z = 500f;  
  29.             } else {  
  30.                 z = -500f;  
  31.             }  
  32.   
  33.             if (posX > 0) {  
  34.                 x = 500f;  
  35.             } else {  
  36.                 x = -500f;  
  37.             }  
  38.   
  39.             z = z + (float)(posZ * 1000);  
  40.             x = x + (float)(posX * 1000);  
  41.             y = y + i * 20;  
  42.   
  43.             newPlace.transform.position = new Vector3 (x, y, z);  
  44.             newPlace.transform.LookAt (this.transform);  
  45.             newPlace.transform.Rotate (new Vector3 (0f, 180f, 0f));  
  46.   
  47.             newPlace.gameObject.GetComponentInChildren<Text> ().text = places [i].Name;  
  48.         }  
  49.     }  
  50.   
  51.     private void ClearPlace(){  
  52.         GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");  
  53.         for (int i = 0; i < oldPlaces.Length; i++) {  
  54.             Destroy (oldPlaces [i].gameObject);  
  55.         }  
  56.     }  
  57.   
  58. }  


5、这个时候显示内容没问题,但是方向会偏移。于是加了个指南针来矫正方向

[csharp] view plain copy
在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UnityEngine.UI;  
  4.   
  5. public class CompassManage : MonoBehaviour {  
  6.   
  7.     public Transform cam;  
  8.   
  9.     void Start () {  
  10.         Input.location.Start ();  
  11.         Input.compass.enabled = true;  
  12.     }  
  13.       
  14.     // Update is called once per frame  
  15.     void Update () {  
  16.         transform.rotation = Quaternion.Euler(0, cam.eulerAngles.y-Input.compass.trueHeading, 0);  
  17.     }  
  18. }  


6、最后遇到的,我无法解决的问题

简单一句话,就是滤波。这个应用需要准确稳定的判断出当前手机方向位置状态,但是,输入的内容,重力,罗盘,加速度都是在不断变化,并且会有偏移的量,需要滤波。

虽然大致知道了是应该用互补滤波和卡尔曼滤波,但是,我的水平只能看懂名字,看不懂内容。

数学无力的我只好放弃。等遇到别人写好的代码再抄下吧。


这是死在半路上的结果的样子




这样的结果呢,当然是不甘心的,但是没时间去仔细研究这个问题了,所以只好放弃。如果哪位大侠知道怎么根据重力,罗盘,加速判断手机状态的,在这里跪求先。

源码和编译的apk:http://download.csdn.net/detail/wuyt2008/9458508

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多