大牛专栏 收藏本版 已有21人收藏 +发表新主题
查看: 20121|回复: 8
打印 上一主题 下一主题

Capricorn|Unity3d利用传感器实现AR应用的SLAM功能(2)

[复制链接]

Capricorn|Unity3d利用传感器实现AR应用的SLAM功能(2)

zzlple 发表于 2016-4-27 22:37:17 浏览:  20121 回复:  8 只看该作者 复制链接
本帖最后由 zzlple 于 2016-5-20 21:58 编辑

在上次的教程中我们介绍给大家一个基于加速计,陀螺仪等传感器于一体的插件,那么在本次的教程中我们就来阐述,怎么使用这个轮子,接下来我们直接贴上代码:
using UnityEngine;
using System.Collections;
namespace com.arinchina.demo
{

    /// <summary>
    /// On slam reset.当重置时,恢复物体到原点
    /// </summary>
    public delegate void OnSlamReset ();

    public class SlamManager : MonoBehaviour
    {
        public static OnSlamReset OnSlamReset;
        public enum SlamType
        {

            Hardware,
            UserDefine
        }

        /// <summary>
        /// The type of the slam.
        /// </summary>
        public SlamType slamType;

        /// <summary>
        /// The ho.
        /// </summary>
        public float PositionY = 30f;
        public float PositionZ = -150f;
        /// <summary>
        /// The en able debug mode.
        /// </summary>
        public bool enableDebugMode;
        /// <summary>
        /// The initial camera rotation.
        /// </summary>
        private Quaternion initialCameraRotation = Quaternion.identity;
        /// <summary>
        /// The rotation euler angle.android
        /// </summary>
        private Vector3 RotationEulerAngle;
        /// <summary>
        /// The sensor fix.iphone
        /// </summary>
        private Quaternion sensorFix;
        /// <summary>
        /// The enable slam.
        /// </summary>
        public bool enableSlam = false;
        /// <summary>
        /// Start this instance.
        /// </summary>
        private bool isBackCamera = true;

        public static bool rotationFixed = false;


        void Awake ()
        {

            Invoke ("AutoSelect", 0.1f);
            initialCameraRotation = Quaternion.identity;
            SensorHelper.ActivateRotation ();
            if (!rotationFixed) {
                StartCoroutine (FixRotation ());
            }


        }




        // Update is called once per frame
        void LateUpdate ()
        {

            #if UNITY_ANDROID
            RotationEulerAngle = SensorHelper.rotation.eulerAngles;
            if (enableSlam && SensorHelper.gotFirstValue) {
            transform.rotation = initialCameraRotation * SensorHelper.rotation;
            }
            #endif

            #if UNITY_IPHONE

            if (enableSlam) {
                sensorFix = new Quaternion (SensorHelper.rotation.x, SensorHelper.rotation.y, -SensorHelper.rotation.z, -SensorHelper.rotation.w);
                transform.rotation = initialCameraRotation * sensorFix;
            }
            #endif

        }


        public void StartSlam (bool isBackCamera)
        {

   
            #if UNITY_ANDROID
            switch (slamType) {
            case SlamType.Hardware:
            transform.localPosition = new Vector3 (0, PositionY, PositionZ);
            transform.localEulerAngles = new Vector3 (0f, 0f, 0f);
            if (isBackCamera) {
            transform.localEulerAngles = new Vector3 (0f, 0f, RotationEulerAngle.z);
            transform.RotateAround (Vector3.zero, Vector3.right, Time.timeScale * (RotationEulerAngle.x));
            } else {
            transform.localEulerAngles = new Vector3 (0, 0, RotationEulerAngle.z + 180);
            transform.RotateAround (Vector3.zero, Vector3.right, Time.timeScale * (RotationEulerAngle.x));
            }
            if (isBackCamera) {
            initialCameraRotation = transform.rotation * Quaternion.Inverse (SensorHelper.rotation);
            } else {
            initialCameraRotation = transform.rotation * Quaternion.Inverse (SensorHelper.rotation);
            }

            enableSlam = true;
            break;

            case SlamType.UserDefine:
            enableSlam = false;

        
            break;
            }

            #endif



            #if UNITY_IPHONE
            switch (slamType) {
            case SlamType.Hardware:
                transform.localPosition = new Vector3 (0, PositionY, PositionZ);
                transform.localEulerAngles = new Vector3 (0f, 0f, 0f);
                sensorFix = new Quaternion (SensorHelper.rotation.x, SensorHelper.rotation.y, -SensorHelper.rotation.z, -SensorHelper.rotation.w);
                float uz = Mathf.Asin (Input.gyro.gravity.x) * Mathf.Rad2Deg;
                float ux = Mathf.Asin (Input.gyro.gravity.z) * Mathf.Rad2Deg;
                transform.localEulerAngles = new Vector3 (0f, 0f, -uz);
                transform.RotateAround (Vector3.zero, Vector3.right, Time.timeScale * (-ux));
                initialCameraRotation = transform.rotation * Quaternion.Inverse (sensorFix);
                enableSlam = true;
                break;

            case SlamType.UserDefine:
                enableSlam = false;

                break;
            }

            #endif




        }



        /// <summary>
        /// Stops the slam.
        /// </summary>
        public void StopSlam ()
        {

            enableSlam = false;
            transform.localPosition = new Vector3 (0, PositionY, PositionZ);
            if (isBackCamera) {
                transform.localEulerAngles = Vector3.zero;
            } else {
                transform.localEulerAngles = Vector3.zero;
            }

            transform.localScale = Vector3.one;

        }

        IEnumerator FixRotation ()
        {
            for (int i = 0; i < 4; i++) {

                if (enableSlam) {
                    #if UNITY_ANDROID
                    initialCameraRotation = transform.rotation * Quaternion.Inverse (SensorHelper.rotation);
                    #endif
                    #if UNITY_IPHONE
                    sensorFix = new Quaternion (SensorHelper.rotation.x, SensorHelper.rotation.y, -SensorHelper.rotation.z, -SensorHelper.rotation.w);
                    initialCameraRotation = transform.rotation * Quaternion.Inverse (sensorFix);
                    #endif

                } else {
                    StopSlam ();
                }
                enableSlam = !enableSlam;
                rotationFixed = false;
                yield return new WaitForFixedUpdate ();
            }
            rotationFixed = true;

        }

        public void AutoSelect ()
        {
            if (Input.gyro.enabled == false && (Input.acceleration.x == 0 && Input.acceleration.y == 0 && Input.acceleration.z == 0)) {
                slamType = SlamType.UserDefine;

                 } else {
                slamType = SlamType.Hardware;
          }

        }

        public void reset ()
        {

            StopSlam ();
            StartSlam (isBackCamera);

            if (null != OnSlamReset) {
            
                OnSlamReset ();
            }
        }

   

        #if UNITY_IPHONE


        #endif

    }

}


好了,今天关于如何使用综合传感器的教程到这里结束,在使用的过程中,如果有什么疑问,欢迎大家踊跃提出来
分享至:
| 人收藏
回复

使用道具 举报

该用户从未签到

沙发
wangyaoyi11 发表于 2016-5-3 14:18:17 只看该作者
好简洁的一句话,佩服!
回复 支持 反对

使用道具 举报

该用户从未签到

板凳
IRON-MAN 发表于 2016-5-3 22:07:30 只看该作者
赞赞赞就是了!
回复 支持 反对

使用道具 举报

该用户从未签到

地板
三目数字 发表于 2016-5-18 15:05:08 只看该作者
好吧 给个赞  我就不提过分的要求了
回复 支持 反对

使用道具 举报

该用户从未签到

5#
JudgementAngel 发表于 2016-8-4 15:35:36 只看该作者
这个脚本应该挂载在Unity场景里的哪个对象上面?
回复 支持 反对

使用道具 举报

该用户从未签到

7#
BlueSky 发表于 2016-8-20 23:40:35 只看该作者
意犹未尽,还有么
回复 支持 反对

使用道具 举报

该用户从未签到

9#
2016mima 发表于 2016-9-22 17:08:49 只看该作者
这是个什么效果,有演示么?
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中级会员

Copyright © 2013-2017 ARinChina-增强现实中国技术论坛   All Rights Reserved.