(轉(zhuǎn))unity3d 嘗試 基于地理定位的 增強現(xiàn)實

首先說,這個嘗試失敗,屬于死在去醫(yī)院的路上那種。

基于地理定位的增強現(xiàn)實,AR全息實景,是一種高大上的說法,說直白點就是山寨類似隨便走這樣的應(yīng)用。

打開應(yīng)用,搜索周邊信息,然后再把信息疊加在攝像頭拍攝到的內(nèi)容上面。


思路:用手機移動來控制unity中的camrea,將攝像頭拍攝到的內(nèi)容作為背景。獲取地理信息,將信息轉(zhuǎn)化成文字添加到unity的世界中。

1、用手機移動控制unity中的camrea。

這段代碼中unity的論壇中找到,但是時間很久遠,改了下發(fā)現(xiàn)能用。

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

using UnityEngine;

using System.Collections;

public class CameraManager : MonoBehaviour {

private bool gyroBool;

private Gyroscope gyro;

private Quaternion rotFix;

public void Start ()

{

Transform currentParent = transform.parent;

GameObject camParent = new GameObject ("GyroCamParent");

camParent.transform.position = transform.position;

transform.parent = camParent.transform;

GameObject camGrandparent = new GameObject ("GyroCamGrandParent");

camGrandparent.transform.position = transform.position;

camParent.transform.parent = camGrandparent.transform;

camGrandparent.transform.parent = currentParent;

gyroBool = SystemInfo.supportsGyroscope;

if (gyroBool) {

gyro = Input.gyro;

gyro.enabled = true;

if (Screen.orientation == ScreenOrientation.LandscapeLeft) {

camParent.transform.eulerAngles = new Vector3 (90, 90, 0);

} else if (Screen.orientation == ScreenOrientation.Portrait) {

camParent.transform.eulerAngles = new Vector3 (90, 180, 0);

} else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {

camParent.transform.eulerAngles = new Vector3 (90, 180, 0);

} else if (Screen.orientation == ScreenOrientation.LandscapeRight) {

camParent.transform.eulerAngles = new Vector3 (90, 180, 0);

} else {

camParent.transform.eulerAngles = new Vector3 (90, 180, 0);

}

if (Screen.orientation == ScreenOrientation.LandscapeLeft) {

rotFix = new Quaternion (0, 0,0.7071f,0.7071f);

} else if (Screen.orientation == ScreenOrientation.Portrait) {

rotFix = new Quaternion (0, 0, 1, 0);

} else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {

rotFix = new Quaternion (0, 0, 1, 0);

} else if (Screen.orientation == ScreenOrientation.LandscapeRight) {

rotFix = new Quaternion (0, 0, 1, 0);

} else {

rotFix = new Quaternion (0, 0, 1, 0);

}

//Screen.sleepTimeout = 0;

} else {

#if UNITY_EDITOR

print("NO GYRO");

#endif

}

}

public void Update ()

{

if (gyroBool) {

Quaternion quatMap;

#if UNITY_IOS

quatMap = gyro.attitude;

#elif UNITY_ANDROID

quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);

#endif

transform.localRotation = quatMap * rotFix;

}

}

}

2、背景攝像頭顯示攝像機內(nèi)容

攝像頭的內(nèi)容可以顯示在guitexure上也可以顯示在plan上,但是在guitexrue上顯示的時候,方向轉(zhuǎn)了90度,最后只好顯示在plan上。

using UnityEngine;

using System.Collections;

public class WebCamManager : MonoBehaviour {

// Use this for initialization

void Start () {

WebCamTexture webcamTexture = new WebCamTexture ();

//如果有后置攝像頭,調(diào)用后置攝像頭

for (int i = 0; i < WebCamTexture.devices.Length; i++) {

if (!WebCamTexture.devices [i].isFrontFacing) {

webcamTexture.deviceName = WebCamTexture.devices [i].name;

break;

}

}

Renderer renderer = GetComponent<Renderer>();?

renderer.material.mainTexture = webcamTexture;?

webcamTexture.Play();?

}

}

3、調(diào)用高德地圖的地理定位和搜索附近

詳細內(nèi)容請看我之前的博客

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

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

4、當(dāng)搜索到內(nèi)容以后,將名稱信息添加到unity的世界里。

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

using UnityEngine.UI;

public class ARMange : MonoBehaviour {

public List<PlaceInfo> places = new List<PlaceInfo>();

public GameObject perfab;

public PlaceInfo location = new PlaceInfo ();

public void ShowPlaces(){

ClearPlace ();

for (int i = 0; i < places.Count; i++) {

GameObject newPlace = Instantiate<GameObject> (perfab);

newPlace.transform.parent = this.transform;

double posZ = places [i].Latitude - location.Latitude;

double posX = places [i].Longitude - location.Longitude;

float z = 0;

float x = 0;

float y = 0;

if (posZ > 0) {

z = 500f;

} else {

z = -500f;

}

if (posX > 0) {

x = 500f;

} else {

x = -500f;

}

z = z + (float)(posZ * 1000);

x = x + (float)(posX * 1000);

y = y + i * 20;

newPlace.transform.position = new Vector3 (x, y, z);

newPlace.transform.LookAt (this.transform);

newPlace.transform.Rotate (new Vector3 (0f, 180f, 0f));

newPlace.gameObject.GetComponentInChildren<Text> ().text = places [i].Name;

}

}

private void ClearPlace(){

GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");

for (int i = 0; i < oldPlaces.Length; i++) {

Destroy (oldPlaces [i].gameObject);

}

}

}

5、這個時候顯示內(nèi)容沒問題,但是方向會偏移。于是加了個指南針來矯正方向

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

public class CompassManage : MonoBehaviour {

public Transform cam;

void Start () {

Input.location.Start ();

Input.compass.enabled = true;

}

// Update is called once per frame

void Update () {

transform.rotation = Quaternion.Euler(0, cam.eulerAngles.y-Input.compass.trueHeading, 0);

}

}

6、最后遇到的,我無法解決的問題

簡單一句話,就是濾波。這個應(yīng)用需要準確穩(wěn)定的判斷出當(dāng)前手機方向位置狀態(tài),但是,輸入的內(nèi)容,重力,羅盤,加速度都是在不斷變化,并且會有偏移的量,需要濾波。

雖然大致知道了是應(yīng)該用互補濾波和卡爾曼濾波,但是,我的水平只能看懂名字,看不懂內(nèi)容。

數(shù)學(xué)無力的我只好放棄。等遇到別人寫好的代碼再抄下吧。

這是死在半路上的結(jié)果的樣子


這樣的結(jié)果呢,當(dāng)然是不甘心的,但是沒時間去仔細研究這個問題了,所以只好放棄。如果哪位大俠知道怎么根據(jù)重力,羅盤,加速判斷手機狀態(tài)的,在這里跪求先。

源碼和編譯的apk:http://download.csdn.net/detail/wuyt2008/9458508

====================

在SearchManage.cs文件中,我把搜索范圍限定在了昆明,

//txtInfo.text = txtInfo.text + "\r\n";

AndroidJavaObject query = amapHelper.Call<AndroidJavaObject>("getPoiSearch",inputQuery.text,"","0871");

txtInfo.text = txtInfo.text + "query get...";

將0871改成其他地方的區(qū)號就可以了,(為空是全國范圍,但是沒驗證過)

原文:https://blog.csdn.net/wuyt2008/article/details/50854262

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容