From bf96aec13dc393dbf4aa736c0c80825c2f4ff13f Mon Sep 17 00:00:00 2001 From: Jason Guo Date: Mon, 17 Aug 2015 10:08:47 -0700 Subject: [PATCH] release-urquhart --- UnityExamples/Assets/Editor/BuildTools.cs | 84 +- UnityExamples/Assets/Editor/BuildUtil.cs | 26 +- UnityExamples/Assets/Google-Unity.meta | 4 +- .../Assets/Google-Unity/Scripts.meta | 4 +- UnityExamples/Assets/Plugins.meta | 4 +- UnityExamples/Assets/Plugins/Android.meta | 4 +- .../Plugins/Android/AndroidManifest.xml.meta | 2 +- .../Assets/Plugins/Android/UnityUxHelper.meta | 4 +- .../UnityUxHelper/AndroidManifest.xml.meta | 6 +- .../Plugins/Android/UnityUxHelper/bin.meta | 4 +- .../bin/AndroidManifest.xml.meta | 6 +- .../Plugins/Android/UnityUxHelper/bin/R.txt | 107 +- .../Android/UnityUxHelper/bin/R.txt.meta | 6 +- .../Android/UnityUxHelper/bin/res.meta | 4 +- .../Android/UnityUxHelper/bin/res/crunch.meta | 4 +- .../bin/res/crunch/drawable-hdpi.meta | 4 +- .../res/crunch/drawable-hdpi/ic_launcher.png | Bin 9193 -> 0 bytes .../crunch/drawable-hdpi/ic_launcher.png.meta | 55 - .../bin/res/crunch/drawable-mdpi.meta | 4 +- .../res/crunch/drawable-mdpi/ic_launcher.png | Bin 5057 -> 0 bytes .../crunch/drawable-mdpi/ic_launcher.png.meta | 55 - .../bin/res/crunch/drawable-xhdpi.meta | 4 +- .../res/crunch/drawable-xhdpi/ic_launcher.png | Bin 14068 -> 0 bytes .../drawable-xhdpi/ic_launcher.png.meta | 55 - .../UnityUxHelper/bin/unityuxhelper.jar | Bin 6192 -> 6236 bytes .../UnityUxHelper/bin/unityuxhelper.jar.meta | 4 +- .../Plugins/Android/UnityUxHelper/libs.meta | 4 +- .../libs/android-support-v4.jar.meta | 4 +- .../Android/UnityUxHelper/project.properties | 2 - .../UnityUxHelper/project.properties.meta | 4 +- .../Plugins/Android/UnityUxHelper/res.meta | 4 +- .../UnityUxHelper/res/drawable-hdpi.meta | 4 +- .../res/drawable-hdpi/ic_launcher.png.meta | 53 +- .../UnityUxHelper/res/drawable-mdpi.meta | 4 +- .../res/drawable-mdpi/ic_launcher.png.meta | 53 +- .../UnityUxHelper/res/drawable-xhdpi.meta | 4 +- .../res/drawable-xhdpi/ic_launcher.png.meta | 53 +- .../Android/UnityUxHelper/res/layout.meta | 4 +- .../res/layout/tango_ux_exceptions.xml.meta | 6 +- .../Android/UnityUxHelper/res/values-v11.meta | 4 +- .../res/values-v11/styles.xml.meta | 6 +- .../Android/UnityUxHelper/res/values-v14.meta | 4 +- .../res/values-v14/styles.xml.meta | 6 +- .../Android/UnityUxHelper/res/values.meta | 4 +- .../UnityUxHelper/res/values/strings.xml.meta | 6 +- .../UnityUxHelper/res/values/styles.xml.meta | 6 +- .../Android/UnityUxHelper/src/com.meta | 9 - .../UnityUxHelper/src/com/projecttango.meta | 9 - .../src/com/projecttango/unityuxhelper.meta | 9 - .../unityuxhelper/TangoUnityUxHelper.java | 130 -- .../TangoUnityUxHelper.java.meta | 8 - .../Plugins/Android/google-unity-wrapper.meta | 4 +- .../AndroidManifest.xml.meta | 2 +- .../Android/google-unity-wrapper/bin.meta | 4 +- .../bin/AndroidManifest.xml.meta | 2 +- .../google-unity-wrapper/bin/classes.meta | 4 +- .../google-unity-wrapper/bin/classes/com.meta | 4 +- .../bin/classes/com/google.meta | 4 +- .../bin/classes/com/google/unity.meta | 4 +- .../com/google/unity/BuildConfig.class.meta | 2 +- .../unity/GoogleUnityActivity$1.class.meta | 2 +- ...tivity$AndroidLifecycleListener.class.meta | 2 +- .../unity/GoogleUnityActivity.class.meta | 2 +- .../bin/google-unity-wrapper.jar | Bin 4528 -> 4528 bytes .../bin/google-unity-wrapper.jar.meta | 2 +- .../project.properties.meta | 2 +- .../Plugins/Android/tango-java-lib.meta | 4 +- .../tango-java-lib/AndroidManifest.xml.meta | 2 +- .../Plugins/Android/tango-java-lib/bin.meta | 4 +- .../bin/AndroidManifest.xml.meta | 2 +- .../Android/tango-java-lib/bin/classes.meta | 4 +- .../tango-java-lib/bin/classes/com.meta | 4 +- .../bin/classes/com/google.meta | 4 +- .../bin/classes/com/google/atap.meta | 4 +- .../bin/classes/com/google/atap/tango.meta | 4 +- .../atap/tango/TangoJNINative.class.meta | 2 +- .../com/google/atap/tango/package.html.meta | 2 +- .../com/google/atap/tangohelperlib.meta | 4 +- .../tangohelperlib/BuildConfig.class.meta | 2 +- .../classes/com/google/atap/tangoservice.meta | 4 +- .../Tango$OnTangoUpdateListener.class.meta | 2 +- .../google/atap/tangoservice/Tango.class.meta | 2 +- .../TangoAreaDescriptionMetaData$1.class.meta | 2 +- .../TangoAreaDescriptionMetaData.class.meta | 2 +- .../TangoCameraIntrinsics$1.class.meta | 2 +- .../TangoCameraIntrinsics.class.meta | 2 +- ...TangoCameraPreview$MainRenderer.class.meta | 2 +- .../TangoCameraPreview.class.meta | 2 +- .../tangoservice/TangoConfig$1.class.meta | 2 +- .../atap/tangoservice/TangoConfig.class.meta | 2 +- .../TangoCoordinateFramePair$1.class.meta | 2 +- .../TangoCoordinateFramePair.class.meta | 2 +- .../TangoErrorException.class.meta | 2 +- .../atap/tangoservice/TangoEvent$1.class.meta | 2 +- .../atap/tangoservice/TangoEvent.class.meta | 2 +- .../tangoservice/TangoException.class.meta | 2 +- .../TangoInvalidException.class.meta | 2 +- .../TangoOutOfDateException.class.meta | 2 +- .../tangoservice/TangoPoseData$1.class.meta | 2 +- .../tangoservice/TangoPoseData.class.meta | 2 +- .../TangoTextureCameraPreview.class.meta | 2 +- .../tangoservice/TangoXyzIjData$1.class.meta | 2 +- .../tangoservice/TangoXyzIjData.class.meta | 2 +- .../tangoservice/TextureRenderer.class.meta | 2 +- .../atap/tangoservice/experimental.meta | 4 +- .../experimental/TangoMesh.class.meta | 2 +- .../experimental/TangoMeshVector$1.class.meta | 2 +- .../experimental/TangoMeshVector.class.meta | 2 +- ...angoMeshVectorAvailableListener.class.meta | 2 +- .../experimental/TangoMesher.class.meta | 2 +- .../experimental/package-info.class.meta | 2 +- .../atap/tangoservice/package-info.class.meta | 2 +- .../tango-java-lib/bin/tango-java-lib.jar | Bin 44052 -> 44052 bytes .../bin/tango-java-lib.jar.meta | 2 +- .../tango-java-lib/project.properties.meta | 2 +- .../Plugins/Android/tango-unity-helper.meta | 4 +- .../AndroidManifest.xml.meta | 2 +- .../Android/tango-unity-helper/bin.meta | 4 +- .../bin/AndroidManifest.xml.meta | 2 +- .../tango-unity-helper/bin/classes.meta | 4 +- .../tango-unity-helper/bin/classes/com.meta | 4 +- .../bin/classes/com/projecttango.meta | 4 +- .../bin/classes/com/projecttango/unity.meta | 4 +- .../projecttango/unity/BuildConfig.class.meta | 2 +- .../projecttango/unity/TangoUnityHelper.class | Bin 1437 -> 3228 bytes .../unity/TangoUnityHelper.class.meta | 2 +- .../bin/tango-unity-helper.jar | Bin 1058 -> 2516 bytes .../bin/tango-unity-helper.jar.meta | 2 +- .../project.properties.meta | 2 +- .../Android/tango-ux-support-library.meta | 4 +- .../AndroidManifest.xml.meta | 6 +- .../Android/tango-ux-support-library/bin.meta | 4 +- .../bin/AndroidManifest.xml | 2 +- .../bin/AndroidManifest.xml.meta | 6 +- .../tango-ux-support-library/bin/R.txt | 86 +- .../tango-ux-support-library/bin/R.txt.meta | 6 +- .../tango-ux-support-library/bin/res.meta | 4 +- .../bin/res/crunch.meta | 4 +- .../bin/res/crunch/drawable-xhdpi.meta | 4 +- .../exception_container_shadow.png | Bin 2448 -> 0 bytes .../exception_container_shadow.png.meta | 55 - .../ic_exception_i_am_dizzy.png | Bin 3267 -> 0 bytes .../ic_exception_i_am_dizzy.png.meta | 55 - .../drawable-xhdpi/ic_exception_i_am_lost.png | Bin 2833 -> 0 bytes .../ic_exception_i_am_lost.png.meta | 55 - .../ic_exception_i_cant_see.png | Bin 3005 -> 0 bytes .../ic_exception_i_cant_see.png.meta | 55 - .../drawable-xhdpi/ic_exception_system.png | Bin 2260 -> 0 bytes .../ic_exception_system.png.meta | 55 - .../drawable-xhdpi/ic_shake_background.png | Bin 23939 -> 0 bytes .../ic_shake_background.png.meta | 55 - .../crunch/drawable-xhdpi/ic_shake_err.png | Bin 4146 -> 0 bytes .../drawable-xhdpi/ic_shake_err.png.meta | 55 - .../res/crunch/drawable-xhdpi/ic_shake_ok.png | Bin 11093 -> 0 bytes .../drawable-xhdpi/ic_shake_ok.png.meta | 55 - .../drawable-xhdpi/ic_shake_ok_tick.png | Bin 503 -> 0 bytes .../drawable-xhdpi/ic_shake_ok_tick.png.meta | 55 - .../res/crunch/drawable-xhdpi/splash_logo.png | Bin 14086 -> 0 bytes .../drawable-xhdpi/splash_logo.png.meta | 55 - .../bin/tango-ux-support-library.jar | Bin 63976 -> 64040 bytes .../bin/tango-ux-support-library.jar.meta | 4 +- .../project.properties | 1 - .../project.properties.meta | 4 +- .../Android/tango-ux-support-library/res.meta | 4 +- .../res/drawable-xhdpi.meta | 4 +- .../exception_container_shadow.png.meta | 53 +- .../ic_exception_i_am_dizzy.png.meta | 53 +- .../ic_exception_i_am_lost.png.meta | 53 +- .../ic_exception_i_cant_see.png.meta | 53 +- .../ic_exception_system.png.meta | 53 +- .../ic_shake_background.png.meta | 53 +- .../res/drawable-xhdpi/ic_shake_err.png.meta | 53 +- .../res/drawable-xhdpi/ic_shake_ok.png.meta | 53 +- .../drawable-xhdpi/ic_shake_ok_tick.png.meta | 53 +- .../res/drawable-xhdpi/splash_logo.png.meta | 53 +- .../tango-ux-support-library/res/layout.meta | 4 +- .../res/layout/exception_component.xml.meta | 6 +- .../res/layout/layout_connection.xml.meta | 6 +- .../res/layout/layout_splash.xml.meta | 6 +- .../res/layout/layout_tango_ux.xml.meta | 6 +- .../tango-ux-support-library/res/values.meta | 4 +- .../res/values/colors.xml.meta | 6 +- .../res/values/dimens.xml.meta | 6 +- .../res/values/strings.xml.meta | 6 +- .../res/values/styles.xml.meta | 6 +- .../Android/tango-ux-support-library/src.meta | 9 - .../tango-ux-support-library/src/.readme | 2 - .../tango-ux-support-library/src/com.meta | 9 - .../src/com/google.meta | 9 - .../src/com/google/atap.meta | 9 - .../src/com/google/atap/tango.meta | 9 - .../src/com/google/atap/tango/ux.meta | 9 - .../atap/tango/ux/BaseExceptionHandler.java | 36 - .../tango/ux/BaseExceptionHandler.java.meta | 8 - .../atap/tango/ux/ConnectionLayout.java | 183 -- .../atap/tango/ux/ConnectionLayout.java.meta | 8 - .../tango/ux/ConnectionLayoutProgressBar.java | 197 -- .../ux/ConnectionLayoutProgressBar.java.meta | 8 - .../atap/tango/ux/ConnectionLayoutTick.java | 57 - .../tango/ux/ConnectionLayoutTick.java.meta | 8 - .../atap/tango/ux/ExceptionComponent.java | 88 - .../tango/ux/ExceptionComponent.java.meta | 8 - .../atap/tango/ux/ExceptionHandler.java | 32 - .../atap/tango/ux/ExceptionHandler.java.meta | 8 - .../google/atap/tango/ux/ExceptionHelper.java | 464 ----- .../atap/tango/ux/ExceptionHelper.java.meta | 8 - .../tango/ux/ExceptionPanelContainer.java | 204 -- .../ux/ExceptionPanelContainer.java.meta | 8 - .../tango/ux/ExceptionStatusComponent.java | 118 -- .../ux/ExceptionStatusComponent.java.meta | 8 - .../atap/tango/ux/MotionDetectionHelper.java | 171 -- .../tango/ux/MotionDetectionHelper.java.meta | 8 - .../ux/MotionTrackingExceptionHandler.java | 61 - .../MotionTrackingExceptionHandler.java.meta | 8 - .../tango/ux/NoQueueExceptionHandler.java | 51 - .../ux/NoQueueExceptionHandler.java.meta | 8 - .../atap/tango/ux/QueuedExceptionHandler.java | 66 - .../tango/ux/QueuedExceptionHandler.java.meta | 8 - .../google/atap/tango/ux/SplashLayout.java | 39 - .../atap/tango/ux/SplashLayout.java.meta | 8 - .../atap/tango/ux/SystemExceptionHandler.java | 43 - .../tango/ux/SystemExceptionHandler.java.meta | 8 - .../atap/tango/ux/TangoExceptionInfo.java | 130 -- .../tango/ux/TangoExceptionInfo.java.meta | 8 - .../src/com/google/atap/tango/ux/TangoUx.java | 358 ---- .../google/atap/tango/ux/TangoUx.java.meta | 8 - .../google/atap/tango/ux/TangoUxLayout.java | 147 -- .../atap/tango/ux/TangoUxLayout.java.meta | 8 - .../com/google/atap/tango/ux/UiSettings.java | 96 - .../google/atap/tango/ux/UiSettings.java.meta | 8 - .../atap/tango/ux/UxExceptionEvent.java | 167 -- .../atap/tango/ux/UxExceptionEvent.java.meta | 8 - .../tango/ux/UxExceptionEventListener.java | 16 - .../ux/UxExceptionEventListener.java.meta | 8 - .../google/atap/tango/ux/package-info.java | 12 - .../atap/tango/ux/package-info.java.meta | 8 - .../Assets/Scenes/AreaLearning.unity | 39 + .../Assets/Scenes/MotionTracking.unity | 40 + UnityExamples/Assets/Scenes/PointCloud.unity | 39 + .../Scripts/AreaLearningFPSCounter.cs | 66 +- .../Scripts/AreaLearningGUIController.cs | 194 +- .../Scripts/AreaLearningPoseController.cs | 283 +-- .../AreaLearning/Scripts/SaveADFController.cs | 57 +- .../Scripts/TrajectoryController.cs | 50 +- .../Sample.meta => TangoExamples/Common.meta} | 4 +- .../Common/Scripts.meta} | 4 +- .../Common/Scripts/SceneSwitcher.cs | 59 + .../Common/Scripts/SceneSwitcher.cs.meta | 12 + .../Common/Textures.meta} | 4 +- .../Textures/ProjectTango_Logo.png} | Bin .../Textures/ProjectTango_Logo.png.meta} | 0 .../Scripts/ARLocationMarker.cs | 44 +- .../Scripts/ARScreen.cs | 127 +- .../Scripts/AugmentedRealityGUIController.cs | 41 +- .../Scripts/BallThrower.cs | 97 +- .../Scripts/CustomPointCloudListener.cs | 665 +++---- .../Scripts/DebugDrawing.cs | 147 +- .../Scripts/DynamicMeshCube.cs | 1648 +++++++++-------- .../Scripts/DynamicMeshManager.cs | 444 +++-- .../Scripts/MeshBuilderPoseController.cs | 166 +- .../Scripts/Polygonizer.cs | 16 - .../Scripts/TopDownFollow.cs | 49 +- .../Scripts/VolumetricHashTree.cs | 660 ++++--- .../ExperimentalMeshBuilder/Scripts/Voxel.cs | 121 +- .../Scripts/VoxelHashTree.cs | 309 ++-- .../Scripts/Controllers/BuildingController.cs | 65 +- .../Controllers/CustomPoseController.cs | 131 +- .../Controllers/DataSavingController.cs | 63 +- .../Controllers/GameCameraEffectController.cs | 100 +- .../Controllers/StartSceneCameraController.cs | 85 +- .../Scripts/Debug/DebugString.cs | 57 +- .../Scripts/GameData/BuildingManager.cs | 348 ++-- .../Scripts/GameData/EventManager.cs | 145 +- .../Scripts/GameData/FileParser.cs | 71 +- .../Scripts/GameData/StartSceneUIManager.cs | 49 +- .../Scripts/GameData/Statics.cs | 52 +- .../Scripts/GameData/TangoInitializer.cs | 79 +- .../Scripts/UI/ADFPicker.cs | 80 +- .../Scripts/UI/ADFPickerButton.cs | 97 +- .../Scripts/UI/AddBuildingPickerButton.cs | 103 +- .../Scripts/UI/BuildingPickerButton.cs | 74 +- .../Scripts/UI/CancelBuildingButton.cs | 76 +- .../Scripts/UI/LoadMapButton.cs | 59 +- .../Scripts/UI/PlaceBuildingButton.cs | 75 +- .../Scripts/UI/SaveGameButton.cs | 76 +- .../Scripts/UI/StartGameButton.cs | 71 +- .../Scripts/UI/TouchableObject.cs | 38 +- .../Scripts/UI/UIInfoPanelController.cs | 113 +- .../Scripts/Utils/ManagerSingleton.cs | 73 +- .../Scripts/CreateHeadsetGeometery.cs | 124 +- .../Scripts/CubeGenerator.cs | 79 +- .../Scripts/CustomTangoController.cs | 221 ++- .../Scripts/PopupManager.cs | 137 +- .../Scripts/StereoCameraManager.cs | 162 +- .../Scripts/MotionTrackingGUIController.cs | 168 +- .../Scripts/PointCloudFPSCounter.cs | 69 +- .../Scripts/PointCloudGUIController.cs | 182 +- .../Scripts/TangoGestureCamera.cs | 19 +- .../TangoPrefabs/Scripts/TangoPointCloud.cs | 268 ++- .../Scripts/TangoPoseController.cs | 24 +- .../TangoPrefabs/Shaders/PointCloud.shader | 4 +- UnityExamples/Assets/TangoSDK.meta | 4 +- UnityExamples/Assets/TangoSDK/Core.meta | 4 +- .../Assets/TangoSDK/Core/Prefabs.meta | 4 +- .../Core/Prefabs/Tango Manager.prefab | 4 +- .../Assets/TangoSDK/Core/Scripts.meta | 4 +- .../Assets/TangoSDK/Core/Scripts/Common.meta | 4 +- .../Core/Scripts/Common/TangoAndroidHelper.cs | 30 + .../Core/Scripts/Common/TangoTypes.cs | 2 +- .../TangoSDK/Core/Scripts/Interfaces.meta | 4 +- .../TangoSDK/Core/Scripts/Listeners.meta | 4 +- .../TangoSDK/Core/Scripts/TangoWrappers.meta | 4 +- UnityExamples/Assets/TangoSDK/Core/Tango.dat | 2 +- .../Assets/TangoSDK/Core/Tango.dat.meta | 2 +- UnityExamples/Assets/TangoSDK/Editor.meta | 4 +- UnityExamples/Assets/TangoSDK/TangoUX.meta | 4 +- .../Assets/TangoSDK/TangoUX/Scripts.meta | 4 + .../TangoSDK/TangoUX/Scripts/Common.meta | 4 + .../TangoUX/Scripts/Common/AndroidHelper.cs | 26 +- .../Scripts/Common/AndroidHelper.cs.meta | 2 + .../TangoUX/Scripts/Common/TangoUxEnums.cs | 64 +- .../Scripts/Common/TangoUxEnums.cs.meta | 2 + .../TangoUX/Scripts/Common/TangoUxTypes.cs | 53 +- .../Scripts/Common/TangoUxTypes.cs.meta | 2 + .../TangoSDK/TangoUX/Scripts/Interfaces.meta | 4 + .../TangoUX/Scripts/Interfaces/ITangoUX.cs | 6 +- .../Scripts/Interfaces/ITangoUX.cs.meta | 2 + .../TangoSDK/TangoUX/Scripts/Listeners.meta | 4 + .../Listeners/UxExceptionEventListener.cs | 107 +- .../UxExceptionEventListener.cs.meta | 2 + .../TangoSDK/TangoUX/Scripts/TangoUx.cs | 14 +- .../TangoSDK/TangoUX/Scripts/TangoUx.cs.meta | 2 + .../ProjectSettings/EditorBuildSettings.asset | 4 +- .../ProjectSettings/ProjectSettings.asset | 16 +- UnityExamples/Settings.StyleCop | 17 +- 335 files changed, 6082 insertions(+), 8644 deletions(-) delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi/ic_launcher.png delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi/ic_launcher.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-mdpi/ic_launcher.png delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-mdpi/ic_launcher.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-xhdpi/ic_launcher.png delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-xhdpi/ic_launcher.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/src/com.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/src/com/projecttango.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/src/com/projecttango/unityuxhelper.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/src/com/projecttango/unityuxhelper/TangoUnityUxHelper.java delete mode 100644 UnityExamples/Assets/Plugins/Android/UnityUxHelper/src/com/projecttango/unityuxhelper/TangoUnityUxHelper.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_dizzy.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_dizzy.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_lost.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_lost.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_system.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_system.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_background.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_background.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_err.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_err.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok_tick.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok_tick.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/splash_logo.png delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/splash_logo.png.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/.readme delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/BaseExceptionHandler.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/BaseExceptionHandler.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ConnectionLayout.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ConnectionLayout.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ConnectionLayoutProgressBar.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ConnectionLayoutProgressBar.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ConnectionLayoutTick.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ConnectionLayoutTick.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionComponent.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionComponent.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionHandler.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionHandler.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionHelper.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionHelper.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionPanelContainer.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionPanelContainer.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionStatusComponent.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/ExceptionStatusComponent.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/MotionDetectionHelper.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/MotionDetectionHelper.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/MotionTrackingExceptionHandler.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/MotionTrackingExceptionHandler.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/NoQueueExceptionHandler.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/NoQueueExceptionHandler.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/QueuedExceptionHandler.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/QueuedExceptionHandler.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/SplashLayout.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/SplashLayout.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/SystemExceptionHandler.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/SystemExceptionHandler.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoExceptionInfo.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoExceptionInfo.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUx.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUx.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java.meta delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java delete mode 100644 UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java.meta rename UnityExamples/Assets/{Google-Unity/Sample.meta => TangoExamples/Common.meta} (67%) rename UnityExamples/Assets/{Google-Unity/Sample/Scenes.meta => TangoExamples/Common/Scripts.meta} (67%) create mode 100644 UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs create mode 100644 UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs.meta rename UnityExamples/Assets/{Plugins/Android/UnityUxHelper/src.meta => TangoExamples/Common/Textures.meta} (67%) rename UnityExamples/Assets/TangoExamples/{ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png => Common/Textures/ProjectTango_Logo.png} (100%) rename UnityExamples/Assets/TangoExamples/{ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png.meta => Common/Textures/ProjectTango_Logo.png.meta} (100%) diff --git a/UnityExamples/Assets/Editor/BuildTools.cs b/UnityExamples/Assets/Editor/BuildTools.cs index 56fc9cb8..1ea00817 100644 --- a/UnityExamples/Assets/Editor/BuildTools.cs +++ b/UnityExamples/Assets/Editor/BuildTools.cs @@ -1,8 +1,19 @@ -//----------------------------------------------------------------------- -// -// +// +// // Copyright 2015 Google Inc. All Rights Reserved. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // //----------------------------------------------------------------------- using System.Collections; @@ -14,37 +25,26 @@ /// all projects. /// /// To use this from the command line, run the following command: -/// /Contents/MacOS/Unity -batchmode -projectPath -executeMethod -quit +/// [FULLPATH_UNITY.APP]/Contents/MacOS/Unity -batchmode -projectPath [FULLPATH] -executeMethod [METHOD_TO_RUN] -quit /// /// For example: /// /Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath ~/Unity/tango-examples-unity/UnityExamples/ -executeMethod BuildTools.BuildAll -quit /// -/// For more info, goto +/// For more info, goto [http://docs.unity3d.com/Manual/CommandLineArguments.html]. /// public class BuildTools { - private static BuildUtil.APKSettings areaLearningAPK = new BuildUtil.APKSettings - { - ProjectName = "Unity Area Learning", - Icon = "TangoExamples/AreaLearning/Textures/icon.png", - Scenes = new string[] { "Scenes/AreaLearning.unity" }, - BundleIdentifier = "com.projecttango.experiments.unityarealearning" - }; - - private static BuildUtil.APKSettings motionTrackingAPK = new BuildUtil.APKSettings - { - ProjectName = "Unity Motion Tracking", - Icon = "TangoExamples/MotionTracking/Textures/icon.png", - Scenes = new string[] { "Scenes/MotionTracking.unity" }, - BundleIdentifier = "com.projecttango.experiments.unitymotiontracking" - }; - - private static BuildUtil.APKSettings pointCloudAPK = new BuildUtil.APKSettings - { - ProjectName = "Unity Point Cloud", - Icon = "TangoExamples/PointCloud/Textures/icon.png", - Scenes = new string[] { "Scenes/PointCloud.unity" }, - BundleIdentifier = "com.projecttango.experiments.unitypointcloud" + private static BuildUtil.APKSettings examplesAPK = new BuildUtil.APKSettings + { + ProjectName = "Unity Examples", + Icon = "TangoExamples/Common/Textures/ProjectTango_Logo.png", + Scenes = new string[] + { + "Scenes/AreaLearning.unity", + "Scenes/MotionTracking.unity", + "Scenes/PointCloud.unity", + }, + BundleIdentifier = "com.google.projecttango.examples" }; private static BuildUtil.APKSettings augmentedRealityAPK = new BuildUtil.APKSettings @@ -66,7 +66,7 @@ public class BuildTools private static BuildUtil.APKSettings persistentStateAPK = new BuildUtil.APKSettings { ProjectName = "Unity Persistent State", - Icon = "TangoExamples/ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png", + Icon = "TangoExamples/Common/Textures/ProjectTango_Logo.png", Scenes = new string[] { "Scenes/ExperimentalPersistentState/ExperimentalPersistentState_StartScene.unity", @@ -101,9 +101,7 @@ public class BuildTools [MenuItem("Tango/Build/All", false, 1)] public static void BuildAll() { - BuildUtil.BuildAPK(areaLearningAPK); - BuildUtil.BuildAPK(motionTrackingAPK); - BuildUtil.BuildAPK(pointCloudAPK); + BuildUtil.BuildAPK(examplesAPK); BuildUtil.BuildAPK(augmentedRealityAPK); BuildUtil.BuildAPK(meshBuilderAPK); BuildUtil.BuildAPK(persistentStateAPK); @@ -133,28 +131,10 @@ public static void BuildSdkPlusPrefabsPackage() /// /// Function for UI. /// - [MenuItem("Tango/Build/Area Learning")] - public static void BuildAreaLearning() - { - BuildUtil.BuildAPK(areaLearningAPK); - } - - /// - /// Function for UI. - /// - [MenuItem("Tango/Build/Motion Tracking")] - public static void BuildMotionTracking() - { - BuildUtil.BuildAPK(motionTrackingAPK); - } - - /// - /// Function for UI. - /// - [MenuItem("Tango/Build/Point Cloud")] - public static void BuildPointCloud() + [MenuItem("Tango/Build/Examples")] + public static void BuildExamples() { - BuildUtil.BuildAPK(pointCloudAPK); + BuildUtil.BuildAPK(examplesAPK); } /// diff --git a/UnityExamples/Assets/Editor/BuildUtil.cs b/UnityExamples/Assets/Editor/BuildUtil.cs index aca924b6..3740fadd 100644 --- a/UnityExamples/Assets/Editor/BuildUtil.cs +++ b/UnityExamples/Assets/Editor/BuildUtil.cs @@ -1,8 +1,19 @@ -//----------------------------------------------------------------------- -// -// +// +// // Copyright 2015 Google Inc. All Rights Reserved. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // //----------------------------------------------------------------------- using System; @@ -61,6 +72,7 @@ public static void BuildAPK(APKSettings settings) string oldKeyaliasPass = PlayerSettings.Android.keyaliasPass; string oldProductName = PlayerSettings.productName; string oldBundleIdentifier = PlayerSettings.bundleIdentifier; + string oldAndroidSdkRoot = EditorPrefs.GetString("AndroidSdkRoot"); // make sure the product folder exists System.IO.Directory.CreateDirectory(BUILD_DIRECTORY_W_SLASH); @@ -84,6 +96,13 @@ public static void BuildAPK(APKSettings settings) PlayerSettings.productName = settings.ProjectName; PlayerSettings.bundleIdentifier = settings.BundleIdentifier; + // Unity won't remember where the Android SDK was when built on Jenkins + string sdkRoot = Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT"); + if (sdkRoot != String.Empty) + { + EditorPrefs.SetString("AndroidSdkRoot", sdkRoot); + } + // and finally... build it! string[] scenesUnityPath = new string[settings.Scenes.Length]; for (int it = 0; it != settings.Scenes.Length; ++it) @@ -101,6 +120,7 @@ public static void BuildAPK(APKSettings settings) PlayerSettings.Android.keyaliasPass = oldKeyaliasPass; PlayerSettings.productName = oldProductName; PlayerSettings.bundleIdentifier = oldBundleIdentifier; + EditorPrefs.SetString("AndroidSdkRoot", oldAndroidSdkRoot); } /// diff --git a/UnityExamples/Assets/Google-Unity.meta b/UnityExamples/Assets/Google-Unity.meta index b9324dfb..11459467 100644 --- a/UnityExamples/Assets/Google-Unity.meta +++ b/UnityExamples/Assets/Google-Unity.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: e57175b76bb6f4a3ca1b2b16d3a389fe folderAsset: yes -timeCreated: 1435687661 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Google-Unity/Scripts.meta b/UnityExamples/Assets/Google-Unity/Scripts.meta index dc890f93..00a49d33 100644 --- a/UnityExamples/Assets/Google-Unity/Scripts.meta +++ b/UnityExamples/Assets/Google-Unity/Scripts.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: ec3f31cb3fcac424ea1629761b78f663 folderAsset: yes -timeCreated: 1435687661 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins.meta b/UnityExamples/Assets/Plugins.meta index 9c4aff8b..5db072a3 100644 --- a/UnityExamples/Assets/Plugins.meta +++ b/UnityExamples/Assets/Plugins.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 1a6d8102e5df548349766721814c6590 folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android.meta b/UnityExamples/Assets/Plugins/Android.meta index bf0dc2d2..c375bc17 100644 --- a/UnityExamples/Assets/Plugins/Android.meta +++ b/UnityExamples/Assets/Plugins/Android.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 1771febdbd7034e6a8db81c274b8b470 folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/AndroidManifest.xml.meta index 5339195c..65d4bfb5 100644 --- a/UnityExamples/Assets/Plugins/Android/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/AndroidManifest.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b9ba921bb485f493f83bbfc2aa20c188 +guid: 1a9553f0df4714d42874fd7e7b357917 TextScriptImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper.meta index 150f657c..b37687e0 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: bbfa75534417f43268e9ae179792ed9f folderAsset: yes -timeCreated: 1438116028 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/AndroidManifest.xml.meta index 7479cf9e..a855f550 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/AndroidManifest.xml.meta @@ -1,8 +1,6 @@ fileFormatVersion: 2 -guid: 6d038c32015e847459ed04f94a18e768 -timeCreated: 1437161551 -licenseType: Pro -TextScriptImporter: +guid: ac4fbd86a0a8349738a155973876ae9a +DefaultImporter: userData: assetBundleName: assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin.meta index 2fd75c6d..fd577744 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 25c2388b544974aecb4c6922931094ed folderAsset: yes -timeCreated: 1437161548 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/AndroidManifest.xml.meta index c1c0d0c5..fe0c1f0f 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/AndroidManifest.xml.meta @@ -1,8 +1,6 @@ fileFormatVersion: 2 -guid: dd9a6829f42974163a9db46339881dbe -timeCreated: 1437161551 -licenseType: Pro -TextScriptImporter: +guid: 45f54d4d0b4324d76a6aa21dbbabb26b +DefaultImporter: userData: assetBundleName: assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt index 62fbf7f9..74e7a112 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt @@ -1,90 +1,17 @@ -int color gray_dark 0x7f040000 -int color tango_blue 0x7f040004 -int color tango_green 0x7f040003 -int color tango_yellow 0x7f040005 -int color text_exception_action_required 0x7f040002 -int color text_exception_description 0x7f040001 -int dimen connection_progress_bar_sub_margin 0x7f050000 -int dimen exception_component_height 0x7f050001 -int dimen exception_status_component_size 0x7f050002 -int dimen shake_ok_tick_height 0x7f050004 -int dimen shake_ok_tick_translation_x 0x7f050005 -int dimen shake_ok_tick_translation_y 0x7f050006 -int dimen shake_ok_tick_width 0x7f050003 -int drawable exception_container_shadow 0x7f020000 -int drawable ic_exception_i_am_dizzy 0x7f020001 -int drawable ic_exception_i_am_lost 0x7f020002 -int drawable ic_exception_i_cant_see 0x7f020003 -int drawable ic_exception_system 0x7f020004 -int drawable ic_launcher 0x7f020005 -int drawable ic_shake_background 0x7f020006 -int drawable ic_shake_err 0x7f020007 -int drawable ic_shake_ok 0x7f020008 -int drawable ic_shake_ok_tick 0x7f020009 -int drawable splash_logo 0x7f02000a -int id connection_layout 0x7f08000a -int id connection_text 0x7f080007 -int id exception_container 0x7f080009 -int id exception_description 0x7f080002 -int id exception_icon 0x7f080000 -int id exception_status 0x7f080003 -int id exception_title 0x7f080001 -int id group_shake_icon 0x7f080004 -int id image_shake_err 0x7f080006 -int id image_shake_ok_tick 0x7f080005 -int id layout_exceptions 0x7f08000b -int id splash_logo 0x7f080008 -int layout exception_component 0x7f030000 -int layout layout_connection 0x7f030001 -int layout layout_splash 0x7f030002 -int layout layout_tango_ux 0x7f030003 -int layout tango_ux_exceptions 0x7f030004 -int string action_required 0x7f060015 -int string connection_layout_description 0x7f060017 -int string connection_layout_message 0x7f060016 -int string device_not_responding_description 0x7f06000c -int string device_not_responding_title 0x7f06000b -int string lying_on_surface_description 0x7f060010 -int string lying_on_surface_title 0x7f06000f -int string motion_track_description 0x7f060012 -int string motion_track_title 0x7f060011 -int string moving_too_fast_description 0x7f060002 -int string moving_too_fast_title 0x7f060001 -int string not_enough_light_description 0x7f060008 -int string not_enough_light_title 0x7f060007 -int string project_tango 0x7f060000 -int string run_time_mismatch_description 0x7f060014 -int string run_time_mismatch_title 0x7f060013 -int string service_updated_description 0x7f06000e -int string service_updated_title 0x7f06000d -int string space_not_recognized_description 0x7f060006 -int string space_not_recognized_title 0x7f060005 -int string too_much_light_description 0x7f06000a -int string too_much_light_title 0x7f060009 -int string unable_to_detect_surface_description 0x7f060004 -int string unable_to_detect_surface_title 0x7f060003 -int string ux_exception_1 0x7f060019 -int string ux_exception_10 0x7f060022 -int string ux_exception_11 0x7f060023 -int string ux_exception_2 0x7f06001a -int string ux_exception_3 0x7f06001b -int string ux_exception_4 0x7f06001c -int string ux_exception_5 0x7f06001d -int string ux_exception_6 0x7f06001e -int string ux_exception_7 0x7f06001f -int string ux_exception_8 0x7f060020 -int string ux_exception_9 0x7f060021 -int string ux_exception_listener 0x7f060018 -int style AppBaseTheme 0x7f07000b -int style AppTheme 0x7f07000c -int style ConnectionLayoutSubtext 0x7f070003 -int style ConnectionLayoutText 0x7f070002 -int style DownloadProgressText 0x7f070004 -int style ExceptionActionRequired 0x7f070007 -int style ExceptionDescription 0x7f070006 -int style ExceptionTitle 0x7f070005 -int style Text20GrayDarkLight 0x7f070001 -int style Text40GrayDarkThin 0x7f070000 -int style TextListContentItem 0x7f07000a -int style TextListTitle 0x7f070008 -int style TextListTitleItem 0x7f070009 +int drawable ic_launcher 0x7f020000 +int id layout_exceptions 0x7f060000 +int layout tango_ux_exceptions 0x7f030000 +int string ux_exception_1 0x7f040001 +int string ux_exception_10 0x7f04000a +int string ux_exception_11 0x7f04000b +int string ux_exception_2 0x7f040002 +int string ux_exception_3 0x7f040003 +int string ux_exception_4 0x7f040004 +int string ux_exception_5 0x7f040005 +int string ux_exception_6 0x7f040006 +int string ux_exception_7 0x7f040007 +int string ux_exception_8 0x7f040008 +int string ux_exception_9 0x7f040009 +int string ux_exception_listener 0x7f040000 +int style AppBaseTheme 0x7f050000 +int style AppTheme 0x7f050001 diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt.meta index 91f9d58d..4eb52683 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/R.txt.meta @@ -1,8 +1,6 @@ fileFormatVersion: 2 -guid: 41d9667eeead04d79903d033562a6dc9 -timeCreated: 1437161551 -licenseType: Pro -TextScriptImporter: +guid: 6b33c66fecfaa4b76baa80de9d867316 +DefaultImporter: userData: assetBundleName: assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res.meta index 48844ddd..885615e8 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: b3b70784b3e1341c7ad1c1ad0fe4e40e folderAsset: yes -timeCreated: 1437161548 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch.meta index 608166e5..644d9de2 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: a5ad7f20cd36c43e88689d3a82576490 folderAsset: yes -timeCreated: 1437161548 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi.meta b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi.meta index a4b5d811..e225ec96 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi.meta +++ b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: e65b2b7405b074e1fb512f25dbe48aef folderAsset: yes -timeCreated: 1437161548 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi/ic_launcher.png b/UnityExamples/Assets/Plugins/Android/UnityUxHelper/bin/res/crunch/drawable-hdpi/ic_launcher.png deleted file mode 100644 index bcfa0581febfc292711358f156e856315e800cbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9193 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�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 delta 1434 zcmca(u)%;Yz?+#xgn@&DgTblygWE(tHx>{**@4w*vYi-v{noJRVBv6)|FJ@`9NjG) zQLR~86LXk$DY520UhL3(N$=7p4zAE$H)9Sz+BEx}a?80b@=M|u)V~f%xi!=8e^&ah ziB^8gpXXg`YF6&|GoE~>`n>J)Kj&W0n{5C8-_LM{>l+jowkF;vxOR2c>otXkznAWQ zwW2Zi*KEh+snMqIR()=&-=^Tf-CM1wX{@4nZbHoE*SoSVZnX*)yCl?SyrgW!=EmID zsolmh-@|?Ni>Dsg;=EW?qUzPIsfK$qkDJR@-@Dqod|9k++b(UMoKA+kSt`Y|AMPq* zX;~W6sc82wq(WN4D%B%Hbhn;lu7`@iVNc1oFVZ?Ro3;iU=hoRr=ogpotACl`Rm^i& z>*YGlbApC?d(tE<_qfhf{ABfvt&GXGBHl^=@P&m_PgwMG^Q_&KSfJnY?^9sYWbV{e zeZgBRCP(j;mUG%>c-Z{)7BQh847EafMk#!U^p%^vdDK_mk>9MnE;-Cg?f!)?zVD3Y z1QpG?w`5hR(&|U+F0|5RAXi4O}F7fLdtC_ZuoydY%U*R%GHG?i`p>>z<$~{l1 zY3Y}IqP|S_P=CH(VCsCeFWXt14*9nIiw(S1yLXw}HWKOWekb;ox>NA;snf5R_Y z|J`mDcGDLo&Wf6M{I9u#O=X>U?Mzds!jcY!*hN3jBS3zziMA}w=4D4vg+38 zj~x$VE|$ug>qhNe8U1X#NPCIOtOHynobkbZam$T9_YrguIO+k8H8s(xRyKu9uYzpR=qx zsP0>6vDus{yuM|wNp;t@L`%7wmS_Klw%`<+MKY-LjWVOq0LZwoOY3>IqbsDdarmU%{3O+hvXJ zmR)!!HaB@o*)#UI2QK@*vrhUs-NTk!(*I(E7*JG`fVR80wd(Ob?3W?|DC6vu0LUK z=9f!zPA=kaHu>z9vA5A%!ri{!_Px%ujMz3O)mhG>%mtm=2U2U;O}|*({i5?}m#m!D zgD2mO0_RO|;STGZ=k!N(laO2d!@ibB@h>KLoa0H}*|vPkG0iS9nOm_-Y6VT5go@89 zZ`qvE-fp#4>Cl&->;c~F9DcmQ-JvWD3`$%K45(!h0}yO>Vg1SkFOfFabJRk3o4Cu7 zg!l4VLU@~h@vmZqC|@D!#0x6P;O0;ME*d2d5^+=e`gIx;1A`(f1A`^V5;$O+Tp;EF z(Y{Aaiiw$Ha-o>Xyg`{Sz?+#xgnRJXv7u%_~?!7~vddHghf*XR@P!J)GSx P5DaHO6v%?Jg9PIM2pSWg delta 108 zcmdm>yg`{Sz?+#xgn@&DgW-JOX}5`d&g@X;#t2Uq7<=;ymJmibhndZs3&xr3C}0m~ Rw+jTr*$)M>;Orp5H~>~kA9nx% diff --git a/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/bin/google-unity-wrapper.jar.meta b/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/bin/google-unity-wrapper.jar.meta index bd72005d..dd718a59 100644 --- a/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/bin/google-unity-wrapper.jar.meta +++ b/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/bin/google-unity-wrapper.jar.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 730a36f1f79d448cab286254a700488c +guid: 72cb5f72a22ad44b7abc7cdfcd99e7db DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/project.properties.meta b/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/project.properties.meta index c00c378d..8870087a 100644 --- a/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/project.properties.meta +++ b/UnityExamples/Assets/Plugins/Android/google-unity-wrapper/project.properties.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d8d600294a94c42a4a7afd4ee8a44454 +guid: dffbba6f698ff41098836a13ae2bfc48 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib.meta index 968c8591..8af4b9c1 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 00eaa1aad644d429c9958627e61314a8 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/AndroidManifest.xml.meta index 27da3b27..13deec31 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/AndroidManifest.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 630441a8bd1904264b7a51c329369ee9 +guid: cb84f03aa70c343b49f514fe37501c0c DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin.meta index 26786238..449e0ee4 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 5abcd22b5d1924911a6fae133ad45259 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/AndroidManifest.xml.meta index 72afa539..23cc11a1 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/AndroidManifest.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c00d4a54c366b4ded90ded8ad0f698a8 +guid: f6405d6bf464d4d0a9c4f06760e1d31c DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes.meta index d395c0ba..000dd9b7 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 9f48ceeaedcdd4ed6a129398670afb0a folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com.meta index 55892296..4fc1a0c7 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 182695de821454fd6921c64666cf1af3 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google.meta index 04bd1b96..a8f7da95 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 15246131f5b974cf2b9d14d2ec46a8da folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap.meta index 606d9aff..386ebc3a 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: d197c0d282e174063b125216c6a22404 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango.meta index 228c609d..c77ac854 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 5bef54d15b8424c17b3bb533d11b41b1 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/TangoJNINative.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/TangoJNINative.class.meta index 7bfd54d2..b6f3f9e0 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/TangoJNINative.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/TangoJNINative.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ed613b4fa34214bcb8a98f997c0cbb5e +guid: 947aa4533803e4b9db3782537b870aff DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/package.html.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/package.html.meta index 5d87967e..1d02f2f3 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/package.html.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tango/package.html.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 334b6391148ce42f5a9b5eb59f6bdff9 +guid: 1ca69a1c9dfd64162aca023165787fb8 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib.meta index f683b67f..d3d5b560 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: afcff3dda4cde4f24868b9249d0e0afe folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib/BuildConfig.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib/BuildConfig.class.meta index 75d73178..6f282600 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib/BuildConfig.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangohelperlib/BuildConfig.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2d234469daff747fcaedf6366c01604c +guid: 54be3d0a8dd104df8ad811e07ea888d3 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice.meta index a6de61f3..97861502 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 42dc9c9efcbc3474887eb565bc4d4ba7 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango$OnTangoUpdateListener.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango$OnTangoUpdateListener.class.meta index 6c9b3f98..3e1fcf60 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango$OnTangoUpdateListener.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango$OnTangoUpdateListener.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 92ad650c3429540a8bf92ecddeac91a1 +guid: 0cd1b85626cab46fda2b2799059bee65 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango.class.meta index ccf95d97..1698e1e9 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/Tango.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f5989a4c6ac1b4476ac6cdcb3ba4c63b +guid: afbe0ccc87ff24f87be023f04490ca1c DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData$1.class.meta index ffa77b97..158b26f5 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2e10e5cf8ee27428fa5d989e496b0ced +guid: 940e3d2ed5bf042cd98eb0bda80e3add DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData.class.meta index 9e66ee93..002d83b6 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoAreaDescriptionMetaData.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1697b385505bf4274ac2916c4276cb02 +guid: 64f3d5c2878f94cbfa228735b2d7f10f DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics$1.class.meta index 495fc0ff..b1427ef8 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 948e4849c706144c0a5c702bc9bc4b6d +guid: afa21f46399eb43b0925736f600dcae7 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics.class.meta index 9421ef05..2ea0913b 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraIntrinsics.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 97044f8512fea4f65867caa6288a2a1a +guid: 362eb4aefb05b432e8eb383ae8d8f6e7 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview$MainRenderer.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview$MainRenderer.class.meta index 1993c45a..000b6b2c 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview$MainRenderer.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview$MainRenderer.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cccc6fea7a5d940578c13f53db0f4a53 +guid: b576b0816aed14803a1040a40d8e6c4a DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview.class.meta index 75b64697..c37303b8 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCameraPreview.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 35c71077994344b2bb4cca0de2139d31 +guid: 8658589d7ffff486e8b8b7ee6e2af7ff DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig$1.class.meta index ade02d9d..de5288be 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 904dd9dba07b64d158e5b22e182907cb +guid: cf2b99fb7c70b402487a118632f6fe90 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig.class.meta index 40e4df85..1b761de5 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoConfig.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: eae574b8125ec4d5694d2709339164ec +guid: cf86974f4c8364723b7610d634dd7faa DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair$1.class.meta index 8f7e2f7b..fdeeeb3f 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9527a2a9342b645a292ec6b2b3ad5a56 +guid: 2bb637587920e4c9f87bfa63bbb069c2 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair.class.meta index d597814d..db71d4f1 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoCoordinateFramePair.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: af740a5c074034b79b2bb83ff9b4dbd1 +guid: 12d2c64ee9486437ba58d3e0869bfccf DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoErrorException.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoErrorException.class.meta index 9ac52c6b..8f997d2a 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoErrorException.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoErrorException.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b6823e230464144a78a0fd9a68c84185 +guid: 873af0425e86b46ae808f25d78d78e02 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent$1.class.meta index 8075cbe9..6dcf8f5c 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 05f0df76962b940808a232122f40340d +guid: 6fa82b1f224034a03afa70a4fdf63064 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent.class.meta index 7edd03b6..21ab978e 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoEvent.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a9e09637d7aa64fb69c63bae3fb722bf +guid: b53b6b395603b42c0861cc295c6be9e2 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoException.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoException.class.meta index b49bb06f..999784ab 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoException.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoException.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b83f5704f88bd4a1693b05db40c07316 +guid: bb43cf37037dd4a70981e5ec8685f683 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoInvalidException.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoInvalidException.class.meta index 10870d5a..1a74ed92 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoInvalidException.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoInvalidException.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4c1cb992fdd4b4f8b80bfee24b09a3c3 +guid: 42fb15e2c5f2a4b35bd640af3b9a9308 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoOutOfDateException.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoOutOfDateException.class.meta index 04cc7993..25a2536f 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoOutOfDateException.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoOutOfDateException.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 05c4ff54d82fd465dbb776b49c4ebc98 +guid: 633b82e8c853647508bf5e2b7c0fbdba DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData$1.class.meta index edcac900..724cb140 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d26926f0a8ab949b28803ecfe2d1f4b6 +guid: 3875e372ffa384775b470d0ab5d50192 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData.class.meta index aa12d2e0..03975dbf 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoPoseData.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b50e3cb7151f945c4a9cb9eee96d2e5e +guid: a8984e43535404e4392cbf275ba79968 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoTextureCameraPreview.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoTextureCameraPreview.class.meta index 724cb0e4..fc38b6e0 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoTextureCameraPreview.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoTextureCameraPreview.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 18f99e3bb5baf440fb18fa64bc03f444 +guid: 3c2b1408cbf1242fca04e869443e9497 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData$1.class.meta index 5cb146eb..1fcf0a36 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 40f4b7bff73e442ca8b79bc365b5c597 +guid: 5a893dd248e1c434cbda0c11df515c27 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData.class.meta index ff636c25..c5d9f6d7 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TangoXyzIjData.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fd81e2eb952ac40fd93cf3d28fc6c539 +guid: 6d589de34b10c49b3bdb572321f511c3 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TextureRenderer.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TextureRenderer.class.meta index b6a974bd..1292a244 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TextureRenderer.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/TextureRenderer.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2740192408c8340758cd8a48663ee02f +guid: 83e3937b5fff8473fb4c107c00bc8b27 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental.meta index c56f3e43..f4b0d2c6 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 80cb9c621c08c41d1bf457684e061a41 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesh.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesh.class.meta index 503d4736..65c32c07 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesh.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesh.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 38f046253cbca4638b5e697db7e9a443 +guid: 04f871f536d814736b3d05943dfdee0c DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector$1.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector$1.class.meta index df66093b..b41d1b70 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector$1.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector$1.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d0954d16a81d24ecf8aca92be071fc31 +guid: f6c9e40a53d1e44eca2a1e25bc456b76 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector.class.meta index 2703c281..2266beff 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMeshVector.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2b263d58a215d42f4809d50b897ed279 +guid: 6373cb540f64249aab352fc74e1229ab DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher$OnTangoMeshVectorAvailableListener.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher$OnTangoMeshVectorAvailableListener.class.meta index 54bc5e08..fb363121 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher$OnTangoMeshVectorAvailableListener.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher$OnTangoMeshVectorAvailableListener.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: dd0e6a2bb538247a1bb4ac1268b0a82b +guid: 3a74a775fe3cb4d849b498ff025956de DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher.class.meta index 6847a0a4..11ca5a58 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/TangoMesher.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7851d17e1a27a438e945f0b3647e7401 +guid: 88f68e481d26441d2bbd600c83a2c5c2 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/package-info.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/package-info.class.meta index 32429397..c7ceacec 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/package-info.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/experimental/package-info.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1f9212106e46a47beaefb55f99ff7b4a +guid: ef724de56c3e240d9910e640698739ae DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/package-info.class.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/package-info.class.meta index 1f068bbc..7d105666 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/package-info.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/classes/com/google/atap/tangoservice/package-info.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8c3b7de040fdf4644b51ef7babadee3f +guid: 3f91df5512ac8479fa1047d7367e5eb3 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/tango-java-lib.jar b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/tango-java-lib.jar index 9f40ef7dbc4ef56b285576ef30fb9cd90af2456d..7e5bedc8ee470d23739e4ad09abab4046f6f6560 100644 GIT binary patch delta 909 zcmbPogK5eQCcXe~W)=|!4j|-DV|Jg&=gbaeZj6}73}bKpz?{Yi=ftv_3Bfp%`FnLI z2P|RTd`3K-2`;#yA0n6|)yf7Jw2d~J+`mv_vy-AHLgkA{kf6ZkE6TT6U@A9n)iCCP zbKaY%u);W#`Qwcy8!YDA9A#w(H)HdBo23Zl-ky^XGEcl)5Prz_w}AU$vi&@W3m*iy zBb4g}XCbUAC@`9QYbpQc2N8^LZJS?2`XM;B(XMdL-k_2bhEs2G*A1w)k zv+b9Lz}d5wM!?xWmm=H{zYO8FRCNjg=n?Eq8F~T{qtY$(m&Sd^x z-N^w;y=18@&!3AxjjVAXml-TT~=!sDIA`&Dhu=$GeEf$!{&095$ zdElJ)CMv8j&Sd_0qsaz~`8G#c*}=`&Jl|$1Lb z!rdM=S9kJ(kW+=dI+59565uv=G;1xW$HYb*c3&Zqo-rt1?v(5ayvk-bV^sj(h zu{nNbEW$-kymdE!m=zCKIyr3aBbb3e|DT1kh3DJD*^%=D;p~m`Q{imc1^#e$@q!FE z`_Y0lINN_=BAmT_VLY5IyC@UR?p+iEXMb1}4rlu<4u!K6MVBPO*>y`|;p|6C z!r*NCr6F+ktfdif_RpmVH^eVPxb66|NVppHDJwzh52&X9ui6n7MuhLNEWy h1h|^Am54BTx)Kp4L91HfYVNH<_{DuS!mf?0lL3YEK&Joz diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/tango-java-lib.jar.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/tango-java-lib.jar.meta index f26f492f..68f9a27d 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/tango-java-lib.jar.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/bin/tango-java-lib.jar.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9afa394fa67af423ba978f97b6d52434 +guid: 2d700e2042a9b48bb9bd5fc8798da3b3 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-java-lib/project.properties.meta b/UnityExamples/Assets/Plugins/Android/tango-java-lib/project.properties.meta index a9e71955..95f5c8bd 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-java-lib/project.properties.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-java-lib/project.properties.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2c520257de3ee405592a6dc2adc45163 +guid: 3ed9b2c7c4ee34f11996f58442b88a17 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper.meta index ff7a03e0..d61f9b28 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: c0a826487b8304d3288512aff8443656 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/AndroidManifest.xml.meta index 1d85adae..28b82877 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/AndroidManifest.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 57076df8fe86d423982a942bf02f7bb7 +guid: a2a85f97152864975a0bc08b4ea55310 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin.meta index 63c628ed..6bd45545 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 721c052a60a1a430685b336ac7c0e42c folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/AndroidManifest.xml.meta index 976dcbd6..b7920f5d 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/AndroidManifest.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 130bef8d7dc7946e292c5591c8f4dcfe +guid: 89e92ee1aedac4d7a93e546bb2834fdc DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes.meta index e24d9aec..d2eb242b 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: fff2a47d7b2134cb8a0b88b47449a730 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com.meta index 492dbbcd..adcc220d 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: eace03ad54b694e10b9708ddb0eb4179 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango.meta index 45fce86b..7604e233 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 199d8b96150bb4600a7b0ec8e3064346 folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity.meta index 3975cae8..9e864f2c 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: d33fb341feda1484ea48e92c5118223e folderAsset: yes -timeCreated: 1438115548 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/BuildConfig.class.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/BuildConfig.class.meta index a6441960..1060a200 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/BuildConfig.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/BuildConfig.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 754946ebd3a9f451996e394a6219df81 +guid: 8792f51eba32349c99c7d1b5d32a98ba DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/TangoUnityHelper.class b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/TangoUnityHelper.class index 817dd711253bbbea0fe098211d1d4e41b414b2b5..55dd5fe9bb357e33e9633993bc2a73aea8b7a942 100644 GIT binary patch literal 3228 zcmbVOS#J|p6#lN0FgO_}BtRhSO9IYnpimYA1rnA(0)Z?vKq(XZ#vX8H%*;3;bZ_ZO z_e!lQwNf7{At6*11c4T*l`6HB`qDSvD)p^zmHGop`^}6UFMt$bX?*Y8bI*70Ip;g) z%y0L<{{g@Te4-#Aur_9nMbegeR>mAhGZJPbW9ZIgWWb#dy3+$Pm6n!*a)CK#wQ((y zq9}4?#MKZ`#`-i%8l0`^aiJ2XnMlbj$bRp|L)jg3^l_p^1!is6iMvyvIXp9!<{^Rd zPBShmQHClN3RHozaPv?Q0@W%iFiW7OM>pi*%-D#u2DFis6sYSlV_IrRvvl`8yIAfd zb(=?fC(poc-gmBVQ;``04R+F;7_c5d(8AzyNyvZ zs$hY@))~g-LH$b9qrr93B7rvF!!xn7d8iUguuQ>HfyS9cQpIwtASV*iIj$RVbD~!> zw1l(-meG98h+C!}kBsYbB2pxeR$&zy6|5Fm^ypnGny^Nomgrq_RLi8CF5OP2v`K-5 zrSMrvv=U*oC}YGkH1;P5RMa0p3i70X7&7V0iIu>qRl59Mcm?dR4UwGE*S>cuw}xn$(HsC|p0y94|j|1m*>D z=N*uwye6IlDm+&6vZrdVe=+QO7sxVJ=Zw?=cVa zeayfq>Q(T_=v~wg6L(=x%T0u)u=qQy6zFZ6!rGm8(LQ_|k!|H|4dqik961w%=diz=fX+x39Z_gLQpVIQF@x zncYYLZu}yz`LwriIgjl_T`YtuIN9HRDzAUi(?3+W{oyD3nyd1f{#9!8C%aIs-_qk1Cy8@l#7JJTH;!H+nKpV)DJC(=E(mp^bEe_|Mav48wcLz7_Qwm@$9jET{B9Pc3vE&VS0-gZGRLo{B=jhCwIUGMKlz#mE@(ozzfhMP@n|-VPajC4# zFFVeMiqL#;Ld#{`)SVT#%6T8n1@qeu3tJ;pne>@r+Prm|0?zteA~HXnD4rwM)D@#y zcc=fNvy*n)gYvR7HUmvwj3jX}TD-EEq6ceSc0ZVa-g&s$kWRB8QD5RnC;X)H_3-Q9Md!-HTsyBv4+!##gG_m9Y~h=7(GyGV_^Q zEBQom$b3Ud47v7b;XAfFM>ei&QX*c$e$uYV#Y|Apd@JWU!O7+>0}d2 k+?KO~Q_dak%6$4vJeWWKO~wt&5H2WWR&CnKj@@NlK=n! diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/TangoUnityHelper.class.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/TangoUnityHelper.class.meta index 9f2723ae..5abe40b5 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/TangoUnityHelper.class.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/classes/com/projecttango/unity/TangoUnityHelper.class.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ba49fa1ba012249b0b9047559e3026c5 +guid: 5d03879fd912642328453e3fa5f6d691 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/tango-unity-helper.jar b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/tango-unity-helper.jar index ed8061bdd3100fb26de21749a2eb38a78e206d10..4c68e04df792301f683700ff210ff29985abb9f4 100644 GIT binary patch delta 2220 zcmZ{mX*3iJ7l3CmuU(cQgb+h^Mk1k*ea{$ckt~y)v4#ngWo)lK2CpTl>|yL%mh4NC zb?m#|=@l^y`Rd1azRr8jckiEj&pqefANR-e6w!QQV=~bPQ$YbVKl73^SUZJD<5%;m z1pF3iX$xR6j1a;Tg$_3JLOY;QUY@$1&R$ZE?hbx_iDvV9AXBK_ysRON`~3(So{jppLOnsF{=}ZzYFiGQ zhA?8(pS=BrG{j}3eu09^-{Z$6$0B%|{9M#Vg2|plqefJ`6z?Vyo3{HNQO_r^Xb#Q> z2{=CDdLz%UZtyZigmcQ;7-I#m!D6+9*>r`1wvyHc@ZJkq;mAWfT~TzpZSUAJtY9_}f|G+Wkn z5!vNM7>%v-;m?}X#wmJ5vnRo7IUbz>dQbNm%D&%xyw}G7;l)+uCOhOg!gia6zB~0% zX6&7PsVlo-1VLf|G|&=4sw(|bliCh6;nk<6;biFOehdTvazOyVzdmQFf+?|>_ktog zFY*HBQCYyj3X`VS(4%zRKcp}RR8y4A8Y8rV+RijbqBbD$KwXn0lS`DunROL|ui^CE&1;zORAP=J zv(|m<-0W`E7WV#wb%|(HXpcAiG}eix+)zo0IJjGRedU{T&sDg}TO&z$a9yCCL!lvv zaq$H_+sA*t7L8fzKW>H<7f@a~(l2n>5YGCRJCa3E?eUQ(FGHhq9Ya96v#g>7lH;bqD z>y-5{uQHGmF^*r#D@pEh6O#IvqeiZO>?Wmp++^-7l`;(Z!c>-OW(}egEBT*J%|cnr z8n0+TU2>&%I9i-EByL=gaX0^BHX$nci!fhYy*Jjm>B4H;5flQk7}?gpqP5sxi*Ms+ z!)NMIjZFX_j;V|nUmiN|@HIF-We8k2Y~{beAe$_h5C^mnA)?|{7VMn2n+eV7y6Nr8W!VU~i|6LOY(c3C z`BGd`ZZ3j^&Vn@hiU*Cg5=B-m2g8T4BrfZs^^l}o)-oKDH9uQS&N@SQdL2mUUvx2;ao_u`wKVk;Sb%LpuTEMkxBD>~#xb^O^uWttJou-(NtN$jr16Zc+)VBqRfefl6AIt?M*ckWgFhC%F~){+DX zmrOk!-)^wU8#qpH%}9<Jqr&ld+D|+#0=U8jBuq~JB z<_eW(pN#f8O$-7^aaaNHjJC%3DCe&UJ>{Zp?UQL6m2Z!@7DTVxI->iX&x{N}h4yoy zS&EURYP3ZIiR%)Yv;Y`^qSCptBompoH%5TE&AOg(O5 zGhu0CYGeAt>=VsY4B`aVt4a1~i9H*io1o`(%j*MAdaFiFvvEwC@6aWYa2msJg%SMq7Lk9>50MJp(Mw2N5J%5cz~)e^o(bKsUy!_zFW5NYD=hiNF%|Q`g;$;?~yNZV5lef4~k39R>GhgzG z&4q*r!{Dh_*VGDaseiAEo(F?eJU9)X&mKav9f(Dja5_2BK9U1dTGW5AtbCY3I3Azw=5sHK*x(v-M3Ck#{ zCU@0iVaP}!&418iYr>&RSh!L`hY!(Zkd?5)knE;RWT?1Hw_fJ%PBW#ixnou8TrkWl zZTeQe)eaDaTg3wj_ZepY1C{X*kLWZXYFtny)Rlnrcfs=oSGoeVb(g3nikidKotkhg zuP_t#WoaCp*?z?b{HalD!eAH*Xrz+ReI|yfe*}qB)qm;l_cYsYAPLW?p07bO#15^R z(D|<6wc1!`FJ(P-n4_i*(-(*#k diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/tango-unity-helper.jar.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/tango-unity-helper.jar.meta index 5b066fbd..c75a0584 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/tango-unity-helper.jar.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/bin/tango-unity-helper.jar.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 718cb2d7b9c9f427993860e267a7ba69 +guid: 9ed3696de034141f1839323557386172 DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/project.properties.meta b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/project.properties.meta index 4fff1962..6102473f 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-unity-helper/project.properties.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-unity-helper/project.properties.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f70bea2200ff4405d8eac91a9b05bbb3 +guid: 74644a775479a4a8b88cecef223564bc DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library.meta index 699575ee..3f67f460 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 9cbaeed14f5ba4a128a3178cee73342c folderAsset: yes -timeCreated: 1438116028 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/AndroidManifest.xml.meta index fbe81e52..b29e7200 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/AndroidManifest.xml.meta @@ -1,8 +1,6 @@ fileFormatVersion: 2 -guid: 4a1d94127b17646fd986e9b6fd79de52 -timeCreated: 1437161551 -licenseType: Pro -TextScriptImporter: +guid: efc607bf81c9c49d4b8216d382fef7e9 +DefaultImporter: userData: assetBundleName: assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin.meta index d90a5212..5bf03938 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 04399f879535b4594ba031c4e7956d1b folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml index bfa61674..3f07b937 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml @@ -20,7 +20,7 @@ android:versionName="0" > \ No newline at end of file diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml.meta index 48920136..81f910bf 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/AndroidManifest.xml.meta @@ -1,8 +1,6 @@ fileFormatVersion: 2 -guid: cda73baa457d0438d881d3168a1a13a2 -timeCreated: 1437161551 -licenseType: Pro -TextScriptImporter: +guid: 221169f9fed3849428ad856d63b38c3e +DefaultImporter: userData: assetBundleName: assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt index a2f5a873..f0f2f10b 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt @@ -1,16 +1,16 @@ int color gray_dark 0x7f040000 -int color tango_blue 0x7f040004 -int color tango_green 0x7f040003 -int color tango_yellow 0x7f040005 -int color text_exception_action_required 0x7f040002 -int color text_exception_description 0x7f040001 +int color tango_blue 0x7f040001 +int color tango_green 0x7f040002 +int color tango_yellow 0x7f040003 +int color text_exception_action_required 0x7f040004 +int color text_exception_description 0x7f040005 int dimen connection_progress_bar_sub_margin 0x7f050000 int dimen exception_component_height 0x7f050001 int dimen exception_status_component_size 0x7f050002 -int dimen shake_ok_tick_height 0x7f050004 -int dimen shake_ok_tick_translation_x 0x7f050005 -int dimen shake_ok_tick_translation_y 0x7f050006 -int dimen shake_ok_tick_width 0x7f050003 +int dimen shake_ok_tick_height 0x7f050003 +int dimen shake_ok_tick_translation_x 0x7f050004 +int dimen shake_ok_tick_translation_y 0x7f050005 +int dimen shake_ok_tick_width 0x7f050006 int drawable exception_container_shadow 0x7f020000 int drawable ic_exception_i_am_dizzy 0x7f020001 int drawable ic_exception_i_am_lost 0x7f020002 @@ -36,38 +36,38 @@ int layout exception_component 0x7f030000 int layout layout_connection 0x7f030001 int layout layout_splash 0x7f030002 int layout layout_tango_ux 0x7f030003 -int string action_required 0x7f060015 -int string connection_layout_description 0x7f060017 -int string connection_layout_message 0x7f060016 -int string device_not_responding_description 0x7f06000c -int string device_not_responding_title 0x7f06000b -int string lying_on_surface_description 0x7f060010 -int string lying_on_surface_title 0x7f06000f -int string motion_track_description 0x7f060012 -int string motion_track_title 0x7f060011 -int string moving_too_fast_description 0x7f060002 -int string moving_too_fast_title 0x7f060001 -int string not_enough_light_description 0x7f060008 -int string not_enough_light_title 0x7f060007 -int string project_tango 0x7f060000 -int string run_time_mismatch_description 0x7f060014 -int string run_time_mismatch_title 0x7f060013 -int string service_updated_description 0x7f06000e -int string service_updated_title 0x7f06000d -int string space_not_recognized_description 0x7f060006 -int string space_not_recognized_title 0x7f060005 -int string too_much_light_description 0x7f06000a -int string too_much_light_title 0x7f060009 -int string unable_to_detect_surface_description 0x7f060004 -int string unable_to_detect_surface_title 0x7f060003 -int style ConnectionLayoutSubtext 0x7f070003 -int style ConnectionLayoutText 0x7f070002 -int style DownloadProgressText 0x7f070004 -int style ExceptionActionRequired 0x7f070007 -int style ExceptionDescription 0x7f070006 +int string action_required 0x7f060000 +int string connection_layout_description 0x7f060001 +int string connection_layout_message 0x7f060002 +int string device_not_responding_description 0x7f060003 +int string device_not_responding_title 0x7f060004 +int string lying_on_surface_description 0x7f060005 +int string lying_on_surface_title 0x7f060006 +int string motion_track_description 0x7f060007 +int string motion_track_title 0x7f060008 +int string moving_too_fast_description 0x7f060009 +int string moving_too_fast_title 0x7f06000a +int string not_enough_light_description 0x7f06000b +int string not_enough_light_title 0x7f06000c +int string project_tango 0x7f06000d +int string run_time_mismatch_description 0x7f06000e +int string run_time_mismatch_title 0x7f06000f +int string service_updated_description 0x7f060010 +int string service_updated_title 0x7f060011 +int string space_not_recognized_description 0x7f060012 +int string space_not_recognized_title 0x7f060013 +int string too_much_light_description 0x7f060014 +int string too_much_light_title 0x7f060015 +int string unable_to_detect_surface_description 0x7f060016 +int string unable_to_detect_surface_title 0x7f060017 +int style ConnectionLayoutSubtext 0x7f070000 +int style ConnectionLayoutText 0x7f070001 +int style DownloadProgressText 0x7f070002 +int style ExceptionActionRequired 0x7f070003 +int style ExceptionDescription 0x7f070004 int style ExceptionTitle 0x7f070005 -int style Text20GrayDarkLight 0x7f070001 -int style Text40GrayDarkThin 0x7f070000 -int style TextListContentItem 0x7f07000a -int style TextListTitle 0x7f070008 -int style TextListTitleItem 0x7f070009 +int style Text20GrayDarkLight 0x7f070006 +int style Text40GrayDarkThin 0x7f070007 +int style TextListContentItem 0x7f070008 +int style TextListTitle 0x7f070009 +int style TextListTitleItem 0x7f07000a diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt.meta index 29fbb761..c71bfc68 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/R.txt.meta @@ -1,8 +1,6 @@ fileFormatVersion: 2 -guid: b5a4cae7989bd433996a1aa47771de7e -timeCreated: 1437161551 -licenseType: Pro -TextScriptImporter: +guid: ef5eb9406f726434d87668201fa5ea38 +DefaultImporter: userData: assetBundleName: assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res.meta index a8ce931b..321e4cf3 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 96d79e81e397344da83727ec1b3441ab folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch.meta index 966f5973..b86ec490 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: ad417e60f348345e8805d4468e6be46c folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi.meta index bb61de9f..ba1795dd 100644 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi.meta +++ b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 8fb6a57c6c7fc4e2f91da6e8989f3302 folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png deleted file mode 100644 index e0da8ceeaef9277ac4451fdc3e5bc9b6f2d98e32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2448 zcmd5-do+~m8h>d-CghS_V-MZNHgifdqzvPXFj9`G%H#wD4`R6|XSqhk<5)0jAi zNS$<9%j6O^MNW1MovozOFl?7L8FDM*Zq6rdf1N+}S?m0hSHt%=fum@!R9#W}PzsKzl>!YEev2NWu zHk(Z#5HvM4;cz&aOioKnqf)6D3U2SI2=44Z)Ihrr>Dnav67RMX*3#%M1sL! z_V)H(US3zPUgh)oF)=Z=wzd=s<@D*(>FMbyDJc+6Bod*J6DLljekCZgKp=?wN+u>I z;o;$s8$?>)Fm@L?RImhtt;9PDn^t*@DVJl$n`{LZOn9lAxR`_{s`(3&pM?P`9f( z)R<5xgetBg`uh4&QBkX=latd*pQ}hvP!Ob_%@4DJ9_;=(|AQno^);}yTH5RN3^tlr z0*!T=Kxc!YvFT=gYx7M;x^NrBmL2vxcRM<};P8L;*zf7J?fXBu61<5P-(j5gy1Dz< zZbv&{&9)-<*`fCAveMf?+5%gT33Y~9P{^i0i@?|k)v=;_>Mu_tearHcY@s{DmgR;6 z-pc~$`g?tqwhSj|MB&~DU_o<-5SXhS0LDj20BG1BLxF&MTi#;g4*)4AMafAxKX@&5w<_Zv{DqyvKGSEwa2MGb2}26|R0Ei?Mt{+1Y_?@lnqvC%Ms#)F@;L z%9DgF)9o!SKPL(3Ca#Vcm$OR?T(x*lXI@9 zurKk9kp2UMLZ;`eH=EBKQgg!`(h%REQR!p~LpwkQPrcDpNZ1!^B&)8MV$qz3R=LKS zIU^t594Ky92N_rg2h4@yrnN%)7$Xvw7TMJ#9hkd#S<1+L{HUbr$*ziOtUl8i+>4l$ z|J0#)-#j_caHlF2&*aXtPp3wHm*2#pjhemhz&ThQ=6q>>rkLq~0l&8$Gm2;8)|(}t z!zwD*R->Ys4zthx!n8R*bw50~V1d7l781=FbiBS_B1yYJCzCb612WlZZw322^F(l5 z^fnsv1v*As(0X{5s2nedoPFX%3(>sX%rNh!)jC(RHK2Avz9=RK#>;P(T<%3sarU^2 zTe)8@MBzlf9Mq_eQCQ_5XD|uN&%!!-f_Nm>F^liWABY~T2uoeVg)Ss=D{mnx>Q{d( zE#!06c-@b~?z||@nXpsSuNPju!hoAs3JPX@9-rNNx$OB8oZcH0g|b4GCIyt@nZxF{ ziUf&Df&?v-x0P;Ua)$eQl*$$h=+G@nWzX{>>k_WL%g;@VJXJR2zOOs)^&rKue>;W_7Zm=!z+mzi98a>8-GhO zk@YuY3AcNlbJCw5Pjt&|`><#=)04DN2r!$B9kjxnX~%E3@(l&{o)txtSMN$B1(zJn zSvtF~-`V4WTM%Z%jr30q06&tL!T&Yw`q**vXLlZwZ&Ui345V$mV z&YP)5xNbJnSzp=h9HIC{HSv-sCL-X=#hy+d!cNIlPbdbI_~_R>wW2t9mGp(=!1Djh M+v6ZX;(jdQKYDnwIRF3v diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png.meta deleted file mode 100644 index e5b9f398..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/exception_container_shadow.png.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: 73d3bc5d893e743a0ad300f5b054bb12 -timeCreated: 1437161550 -licenseType: Pro -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_dizzy.png b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_dizzy.png deleted file mode 100644 index 422960963399c7cf5ab86c220938d819950cfef5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3267 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 diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_lost.png.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_lost.png.meta deleted file mode 100644 index 4818cd9d..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_am_lost.png.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: f69a7b71912eb48958bbafba0edce994 -timeCreated: 1437161551 -licenseType: Pro -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png deleted file mode 100644 index af53817a6de1eca977439dd7520227e591680afe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3005 zcmV;u3qtgXP)qZu+RY{mSh1FfRiJ9_XV&Scmr4m92m;Uiy_pY>wu-eHvnS@pW!WF4e&Q0IMM+! zf!l#wfm0Y>sR333e+D{IHK=MsU2JBhpJT=C8t-eLn zh_or#2cN*Mc^Z*XhB5a+ROdlZY8dd5sH6KZX0AZw%ttl9inaefMB0>ON=*~Ev(NDT z7{x|M)e6n!p!SWJ( zYdXRXLRt|hD;dZG=mvtn8?kP=JUMXC&d@yp0?mYWd=K-?^_b<45Zo{ex*EV!0LpeA z+6K!HRwv5xYCoYYZK~ZSsch#n3DS))GQb!IM!KUFN{DxX4{d7>Ou0n`$(@_mCVOKqfEV~VJ-eZKeU50RFL9h)KXaQ*=JjIYX6PY#{ zkzNX(N#M!`;rI*{gwRpwYDD>}QT|%+RinIBU)e;yLt^G zd(L3MIW|zOJl4eWfy1eBm>np89j50Nw1+0D~9lLACuC z;V!^j^f6#yw`@U9T9VSJW;ecq%q<639-)opsP;XG`~_h9Q+1190e5%Lcu6Xv34l7f z3z0SjQFNtNb$33p@RF2=d^zbN@DzgOM-*O)$T}I-zC-)C)ZFXhZWA-nE#Bl=LSaI% z73DjCEV>Fg?Jh*ttYJ;0m9H9m&z;ycs}X6F!CjCFUz9JMx+{5bqzn8ts6Z3Otlwjt z{@k#G1N3Im^BzN4e()Xu;Tr6)3#3DcB@K@1+z-OUJaZlLD?bZg*|zPdmQAVEmcwtO z+IL2tQt3^YXTJ{a0#wKD!GcsFlcqGJ3)Qh7%p8o0*Ae5-3k&?YdVdL_cPg~f5AHX_DN(;&&DL7E}aE!%{Bj`CI`%uLL) z-|R6d6==q;c}hRb=fA_=w^BRoj51XFM_BJ(gsOceIdE#$U~Rn&)v+6qaT3B)jJ@{( z?En2qe}8CoPvQt5JVlt5Zy_?K>f$*$kfw;>hPm&ONRLZM?U4QTnCEOp87&hfz)I5CwCvn_fdTzSws?Gs-Z}cur^W zmN!u{FIPH+S^TDT^iyQ%O~@%r`&nEgejC^vfSaR656ViA)VqZzA_@vj7Xb|G3yU~=h?aq`|u{6e<*uk+EsKPpg+Q7yuCGJnos~F1~VXx#h*Kdlr#i5?yVDf%4ZOiocV5W@~04 zim!HBI#C?0Qi!x7?3%wvoRgUFb!2`ebT!6v*H#JC#r8e*h=~`6k>Gay^Qfbrf;&I@ z5TT>GRw`LGxC*}XX7EgO!gUnx$X$SH-;P}$xqBrFzl{ns$J3r_mOyPxI#s%m1&hO{ zQu_?J^P-dULZZA?h)I{|hZ|%;Dhn^y%wnwgVrHXi)zoK8kxDoq{H=XW56oBj?7-_nhmkJ)Jk)v*V=X&oY?EP7~H+L6oB)M!r+NF~c4*cwO3 zFT-wJs~vlP$($8W-|l^hJ~;CBfKMn)$e7wMFM>~^^NKAqJE z&_{~G>)DXEw?klfbcBf2oD-(*QH6#89MEK$F)sE(p?ay8P)DEaUIP~K+MXU^|IG_+ zKsH}Wu7gEbNxR}pY*^V1P9zO7ot!A`1O_M{IC3l>)Tgijet80ebMLX>MAD#csYV}p zI+3Kq@jX_5Mlq6Ha{_A5(*EE?186JyEW?Q+|8{=Dvy~X9o~sxc=TL`I+Rih`e(Sr#ikG`05Y? z^8xS=;3@QZx0H$)hPU9AJAUc{ppv+^{6*E)t-uE0Ke0-M(E!k~Qi$HTz5xBkgHrU{ z9rDm;MY~Pj27Ev((1df}PIa!y^9&$W;Q-2Qnrj00000NkvXXu0mjf&&;a? diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png.meta deleted file mode 100644 index 4bf7d412..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_i_cant_see.png.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: e1b7162faee364063b9d6376789352a0 -timeCreated: 1437161551 -licenseType: Pro -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_system.png b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_exception_system.png deleted file mode 100644 index 7d4fc8e0ec47b73d592b31b5b1a4438c6f91177b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2260 zcmV;_2rKuAP)^EN>M{fszw3|NL5pnsKjkT zQKecD5{?KZCaFRLsYLUD8k&bt8!1t!1hfjp>%mT*Cdi&vw0eDL+%J9qwb&OMJg_uBk!H%UY`Fhje(1xyACfic?u99q9SfCsn+v;YmjY2bu* z-ALAi)g;{Ge&BK7`@nZJGKRuPU@S0E=YO5R7r@8BA>fReled{9K@MOAuo8I0W+ zl(VH!{eY`21-`+q&jA0ZwXeMN$Y_r1>Hvq1hr_U`XJo+LyU^SmeD(H%YN(s00{emI%yJZ01FsqWZg1a)QKO);GPwQp zX}ER`91f%JxD#+{?tozg{m2w@0Ipw$$&=xQ7lPZXs^IKdxc6Q&?z&BLDr=2Uu?4^% zOLU_5AQ@v(9eLPVMx$DdRc%_f*e{TJY4Zxz!iz0=M4=b z(hnJ-QWQv#4frMh$Mb;^Mj$~ekYxFA#|R{sK8TytQG|!nKOff*byVFB50Ntf?Vt;XqjaKotq2o?XYfLaC>$(j2#PoeOAqEIZ)lN zVv8*!$nOW6O{698Qj}x`tl_Y@U&WljcP*QSqJY;6SFQxNj~@>%m!v(cK^c&xYWilG zveVrS1qHA=B=pE1m>u~Y)g&m&6_ZKG&~-XyE<|Njvcd-Ab{BlW_{E0 z`J!7x!etbDd!x%J`u%3Q10@PjZ1|eu_d{2gnCfUA(q;=kP9&(RsAyN0^i>Sc?M+sJ z0>f1%Hy7S`1NQ8J_uq%&;_!=YPL7!Q(4>7+6O0=dnVg0OC@+U+o`IKMl5t!vBcCSU z=6Aa<0pBoe$UAqyjXP*_59U60ay&`QL9njVWmoLlJ)+TK?ZitkG zs@D1Q@buF#e?HXK!if`5SZIdVt=jx<_YI^z&^Xv^^6(cfz`lJjZ5mWm$fE6Zih3xD ztUq~qFlLN|7Iyo91@m~M-_@(K2>10#|K486%7R0OWc&?>J&_zC=w74Zru{gRaz=mYwK2c^ih#mbAsAt z6{#9EmLOFX)#&VmHETq20H#k*Y+RR1$N@3$UazRy=+WX57$3KFsla87to2bJ5{eh6b@%Z@vll-Iu(OvanD{nl($`oroXx3UJ&Ia+;c;s0eoM6!i*4YpYnG zL~;DM_)4L0IAF&Pm@)+#8;v6AxPla8_9SGj`u&=k8hs1(;fJtnnK+CaH%e7mtmx^1 zO`BlVDp};ZnrQIq1&%66rPXH%dCn~@@ZyWI_6)KET@r5i{ZdJ` zcP|_`5c_=&9)#Vy#VNGeWXz6^!TrXMhnHWL*e?8zOvC z8#hkU5lu~S^r*y76&11HtGpb_%48jDY=o67#e)uq_3MSm+i~x2*$2U!S^f#kiz(h} zY!oN3s%q%|pMNgpy%iPlN8LR=qMrHr;{ObV>S|Hx;^J66?XT*<1DE<5;H{Was;Uan z?iMO5OWdY7o$%z7(f6;cl!Tqv8>@e`?WD^zz>N*s7WMK?I=@C(P7jmd7=7J)Qs#&(N9ziG4vzAMO`aq zvq`EmT@YTyBJS%SDw1m?iY-HFjHST2L)*z>{{2|TB`6)5%rH?h6v{TbtUm6nQ2i(MX&_F!twgbrdKlN!u&VP|w%=cpb zVZ8asdf?k>qHeW7DUt*uSp@Y*zN?Yb49=z?F&BVJ%>u{$P1=Z}zP};|iEIM8Q-Bx` zPz8Jw_#n~2jH-I{Yk8Dncn|PTrQ}V*+zE7hxs?#{}M^wPz#c{~&4Kn@H_as}?Yy i2L7#Cqie~U@c#fsQHG!A@92X70000T2Y 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 CW!*gh diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_err.png.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_err.png.meta deleted file mode 100644 index 9ac1757a..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_err.png.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: 0ad723d3552a345bf93e02e15fb5cf55 -timeCreated: 1437161550 -licenseType: Pro -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png deleted file mode 100644 index 3d4700788061054782d94f66e9a31abb3b5903e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11093 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 diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png.meta deleted file mode 100644 index 596b07fb..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok.png.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: dbd70a5a79675492c95b3bdaecfb14f3 -timeCreated: 1437161551 -licenseType: Pro -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok_tick.png b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/ic_shake_ok_tick.png deleted file mode 100644 index d4c04a0ef0e1485d842e51cbf0db00500b4cc542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 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 diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/splash_logo.png.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/splash_logo.png.meta deleted file mode 100644 index 5d2fbec4..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/res/crunch/drawable-xhdpi/splash_logo.png.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: 3e1fae1a672a84beebacba279de03090 -timeCreated: 1437161550 -licenseType: Pro -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/tango-ux-support-library.jar b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/bin/tango-ux-support-library.jar index 566682c76bb9c8702307a1cb1f58178b26336bc7..504a59d94a67e098b6092f44628787762acb2096 100644 GIT binary patch literal 64040 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 QDc~PA2?7Gz%-;Y04_wu)N&o-= literal 63976 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 W4hwtNs#k!2Q^5Dk2=M0^82

- * When a particular component is not explicitly this class will - * use its default implementation. - */ - public static class Builder { - private final Context mContext; - private boolean mIsMotionTrackingEnabled = true; - private TangoUxLayout mTangoUxLayout; - private UxExceptionEventListener mUxExceptionEventListener; - - /** - * Constructor using a context for this builder and the {@link TangoUx} it creates. - */ - public Builder(Context context) { - mContext = context; - } - - /** - * Disables motion tracking. - * This is only required if Tango is not using Motion Tracking - * and no pose status will be forward to TangoUx. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public Builder disableMotionTracking() { - mIsMotionTrackingEnabled = false; - return this; - } - - /** - * Sets the {@link TangoUxLayout} to be notified by TangoUx. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public Builder setTangoUxLayout(TangoUxLayout tangoUxLayout) { - mTangoUxLayout = tangoUxLayout; - return this; - } - - /** - * Sets the callback to be invoked when a exception should be raised or dismissed. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public Builder setUxExceptionEventListener(UxExceptionEventListener uxExceptionListener) { - mUxExceptionEventListener = uxExceptionListener; - return this; - } - - /** - * Creates a {@link TangoUx} with the arguments supplied to this builder. - */ - public TangoUx build() { - final TangoUx tangoUx = new TangoUx(mContext, mIsMotionTrackingEnabled, mTangoUxLayout); - tangoUx.setUxExceptionEventListener(mUxExceptionEventListener); - return tangoUx; - } - } - -} diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUx.java.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUx.java.meta deleted file mode 100644 index c58ac5eb..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUx.java.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9d13fff9ee4e9448097ec50b21299c29 -timeCreated: 1437161548 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java deleted file mode 100644 index 7ebffd40..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * Distributed under the Project Tango Preview Development Kit (PDK) Agreement. - * CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE. - */ - -package com.google.atap.tango.ux; - -import com.google.atap.tango.ux.UiSettings.UiSettingsListener; -import com.google.atap.tango.uxsupportlibrary.R; -import com.google.atap.tangoservice.TangoPoseData; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.Log; -import android.view.View; -import android.widget.FrameLayout; - -/** - * Layout that implements the management of exception notifications UI and the - * connection screen. Automatically shows or dismisses UI notifications with information - * on problems that are currently happening and how to fix them. - */ -public class TangoUxLayout extends FrameLayout { - - private static final String TAG = "TangoUxLayout"; - - private UiSettings mSettings; - - private ExceptionPanelContainer mExceptionContainer; - private ConnectionLayout mConnectionLayout; - private TangoUx mTangoUx; - - public TangoUxLayout(Context context) { - super(context); - init(context); - } - - public TangoUxLayout(Context context, AttributeSet attrs) { - super(context, attrs); - init(context); - } - - public TangoUxLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context); - } - - public UiSettings getUiSettings() { - return mSettings; - } - - private void init(Context context) { - View.inflate(getContext(), R.layout.layout_tango_ux, this); - mSettings = new UiSettings(mUiSettingsListener); - mExceptionContainer = (ExceptionPanelContainer) findViewById(R.id.exception_container); - mConnectionLayout = (ConnectionLayout) findViewById(R.id.connection_layout); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mTangoUx = null; - } - - void setTangoUx(TangoUx tangoUx) { - mTangoUx = tangoUx; - } - - void reset() { - hideExceptionsLayout(); - showConnectionLayout(); - } - - void onPoseAvailable(int statusCode) { - if (mConnectionLayout.isShowing() && statusCode == TangoPoseData.POSE_VALID) { - mConnectionLayout.hide(true); - } - } - - /** - * Hide exceptions layout and remove current showing exceptions. - */ - void hideExceptionsLayout() { - mExceptionContainer.dismiss(); - } - - /** - * Hide connection layout. - */ - void hideConnectionLayout() { - mConnectionLayout.hide(false); - } - - /** - * Shows the connection layout; it will self-dismiss on the next valid pose. - */ - void showConnectionLayout() { - if (mTangoUx == null) { - Log.w(TAG, "TangoUx null when showing connection layout."); - } else if (mSettings.isConnectionLayoutEnabled() && mTangoUx.mIsMotionTrackingEnabled) { - mConnectionLayout.show(); - } - } - - private UiSettingsListener mUiSettingsListener = new UiSettingsListener() { - - @Override - public void onExceptionsEnabled() { - mExceptionContainer.enableUi(true); - } - - @Override - public void onExceptionsDisabled() { - mExceptionContainer.enableUi(false); - } - - @Override - public void onConnectionLayoutEnabled() { - } - - @Override - public void onConnectionLayoutDisabled() { - mConnectionLayout.hide(false); - } - }; - - void onException(TangoExceptionInfo exception) { - mExceptionContainer.onException(exception); - } - - void hideExceptions(TangoExceptionInfo[] exceptions) { - mExceptionContainer.hideExceptions(exceptions); - } - - TangoExceptionInfo getHighestPriorityException() { - if (mTangoUx != null) { - return mTangoUx.getHighestPriorityException(); - } else { - return null; - } - } - - void onShakeDetected() { - mConnectionLayout.onShakeDetected(); - } -} diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java.meta deleted file mode 100644 index 4384e727..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/TangoUxLayout.java.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7bf34742f6a154304aa583ac3cae49f3 -timeCreated: 1437161548 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java deleted file mode 100644 index 80d0b1e0..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * Distributed under the Project Tango Preview Development Kit (PDK) Agreement. - * CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE. - */ - -package com.google.atap.tango.ux; - -/** - * Defines the UI settings for Tango Ux layout. - */ -public final class UiSettings { - - private boolean mConnectionLayoutEnabled = true; - private boolean mExceptionsEnabled = true; - private UiSettingsListener mListener; - - /** - * Listener used to notify Settings changes. - */ - interface UiSettingsListener { - /** - * This method will be invoked if Exceptions are enabled. - */ - void onExceptionsEnabled(); - - /** - * This method will be invoked if Exceptions are disabled. - */ - void onExceptionsDisabled(); - - /** - * This method will be invoked if ConnectionScreen is enabled. - */ - void onConnectionLayoutEnabled(); - - /** - * This method will be invoked if ConnectionScreen is disabled. - */ - void onConnectionLayoutDisabled(); - } - - UiSettings(UiSettingsListener listener) { - mListener = listener; - } - - /** - * Gets whether the Connection layout is enabled/disabled. - * - * @return true if the Connection layout is enabled; false if the - * Connection layout is disabled. - */ - public boolean isConnectionLayoutEnabled() { - return mConnectionLayoutEnabled; - } - - /** - * Specifies whether the Connection layout should be enabled. - * - * @param enabled true to enable the Connection layout; false to - * disable the Connection layout. - */ - public void setConnectionLayoutEnabled(boolean enabled) { - mConnectionLayoutEnabled = enabled; - if (enabled) { - mListener.onConnectionLayoutEnabled(); - } else { - mListener.onConnectionLayoutDisabled(); - } - } - - /** - * Gets whether the Exceptions are enabled/disabled. - * - * @return true if the Exceptions are enabled; false if the Exceptions - * are disabled. - */ - public boolean isExceptionsEnabled() { - return mExceptionsEnabled; - } - - /** - * Specifies whether the Exceptions should be enabled. - * - * @param enabled true to enable the Exceptions; false to disable the - * Exceptions. - */ - public void setExceptionsEnabled(boolean enabled) { - mExceptionsEnabled = enabled; - if (enabled) { - mListener.onExceptionsEnabled(); - } else { - mListener.onExceptionsDisabled(); - } - } -} diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java.meta deleted file mode 100644 index 656ce090..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UiSettings.java.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ac3d2b52704184f98b8b1f43d5feb52d -timeCreated: 1437161548 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java deleted file mode 100644 index edfd0346..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * Distributed under the Project Tango Preview Development Kit (PDK) Agreement. - * CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE. - */ - -package com.google.atap.tango.ux; - -/** - * Object used to report exception events. - * Whenever an exception is detected or resolved, an event is triggered. - * Exception events may hold a value, depending on the type of the exception. - */ -public class UxExceptionEvent { - - int mType; - - float mValue; - - int mStatus; - - /** - * Constant for {@link #getStatus}: The exception was detected. - */ - public static final int STATUS_DETECTED = 1; - - /** - * Constant for {@link #getStatus}: The exception was resolved. - */ - public static final int STATUS_RESOLVED = 0; - - /** - * Constant for {@link #getType}: Camera is over exposed exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- * - *

- * Use {@link #getValue} to retrieve exposure value. - *

- */ - public static final int TYPE_OVER_EXPOSED = 0; - - /** - * Constant for {@link #getType}: Camera is under exposed exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- * - *

- * Use {@link #getValue} to retrieve exposure value. - *

- */ - public static final int TYPE_UNDER_EXPOSED = 1; - - /** - * Constant for {@link #getType}: Device is being moved too fast exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- */ - public static final int TYPE_MOVING_TOO_FAST = 2; - - /** - * Constant for {@link #getType}: Too few features exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- * - *

- * Use {@link #getValue} to retrieve the number of features tracked. - *

- */ - public static final int TYPE_FEW_FEATURES = 3; - - /** - * Constant for {@link #getType}: Unable to detect any surface exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- * - *

- * Use {@link #getValue} to retrieve points the number of points detected. - *

- */ - public static final int TYPE_FEW_DEPTH_POINTS = 4; - - /** - * Constant for {@link #getType}: Device is lying on a surface exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- */ - public static final int TYPE_LYING_ON_SURFACE = 5; - - /** - * Constant for {@link #getType}: Motion tracking is invalid exception event. - * - *

- * Use {@link #getStatus} to know if the exception was detected or resolved. - *

- */ - public static final int TYPE_MOTION_TRACK_INVALID = 6; - - /** - * Constant for {@link #getType}: Tango Service stopped responding exception event. - * - *

- * {@link #getStatus} is always {@link #STATUS_DETECTED}. - *

- */ - public static final int TYPE_TANGO_SERVICE_NOT_RESPONDING = 7; - - /** - * Constant for {@link #getType}: Incompatible vm is found exception event. - * - *

- * {@link #getStatus} is always {@link #STATUS_DETECTED}. - *

- */ - public static final int TYPE_INCOMPATIBLE_VM = 8; - - /** - * Constant for {@link #getType}: Tango version update is needed exception event. - * - *

- * {@link #getStatus} is always {@link #STATUS_DETECTED}. - *

- */ - public static final int TYPE_TANGO_UPDATE_NEEDED = 9; - - /** - * Get the exception type. - * - * @return The type of this exception event, - * it will be one of the exception types described above. - */ - public int getType(){ - return mType; - } - - /** - * Get the exception value. - * - * @return The value of this exception event. Can be {@code NaN} if no value is available. - */ - public float getValue() { - return mValue; - } - - /** - * Get the exception status. - * - * @return {@link #STATUS_DETECTED} if the exception is detected, - * {@link #STATUS_RESOLVED} if the exception is resolved. - */ - public int getStatus(){ - return mStatus; - } - -} diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java.meta deleted file mode 100644 index 7127ff0e..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEvent.java.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 00f25cac2cf3b48c79a2f04b338f3bfe -timeCreated: 1437161548 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java deleted file mode 100644 index 95c35571..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * Distributed under the Project Tango Preview Development Kit (PDK) Agreement. - * CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE. - */ - -package com.google.atap.tango.ux; - -/** - * Listener used to notify UX exception. If apps want to handle themselves the exceptions, they will - * be notified by this listener when an exceptions should be raised or dismissed. - */ -public interface UxExceptionEventListener { - - void onUxExceptionEvent(UxExceptionEvent event); -} diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java.meta deleted file mode 100644 index 1707ad9d..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/UxExceptionEventListener.java.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 453802000d3c04aec828a5685b53fcb2 -timeCreated: 1437161548 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java deleted file mode 100644 index d6f3e358..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * Distributed under the Project Tango Preview Development Kit (PDK) Agreement. - * CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE. - */ - -/** - * Provides classes to access Tango Ux Support Library features. - */ - -package com.google.atap.tango.ux; - diff --git a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java.meta b/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java.meta deleted file mode 100644 index 3c50188f..00000000 --- a/UnityExamples/Assets/Plugins/Android/tango-ux-support-library/src/com/google/atap/tango/ux/package-info.java.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7ef334a158c6746f091aa90f1728b323 -timeCreated: 1437161548 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityExamples/Assets/Scenes/AreaLearning.unity b/UnityExamples/Assets/Scenes/AreaLearning.unity index d61ecf25..979a4377 100644 --- a/UnityExamples/Assets/Scenes/AreaLearning.unity +++ b/UnityExamples/Assets/Scenes/AreaLearning.unity @@ -723,6 +723,45 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_RootOrder: 5 +--- !u!1 &1053500148 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 4 + m_Component: + - 4: {fileID: 1053500150} + - 114: {fileID: 1053500149} + m_Layer: 0 + m_Name: SceneSwitcher + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1053500149 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1053500148} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b0efa6adf1b76443897844b6aef0ec90, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1053500150 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1053500148} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 8 --- !u!1 &1078994384 GameObject: m_ObjectHideFlags: 0 diff --git a/UnityExamples/Assets/Scenes/MotionTracking.unity b/UnityExamples/Assets/Scenes/MotionTracking.unity index 7ac42eb5..10f92cef 100644 --- a/UnityExamples/Assets/Scenes/MotionTracking.unity +++ b/UnityExamples/Assets/Scenes/MotionTracking.unity @@ -203,6 +203,46 @@ Transform: m_Children: [] m_Father: {fileID: 1915991091} m_RootOrder: 0 +--- !u!1 &1084286113 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 181456, guid: fa1184bcf7cf045e1ab0beb93e5172e4, type: 2} + m_PrefabInternal: {fileID: 0} + serializedVersion: 4 + m_Component: + - 4: {fileID: 1084286115} + - 114: {fileID: 1084286114} + m_Layer: 0 + m_Name: SceneSwitcher + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1084286114 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 11463662, guid: fa1184bcf7cf045e1ab0beb93e5172e4, + type: 2} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1084286113} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b0efa6adf1b76443897844b6aef0ec90, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1084286115 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 491958, guid: fa1184bcf7cf045e1ab0beb93e5172e4, type: 2} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1084286113} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 4 --- !u!114 &1208698735 stripped MonoBehaviour: m_PrefabParentObject: {fileID: 11452320, guid: 42ac6d01707274a8f924549e80f1666e, diff --git a/UnityExamples/Assets/Scenes/PointCloud.unity b/UnityExamples/Assets/Scenes/PointCloud.unity index 7e3a71dc..5263d72c 100644 --- a/UnityExamples/Assets/Scenes/PointCloud.unity +++ b/UnityExamples/Assets/Scenes/PointCloud.unity @@ -411,3 +411,42 @@ MonoBehaviour: type: 2} m_PrefabInternal: {fileID: 1420337780} m_Script: {fileID: 11500000, guid: 5f0fe6879878e49aab22e27b32350111, type: 3} +--- !u!1 &1872129014 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 4 + m_Component: + - 4: {fileID: 1872129016} + - 114: {fileID: 1872129015} + m_Layer: 0 + m_Name: SceneSwitcher + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1872129015 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1872129014} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b0efa6adf1b76443897844b6aef0ec90, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1872129016 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1872129014} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 diff --git a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningFPSCounter.cs b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningFPSCounter.cs index ba84701f..2edd5fd6 100644 --- a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningFPSCounter.cs +++ b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningFPSCounter.cs @@ -1,25 +1,30 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using UnityEngine; using Tango; /// /// FPS counter. /// -public class AreaLearningFPSCounter : MonoBehaviour { +public class AreaLearningFPSCounter : MonoBehaviour +{ public float m_updateFrequency = 1.0f; public string m_FPSText; @@ -31,43 +36,50 @@ public class AreaLearningFPSCounter : MonoBehaviour { private Rect m_label; private TangoApplication m_tangoApplication; - // Use this for initialization - void Start () + /// + /// Use this for initialization. + /// + private void Start() { m_currentFPS = 0; m_framesSinceUpdate = 0; m_currentTime = 0.0f; m_FPSText = "FPS = Calculating"; - m_label = new Rect(Screen.width * 0.025f - 50, Screen.height * 0.96f - 25, 600.0f, 50.0f); + m_label = new Rect((Screen.width * 0.025f) - 50, (Screen.height * 0.96f) - 25, 600.0f, 50.0f); m_tangoApplication = FindObjectOfType(); } - // Update is called once per frame - void Update () + /// + /// Update is called once per frame. + /// + private void Update() { m_currentTime += Time.deltaTime; ++m_framesSinceUpdate; m_accumulation += Time.timeScale / Time.deltaTime; - if(m_currentTime >= m_updateFrequency) + if (m_currentTime >= m_updateFrequency) { - m_currentFPS = (int)(m_accumulation/m_framesSinceUpdate); + m_currentFPS = (int)(m_accumulation / m_framesSinceUpdate); m_currentTime = 0.0f; m_framesSinceUpdate = 0; m_accumulation = 0.0f; m_FPSText = "FPS: " + m_currentFPS; } } - - void OnGUI() + + /// + /// OnGUI displays simple 2D UI on top of the world. + /// + private void OnGUI() { - if(m_tangoApplication.HasRequestedPermissions()) + if (m_tangoApplication.HasRequestedPermissions()) { Color oldColor = GUI.color; GUI.color = Color.black; GUI.Label(new Rect(Common.UI_LABEL_START_X, Common.UI_FPS_LABEL_START_Y, - Common.UI_LABEL_SIZE_X , + Common.UI_LABEL_SIZE_X, Common.UI_LABEL_SIZE_Y), Common.UI_FONT_SIZE + m_FPSText + ""); GUI.color = oldColor; diff --git a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningGUIController.cs b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningGUIController.cs index d39e46c6..942b8b9c 100644 --- a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningGUIController.cs +++ b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningGUIController.cs @@ -1,27 +1,31 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; +using UnityEngine; using Tango; /// /// FPS counter. /// -public class AreaLearningGUIController : MonoBehaviour { - +public class AreaLearningGUIController : MonoBehaviour +{ public const float UI_LABEL_START_X = 15.0f; public const float UI_LABEL_START_Y = 15.0f; public const float UI_LABEL_SIZE_X = 1920.0f; @@ -52,8 +56,8 @@ public class AreaLearningGUIController : MonoBehaviour { public const float SECOND_TO_MILLISECOND = 1000.0f; public AreaLearningPoseController m_tangoPoseController; - private const float m_updateFrequency = 1.0f; - private string m_FPSText; + private const float UPDATE_FREQUENCY = 1.0f; + private string m_fpsText; private int m_currentFPS; private int m_framesSinceUpdate; private float m_accumulation; @@ -62,39 +66,45 @@ public class AreaLearningGUIController : MonoBehaviour { private Rect m_label; private TangoApplication m_tangoApplication; - // Use this for initialization - void Start () + /// + /// Use this for initialization. + /// + private void Start() { m_currentFPS = 0; m_framesSinceUpdate = 0; m_currentTime = 0.0f; - m_FPSText = "FPS = Calculating"; - m_label = new Rect(Screen.width * 0.025f - 50, Screen.height * 0.96f - 25, 600.0f, 50.0f); + m_fpsText = "FPS = Calculating"; + m_label = new Rect((Screen.width * 0.025f) - 50, (Screen.height * 0.96f) - 25, 600.0f, 50.0f); m_tangoApplication = FindObjectOfType(); } - // Update is called once per frame - void Update () + /// + /// Update is called once per frame. + /// + private void Update() { m_currentTime += Time.deltaTime; ++m_framesSinceUpdate; m_accumulation += Time.timeScale / Time.deltaTime; - if(m_currentTime >= m_updateFrequency) + if (m_currentTime >= UPDATE_FREQUENCY) { - m_currentFPS = (int)(m_accumulation/m_framesSinceUpdate); + m_currentFPS = (int)(m_accumulation / m_framesSinceUpdate); m_currentTime = 0.0f; m_framesSinceUpdate = 0; m_accumulation = 0.0f; - m_FPSText = "FPS: " + m_currentFPS; + m_fpsText = "FPS: " + m_currentFPS; } } /// /// Construct readable string from TangoPoseStatusType. /// + /// Pose status from Tango. + /// Printable version of pose status. private string _GetLoggingStringFromPoseStatus(TangoEnums.TangoPoseStatusType status) { - string statusString = ""; + string statusString = string.Empty; switch (status) { case TangoEnums.TangoPoseStatusType.TANGO_POSE_INITIALIZING: @@ -119,9 +129,11 @@ private string _GetLoggingStringFromPoseStatus(TangoEnums.TangoPoseStatusType st /// /// Reformat string from vector3 type for data logging. /// + /// The vector to log. + /// Printable version of Vec3. private string _GetLoggingStringFromVec3(Vector3 vec) { - if(vec == Vector3.zero) + if (vec == Vector3.zero) { return "N/A"; } @@ -137,9 +149,11 @@ private string _GetLoggingStringFromVec3(Vector3 vec) /// /// Reformat string from quaternion type for data logging. /// + /// The quaternion to log. + /// Printable version of Quaternion. private string _GetLoggingStringFromQuaternion(Quaternion quat) { - if(quat == Quaternion.identity) + if (quat == Quaternion.identity) { return "N/A"; } @@ -152,15 +166,16 @@ private string _GetLoggingStringFromQuaternion(Quaternion quat) quat.w.ToString(UI_FLOAT_FORMAT)); } } - + /// /// Return a string to the get logging from frame count. /// /// The get logging string from frame count. /// Frame count. + /// Printable version of frame count. private string _GetLoggingStringFromFrameCount(int frameCount) { - if(frameCount == -1.0) + if (frameCount == -1.0) { return "N/A"; } @@ -171,13 +186,13 @@ private string _GetLoggingStringFromFrameCount(int frameCount) } /// - /// Return a string to get logging of FrameDeltaTime + /// Return a string to get logging of FrameDeltaTime. /// /// The get loggin string from frame delta time. /// Frame delta time. private string _GetLogginStringFromFrameDeltaTime(float frameDeltaTime) { - if(frameDeltaTime == -1.0) + if (frameDeltaTime == -1.0) { return "N/A"; } @@ -192,72 +207,61 @@ private string _GetLogginStringFromFrameDeltaTime(float frameDeltaTime) ///
private void OnGUI() { - Color oldColor = GUI.color; - GUI.color = Color.black; + Color oldColor = GUI.color; + GUI.color = Color.black; - if(m_tangoApplication.HasRequestedPermissions()) - { - int guiIndex = 0; - GUI.Label(new Rect(UI_LABEL_START_X, - UI_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TANGO_SERVICE_VERSION, m_tangoPoseController.m_tangoServiceVersionName) + ""); + if (m_tangoApplication.HasRequestedPermissions()) + { + int guiIndex = 0; + string logString; - // MOTION TRACKING - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y - UI_LABEL_OFFSET, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, - "Device", - "Start") + ""); + GUI.Label(new Rect(UI_LABEL_START_X, UI_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TANGO_SERVICE_VERSION, m_tangoPoseController.m_tangoServiceVersionName) + ""); - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y + UI_LABEL_OFFSET * guiIndex, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_STATUS, - _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status[AreaLearningPoseController.DEVICE_TO_START]), - _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount[AreaLearningPoseController.DEVICE_TO_START]), - _GetLoggingStringFromVec3(m_tangoPoseController.m_tangoPosition[AreaLearningPoseController.DEVICE_TO_START]), - _GetLoggingStringFromQuaternion(m_tangoPoseController.m_tangoRotation[AreaLearningPoseController.DEVICE_TO_START])) + ""); + // MOTION TRACKING + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y - UI_LABEL_OFFSET, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, "Device", "Start") + ""); - if(m_tangoPoseController.m_useADF || m_tangoApplication.m_enableAreaLearning) - { - // ADF - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y + UI_LABEL_OFFSET * (++guiIndex), - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, - "Device", - "ADF") + ""); + logString = String.Format(UX_STATUS, + _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status[AreaLearningPoseController.DEVICE_TO_START]), + _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount[AreaLearningPoseController.DEVICE_TO_START]), + _GetLoggingStringFromVec3(m_tangoPoseController.m_tangoPosition[AreaLearningPoseController.DEVICE_TO_START]), + _GetLoggingStringFromQuaternion(m_tangoPoseController.m_tangoRotation[AreaLearningPoseController.DEVICE_TO_START])); + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y + (UI_LABEL_OFFSET * guiIndex), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + logString + ""); + ++guiIndex; - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y + UI_LABEL_OFFSET * (++guiIndex), - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_STATUS, - _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status[AreaLearningPoseController.DEVICE_TO_ADF]), - _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount[AreaLearningPoseController.DEVICE_TO_ADF]), - _GetLoggingStringFromVec3(m_tangoPoseController.m_tangoPosition[AreaLearningPoseController.DEVICE_TO_ADF]), - _GetLoggingStringFromQuaternion(m_tangoPoseController.m_tangoRotation[AreaLearningPoseController.DEVICE_TO_ADF])) + ""); + if (m_tangoPoseController.m_useADF || m_tangoApplication.m_enableAreaLearning) + { + // ADF + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y + (UI_LABEL_OFFSET * guiIndex), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, "Device", "ADF") + ""); + ++guiIndex; - // RELOCALIZATION - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y + UI_LABEL_OFFSET * (++guiIndex), - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, - "Start", - "ADF") + ""); + logString = String.Format(UX_STATUS, + _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status[AreaLearningPoseController.DEVICE_TO_ADF]), + _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount[AreaLearningPoseController.DEVICE_TO_ADF]), + _GetLoggingStringFromVec3(m_tangoPoseController.m_tangoPosition[AreaLearningPoseController.DEVICE_TO_ADF]), + _GetLoggingStringFromQuaternion(m_tangoPoseController.m_tangoRotation[AreaLearningPoseController.DEVICE_TO_ADF])); + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y + (UI_LABEL_OFFSET * guiIndex), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + logString + ""); + ++guiIndex; - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y + UI_LABEL_OFFSET * (++guiIndex), - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_STATUS, - _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status[AreaLearningPoseController.START_TO_ADF]), - _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount[AreaLearningPoseController.START_TO_ADF]), - _GetLoggingStringFromVec3(m_tangoPoseController.m_tangoPosition[AreaLearningPoseController.START_TO_ADF]), - _GetLoggingStringFromQuaternion(m_tangoPoseController.m_tangoRotation[AreaLearningPoseController.START_TO_ADF])) + ""); + // RELOCALIZATION + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y + (UI_LABEL_OFFSET * guiIndex), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, "Start", "ADF") + ""); + guiIndex++; + + logString = String.Format(UX_STATUS, + _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status[AreaLearningPoseController.START_TO_ADF]), + _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount[AreaLearningPoseController.START_TO_ADF]), + _GetLoggingStringFromVec3(m_tangoPoseController.m_tangoPosition[AreaLearningPoseController.START_TO_ADF]), + _GetLoggingStringFromQuaternion(m_tangoPoseController.m_tangoRotation[AreaLearningPoseController.START_TO_ADF])); + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y + (UI_LABEL_OFFSET * guiIndex), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + logString + ""); + ++guiIndex; + } } + GUI.color = oldColor; } - GUI.color = oldColor; - } - } diff --git a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningPoseController.cs b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningPoseController.cs index b7a5dfcb..425ca5a1 100644 --- a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningPoseController.cs +++ b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/AreaLearningPoseController.cs @@ -1,22 +1,26 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- +using System; using System.Collections; using UnityEngine; using Tango; -using System; /// /// This is a basic movement controller based on @@ -42,7 +46,7 @@ public class AreaLearningPoseController : MonoBehaviour, ITangoPose // Index 2: start with respect to adf frame. [HideInInspector] public float[] m_frameDeltaTime; - private float[] m_prevFrameTimestamp; + [HideInInspector] public int[] m_frameCount; [HideInInspector] @@ -53,7 +57,10 @@ public class AreaLearningPoseController : MonoBehaviour, ITangoPose public Vector3[] m_tangoPosition; [HideInInspector] public bool m_isRelocalized = false; - + + // Indexing is same as for m_frameDeltaTime. + private float[] m_prevFrameTimestamp; + private TangoApplication m_tangoApplication; private Vector3 m_startingOffset; private Quaternion m_startingRotation; @@ -82,7 +89,109 @@ public bool IsLocalized() { return m_isRelocalized; } - + + /// + /// Handle the callback sent by the Tango Service + /// when a new pose is sampled. + /// DO NOT USE THE UNITY API FROM INSIDE THIS FUNCTION. + /// + /// Pose. + public void OnTangoPoseAvailable(TangoPoseData pose) + { + int currentIndex = 0; + + // Get out of here if the pose is null + if (pose == null) + { + Debug.Log("TangoPoseDate is null."); + return; + } + + if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && + pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) + { + // The callback pose is for device with respect to start of service pose. + currentIndex = DEVICE_TO_START; + } + else if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION && + pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) + { + // The callback pose is for device with respect to area description file pose. + currentIndex = DEVICE_TO_ADF; + } + else if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION && + pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE) + { + // The callback pose is for start of service with respect to area description file pose. + currentIndex = START_TO_ADF; + } + + if (!m_isRelocalized) + { + // check to see if we are recently relocalized + if (currentIndex == 2) + { + m_isRelocalized = true; + } + } + + if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) + { + // Create a new Vec3 and Quaternion from the Pose Data received. + m_tangoPosition[currentIndex] = new Vector3((float)pose.translation[0], + (float)pose.translation[1], + (float)pose.translation[2]); + + m_tangoRotation[currentIndex] = new Quaternion((float)pose.orientation[0], + (float)pose.orientation[1], + (float)pose.orientation[2], + (float)pose.orientation[3]); + } + else + { + // if the current pose is not valid we set the pose to identity + m_tangoPosition[currentIndex] = Vector3.zero; + m_tangoRotation[currentIndex] = Quaternion.identity; + m_isRelocalized = false; + } + + // Reset the current status frame count if the status code changed. + if (pose.status_code != m_status[currentIndex]) + { + m_frameCount[currentIndex] = 0; + } + + // Update the stats for the pose for the debug text + m_status[currentIndex] = pose.status_code; + m_frameCount[currentIndex]++; + + // Compute delta frame timestamp. + m_frameDeltaTime[currentIndex] = (float)pose.timestamp - m_prevFrameTimestamp[currentIndex]; + m_prevFrameTimestamp[currentIndex] = (float)pose.timestamp; + + Matrix4x4 matrixssTd; + + if (!m_isRelocalized) + { + // If not relocalized MotionTracking pose(Device wrt Start of Service) is used. + matrixssTd = Matrix4x4.TRS(m_tangoPosition[0], m_tangoRotation[0], Vector3.one); + } + else + { + // If relocalized Device wrt ADF pose is used. + matrixssTd = Matrix4x4.TRS(m_tangoPosition[1], m_tangoRotation[1], Vector3.one); + } + + // Converting from Tango coordinate frame to Unity coodinate frame. + Matrix4x4 matrixuwTuc = m_matrixuwTss * matrixssTd * m_matrixdTuc; + + // Extract new local position + transform.position = matrixuwTuc.GetColumn(3); + + // Extract new local rotation + transform.rotation = Quaternion.LookRotation(matrixuwTuc.GetColumn(2), matrixuwTuc.GetColumn(1)); + } + /// /// Initialize the controller. /// @@ -90,14 +199,15 @@ private void Awake() { m_startingOffset = transform.position; m_startingRotation = transform.rotation; - m_frameDeltaTime = new float[]{-1.0f,-1.0f,-1.0f}; - m_prevFrameTimestamp = new float[]{-1.0f,-1.0f,-1.0f}; - m_frameCount = new int[]{-1,-1,-1}; - m_status = new TangoEnums.TangoPoseStatusType[]{TangoEnums.TangoPoseStatusType.NA, - TangoEnums.TangoPoseStatusType.NA, TangoEnums.TangoPoseStatusType.NA}; - m_tangoRotation = new Quaternion[]{Quaternion.identity, - Quaternion.identity, Quaternion.identity}; - m_tangoPosition = new Vector3[]{Vector3.one,Vector3.one,Vector3.one}; + m_frameDeltaTime = new float[] { -1.0f, -1.0f, -1.0f }; + m_prevFrameTimestamp = new float[] { -1.0f, -1.0f, -1.0f }; + m_frameCount = new int[] { -1, -1, -1 }; + m_status = new TangoEnums.TangoPoseStatusType[] + { + TangoEnums.TangoPoseStatusType.NA, TangoEnums.TangoPoseStatusType.NA, TangoEnums.TangoPoseStatusType.NA + }; + m_tangoRotation = new Quaternion[] { Quaternion.identity, Quaternion.identity, Quaternion.identity }; + m_tangoPosition = new Vector3[] { Vector3.one, Vector3.one, Vector3.one }; // Constant matrix converting start of service frame to Unity world frame. m_matrixuwTss = new Matrix4x4(); @@ -121,9 +231,9 @@ private void Start() { m_tangoApplication = FindObjectOfType(); - if(m_tangoApplication != null) + if (m_tangoApplication != null) { - if(AndroidHelper.IsTangoCorePresent()) + if (AndroidHelper.IsTangoCorePresent()) { // Request Tango permissions m_tangoApplication.RegisterPermissionsCallback(_OnTangoApplicationPermissionsEvent); @@ -146,6 +256,7 @@ private void Start() /// /// Informs the user that they should install Tango Core via Android toast. /// + /// IEnumerator for coroutine. private IEnumerator _InformUserNoTangoCore() { AndroidHelper.ShowAndroidToastMessage("Please install Tango Core", false); @@ -180,116 +291,30 @@ private void Update() transform.position = tempPosition; #endif } - + /// - /// Handle the callback sent by the Tango Service - /// when a new pose is sampled. - /// DO NOT USE THE UNITY API FROM INSIDE THIS FUNCTION! + /// Unit callback when the GameObject is destroyed. /// - /// Callback context. - /// Pose. - public void OnTangoPoseAvailable(TangoPoseData pose) + private void OnDestroy() { - int currentIndex = 0; - - // Get out of here if the pose is null - if (pose == null) - { - Debug.Log("TangoPoseDate is null."); - return; - } - - // The callback pose is for device with respect to start of service pose. - if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && - pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) - { - currentIndex = DEVICE_TO_START; - } - // The callback pose is for device with respect to area description file pose. - else if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION && - pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) - { - currentIndex = DEVICE_TO_ADF; - } - // The callback pose is for start of service with respect to area description file pose. - else if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION && - pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE) - { - currentIndex = START_TO_ADF; - } - - // check to see if we are recently relocalized - if(!m_isRelocalized) - { - m_isRelocalized = (currentIndex == 2); - } - - if(pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) - { - // Create a new Vec3 and Quaternion from the Pose Data received. - m_tangoPosition[currentIndex] = new Vector3((float)pose.translation [0], - (float)pose.translation [1], - (float)pose.translation [2]); - - m_tangoRotation[currentIndex] = new Quaternion((float)pose.orientation [0], - (float)pose.orientation [1], - (float)pose.orientation [2], - (float)pose.orientation [3]); - } - else // if the current pose is not valid we set the pose to identity - { - m_tangoPosition[currentIndex] = Vector3.zero; - m_tangoRotation[currentIndex] = Quaternion.identity; - m_isRelocalized = false; - } - - // Reset the current status frame count if the status code changed. - if (pose.status_code != m_status[currentIndex]) - { - m_frameCount[currentIndex] = 0; - } - - // Update the stats for the pose for the debug text - m_status[currentIndex] = pose.status_code; - m_frameCount[currentIndex]++; - - // Compute delta frame timestamp. - m_frameDeltaTime[currentIndex] = (float)pose.timestamp - m_prevFrameTimestamp[currentIndex]; - m_prevFrameTimestamp [currentIndex] = (float)pose.timestamp; - - Matrix4x4 matrixssTd; - // If not relocalized MotionTracking pose(Device wrt Start of Service) is used. - if (!m_isRelocalized) - { - // Construct the device with respect to start of service matrix from the pose. - matrixssTd = Matrix4x4.TRS(m_tangoPosition[0], m_tangoRotation[0], Vector3.one); - } - // If relocalized Device wrt ADF pose is used. - else - { - // Construct the device with respect to ADF matrix from the pose. - matrixssTd = Matrix4x4.TRS(m_tangoPosition[1], m_tangoRotation[1], Vector3.one); - } - // Converting from Tango coordinate frame to Unity coodinate frame. - Matrix4x4 matrixuwTuc = m_matrixuwTss * matrixssTd * m_matrixdTuc; - - // Extract new local position - transform.position = matrixuwTuc.GetColumn(3); - - // Extract new local rotation - transform.rotation = Quaternion.LookRotation(matrixuwTuc.GetColumn(2), matrixuwTuc.GetColumn(1)); + m_tangoApplication.Shutdown(); } - + + /// + /// Tango permission event callback. + /// + /// If set to true permissions granted. private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { - if(permissionsGranted) + if (permissionsGranted) { m_tangoApplication.InitApplication(); - if(m_useADF) + if (m_useADF) { // Query the full adf list. PoseProvider.RefreshADFList(); + // loading last recorded ADF string uuid = PoseProvider.GetLatestADFUUID().GetStringDataUUID(); m_tangoApplication.InitProviders(uuid); @@ -309,7 +334,9 @@ private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) /// /// Unity callback when application is paused. /// - void OnApplicationPause(bool pauseStatus) { + /// If the application is paused. + private void OnApplicationPause(bool pauseStatus) + { m_frameDeltaTime = new float[3]; m_prevFrameTimestamp = new float[3]; m_frameCount = new int[3]; diff --git a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/SaveADFController.cs b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/SaveADFController.cs index bf78992f..c0ba0a98 100644 --- a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/SaveADFController.cs +++ b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/SaveADFController.cs @@ -1,28 +1,31 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; using Tango; /// /// Save ADF controller. /// -public class SaveADFController : MonoBehaviour { - +public class SaveADFController : MonoBehaviour +{ private TangoApplication m_tangoApplication; private TouchScreenKeyboard m_keyboard; private KeyboardState m_keyboardState; @@ -43,11 +46,11 @@ public enum KeyboardState /// /// Start is called after Awake.Make any initilizations here. /// - void Start () + private void Start() { m_tangoApplication = FindObjectOfType(); m_adfUnityHolder = new UUIDUnityHolder(); - m_keyboardState= KeyboardState.NONE; + m_keyboardState = KeyboardState.NONE; } /// @@ -55,7 +58,7 @@ void Start () /// private void OnGUI() { - if(m_tangoApplication.m_enableAreaLearning) + if (m_tangoApplication.m_enableAreaLearning) { if (GUI.Button(new Rect(Common.UI_BUTTON_GAP_X, Screen.height - (Common.UI_BUTTON_SIZE_Y + Common.UI_LABEL_GAP_Y), @@ -74,20 +77,20 @@ private void OnGUI() /// private void KeyBoardBehaviour() { - if(m_keyboardState == KeyboardState.OPEN) + if (m_keyboardState == KeyboardState.OPEN) { - m_keyboard = TouchScreenKeyboard.Open(m_keyboardString,TouchScreenKeyboardType.Default, false); + m_keyboard = TouchScreenKeyboard.Open(m_keyboardString, TouchScreenKeyboardType.Default, false); m_keyboardState = KeyboardState.ACTIVE; } - if(m_keyboard!=null) + if (m_keyboard != null) { - if(m_keyboard.done && m_keyboardState!=KeyboardState.DONE) + if (m_keyboard.done && m_keyboardState != KeyboardState.DONE) { m_keyboardState = KeyboardState.DONE; m_keyboardString = m_keyboard.text; PoseProvider.SaveAreaDescription(m_adfUnityHolder); PoseProvider.GetAreaDescriptionMetaData(m_adfUnityHolder); - PoseProvider.AreaDescriptionMetaData_set(Common.MetaDataKeyType.KEY_NAME, m_keyboardString,m_adfUnityHolder); + PoseProvider.AreaDescriptionMetaData_set(Common.MetaDataKeyType.KEY_NAME, m_keyboardString, m_adfUnityHolder); PoseProvider.SaveAreaDescriptionMetaData(m_adfUnityHolder); } else diff --git a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/TrajectoryController.cs b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/TrajectoryController.cs index b08ec027..7279eb68 100644 --- a/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/TrajectoryController.cs +++ b/UnityExamples/Assets/TangoExamples/AreaLearning/Scripts/TrajectoryController.cs @@ -1,24 +1,30 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class TrajectoryController : MonoBehaviour { - +/// +/// Switches between using the Blue and Green trails based on if localized or not. +/// +public class TrajectoryController : MonoBehaviour +{ public AreaLearningPoseController m_sampleController; private GameObject m_blueTrajectory; private GameObject m_greenTrajectory; @@ -26,7 +32,7 @@ public class TrajectoryController : MonoBehaviour { /// /// Used to initialize objects. /// - void Awake () + private void Awake() { m_blueTrajectory = GameObject.Find("BlueTrajectory"); m_greenTrajectory = GameObject.Find("GreenTrajectory"); @@ -35,9 +41,9 @@ void Awake () /// /// Update is called once per frame. /// - void Update () + private void Update() { - if(m_sampleController.IsLocalized()) + if (m_sampleController.IsLocalized()) { m_greenTrajectory.transform.position = m_sampleController.transform.position; } diff --git a/UnityExamples/Assets/Google-Unity/Sample.meta b/UnityExamples/Assets/TangoExamples/Common.meta similarity index 67% rename from UnityExamples/Assets/Google-Unity/Sample.meta rename to UnityExamples/Assets/TangoExamples/Common.meta index 54caea96..0e6b7578 100644 --- a/UnityExamples/Assets/Google-Unity/Sample.meta +++ b/UnityExamples/Assets/TangoExamples/Common.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 73a4a6d02bd9b45b9934c1414443c9d0 +guid: 4866f4a99dfec492f9a5e75c285a1369 folderAsset: yes -timeCreated: 1435687661 +timeCreated: 1438044308 licenseType: Pro DefaultImporter: userData: diff --git a/UnityExamples/Assets/Google-Unity/Sample/Scenes.meta b/UnityExamples/Assets/TangoExamples/Common/Scripts.meta similarity index 67% rename from UnityExamples/Assets/Google-Unity/Sample/Scenes.meta rename to UnityExamples/Assets/TangoExamples/Common/Scripts.meta index 165a6e06..f6a84aa0 100644 --- a/UnityExamples/Assets/Google-Unity/Sample/Scenes.meta +++ b/UnityExamples/Assets/TangoExamples/Common/Scripts.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: b77a92dcaef51492b91db4267192903e +guid: cab820b782c8045958fb65fdf0d47425 folderAsset: yes -timeCreated: 1435687661 +timeCreated: 1438044364 licenseType: Pro DefaultImporter: userData: diff --git a/UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs b/UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs new file mode 100644 index 00000000..0839ae9f --- /dev/null +++ b/UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- +using System.Collections; +using UnityEngine; +using Tango; + +/// +/// Script that displays a scene switching UI. +/// +public class SceneSwitcher : MonoBehaviour +{ + private const int SCENE_BUTTON_SIZE_X = 250; + private const int SCENE_BUTTON_SIZE_Y = 65; + + /// + /// The names of all the scenes this can switch between. + /// + private readonly string[] m_sceneNames = + { + "AreaLearning", + "MotionTracking", + "PointCloud" + }; + + /// + /// Scene switching GUI. + /// + private void OnGUI() + { + for (int it = 0; it < m_sceneNames.Length; ++it) + { + Rect buttonRect = new Rect(Screen.width - Common.UI_BUTTON_GAP_X - SCENE_BUTTON_SIZE_X, + Common.UI_LABEL_GAP_Y + ((Common.UI_LABEL_GAP_Y + SCENE_BUTTON_SIZE_Y) * it), + SCENE_BUTTON_SIZE_X, + SCENE_BUTTON_SIZE_Y); + if (GUI.Button(buttonRect, "" + m_sceneNames[it] + "")) + { + Application.LoadLevel(m_sceneNames[it]); + } + } + } +} diff --git a/UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs.meta b/UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs.meta new file mode 100644 index 00000000..173c7b15 --- /dev/null +++ b/UnityExamples/Assets/TangoExamples/Common/Scripts/SceneSwitcher.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b0efa6adf1b76443897844b6aef0ec90 +timeCreated: 1437583999 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/src.meta b/UnityExamples/Assets/TangoExamples/Common/Textures.meta similarity index 67% rename from UnityExamples/Assets/Plugins/Android/UnityUxHelper/src.meta rename to UnityExamples/Assets/TangoExamples/Common/Textures.meta index 26724215..aedfc861 100644 --- a/UnityExamples/Assets/Plugins/Android/UnityUxHelper/src.meta +++ b/UnityExamples/Assets/TangoExamples/Common/Textures.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: bdc9c9073069a4bb088bc89c8b0e08ee +guid: ae7de5c2f92e542d28abed9730a35002 folderAsset: yes -timeCreated: 1437161548 +timeCreated: 1438105468 licenseType: Pro DefaultImporter: userData: diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png b/UnityExamples/Assets/TangoExamples/Common/Textures/ProjectTango_Logo.png similarity index 100% rename from UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png rename to UnityExamples/Assets/TangoExamples/Common/Textures/ProjectTango_Logo.png diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png.meta b/UnityExamples/Assets/TangoExamples/Common/Textures/ProjectTango_Logo.png.meta similarity index 100% rename from UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Textures/Moto-ProjectTango_Logo Only Square copy.png.meta rename to UnityExamples/Assets/TangoExamples/Common/Textures/ProjectTango_Logo.png.meta diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARLocationMarker.cs b/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARLocationMarker.cs index 8c709fb1..c54f2290 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARLocationMarker.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARLocationMarker.cs @@ -1,24 +1,58 @@ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class ARLocationMarker : MonoBehaviour { +/// +/// Location marker script to show hide/show animations. +/// +/// Instead of calling destroy on this, send the "Hide" message. +/// +public class ARLocationMarker : MonoBehaviour +{ /// /// The animation playing. /// private Animation m_anim; - public void Start() + /// + /// Start this instance. + /// + private void Start() { m_anim = GetComponent(); m_anim.Play("Show", PlayMode.StopAll); } - public void Hide() + /// + /// Plays an animation, then destroys. + /// + private void Hide() { m_anim.Play("Hide", PlayMode.StopAll); } - public void HideDone() + /// + /// Callback for the animation system. + /// + private void HideDone() { Destroy(gameObject); } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARScreen.cs b/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARScreen.cs index 16ce423b..594a6d72 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARScreen.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/ARScreen.cs @@ -1,18 +1,22 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using UnityEngine; using Tango; @@ -30,6 +34,12 @@ public class ARScreen : MonoBehaviour { public Camera m_renderCamera; public Material m_screenMaterial; + + // Values for debug display. + [HideInInspector] + public TangoEnums.TangoPoseStatusType m_status; + [HideInInspector] + public int m_frameCount; private TangoApplication m_tangoApplication; private YUVTexture m_textures; @@ -37,23 +47,21 @@ public class ARScreen : MonoBehaviour // Matrix for Tango coordinate frame to Unity coordinate frame conversion. // Start of service frame with respect to Unity world frame. private Matrix4x4 m_uwTss; + // Unity camera frame with respect to color camera frame. private Matrix4x4 m_cTuc; + // Device frame with respect to IMU frame. private Matrix4x4 m_imuTd; + // Color camera frame with respect to IMU frame. private Matrix4x4 m_imuTc; + // Unity camera frame with respect to IMU frame, this is composed by // Matrix4x4.Inverse(m_imuTd) * m_imuTc * m_cTuc; // We pre-compute this matrix to save some computation in update(). private Matrix4x4 m_dTuc; - // Values for debug display. - [HideInInspector] - public TangoEnums.TangoPoseStatusType m_status; - [HideInInspector] - public int m_frameCount; - /// /// Initialize the AR Screen. /// @@ -61,22 +69,22 @@ private void Start() { // Constant matrix converting start of service frame to Unity world frame. m_uwTss = new Matrix4x4(); - m_uwTss.SetColumn (0, new Vector4 (1.0f, 0.0f, 0.0f, 0.0f)); - m_uwTss.SetColumn (1, new Vector4 (0.0f, 0.0f, 1.0f, 0.0f)); - m_uwTss.SetColumn (2, new Vector4 (0.0f, 1.0f, 0.0f, 0.0f)); - m_uwTss.SetColumn (3, new Vector4 (0.0f, 0.0f, 0.0f, 1.0f)); + m_uwTss.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + m_uwTss.SetColumn(1, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); + m_uwTss.SetColumn(2, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + m_uwTss.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); // Constant matrix converting Unity world frame frame to device frame. - m_cTuc.SetColumn (0, new Vector4 (1.0f, 0.0f, 0.0f, 0.0f)); - m_cTuc.SetColumn (1, new Vector4 (0.0f, -1.0f, 0.0f, 0.0f)); - m_cTuc.SetColumn (2, new Vector4 (0.0f, 0.0f, 1.0f, 0.0f)); - m_cTuc.SetColumn (3, new Vector4 (0.0f, 0.0f, 0.0f, 1.0f)); + m_cTuc.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + m_cTuc.SetColumn(1, new Vector4(0.0f, -1.0f, 0.0f, 0.0f)); + m_cTuc.SetColumn(2, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); + m_cTuc.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); m_tangoApplication = FindObjectOfType(); - if(m_tangoApplication != null) + if (m_tangoApplication != null) { - if(AndroidHelper.IsTangoCorePresent()) + if (AndroidHelper.IsTangoCorePresent()) { // Request Tango permissions m_tangoApplication.RegisterPermissionsCallback(_OnTangoApplicationPermissionsEvent); @@ -93,9 +101,10 @@ private void Start() { Debug.Log("No Tango Manager found in scene."); } - if(m_tangoApplication != null) + if (m_tangoApplication != null) { m_textures = m_tangoApplication.GetVideoOverlayTextureYUV(); + // Pass YUV textures to shader for process. m_screenMaterial.SetTexture("_YTex", m_textures.m_videoOverlayTextureY); m_screenMaterial.SetTexture("_UTex", m_textures.m_videoOverlayTextureCb); @@ -108,10 +117,11 @@ private void Start() /// /// Unity update function, we update our texture from here. /// - private void Update() { - if(Input.GetKeyDown(KeyCode.Escape)) + private void Update() + { + if (Input.GetKeyDown(KeyCode.Escape)) { - if(m_tangoApplication != null) + if (m_tangoApplication != null) { m_tangoApplication.Shutdown(); } @@ -121,19 +131,18 @@ private void Update() { // results in a hard crash. AndroidHelper.AndroidQuit(); } - double timestamp = VideoOverlayProvider.RenderLatestFrame (TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR); + double timestamp = VideoOverlayProvider.RenderLatestFrame(TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR); _UpdateTransformation(timestamp); - GL.InvalidateState (); + GL.InvalidateState(); } - - /// /// This callback function is called after user appoved or declined the permission to use Motion Tracking. /// + /// If the permissions were granted. private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { - if(permissionsGranted) + if (permissionsGranted) { m_tangoApplication.InitApplication(); m_tangoApplication.InitProviders(string.Empty); @@ -152,7 +161,9 @@ private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) /// /// Update the camera gameobject's transformation to the pose that on current timestamp. /// - private void _UpdateTransformation(double timestamp) { + /// Time to update the camera to. + private void _UpdateTransformation(double timestamp) + { TangoPoseData pose = new TangoPoseData(); TangoCoordinateFramePair pair; pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE; @@ -162,14 +173,14 @@ private void _UpdateTransformation(double timestamp) { m_status = pose.status_code; if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) { - Vector3 m_tangoPosition = new Vector3((float)pose.translation [0], - (float)pose.translation [1], - (float)pose.translation [2]); + Vector3 m_tangoPosition = new Vector3((float)pose.translation[0], + (float)pose.translation[1], + (float)pose.translation[2]); - Quaternion m_tangoRotation = new Quaternion((float)pose.orientation [0], - (float)pose.orientation [1], - (float)pose.orientation [2], - (float)pose.orientation [3]); + Quaternion m_tangoRotation = new Quaternion((float)pose.orientation[0], + (float)pose.orientation[1], + (float)pose.orientation[2], + (float)pose.orientation[3]); Matrix4x4 ssTd = Matrix4x4.TRS(m_tangoPosition, m_tangoRotation, Vector3.one); @@ -184,7 +195,8 @@ private void _UpdateTransformation(double timestamp) { m_renderCamera.transform.rotation = Quaternion.LookRotation(uwTuc.GetColumn(2), uwTuc.GetColumn(1)); m_frameCount++; } - else { + else + { m_frameCount = 0; } } @@ -194,11 +206,13 @@ private void _UpdateTransformation(double timestamp) { /// applying any project matrix or view matrix. So it's drawing space is the normalized /// screen space, that is [-1.0f, 1.0f] for both width and height. ///
+ /// Horizontal padding to add to the left and right edges. + /// Vertical padding to add to top and bottom edges. private void _SetScreenVertices(float normalizedOffsetX, float normalizedOffsetY) { MeshFilter meshFilter = GetComponent(); Mesh mesh = meshFilter.mesh; - mesh.Clear (); + mesh.Clear(); // Set the vertices base on the offset, note that the offset is used to compensate // the ratio differences between the camera image and device screen. @@ -241,7 +255,8 @@ private void _SetScreenVertices(float normalizedOffsetX, float normalizedOffsetY /// The device with respect to IMU frame is not directly queryable from API, so we use the IMU /// frame as a temporary value to get the device frame with respect to IMU frame. /// - private void _SetCameraExtrinsics() { + private void _SetCameraExtrinsics() + { double timestamp = 0.0; TangoCoordinateFramePair pair; TangoPoseData poseData = new TangoPoseData(); @@ -257,7 +272,7 @@ private void _SetCameraExtrinsics() { (float)poseData.orientation[1], (float)poseData.orientation[2], (float)poseData.orientation[3]); - m_imuTd = Matrix4x4.TRS(position, quat, new Vector3 (1.0f, 1.0f, 1.0f)); + m_imuTd = Matrix4x4.TRS(position, quat, new Vector3(1.0f, 1.0f, 1.0f)); // Getting the transformation of IMU frame with respect to color camera frame. pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_IMU; @@ -270,7 +285,7 @@ private void _SetCameraExtrinsics() { (float)poseData.orientation[1], (float)poseData.orientation[2], (float)poseData.orientation[3]); - m_imuTc = Matrix4x4.TRS(position, quat, new Vector3 (1.0f, 1.0f, 1.0f)); + m_imuTc = Matrix4x4.TRS(position, quat, new Vector3(1.0f, 1.0f, 1.0f)); m_dTuc = Matrix4x4.Inverse(m_imuTd) * m_imuTc * m_cTuc; } @@ -283,7 +298,7 @@ private void _SetCameraIntrinsics() VideoOverlayProvider.GetIntrinsics(TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR, intrinsics); float verticalFOV = 2.0f * Mathf.Rad2Deg * Mathf.Atan((intrinsics.height * 0.5f) / (float)intrinsics.fy); - if(!float.IsNaN(verticalFOV)) + if (!float.IsNaN(verticalFOV)) { m_renderCamera.fieldOfView = verticalFOV; @@ -295,12 +310,12 @@ private void _SetCameraIntrinsics() float heightRatio = (float)Screen.height / (float)intrinsics.height; if (widthRatio >= heightRatio) { - float normalizedOffset = (widthRatio / heightRatio - 1.0f) / 2.0f; + float normalizedOffset = ((widthRatio / heightRatio) - 1.0f) / 2.0f; _SetScreenVertices(0, normalizedOffset); } else { - float normalizedOffset = (heightRatio / widthRatio - 1.0f) / 2.0f; + float normalizedOffset = ((heightRatio / widthRatio) - 1.0f) / 2.0f; _SetScreenVertices(normalizedOffset, 0); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/AugmentedRealityGUIController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/AugmentedRealityGUIController.cs index b2f90b83..173b6530 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/AugmentedRealityGUIController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalAugmentedReality/Scripts/AugmentedRealityGUIController.cs @@ -1,11 +1,24 @@ //----------------------------------------------------------------------- // -// +// // Copyright 2015 Google Inc. All Rights Reserved. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // //----------------------------------------------------------------------- using System; +using System.Collections.Generic; using UnityEngine; using Tango; @@ -45,9 +58,14 @@ public class AugmentedRealityGUIController : MonoBehaviour public const float SECOND_TO_MILLISECOND = 1000.0f; /// - /// How big (in pixels) is a tap? + /// How big (in pixels) is a tap. /// - public const int TAP_PIXEL_TOLERANCE = 40; + public const float TAP_PIXEL_TOLERANCE = 40; + + /// + /// Minimum inlier percentage to consider a plane a fit. + /// + public const float MIN_PLANE_FIT_PERCENTAGE = 0.8f; public ARScreen m_arScreen; @@ -281,8 +299,13 @@ private void _UpdatePlacedLocation() } Camera cam = m_arScreen.m_renderCamera; - int closestIndex = m_pointCloud.FindClosestPoint(cam, t.position, TAP_PIXEL_TOLERANCE); - if (closestIndex < 0) + + // Find the plane for the selected point. + Vector3 planeCenter; + Plane plane; + if (!m_pointCloud.FindPlane(cam, t.position, + TAP_PIXEL_TOLERANCE, MIN_PLANE_FIT_PERCENTAGE, + out planeCenter, out plane)) { return; } @@ -292,12 +315,6 @@ private void _UpdatePlacedLocation() m_placedLocation.SendMessage("Hide"); } - float closestDepth = cam.WorldToScreenPoint(m_pointCloud.m_points[closestIndex]).z; - Ray touchRay = cam.ScreenPointToRay(new Vector3(t.position[0], t.position[1], 0)); - Vector3 pos = touchRay.origin + (touchRay.direction * closestDepth); - - Vector3 rot = cam.transform.eulerAngles; - rot[0] = rot[2] = 0; - m_placedLocation = (GameObject)Instantiate(m_prefabLocation, pos, Quaternion.Euler(rot)); + m_placedLocation = (GameObject)Instantiate(m_prefabLocation, planeCenter, Quaternion.FromToRotation(Vector3.up, plane.normal)); } } \ No newline at end of file diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/BallThrower.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/BallThrower.cs index fa82a43c..d85243a3 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/BallThrower.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/BallThrower.cs @@ -1,61 +1,72 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -/** - * Class for throwing balls - */ - -public class BallThrower : MonoBehaviour { +/// +/// Class for throwing balls. +/// +public class BallThrower : MonoBehaviour +{ public GameObject ballPrefab; public Camera mainCamera; - float forwardVelocity = 5.0f; + private float forwardVelocity = 5.0f; - GameObject[] ballArray = new GameObject[10]; - int currentBallID = 0; + private GameObject[] ballArray = new GameObject[10]; + private int currentBallID = 0; - // Use this for initialization - void Start () { - for(int i = 0; i < ballArray.Length; i++){ - ballArray[i] = (GameObject)Instantiate (ballPrefab); - ballArray[i].SetActive (false); + /// + /// Use this for initialization. + /// + private void Start() + { + for (int i = 0; i < ballArray.Length; i++) + { + ballArray[i] = (GameObject)Instantiate(ballPrefab); + ballArray[i].SetActive(false); ballArray[i].transform.parent = transform; } currentBallID = 0; } - // Update is called once per frame - void Update () { - - if (Input.GetKeyDown (KeyCode.Space)) { - ballArray[currentBallID].transform.position = mainCamera.transform.position - mainCamera.transform.up*ballPrefab.transform.localScale.y; - ballArray[currentBallID].GetComponent().velocity = mainCamera.transform.forward * forwardVelocity + mainCamera.transform.up*forwardVelocity/2; + /// + /// Update is called once per frame. + /// + private void Update() + { + if (Input.GetKeyDown(KeyCode.Space)) + { + ballArray[currentBallID].transform.position = mainCamera.transform.position - (mainCamera.transform.up * ballPrefab.transform.localScale.y); + ballArray[currentBallID].GetComponent().velocity = (mainCamera.transform.forward * forwardVelocity) + (mainCamera.transform.up * forwardVelocity / 2); ballArray[currentBallID].SetActive(true); - currentBallID = (currentBallID + 1)%ballArray.Length; + currentBallID = (currentBallID + 1) % ballArray.Length; } - for (var i = 0; i < Input.touchCount; ++i) { - if (Input.GetTouch(i).phase == TouchPhase.Began) { - - ballArray[currentBallID].transform.position = mainCamera.transform.position - mainCamera.transform.up*ballPrefab.transform.localScale.y; - ballArray[currentBallID].GetComponent().velocity = mainCamera.transform.forward * forwardVelocity + mainCamera.transform.up*forwardVelocity/2; + for (var i = 0; i < Input.touchCount; ++i) + { + if (Input.GetTouch(i).phase == TouchPhase.Began) + { + ballArray[currentBallID].transform.position = mainCamera.transform.position - (mainCamera.transform.up * ballPrefab.transform.localScale.y); + ballArray[currentBallID].GetComponent().velocity = (mainCamera.transform.forward * forwardVelocity) + (mainCamera.transform.up * forwardVelocity / 2); ballArray[currentBallID].SetActive(true); - currentBallID = (currentBallID + 1)%ballArray.Length; + currentBallID = (currentBallID + 1) % ballArray.Length; } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/CustomPointCloudListener.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/CustomPointCloudListener.cs index 58ccd1df..a0962502 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/CustomPointCloudListener.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/CustomPointCloudListener.cs @@ -1,32 +1,33 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- +using System; using System.Collections; using System.Collections.Generic; -using System; +using System.IO; using System.Runtime.InteropServices; using UnityEngine; using Tango; -using System.IO; - -/** - * CustomPointCloudListener - * Manages points cloud data either from the API, playback file, synthetic room, or test generation - */ +/// +/// Manages points cloud data either from the API, playback file, synthetic room, or test generation. +/// public class CustomPointCloudListener : MonoBehaviour, ITangoDepth { /** @@ -127,7 +128,7 @@ public class CustomPointCloudListener : MonoBehaviour, ITangoDepth /** * Scratch space for raycasting synthetic data */ - private RaycastHit hitInfo = new RaycastHit (); + private RaycastHit hitInfo = new RaycastHit(); /** * Raycast layer for synthetic room @@ -185,18 +186,18 @@ public void Start() m_initCameraPosition = m_mainCamera.transform.position; m_coordinatePair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE; - m_coordinatePair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE;//FIX should be depth sensor + m_coordinatePair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE; // FIX should be depth sensor m_cubes = new GameObject[m_insertionCount]; float size = 0.02f; - for (int i =0; i < m_insertionCount; i++) + for (int i = 0; i < m_insertionCount; i++) { - m_cubes[i] = (GameObject)GameObject.CreatePrimitive (PrimitiveType.Cube); + m_cubes[i] = (GameObject)GameObject.CreatePrimitive(PrimitiveType.Cube); m_cubes[i].transform.localScale = new Vector3(size, size, size); m_cubes[i].transform.parent = transform; } - syntheticRoom.SetActive (m_syntheticData); + syntheticRoom.SetActive(m_syntheticData); ClearLivePreviewCubes(); #if UNITY_ANDROID && !UNITY_EDITOR @@ -208,7 +209,7 @@ public void Start() if (m_playbackData) { m_recordData = false; - string filename = m_recordingID +".dat"; + string filename = m_recordingID + ".dat"; m_fileReader = new BinaryReader(File.Open(Application.persistentDataPath + "/" + filename, FileMode.Open)); m_debugText = "Loading from: " + filename + " " + m_fileReader.ToString(); } @@ -216,37 +217,239 @@ public void Start() m_tangoApplication = FindObjectOfType(); m_tangoApplication.Register(this); - if (m_testData) { - GenerateTestData (); + if (m_testData) + { + GenerateTestData(); } } - /** - * Generate synthetic test point cloud data for performance and debugging - */ - public void GenerateTestData() { - Debug.Log ("Generating Test Data"); + /// + /// Generate synthetic test point cloud data for performance and debugging. + /// + public void GenerateTestData() + { + Debug.Log("Generating Test Data"); - Vector3 obs = new Vector3 (0, -1, 0); + Vector3 obs = new Vector3(0, -1, 0); float range = 6.0f; float step = 0.025f; - for(float x = -range; x < range; x += step) { - for(float z = -range; z < range; z += step) { - float y = 0.5f*Mathf.Sin(2*Mathf.Sqrt(x*x + z*z)); - m_meshManager.InsertPoint(new Vector3(x,y,z+range),obs,1.0f); + for (float x = -range; x < range; x += step) + { + for (float z = -range; z < range; z += step) + { + float y = 0.5f * Mathf.Sin(2 * Mathf.Sqrt((x * x) + (z * z))); + m_meshManager.InsertPoint(new Vector3(x, y, z + range), obs, 1.0f); } } - m_meshManager.QueueDirtyMeshesForRegeneration (); + m_meshManager.QueueDirtyMeshesForRegeneration(); } - /** - * Create file for recording - */ - void PrepareRecording() + /// + /// Reset Point Cloud preview, history, and mesh data. + /// + public void Reset() + { + ClearLivePreviewCubes(); + m_positionHistory.Clear(); + m_meshManager.Clear(); + } + + /// + /// Write pose data to file. + /// + /// File writer. + /// Tango pose data. + public void WritePoseToFile(BinaryWriter writer, TangoPoseData pose) + { + if (writer == null) + { + return; + } + + writer.Write("poseframe\n"); + writer.Write(pose.timestamp + "\n"); + writer.Write((int)pose.framePair.baseFrame); + writer.Write((int)pose.framePair.targetFrame); + writer.Write((int)pose.status_code); + writer.Write(pose.translation[0]); + writer.Write(pose.translation[1]); + writer.Write(pose.translation[2]); + writer.Write(pose.orientation[0]); + writer.Write(pose.orientation[1]); + writer.Write(pose.orientation[2]); + writer.Write(pose.orientation[3]); + writer.Flush(); + } + + /// + /// Read pose from file. + /// + /// The pose from file. + /// File reader. + /// Tango pose data. + public int ReadPoseFromFile(BinaryReader reader, ref TangoPoseData pose) + { + if (reader == null) + { + return -1; + } + + string frameMarker; + try + { + frameMarker = reader.ReadString(); + } + catch (EndOfStreamException x) + { + reader.BaseStream.Position = 0; + Reset(); + print("Restarting log file: " + x.ToString()); + frameMarker = reader.ReadString(); + } + + if (frameMarker.CompareTo("poseframe\n") != 0) + { + m_debugText = "Failed to read pose"; + return -1; + } + + pose.timestamp = double.Parse(reader.ReadString()); + + TangoCoordinateFramePair pair = new TangoCoordinateFramePair(); + pair.baseFrame = (Tango.TangoEnums.TangoCoordinateFrameType)reader.ReadInt32(); + pair.targetFrame = (Tango.TangoEnums.TangoCoordinateFrameType)reader.ReadInt32(); + pose.framePair = pair; + + pose.status_code = (Tango.TangoEnums.TangoPoseStatusType)reader.ReadInt32(); + pose.translation[0] = reader.ReadDouble(); + pose.translation[1] = reader.ReadDouble(); + pose.translation[2] = reader.ReadDouble(); + pose.orientation[0] = reader.ReadDouble(); + pose.orientation[1] = reader.ReadDouble(); + pose.orientation[2] = reader.ReadDouble(); + pose.orientation[3] = reader.ReadDouble(); + return 0; + } + + /// + /// Write depth data to file. + /// + /// File writer. + /// Tango depth data. + public void WriteDepthToFile(BinaryWriter writer, TangoUnityDepth depthFrame) + { + if (writer == null) + { + return; + } + + writer.Write("depthframe\n"); + writer.Write(depthFrame.m_timestamp + "\n"); + writer.Write(depthFrame.m_pointCount + "\n"); + + for (int i = 0; i < depthFrame.m_pointCount; i++) + { + writer.Write(depthFrame.m_points[(3 * i) + 0]); + writer.Write(depthFrame.m_points[(3 * i) + 1]); + writer.Write(depthFrame.m_points[(3 * i) + 2]); + } + writer.Flush(); + } + + /// + /// Read depth data from file. + /// + /// The depth from file. + /// File reader. + /// Tango depth data. + public int ReadDepthFromFile(BinaryReader reader, ref TangoUnityDepth depthFrame) + { + string frameMarker; + try + { + frameMarker = reader.ReadString(); + } + catch (EndOfStreamException x) + { + reader.BaseStream.Position = 0; + Reset(); + + print("Restarting log file: " + x.ToString()); + frameMarker = reader.ReadString(); + } + + if (frameMarker.CompareTo("depthframe\n") != 0) + { + m_debugText = "Failed to read depth"; + return -1; + } + depthFrame.m_timestamp = double.Parse(reader.ReadString()); + depthFrame.m_pointCount = int.Parse(reader.ReadString()); + if (depthFrame.m_pointCount > depthFrame.m_points.Length) + { + depthFrame.m_points = new float[3 * (int)(1.5f * depthFrame.m_pointCount)]; + } + + // load up the data + for (int i = 0; i < depthFrame.m_pointCount; i++) + { + depthFrame.m_points[(3 * i) + 0] = reader.ReadSingle(); + depthFrame.m_points[(3 * i) + 1] = reader.ReadSingle(); + depthFrame.m_points[(3 * i) + 2] = reader.ReadSingle(); + } + + return 0; + } + + /// + /// An event notifying when new depth data is available. OnTangoDepthAvailable events are thread safe. + /// + /// Depth data that we get from API. + public void OnTangoDepthAvailable(TangoUnityDepth tangoDepth) + { + // Fill in the data to draw the point cloud. + if (tangoDepth != null) + { + if (tangoDepth.m_points == null) + { + Debug.Log("Depth points are null"); + return; + } + + if (tangoDepth.m_pointCount > m_currTangoDepth.m_points.Length) + { + m_currTangoDepth.m_points = new float[3 * (int)(1.5f * tangoDepth.m_pointCount)]; + } + + for (int i = 0; i < tangoDepth.m_pointCount; i += 3) + { + m_currTangoDepth.m_points[(3 * i) + 0] = tangoDepth.m_points[(i * 3) + 0]; + m_currTangoDepth.m_points[(3 * i) + 1] = tangoDepth.m_points[(i * 3) + 1]; + m_currTangoDepth.m_points[(3 * i) + 2] = tangoDepth.m_points[(i * 3) + 2]; + } + m_currTangoDepth.m_timestamp = tangoDepth.m_timestamp; + m_currTangoDepth.m_pointCount = tangoDepth.m_pointCount; + + PoseProvider.GetPoseAtTime(m_poseAtDepthTimestamp, m_currTangoDepth.m_timestamp, m_coordinatePair); + + if (m_poseAtDepthTimestamp.status_code != TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) + { + return; + } + + m_isDirty = true; + } + return; + } + + /// + /// Create file for recording. + /// + private void PrepareRecording() { m_sessionTimestamp = DateTime.Now.ToString("yyyy_MM_dd_HHmmss"); - string filename = m_sessionTimestamp+".dat"; + string filename = m_sessionTimestamp + ".dat"; if (m_fileWriter != null) { m_fileWriter.Close(); @@ -256,104 +459,106 @@ void PrepareRecording() m_debugText = "Saving to: " + filename + " " + m_fileWriter.ToString(); } - /** - * Draw debug frustum lines - */ - void DrawDebugLines() + /// + /// Draw debug frustum lines. + /// + private void DrawDebugLines() { float frustumSize = 2; Color frustumColor = Color.red; - Debug.DrawLine(transform.position, transform.position + frustumSize*transform.forward+transform.right+transform.up, frustumColor); - Debug.DrawLine(transform.position, transform.position + frustumSize*transform.forward-transform.right+transform.up, frustumColor); - Debug.DrawLine(transform.position, transform.position + frustumSize*transform.forward-transform.right-transform.up, frustumColor); - Debug.DrawLine(transform.position, transform.position + frustumSize*transform.forward+transform.right-transform.up, frustumColor); - Debug.DrawLine(transform.position + frustumSize*transform.forward+transform.right+transform.up, transform.position + frustumSize*transform.forward+transform.right-transform.up, frustumColor); - Debug.DrawLine(transform.position + frustumSize*transform.forward+transform.right+transform.up, transform.position + frustumSize*transform.forward-transform.right+transform.up, frustumColor); - Debug.DrawLine(transform.position + frustumSize*transform.forward-transform.right-transform.up, transform.position + frustumSize*transform.forward-transform.right+transform.up, frustumColor); - Debug.DrawLine(transform.position + frustumSize*transform.forward-transform.right-transform.up, transform.position + frustumSize*transform.forward+transform.right-transform.up, frustumColor); + Debug.DrawLine(transform.position, transform.position + (frustumSize * transform.forward) + transform.right + transform.up, frustumColor); + Debug.DrawLine(transform.position, transform.position + (frustumSize * transform.forward) - transform.right + transform.up, frustumColor); + Debug.DrawLine(transform.position, transform.position + (frustumSize * transform.forward) - transform.right - transform.up, frustumColor); + Debug.DrawLine(transform.position, transform.position + (frustumSize * transform.forward) + transform.right - transform.up, frustumColor); + Debug.DrawLine(transform.position + (frustumSize * transform.forward) + transform.right + transform.up, transform.position + (frustumSize * transform.forward) + transform.right - transform.up, frustumColor); + Debug.DrawLine(transform.position + (frustumSize * transform.forward) + transform.right + transform.up, transform.position + (frustumSize * transform.forward) - transform.right + transform.up, frustumColor); + Debug.DrawLine(transform.position + (frustumSize * transform.forward) - transform.right - transform.up, transform.position + (frustumSize * transform.forward) - transform.right + transform.up, frustumColor); + Debug.DrawLine(transform.position + (frustumSize * transform.forward) - transform.right - transform.up, transform.position + (frustumSize * transform.forward) + transform.right - transform.up, frustumColor); } - /** - * Update is called once per frame - * It processes input keyfor pausing, steping. It will also playback/record data or generate synthetic data. - * If running on Tango device it will process depth data that was copied for the depth callback. - */ + /// + /// Update is called once per frame + /// It processes input keyfor pausing, steping. It will also playback/record data or generate synthetic data. + /// If running on Tango device it will process depth data that was copied for the depth callback. + /// private void Update() { m_frameCount++; - if (Input.GetKeyDown(KeyCode.P)) { m_pause = !m_pause; } - if (Input.GetKeyDown (KeyCode.Slash)) + if (Input.GetKeyDown(KeyCode.Slash)) { m_step = true; } - //history - for (int i =0; i < m_positionHistory.Count-1; i++) { - Debug.DrawLine(m_positionHistory[i], m_positionHistory[i+1], Color.white); + // history + for (int i = 0; i < m_positionHistory.Count - 1; i++) + { + Debug.DrawLine(m_positionHistory[i], m_positionHistory[i + 1], Color.white); } - if (m_pause && !m_step) { + if (m_pause && !m_step) + { DrawDebugLines(); return; } m_step = false; - if(m_recordData && !m_playbackData) { + if (m_recordData && !m_playbackData) + { WritePoseToFile(m_fileWriter, m_poseAtDepthTimestamp); WriteDepthToFile(m_fileWriter, m_currTangoDepth); m_debugText = "Recording Session: " + m_sessionTimestamp + " Points: " + m_currTangoDepth.m_timestamp; } - if (m_playbackData) { - ReadPoseFromFile(m_fileReader,ref m_poseAtDepthTimestamp); + if (m_playbackData) + { + ReadPoseFromFile(m_fileReader, ref m_poseAtDepthTimestamp); ReadDepthFromFile(m_fileReader, ref m_currTangoDepth); m_mainCamera.transform.position = transform.position; m_mainCamera.transform.rotation = transform.rotation; m_isDirty = true; } - if (m_syntheticData) { - - //FIX - proper simulation should populate m_poseAtDepthTimestamp and m_currTangoDepth + if (m_syntheticData) + { + // FIX - proper simulation should populate m_poseAtDepthTimestamp and m_currTangoDepth // and the let the inset loop at the bottom execute normally. // This implementation overrides the insert loop. - transform.position = m_mainCamera.transform.position; transform.rotation = m_mainCamera.transform.rotation; m_currTangoDepth.m_pointCount = 0; -// m_currTangoDepth.m_timestamp = UnityEngine.Time.realtimeSinceStartup; -// m_poseAtDepthTimestamp.timestamp = UnityEngine.Time.realtimeSinceStartup; -// m_poseAtDepthTimestamp.status_code = TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID; +//// m_currTangoDepth.m_timestamp = UnityEngine.Time.realtimeSinceStartup; +//// m_poseAtDepthTimestamp.timestamp = UnityEngine.Time.realtimeSinceStartup; +//// m_poseAtDepthTimestamp.status_code = TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID; - if ((m_frameCount % 6) == 0) { + if ((m_frameCount % 6) == 0) + { float start = Time.realtimeSinceStartup; - for (int i = 0; i < m_insertionCount; i++) { - int x = UnityEngine.Random.Range (0, Screen.width); - int y = UnityEngine.Random.Range (0, Screen.height); - Ray ray = m_mainCamera.ScreenPointToRay (new Vector3 (x, y, 0)); - if (Physics.Raycast (ray, out hitInfo, syntheticRaycastMaxDistance, syntheticRoomLayer)) { - m_meshManager.InsertPoint (hitInfo.point, ray.direction, 1.0f/(hitInfo.distance+1)); + for (int i = 0; i < m_insertionCount; i++) + { + int x = UnityEngine.Random.Range(0, Screen.width); + int y = UnityEngine.Random.Range(0, Screen.height); + Ray ray = m_mainCamera.ScreenPointToRay(new Vector3(x, y, 0)); + if (Physics.Raycast(ray, out hitInfo, syntheticRaycastMaxDistance, syntheticRoomLayer)) + { + m_meshManager.InsertPoint(hitInfo.point, ray.direction, 1.0f / (hitInfo.distance + 1)); } } - m_meshManager.QueueDirtyMeshesForRegeneration (); + m_meshManager.QueueDirtyMeshesForRegeneration(); float stop = Time.realtimeSinceStartup; - m_meshManager.InsertionTime = m_meshManager.InsertionTime*m_meshManager.TimeSmoothing + (1.0f-m_meshManager.TimeSmoothing)*(stop - start); - + m_meshManager.InsertionTime = (m_meshManager.InsertionTime * m_meshManager.TimeSmoothing) + ((1.0f - m_meshManager.TimeSmoothing) * (stop - start)); } - } else if (m_isDirty) { - ClearLivePreviewCubes(); SetTransformUsingTangoPose(transform, m_poseAtDepthTimestamp); @@ -366,291 +571,116 @@ private void Update() for (int i = 0; i < m_insertionCount; i++) { - if(i > m_currTangoDepth.m_pointCount) + if (i > m_currTangoDepth.m_pointCount) + { break; + } - //randomly sub sample + // randomly sub sample int index = i; - //need to be more graceful than this, does not behave continuously - if(m_insertionCount < m_currTangoDepth.m_pointCount) - index = UnityEngine.Random.Range(0,m_currTangoDepth.m_pointCount); - Vector3 p = new Vector3(m_currTangoDepth.m_points[3*index],-m_currTangoDepth.m_points[3*index+1],m_currTangoDepth.m_points[3*index+2]); + // need to be more graceful than this, does not behave continuously + if (m_insertionCount < m_currTangoDepth.m_pointCount) + { + index = UnityEngine.Random.Range(0, m_currTangoDepth.m_pointCount); + } + + Vector3 p = new Vector3(m_currTangoDepth.m_points[3 * index], -m_currTangoDepth.m_points[(3 * index) + 1], m_currTangoDepth.m_points[(3 * index) + 2]); float sqrmag = p.sqrMagnitude; - if(sqrmag < m_sqrMinimumDepthDistance) + if (sqrmag < m_sqrMinimumDepthDistance) + { continue; + } Vector3 tp = transform.TransformPoint(p); - //less weight for things farther away, because of noise + // less weight for things farther away, because of noise if (m_recordData) { SetLivePreviewCube(tp); } else { - m_meshManager.InsertPoint (tp, transform.forward, 1.0f / (sqrmag + 1.0f)); + m_meshManager.InsertPoint(tp, transform.forward, 1.0f / (sqrmag + 1.0f)); } } float insertionStopTime = Time.realtimeSinceStartup; - m_meshManager.InsertionTime = m_meshManager.InsertionTime * m_meshManager.TimeSmoothing + (1.0f - m_meshManager.TimeSmoothing) * (insertionStopTime - insertionStartTime); - m_meshManager.QueueDirtyMeshesForRegeneration (); + m_meshManager.InsertionTime = (m_meshManager.InsertionTime * m_meshManager.TimeSmoothing) + ((1.0f - m_meshManager.TimeSmoothing) * (insertionStopTime - insertionStartTime)); + m_meshManager.QueueDirtyMeshesForRegeneration(); m_isDirty = false; } } - /** - * Clear live preview cubes - */ + /// + /// Clear live preview cubes. + /// private void ClearLivePreviewCubes() { - for (int i = 0; i < m_insertionCount; i++) { + for (int i = 0; i < m_insertionCount; i++) + { m_cubes[i].SetActive(false); } m_cubeIndex = 0; } - /** - * Set Live preview cube position - * @param p position to set the preview cube - */ + /// + /// Set Live preview cube position. + /// + /// Position to set the preview cube. private void SetLivePreviewCube(Vector3 p) { m_cubes[m_cubeIndex].transform.position = p; - m_cubes[m_cubeIndex].SetActive (true); + m_cubes[m_cubeIndex].SetActive(true); m_cubeIndex++; } - /** - * Tranform Tango pose data to Unity transform - * @param xform Unity Transform output - * @param pose Tango Pose Data - */ + /// + /// Tranform Tango pose data to Unity transform. + /// + /// Unity Transform output. + /// Tango Pose Data. private void SetTransformUsingTangoPose(Transform xform, TangoPoseData pose) { - xform.position = new Vector3((float)pose.translation [0], - (float)pose.translation [2], - (float)pose.translation [1]) + m_initCameraPosition; + xform.position = new Vector3((float)pose.translation[0], + (float)pose.translation[2], + (float)pose.translation[1]) + m_initCameraPosition; - Quaternion quat = new Quaternion((float)pose.orientation [0], - (float)pose.orientation [2], // these rotation values are swapped on purpose - (float)pose.orientation [1], - (float)pose.orientation [3]); + Quaternion quat = new Quaternion((float)pose.orientation[0], + (float)pose.orientation[2], // these rotation values are swapped on purpose + (float)pose.orientation[1], + (float)pose.orientation[3]); Quaternion axisFixedQuat = Quaternion.Euler(-quat.eulerAngles.x, -quat.eulerAngles.z, quat.eulerAngles.y); - //FIX - should query API for depth camera extrinsics + // FIX - should query API for depth camera extrinsics Quaternion extrinsics = Quaternion.Euler(-12.0f, 0, 0); xform.rotation = Quaternion.Euler(90.0f, 0.0f, 0.0f) * axisFixedQuat * extrinsics; } - /** - * Reset Point Cloud preview, history, and mesh data. - */ - public void Reset() - { - ClearLivePreviewCubes (); - m_positionHistory.Clear (); - m_meshManager.Clear (); - } - /// - /// An event notifying when new depth data is available. OnTangoDepthAvailable events are thread safe. + /// Display some on screen debug infromation and handles the record button. /// - /// Depth data that we get from API. - public void OnTangoDepthAvailable(TangoUnityDepth tangoDepth) + private void OnGUI() { - // Fill in the data to draw the point cloud. - if (tangoDepth != null) - { - if(tangoDepth.m_points == null) { - Debug.Log("Depth points are null"); - return; - } - - if(tangoDepth.m_pointCount > m_currTangoDepth.m_points.Length) { - m_currTangoDepth.m_points = new float[3*((int)(1.5f*tangoDepth.m_pointCount))]; - } - - for (int i = 0; i < tangoDepth.m_pointCount; i+=3) - { - m_currTangoDepth.m_points[3 * i] = tangoDepth.m_points[i * 3]; - m_currTangoDepth.m_points[3 * i + 1] = tangoDepth.m_points[i * 3 + 1]; - m_currTangoDepth.m_points[3 * i + 2] = tangoDepth.m_points[i * 3 + 2]; - } - m_currTangoDepth.m_timestamp = tangoDepth.m_timestamp; - m_currTangoDepth.m_pointCount = tangoDepth.m_pointCount; - - PoseProvider.GetPoseAtTime(m_poseAtDepthTimestamp, m_currTangoDepth.m_timestamp,m_coordinatePair); - - if(m_poseAtDepthTimestamp.status_code != TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) - return; - - m_isDirty = true; - } - return; - } - - /** - * Write pose data to file - * @param writer File writer - * @param pose Tango pose data - */ - public void WritePoseToFile(BinaryWriter writer, TangoPoseData pose) { - if(writer == null) - { - return; - } - - writer.Write("poseframe\n"); - writer.Write(pose.timestamp+"\n"); - writer.Write((int)pose.framePair.baseFrame); - writer.Write((int)pose.framePair.targetFrame); - writer.Write((int)pose.status_code); - writer.Write(pose.translation[0]); - writer.Write(pose.translation[1]); - writer.Write(pose.translation[2]); - writer.Write(pose.orientation[0]); - writer.Write(pose.orientation[1]); - writer.Write(pose.orientation[2]); - writer.Write(pose.orientation[3]); - writer.Flush(); - } - - - /** - * Read pose from file - * @param reader File reader - * @param pose Tango pose data - */ - public int ReadPoseFromFile(BinaryReader reader, ref TangoPoseData pose) - { - if(reader == null) - { - return -1; - } - - string frameMarker; - try { - frameMarker = reader.ReadString(); - } catch (EndOfStreamException x) { - reader.BaseStream.Position = 0; - Reset(); - print ("Restarting log file: " + x.ToString()); - frameMarker = reader.ReadString(); - } - - if(frameMarker.CompareTo("poseframe\n") != 0) - { - m_debugText = "Failed to read pose"; - return -1; - } - - pose.timestamp = double.Parse(reader.ReadString()); - - TangoCoordinateFramePair pair = new TangoCoordinateFramePair(); - pair.baseFrame = (Tango.TangoEnums.TangoCoordinateFrameType)reader.ReadInt32(); - pair.targetFrame = (Tango.TangoEnums.TangoCoordinateFrameType)reader.ReadInt32(); - pose.framePair = pair; - - pose.status_code = (Tango.TangoEnums.TangoPoseStatusType)reader.ReadInt32(); - pose.translation[0] = reader.ReadDouble(); - pose.translation[1] = reader.ReadDouble(); - pose.translation[2] = reader.ReadDouble(); - pose.orientation[0] = reader.ReadDouble(); - pose.orientation[1] = reader.ReadDouble(); - pose.orientation[2] = reader.ReadDouble(); - pose.orientation[3] = reader.ReadDouble(); - return 0; - } - - /** - * Write depth data to file - * @param writer File writer - * @param depthFrame Tango depth data - */ - public void WriteDepthToFile(BinaryWriter writer, TangoUnityDepth depthFrame) - { - if(writer == null) - { - return; - } - - writer.Write("depthframe\n"); - writer.Write(depthFrame.m_timestamp+"\n"); - writer.Write(depthFrame.m_pointCount+"\n"); - - for(int i = 0; i < depthFrame.m_pointCount; i++) - { - writer.Write(depthFrame.m_points[3*i]); - writer.Write(depthFrame.m_points[3*i+1]); - writer.Write(depthFrame.m_points[3*i+2]); - } - writer.Flush(); - } - - /** - * Read depth data from file - * @param reader File reader - * @param depthFrame Tango depth data. - */ - public int ReadDepthFromFile(BinaryReader reader, ref TangoUnityDepth depthFrame) - { - string frameMarker; - try { - frameMarker = reader.ReadString(); - } catch (EndOfStreamException x) { - reader.BaseStream.Position = 0; - Reset(); - - print ("Restarting log file: " + x.ToString()); - frameMarker = reader.ReadString(); - } - - if(frameMarker.CompareTo("depthframe\n") != 0) { - m_debugText = "Failed to read depth"; - return -1; - } - depthFrame.m_timestamp = double.Parse(reader.ReadString()); - depthFrame.m_pointCount = int.Parse(reader.ReadString()); - if (depthFrame.m_pointCount > depthFrame.m_points.Length) - depthFrame.m_points = new float[3 * ((int)(1.5f * depthFrame.m_pointCount))]; - - //load up the data - for(int i = 0; i < depthFrame.m_pointCount; i++) - { - depthFrame.m_points[3*i] = reader.ReadSingle(); - depthFrame.m_points[3*i+1] = reader.ReadSingle(); - depthFrame.m_points[3*i+2] = reader.ReadSingle(); - } - - return 0; - } - - /** - * Display some on screen debug infromation and handles the record button. - */ - void OnGUI() - { - GUI.Label(new Rect(10,180,1000,30), "Depth Points: " + m_currTangoDepth.m_pointCount); - GUI.Label(new Rect(10,200,1000,30), "Debug: " + m_debugText); + GUI.Label(new Rect(10, 180, 1000, 30), "Depth Points: " + m_currTangoDepth.m_pointCount); + GUI.Label(new Rect(10, 200, 1000, 30), "Debug: " + m_debugText); if (!m_recordData) { - if (GUI.Button (new Rect (Screen.width - 160, 120, 140, 80), "Start Record")) + if (GUI.Button(new Rect(Screen.width - 160, 120, 140, 80), "Start Record")) { m_meshManager.Clear(); - PrepareRecording (); + PrepareRecording(); m_recordData = true; } } else { - if (GUI.Button (new Rect (Screen.width - 160, 120, 140, 80), "Stop Record")) + if (GUI.Button(new Rect(Screen.width - 160, 120, 140, 80), "Stop Record")) { m_recordData = false; m_fileWriter.Close(); @@ -661,8 +691,11 @@ void OnGUI() string buttonName = "Pause"; if (m_pause) + { buttonName = "Resume"; - if (GUI.Button (new Rect (Screen.width - 160, 220, 140, 80), buttonName)) { + } + if (GUI.Button(new Rect(Screen.width - 160, 220, 140, 80), buttonName)) + { m_pause = !m_pause; } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DebugDrawing.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DebugDrawing.cs index 9cce1f5c..a0890317 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DebugDrawing.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DebugDrawing.cs @@ -1,77 +1,100 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; +using UnityEngine; -/** - * Utility functions for drawing debug lines for more complex shapes - */ -public class DebugDrawing { +/// +/// Utility functions for drawing debug lines for more complex shapes. +/// +public class DebugDrawing +{ + /// + /// Draws a box. + /// + /// One edge of the box. + /// Other edge of the box. + /// Color to draw lines for. + public static void Box(Vector3 min, Vector3 max, Color c) + { + Debug.DrawLine(min, new Vector3(min.x, min.y, max.z), c); + Debug.DrawLine(min, new Vector3(min.x, max.y, min.z), c); + Debug.DrawLine(min, new Vector3(max.x, min.y, min.z), c); - /** - * Draws a box - */ - public static void Box(Vector3 min, Vector3 max, Color c) { - Debug.DrawLine (min, new Vector3 (min.x, min.y, max.z), c); - Debug.DrawLine (min, new Vector3 (min.x, max.y, min.z), c); - Debug.DrawLine (min, new Vector3 (max.x, min.y, min.z), c); - - Debug.DrawLine (new Vector3 (min.x, max.y, max.z), new Vector3 (min.x, min.y, max.z), c); - Debug.DrawLine (new Vector3 (min.x, max.y, max.z), new Vector3 (min.x, max.y, min.z), c); - - Debug.DrawLine (new Vector3 (max.x, max.y, min.z), new Vector3 (max.x, min.y, min.z), c); - Debug.DrawLine (new Vector3 (max.x, max.y, min.z), new Vector3 (min.x, max.y, min.z), c); - - Debug.DrawLine (new Vector3 (max.x, min.y, max.z), new Vector3 (min.x, min.y, max.z), c); - Debug.DrawLine (new Vector3 (max.x, min.y, max.z), new Vector3 (max.x, min.y, min.z), c); - - - Debug.DrawLine (max, new Vector3 (min.x, max.y, max.z), c); - Debug.DrawLine (max, new Vector3 (max.x, max.y, min.z), c); - Debug.DrawLine (max, new Vector3 (max.x, min.y, max.z), c); + Debug.DrawLine(new Vector3(min.x, max.y, max.z), new Vector3(min.x, min.y, max.z), c); + Debug.DrawLine(new Vector3(min.x, max.y, max.z), new Vector3(min.x, max.y, min.z), c); + + Debug.DrawLine(new Vector3(max.x, max.y, min.z), new Vector3(max.x, min.y, min.z), c); + Debug.DrawLine(new Vector3(max.x, max.y, min.z), new Vector3(min.x, max.y, min.z), c); + + Debug.DrawLine(new Vector3(max.x, min.y, max.z), new Vector3(min.x, min.y, max.z), c); + Debug.DrawLine(new Vector3(max.x, min.y, max.z), new Vector3(max.x, min.y, min.z), c); + + Debug.DrawLine(max, new Vector3(min.x, max.y, max.z), c); + Debug.DrawLine(max, new Vector3(max.x, max.y, min.z), c); + Debug.DrawLine(max, new Vector3(max.x, min.y, max.z), c); } - /** - * Draws a crosshair - */ - public static void CrossHair(Vector3 point, float size, Color c) { - Debug.DrawLine (new Vector3 (point.x + size, point.y, point.z), new Vector3 (point.x - size, point.y, point.z), c); - Debug.DrawLine (new Vector3 (point.x, point.y+ size, point.z), new Vector3 (point.x , point.y - size, point.z), c); - Debug.DrawLine (new Vector3 (point.x, point.y, point.z+ size), new Vector3 (point.x , point.y, point.z - size), c); + /// + /// Draws a crosshair. + /// + /// Crosshair center. + /// Size of the lines. + /// Color to draw lines for. + public static void CrossHair(Vector3 point, float size, Color c) + { + Debug.DrawLine(new Vector3(point.x + size, point.y, point.z), new Vector3(point.x - size, point.y, point.z), c); + Debug.DrawLine(new Vector3(point.x, point.y + size, point.z), new Vector3(point.x, point.y - size, point.z), c); + Debug.DrawLine(new Vector3(point.x, point.y, point.z + size), new Vector3(point.x, point.y, point.z - size), c); float inc = Mathf.PI / 16; - for (float theta = 0; theta <= 2*Mathf.PI; theta += inc) + for (float theta = 0; theta <= 2 * Mathf.PI; theta += inc) { - Debug.DrawLine (new Vector3 (point.x + size*Mathf.Cos(theta), point.y + size*Mathf.Sin(theta), point.z), new Vector3 (point.x + size*Mathf.Cos(theta+inc), point.y + size*Mathf.Sin(theta+inc), point.z), c); - Debug.DrawLine (new Vector3 (point.x + size*Mathf.Cos(theta), point.y, point.z + size*Mathf.Sin(theta)), new Vector3 (point.x + size*Mathf.Cos(theta+inc), point.y , point.z+ size*Mathf.Sin(theta+inc)), c); - Debug.DrawLine (new Vector3 (point.x , point.y + size*Mathf.Sin(theta), point.z+ size*Mathf.Cos(theta)), new Vector3 (point.x , point.y + size*Mathf.Sin(theta+inc), point.z+ size*Mathf.Cos(theta+inc)), c); - + float cosPartBegin = size * Mathf.Cos(theta); + float sinPartBegin = size * Mathf.Sin(theta); + float cosPartEnd = size * Mathf.Cos(theta + inc); + float sinPartEnd = size * Mathf.Sin(theta + inc); + Debug.DrawLine(new Vector3(point.x + cosPartBegin, point.y + sinPartBegin, point.z), + new Vector3(point.x + cosPartEnd, point.y + sinPartEnd, point.z), + c); + Debug.DrawLine(new Vector3(point.x + cosPartBegin, point.y, point.z + sinPartBegin), + new Vector3(point.x + cosPartEnd, point.y, point.z + sinPartEnd), + c); + Debug.DrawLine(new Vector3(point.x, point.y + sinPartBegin, point.z + cosPartBegin), + new Vector3(point.x, point.y + sinPartEnd, point.z + cosPartEnd), + c); } } - /** - * Draws cross X - */ - public static void CrossX(Vector3 p, float size, Color c) { - Debug.DrawLine (p + new Vector3 (-size, -size, -size), p + new Vector3 (size, size, size), c); - Debug.DrawLine (p + new Vector3 (size, -size, -size), p + new Vector3 (-size, size, size), c); - Debug.DrawLine (p + new Vector3 (size, size, -size), p + new Vector3 (-size, -size, size), c); - Debug.DrawLine (p + new Vector3 (-size, size, -size), p + new Vector3 (size, -size, size), c); + /// + /// Draws cross X. + /// + /// Cross center. + /// Size of the lines. + /// Color to draw lines for. + public static void CrossX(Vector3 p, float size, Color c) + { + Debug.DrawLine(p + new Vector3(-size, -size, -size), p + new Vector3(size, size, size), c); + Debug.DrawLine(p + new Vector3(size, -size, -size), p + new Vector3(-size, size, size), c); + Debug.DrawLine(p + new Vector3(size, size, -size), p + new Vector3(-size, -size, size), c); + Debug.DrawLine(p + new Vector3(-size, size, -size), p + new Vector3(size, -size, size), c); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshCube.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshCube.cs index 0ef644d1..7803247b 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshCube.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshCube.cs @@ -1,183 +1,184 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; +using UnityEngine; -/** - * Dynamic Meshing Cube - * Manages the voxels and mesh data for each cube volume - */ -public class DynamicMeshCube : MonoBehaviour { - - /** - * resolution of the voxels which determines mesh resolution - */ +/// +/// Manages the voxels and mesh data for each cube volume. +/// +public class DynamicMeshCube : MonoBehaviour +{ + /// + /// Resolution of the voxels which determines mesh resolution. + /// public int m_voxelResolution = 10; - /** - * dimension size of the voxel grid. This is larger than the voxel resolution for buffer margin on each side - */ + /// + /// Dimension size of the voxel grid. This is larger than the voxel resolution for buffer margin on each side. + /// private int m_voxelGridDimension = 10; - /** - * margin count for voxels - */ + /// + /// Margin count for voxels. + /// private int m_voxelMarginCount = 2; - /** - * size of each voxel - */ + /// + /// Size of each voxel. + /// private float m_voxelSize = 0.1f; - /** - * threshold for boundard insertions - */ + /// + /// Threshold for boundard insertions. + /// private float m_epsilon = 0.001f; - /** - * spatial hashkey of this meshing cube - */ + /// + /// Spatial hashkey of this meshing cube. + /// private int m_hashKey = int.MinValue; - /** - * flag used for thread safety - */ + /// + /// Flag used for thread safety. + /// private bool m_isRegenerating = false; - /** - * Unity Mesh Filter object that handles mesh management - */ + /// + /// Unity Mesh Filter object that handles mesh management. + /// private MeshFilter m_meshFilter = null; - /** - * list of vertices in the mesh - */ + /// + /// List of vertices in the mesh. + /// private List m_vertices = new List(); - /** - * list of normals in the mesh - */ + /// + /// List of normals in the mesh. + /// private List m_normals = new List(); - /** - * list of triangles in the mesh - */ + /// + /// List of triangles in the mesh. + /// private List m_triangles = new List(); - /** - * list of texture uvs in the mesh - */ + /// + /// List of texture uvs in the mesh. + /// private List m_uvs = new List(); - /** - * isolevel for surfce computation in polygonization - */ + /// + /// Isolevel for surfce computation in polygonization. + /// private float m_meshingIsolevel = 0.0f; - /** - * default initial voxel value - */ + /// + /// Default initial voxel value. + /// private float m_initialVoxelValue = -1.0f; - /** - * maximum voxel weight - */ + /// + /// Maximum voxel weight. + /// private float m_maximumVoxelWeight = 100; - /** - * percentage change in the voxel value as a function of size for the mesh to be considered dirty - */ + /// + /// Percentage change in the voxel value as a function of size for the mesh to be considered dirty. + /// private float m_minimumVoxelPercentageChangeForDirty = 0.33f; - /** - * minimum change for the voxel to make the entire mesh dirty. get calcuated using percentage change. - */ - private float m_minimumVoxelChangeForDirty = 0.01f;//will get updated when voxel size is computed + /// + /// Minimum change for the voxel to make the entire mesh dirty. get calcuated using percentage change. + /// + private float m_minimumVoxelChangeForDirty = 0.01f; // will get updated when voxel size is computed - /** - * Hash tree storage for the voxel data. - */ + /// + /// Hash tree storage for the voxel data. + /// private VoxelHashTree voxelStorage = new VoxelHashTree(); - /** - * LUT for UV coorinadate combinations - */ + /// + /// LUT for UV coorinadate combinations. + /// private Vector2[] uvOptions = new Vector2[4]; - /** - * Flag to indicate if mesh is dirty. - */ + /// + /// Flag to indicate if mesh is dirty. + /// private bool isDirty = true; - /** - * Gets list of vertices in the mesh - */ - public List Vertices { - get { - return m_vertices; - } + /// + /// Gets list of vertices in the mesh. + /// + /// The vertices. + public List Vertices + { + get { return m_vertices; } } - /** - * Gets list of vertices in the mesh - */ - public List Triangles { - get { - return m_triangles; - } + /// + /// Gets list of vertices in the mesh. + /// + /// The triangles. + public List Triangles + { + get { return m_triangles; } } - /** - * Gets list of UVs in the mesh - */ - public List UVs { - get { - return m_uvs; - } + /// + /// Gets list of UVs in the mesh. + /// + /// The UVs. + public List UVs + { + get { return m_uvs; } } - /** - * Gets regeneration state - */ - public bool IsRegenerating { - get { - return m_isRegenerating; - } + /// + /// Gets regeneration state. + /// + /// true if this instance is regenerating; otherwise, false. + public bool IsRegenerating + { + get { return m_isRegenerating; } } - /** - * Gets hashkey of this meshing cube - */ - public int Key { - get { - return m_hashKey; - } - set { - m_hashKey = value; - } + /// + /// Gets hashkey of this meshing cube. + /// + /// The key. + public int Key + { + get { return m_hashKey; } + set { m_hashKey = value; } } - /** - * Prints Debug Info for this meshing cube. - */ - public void PrintDebugInfo() { - string info = ""; + /// + /// Prints Debug Info for this meshing cube. + /// + public void PrintDebugInfo() + { + string info = string.Empty; info += "Mesh Volume Key: " + m_hashKey + "\n"; info += "Root Voxel Key: " + voxelStorage.Key + "\n"; @@ -185,34 +186,46 @@ public void PrintDebugInfo() { { info += " " + t.Key + "\n"; } - Debug.Log (info); + Debug.Log(info); } - public float VoxelSize { - get { + /// + /// Gets or sets the size of the voxels. + /// + /// The size of the voxel. + public float VoxelSize + { + get + { return m_voxelSize; } - set { + + set + { m_voxelSize = value; - m_epsilon = m_voxelSize/100.0f; + m_epsilon = m_voxelSize / 100.0f; } } - /** - * Initializes the Meshing Cube. - */ - void Start () { - - uvOptions [0] = new Vector3 (-1, -1); - uvOptions [1] = new Vector3 (0, 1); - uvOptions [2] = new Vector3 (1, 1); - uvOptions [3] = new Vector3 (0, 0); - m_meshFilter = gameObject.GetComponent (); + /// + /// Initializes the Meshing Cube. + /// + public void Start() + { + uvOptions[0] = new Vector3(-1, -1); + uvOptions[1] = new Vector3(0, 1); + uvOptions[2] = new Vector3(1, 1); + uvOptions[3] = new Vector3(0, 0); + m_meshFilter = gameObject.GetComponent(); if (m_meshFilter == null) - m_meshFilter = gameObject.AddComponent (); + { + m_meshFilter = gameObject.AddComponent(); + } if (m_meshFilter == null) - Debug.LogError ("Could not get or add MeshFilter"); + { + Debug.LogError("Could not get or add MeshFilter"); + } Mesh mesh = m_meshFilter.sharedMesh; if (mesh == null) @@ -222,142 +235,171 @@ void Start () { } if (mesh == null) { - Debug.LogError ("Could not get or create Mesh"); + Debug.LogError("Could not get or create Mesh"); } } - /** - * Sets the voxel resolution for this meshing cube. - * @param voxelResolution number of voxel divisions in this cube. - */ - public void SetProperties(int voxelResolution) { + /// + /// Sets the voxel resolution for this meshing cube. + /// + /// Number of voxel divisions in this cube. + public void SetProperties(int voxelResolution) + { this.m_voxelResolution = voxelResolution; - m_voxelGridDimension = voxelResolution + 2*m_voxelMarginCount; + m_voxelGridDimension = voxelResolution + (2 * m_voxelMarginCount); VoxelSize = transform.localScale.x / voxelResolution; m_minimumVoxelChangeForDirty = VoxelSize * m_minimumVoxelPercentageChangeForDirty; - Clear (); + Clear(); } - /** - * Gets dirty flag - */ - public bool IsDirty { - get { - return isDirty; - } + /// + /// Gets dirty flag. + /// + /// true if this instance is dirty; otherwise, false. + public bool IsDirty + { + get { return isDirty; } } - /** - * Computes hashkey for particular voxel index - * @return the hashKey - */ - public int ComputeVoxelHashKey(int x, int y, int z) { - return x+m_voxelMarginCount + (y+m_voxelMarginCount)*m_voxelGridDimension + (z+m_voxelMarginCount)*m_voxelGridDimension*m_voxelGridDimension; + /// + /// Computes hashkey for particular voxel index. + /// + /// The voxel hash key. + /// The x coordinate. + /// The y coordinate. + /// The z coordinate. + public int ComputeVoxelHashKey(int x, int y, int z) + { + return x + m_voxelMarginCount + + ((y + m_voxelMarginCount) * m_voxelGridDimension) + + ((z + m_voxelMarginCount) * m_voxelGridDimension * m_voxelGridDimension); } - /** - * Computes hashkey for particular 3D point - * @return the haskKey - */ - public int ComputeVoxelHashKey(Vector3 p) { - return ((int)Mathf.Floor(p.x))+m_voxelMarginCount + (((int)Mathf.Floor(p.y))+m_voxelMarginCount)*m_voxelGridDimension + (((int)Mathf.Floor(p.z))+m_voxelMarginCount)*m_voxelGridDimension*m_voxelGridDimension; + /// + /// Computes hashkey for particular 3D point. + /// + /// The voxel hash key. + /// The point. + public int ComputeVoxelHashKey(Vector3 p) + { + return ComputeVoxelHashKey(Mathf.FloorToInt(p.x), Mathf.FloorToInt(p.y), Mathf.FloorToInt(p.z)); } - /** - * Clips the point+dir ray to the bounds of the meshing cube - */ + /// + /// Clips the point+dir ray to the bounds of the meshing cube. + /// + /// The point. + /// The dir ray. public void ClipRayToBounds(ref Vector3 point, Vector3 dir) { if (point.x < 0) - point = point + dir*(0 - point.x) / dir.x; + { + point = point + (dir * (0 - point.x) / dir.x); + } if (point.y < 0) - point = point + dir*(0 - point.y) / dir.y; + { + point = point + (dir * (0 - point.y) / dir.y); + } if (point.z < 0) - point = point + dir*(0 - point.z) / dir.z; + { + point = point + (dir * (0 - point.z) / dir.z); + } if (point.x > 1) - point = point + dir*(1 - point.x) / dir.x; + { + point = point + (dir * (1 - point.x) / dir.x); + } if (point.y > 1) - point = point + dir*(1 - point.y) / dir.y; + { + point = point + (dir * (1 - point.y) / dir.y); + } if (point.z > 1) - point = point + dir*(1 - point.z) / dir.z; + { + point = point + (dir * (1 - point.z) / dir.z); + } } - /** - * Raycast into this meshing cube for a list of voxels that are intersected - * @param start start point of the ray - * @param stop stop point of the ray - * @param dir the unit direction vector of the ray - * @return list of populated voxels that are intersected by the ray - */ - public List RayCastVoxelHitlist(Vector3 start, Vector3 stop, Vector3 dir) { - - List hits = new List (); + /// + /// Raycast into this meshing cube for a list of voxels that are intersected. + /// + /// List of populated voxels that are intersected by the ray. + /// Start point of the ray. + /// Stop point of the ray. + /// The unit direction vector of the ray. + public List RayCastVoxelHitlist(Vector3 start, Vector3 stop, Vector3 dir) + { + List hits = new List(); List hitKeys = new List(); Vector3 adjustedStart = start - transform.position; Vector3 adjustedStop = stop - transform.position; - ClipRayToBounds (ref adjustedStart, dir); - ClipRayToBounds (ref adjustedStop, dir); + ClipRayToBounds(ref adjustedStart, dir); + ClipRayToBounds(ref adjustedStop, dir); - //converts it to integer space + // converts it to integer space adjustedStart *= m_voxelResolution; adjustedStop *= m_voxelResolution; - //x crosses + // x crosses if (dir.x > 0) { - for (float x = Mathf.Ceil(adjustedStart.x)+m_epsilon; x < adjustedStop.x; x++) { - + for (float x = Mathf.Ceil(adjustedStart.x) + m_epsilon; x < adjustedStop.x; x++) + { float scale = (x - adjustedStart.x) / dir.x; - hitKeys.Add (ComputeVoxelHashKey (adjustedStart + scale * dir)); + hitKeys.Add(ComputeVoxelHashKey(adjustedStart + (scale * dir))); } } else { - for (float x = Mathf.Floor(adjustedStart.x)-m_epsilon; x > adjustedStop.x; x -= 1) { + for (float x = Mathf.Floor(adjustedStart.x) - m_epsilon; x > adjustedStop.x; x -= 1) + { float scale = (x - adjustedStart.x) / dir.x; - hitKeys.Add (ComputeVoxelHashKey (adjustedStart + scale * dir)); + hitKeys.Add(ComputeVoxelHashKey(adjustedStart + (scale * dir))); } } - //y crosses + // y crosses if (dir.y > 0) { - for (float y = Mathf.Ceil(adjustedStart.y)+m_epsilon; y < adjustedStop.y; y += 1) { + for (float y = Mathf.Ceil(adjustedStart.y) + m_epsilon; y < adjustedStop.y; y += 1) + { float scale = (y - adjustedStart.y) / dir.y; - hitKeys.Add (ComputeVoxelHashKey (adjustedStart + scale * dir)); + hitKeys.Add(ComputeVoxelHashKey(adjustedStart + (scale * dir))); } } else { - for (float y = Mathf.Floor(adjustedStart.y)-m_epsilon; y > adjustedStop.y; y -= 1) { + for (float y = Mathf.Floor(adjustedStart.y) - m_epsilon; y > adjustedStop.y; y -= 1) + { float scale = (y - adjustedStart.y) / dir.y; - hitKeys.Add (ComputeVoxelHashKey (adjustedStart + scale * dir)); + hitKeys.Add(ComputeVoxelHashKey(adjustedStart + (scale * dir))); } } - //z crosses + // z crosses if (dir.z > 0) { - for (float z = Mathf.Ceil(adjustedStart.z)+m_epsilon; z < adjustedStop.z; z += 1) { + for (float z = Mathf.Ceil(adjustedStart.z) + m_epsilon; z < adjustedStop.z; z += 1) + { float scale = (z - adjustedStart.z) / dir.z; - hitKeys.Add (ComputeVoxelHashKey (adjustedStart + scale * dir)); + hitKeys.Add(ComputeVoxelHashKey(adjustedStart + (scale * dir))); } } else { - for (float z = Mathf.Floor(adjustedStart.z)-m_epsilon; z > adjustedStop.z; z -= 1) { + for (float z = Mathf.Floor(adjustedStart.z) - m_epsilon; z > adjustedStop.z; z -= 1) + { float scale = (z - adjustedStart.z) / dir.z; - hitKeys.Add (ComputeVoxelHashKey (adjustedStart + scale * dir)); + hitKeys.Add(ComputeVoxelHashKey(adjustedStart + (scale * dir))); } } foreach (int key in hitKeys) { Voxel v = voxelStorage.Query(key); - if(v != null) { + if (v != null) + { hits.Add(v); } } @@ -365,713 +407,859 @@ public List RayCastVoxelHitlist(Vector3 start, Vector3 stop, Vector3 dir) return hits; } - /** - * Query if a voxel exists at the query location. - * @param x x query index - * @param y y query index - * @param z z query index - * @return the voxel if it exists, null if it does not exist - */ - public Voxel QueryVoxel(int x, int y, int z) { - return voxelStorage.Query(ComputeVoxelHashKey(x,y,z)); + /// + /// Query if a voxel exists at the query location. + /// + /// The voxel if it exists, null if it does not exist. + /// X query index. + /// Y query index. + /// Z query index. + public Voxel QueryVoxel(int x, int y, int z) + { + return voxelStorage.Query(ComputeVoxelHashKey(x, y, z)); } - /** - * Query if a voxel exists at the query location. If ti does not exits, create it. - * @param x x query index - * @param y y query index - * @param z z query index - * @return the voxel - */ - public Voxel QueryCreateVoxel(int x, int y, int z) { - int hashKey = ComputeVoxelHashKey(x,y,z); + /// + /// Query if a voxel exists at the query location. If it does not exist, create it. + /// + /// The created voxel. + /// X query index. + /// Y query index. + /// Z query index. + public Voxel QueryCreateVoxel(int x, int y, int z) + { + int hashKey = ComputeVoxelHashKey(x, y, z); Voxel v = voxelStorage.Query(hashKey); - if (v == null) { - v = InitializeVoxel (x, y, z, m_voxelSize, m_initialVoxelValue, 0); - voxelStorage.Insert(v,hashKey); + if (v == null) + { + v = InitializeVoxel(x, y, z, m_voxelSize, m_initialVoxelValue, 0); + voxelStorage.Insert(v, hashKey); } return v; } + /// + /// Insert point into this meshing cube, with output position index of the affected voxel. + /// + /// The final value of the adjusted voxel. + /// Point to be inserted. + /// Observation direction of this point. + /// Weight of the observation. + /// Index output position index of the voxel. + public float InsertPoint(Vector3 p, Vector3 obs, float weight, ref int[] index) + { + if (m_isRegenerating) + { + return -1; + } + index[0] = Mathf.FloorToInt((p.x - transform.position.x) / m_voxelSize); + index[1] = Mathf.FloorToInt((p.y - transform.position.y) / m_voxelSize); + index[2] = Mathf.FloorToInt((p.z - transform.position.z) / m_voxelSize); + + return AdjustWeight(QueryCreateVoxel(index[0], index[1], index[2]), p - transform.position, obs, weight); + } + + /// + /// Insert point into this meshing cube. + /// + /// The point. + /// Query point. + /// Point to be inserted. + /// Observation direction of this point. + /// Weight of the observation. + public float InsertPoint(Vector3 queryPoint, Vector3 p, Vector3 obs, float weight) + { + if (m_isRegenerating) + { + return -1; + } + + int x = Mathf.FloorToInt((queryPoint.x - transform.position.x) / m_voxelSize); + int y = Mathf.FloorToInt((queryPoint.y - transform.position.y) / m_voxelSize); + int z = Mathf.FloorToInt((queryPoint.z - transform.position.z) / m_voxelSize); + + return AdjustWeight(QueryCreateVoxel(x, y, z), p - transform.position, obs, weight); + } + + /// + /// Clears data from the meshing cube. + /// + public void Clear() + { + if (m_vertices != null) + { + m_vertices.Clear(); + } + if (m_triangles != null) + { + m_triangles.Clear(); + } + if (m_normals != null) + { + m_normals.Clear(); + } + if (m_uvs != null) + { + m_uvs.Clear(); + } + if (voxelStorage != null) + { + voxelStorage.Clear(); + } + if (m_meshFilter != null) + { + if (m_meshFilter.sharedMesh != null) + { + m_meshFilter.sharedMesh.Clear(); + } + } + + isDirty = true; + } + + /// + /// EXPERIMENTAL - simplfying planar sections of the mesh. + /// + /// Voxel 0. + /// Voxel 1. + /// Voxel 2. + /// Voxel 3. + public void SimplifyPlanarGroup(Voxel v0, Voxel v1, Voxel v2, Voxel v3) + { + Voxel[] voxels = new Voxel[4]; + voxels[0] = v0; + voxels[1] = v1; + voxels[2] = v2; + voxels[3] = v3; + + int totalTriangles = 0; + Vector3 averageNormal = new Vector3(0, 0, 0); + List triIndicies = new List(); + + foreach (Voxel v in voxels) + { + if (v == null) + { + return; + } + + // only do planar groups right now + if (v.trianglesIndicies.Count != 2) + { + return; + } + totalTriangles += v.trianglesIndicies.Count; + foreach (int triIndex in v.trianglesIndicies) + { + averageNormal += m_normals[m_triangles[triIndex]]; + } + } + + averageNormal /= totalTriangles; + + // too contentious + if (averageNormal.magnitude < 0.75f) + { + return; + } + + // we have 4 voxel neighors with triangles + // see if the normals are within tolernace + float variance = 0; + foreach (Voxel v in voxels) + { + foreach (int triIndex in v.trianglesIndicies) + { + variance += Vector3.SqrMagnitude(m_normals[m_triangles[triIndex]] - averageNormal); + triIndicies.Add(triIndex); + } + } + variance /= totalTriangles; + + if (variance > 0.05) + { + return; + } + + // we have triangles in a plane + Vector3 avg = new Vector3(); + foreach (int index in triIndicies) + { + avg += m_vertices[m_triangles[index]]; + avg += m_vertices[m_triangles[index + 1]]; + avg += m_vertices[m_triangles[index + 2]]; + } + avg /= totalTriangles * 3; + + foreach (int index in triIndicies) + { + bool remove = false; + if (Vector3.SqrMagnitude(m_vertices[m_triangles[index]] - avg) < 0.05f) + { + remove = true; + } + if (Vector3.SqrMagnitude(m_vertices[m_triangles[index + 1]] - avg) < 0.05f) + { + remove = true; + } + if (Vector3.SqrMagnitude(m_vertices[m_triangles[index + 2]] - avg) < 0.05f) + { + remove = true; + } + + if (remove) + { + m_triangles.RemoveAt(index); + m_triangles.RemoveAt(index + 1); + m_triangles.RemoveAt(index + 2); + } + } + + DebugDrawing.CrossX(avg + transform.position, 0.01f, Color.magenta); + + // lets create the neighbor graph + } + + /// + /// EXPERIMENTAL - simpligy planar parts of the mesh. + /// + /// Voxel to simplify around. + public void SimplifyByVoxel(Voxel v) + { + // this conditions te input to the polygonize, and make sure all the neighbors have valid entries + // if all input voxels are gauranteed to not be edge voxels, this may not be necessary. + Voxel v0 = v; + Voxel v1 = QueryVoxel(v.xID + 1, v.yID, v.zID); + Voxel v2 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID); + Voxel v3 = QueryVoxel(v.xID, v.yID + 1, v.zID); + Voxel v4 = QueryVoxel(v.xID, v.yID, v.zID + 1); + Voxel v5 = QueryVoxel(v.xID + 1, v.yID, v.zID + 1); + Voxel v6 = QueryVoxel(v.xID, v.yID + 1, v.zID + 1); + + // three planar directions.. diagonals aren't necessary? + SimplifyPlanarGroup(v0, v1, v2, v3); + SimplifyPlanarGroup(v0, v1, v4, v5); + SimplifyPlanarGroup(v0, v2, v3, v6); + } + + /// + /// Rebuild the Unity mesh. + /// + /// 1 if successful, -1 if there was an error. + public int RegenerateMesh() + { + if (!isDirty) + { + return 0; + } + if (m_isRegenerating) + { + return 0; + } + + if (m_meshFilter == null) + { + Debug.Log("mesh filter is null"); + return -1; + } + + Mesh mesh = m_meshFilter.sharedMesh; + if (mesh == null) + { + Debug.Log("shared mesh was null, creating new"); + m_meshFilter.mesh = new Mesh(); + mesh = m_meshFilter.sharedMesh; + } + + if (mesh == null) + { + Debug.Log("mesh is null"); + return -1; + } + + m_isRegenerating = true; + + mesh.Clear(); + m_vertices.Clear(); + m_triangles.Clear(); + m_normals.Clear(); + m_uvs.Clear(); + + PrepareVoxels(); + + foreach (VoxelHashTree t in voxelStorage.GetEnumerable()) + { + if (t.Voxel == null) + { + Debug.Log("Error: VoxelTree has null voxel"); + continue; + } + + if (Polygonize(t.Voxel) == 0) + { + // no triangles were created, consider deleting this voxel? + // just delecting, causes a lot of re-creation. need o be smarter + } + } + + SetMesh(); + isDirty = false; + m_isRegenerating = false; + + return 1; + } + + /// + /// Update the Unity Meshfilter data. + /// + public void SetMesh() + { + if (m_vertices == null) + { + Debug.Log("vertices null"); + return; + } + if (m_normals == null) + { + Debug.Log("normals null"); + return; + } + if (m_uvs == null) + { + Debug.Log("uvs null"); + return; + } + if (m_triangles == null) + { + Debug.Log("triangles null"); + return; + } + + if (m_meshFilter == null) + { + Debug.Log("mf is null"); + return; + } + + Mesh mesh = m_meshFilter.sharedMesh; + if (mesh == null) + { + m_meshFilter.mesh = new Mesh(); + mesh = m_meshFilter.sharedMesh; + } + + if (mesh == null) + { + Debug.Log("mesh is null"); + return; + } + mesh.Clear(); + mesh.MarkDynamic(); + mesh.vertices = m_vertices.ToArray(); + mesh.normals = m_normals.ToArray(); + mesh.uv = m_uvs.ToArray(); + + if (mesh.vertices == null) + { + Debug.Log("mesh vertices null"); + return; + } + + if (mesh.normals == null) + { + Debug.Log("mesh normals null"); + return; + } + + if (mesh.uv == null) + { + Debug.Log("mesh uv null"); + return; + } + + mesh.triangles = m_triangles.ToArray(); + + if (mesh.triangles == null) + { + Debug.Log("mesh triangles null"); + return; + } + + mesh.RecalculateBounds(); + mesh.Optimize(); + + GetComponent().sharedMesh = null; + GetComponent().sharedMesh = mesh; + } + + /// + /// Debug Draw the normals. + /// + public void DebugDrawNormals() + { + for (int i = 0; i < m_vertices.Count; i++) + { + Vector3 p = transform.position + m_vertices[i]; + Debug.DrawLine(p, p + (m_normals[i] * m_voxelSize), Color.red); + } + } - /** - * Initialize a new voxel at a given location - * @param xID x index - * @param yID y index - * @param zID z index - * @param voxelSize size of the voxel - * @param initialValue initialValue of the voxel - * @param initialWeight initialWeight of the voxel - * @return the created voxel - */ - Voxel InitializeVoxel(int xID, int yID, int zID, float voxelSize, float initialValue, float initialWeight) { + /// + /// Initialize a new voxel at a given location. + /// + /// The voxel. + /// X index. + /// Y index. + /// Z index. + /// Size of the voxel. + /// Initial value of the voxel. + /// Initial weight of the voxel. + private Voxel InitializeVoxel(int xID, int yID, int zID, float voxelSize, float initialValue, float initialWeight) + { Voxel v = new Voxel(); v.size = voxelSize; v.value = initialValue; v.weight = initialWeight; - v.normal = new Vector3 (0, 1, 0); + v.normal = new Vector3(0, 1, 0); v.parent = transform; v.xID = xID; v.yID = yID; v.zID = zID; - - v.anchor = new Vector3 (xID * v.size, yID * v.size, zID * v.size); - v.anchor.x += v.size/2; - v.anchor.y += v.size/2; - v.anchor.z += v.size/2; - + + v.anchor = new Vector3(xID * v.size, yID * v.size, zID * v.size); + v.anchor.x += v.size / 2; + v.anchor.y += v.size / 2; + v.anchor.z += v.size / 2; + v.neighborsCreated = false; - + return v; } - /** - * Adjust the weight of the voxel given the 3D point observation - * @param v the Voxel to be adjusted - * @param p the point inserted - * @param obs observation direction of the point - * @param weight weight of the observation - * @return final value of the adjusted voxel - */ - float AdjustWeight(Voxel v, Vector3 p, Vector3 obs, float weight) { - if (v.weight > m_maximumVoxelWeight) { - v.weight += weight; //keep accumulating, so we know when to subdivide + /// + /// Adjust the weight of the voxel given the 3D point observation. + /// + /// The final value of the adjusted voxel. + /// The Voxel to be adjusted. + /// The point inserted. + /// Observation direction of the point. + /// Weight of the observation . + private float AdjustWeight(Voxel v, Vector3 p, Vector3 obs, float weight) + { + if (v.weight > m_maximumVoxelWeight) + { + v.weight += weight; // keep accumulating, so we know when to subdivide return v.value; } - - float penetration = Vector3.Dot (obs, v.anchor - p); - v.value = (v.value * v.weight + penetration * weight) / (v.weight + weight); + + float penetration = Vector3.Dot(obs, v.anchor - p); + v.value = ((v.value * v.weight) + (penetration * weight)) / (v.weight + weight); v.weight += weight; - - if (v.value < -1) { + + if (v.value < -1) + { v.value = -1; v.weight = 0; } - // if (v.value > 1) - // v.value = 1; - // if (v.weight > maximumWeight) - // v.weight = maximumWeight; + //// if (v.value > 1) + //// v.value = 1; + //// if (v.weight > maximumWeight) + //// v.weight = maximumWeight; - if(Mathf.Abs(v.lastMeshedValue - v.value) > m_minimumVoxelChangeForDirty) - isDirty = true; - return v.value; - } - - /** - * Insert point into this meshing cube, with output position index of the affected voxel - * @param p point to be inserted - * @param obs observation direction of this point - * @param weight of the observation - * @param index output position index of the voxel - * @return the final value of the adjusted voxel - */ - public float InsertPoint(Vector3 p, Vector3 obs, float weight, ref int[] index) { - - if (m_isRegenerating) - return -1; - index[0] = (int)Math.Floor((p.x-transform.position.x)/m_voxelSize); - index[1] = (int)Math.Floor((p.y-transform.position.y)/m_voxelSize); - index[2] = (int)Math.Floor((p.z-transform.position.z)/m_voxelSize); - - return AdjustWeight (QueryCreateVoxel(index[0], index[1], index[2]), p-transform.position, obs, weight); - } - - /** - * Insert point into this meshing cube - * @param p point to be inserted - * @param obs observation direction of this point - * @param weight of the observation - * @return the final value of the adjusted voxel - */ - public float InsertPoint(Vector3 queryPoint, Vector3 p, Vector3 obs, float weight) { - if (m_isRegenerating) - return -1; - - int x = (int)Math.Floor ((queryPoint.x - transform.position.x) / m_voxelSize); - int y = (int)Math.Floor ((queryPoint.y - transform.position.y) / m_voxelSize); - int z = (int)Math.Floor ((queryPoint.z - transform.position.z) / m_voxelSize); - - return AdjustWeight (QueryCreateVoxel (x,y,z), p - transform.position, obs, weight); - } - - - /** - * Clears data from the meshing cube - */ - public void Clear() { - - if(m_vertices != null) - m_vertices.Clear (); - if(m_triangles != null) - m_triangles.Clear (); - if (m_normals != null) - m_normals.Clear (); - if(m_uvs != null) - m_uvs.Clear (); - if(voxelStorage != null) - voxelStorage.Clear (); - if (m_meshFilter != null) { - if (m_meshFilter.sharedMesh != null) { - m_meshFilter.sharedMesh.Clear (); - } + if (Mathf.Abs(v.lastMeshedValue - v.value) > m_minimumVoxelChangeForDirty) + { + isDirty = true; } - - isDirty = true; + return v.value; } - /** - * Walks through the voxel space prior to meshing to ensure all populated voxel have neighbors that are below the isosurface. - * Having populated voxels surrounded by neighbors below the isosurface is required to create valid meshes. - */ - void PrepareVoxels() { - - //for each voxel above ISO, making sure neighboring lower voxels exist - foreach (VoxelHashTree t in voxelStorage.GetEnumerable()) { + /// + /// Walks through the voxel space prior to meshing to ensure all populated voxel have neighbors that are below + /// the isosurface. Having populated voxels surrounded by neighbors below the isosurface is required to create + /// valid meshes. + /// + private void PrepareVoxels() + { + // for each voxel above ISO, making sure neighboring lower voxels exist + foreach (VoxelHashTree t in voxelStorage.GetEnumerable()) + { Voxel v = t.Voxel; - if (v == null) { + if (v == null) + { Debug.Log("Error: Prepare Voxels - VoxelTree has null voxel"); continue; } - //clear the stored triangle data used to compute voxel normal + // clear the stored triangle data used to compute voxel normal v.trianglesIndicies.Clear(); - if(v.neighborsCreated) + if (v.neighborsCreated) + { continue; + } - //create lower padding voxels as needed, so marching cubes will work correctly - if(v.value > m_meshingIsolevel) { - - //neighboring 8 - QueryCreateVoxel(v.xID-1, v.yID-1, v.zID); - QueryCreateVoxel(v.xID-1, v.yID, v.zID); - QueryCreateVoxel(v.xID-1, v.yID+1, v.zID); - - QueryCreateVoxel(v.xID, v.yID-1, v.zID); - QueryCreateVoxel(v.xID, v.yID+1, v.zID); - - QueryCreateVoxel(v.xID+1, v.yID-1, v.zID); - QueryCreateVoxel(v.xID+1, v.yID, v.zID); - QueryCreateVoxel(v.xID+1, v.yID+1, v.zID); - - //upper 9 - QueryCreateVoxel(v.xID-1, v.yID-1, v.zID+1); - QueryCreateVoxel(v.xID-1, v.yID, v.zID+1); - QueryCreateVoxel(v.xID-1, v.yID+1, v.zID+1); + // create lower padding voxels as needed, so marching cubes will work correctly + if (v.value > m_meshingIsolevel) + { + // neighboring 8 + QueryCreateVoxel(v.xID - 1, v.yID - 1, v.zID); + QueryCreateVoxel(v.xID - 1, v.yID, v.zID); + QueryCreateVoxel(v.xID - 1, v.yID + 1, v.zID); + + QueryCreateVoxel(v.xID, v.yID - 1, v.zID); + QueryCreateVoxel(v.xID, v.yID + 1, v.zID); + + QueryCreateVoxel(v.xID + 1, v.yID - 1, v.zID); + QueryCreateVoxel(v.xID + 1, v.yID, v.zID); + QueryCreateVoxel(v.xID + 1, v.yID + 1, v.zID); + + // upper 9 + QueryCreateVoxel(v.xID - 1, v.yID - 1, v.zID + 1); + QueryCreateVoxel(v.xID - 1, v.yID, v.zID + 1); + QueryCreateVoxel(v.xID - 1, v.yID + 1, v.zID + 1); - QueryCreateVoxel(v.xID, v.yID+1, v.zID+1); - QueryCreateVoxel(v.xID, v.yID, v.zID+1); - QueryCreateVoxel(v.xID, v.yID-1, v.zID+1); + QueryCreateVoxel(v.xID, v.yID + 1, v.zID + 1); + QueryCreateVoxel(v.xID, v.yID, v.zID + 1); + QueryCreateVoxel(v.xID, v.yID - 1, v.zID + 1); - QueryCreateVoxel(v.xID+1, v.yID-1, v.zID+1); - QueryCreateVoxel(v.xID+1, v.yID, v.zID+1); - QueryCreateVoxel(v.xID+1, v.yID+1, v.zID+1); - - //lower 9 - QueryCreateVoxel(v.xID-1, v.yID-1, v.zID-1); - QueryCreateVoxel(v.xID-1, v.yID, v.zID-1); - QueryCreateVoxel(v.xID-1, v.yID+1, v.zID-1); + QueryCreateVoxel(v.xID + 1, v.yID - 1, v.zID + 1); + QueryCreateVoxel(v.xID + 1, v.yID, v.zID + 1); + QueryCreateVoxel(v.xID + 1, v.yID + 1, v.zID + 1); + + // lower 9 + QueryCreateVoxel(v.xID - 1, v.yID - 1, v.zID - 1); + QueryCreateVoxel(v.xID - 1, v.yID, v.zID - 1); + QueryCreateVoxel(v.xID - 1, v.yID + 1, v.zID - 1); - QueryCreateVoxel(v.xID, v.yID+1, v.zID-1); - QueryCreateVoxel(v.xID, v.yID, v.zID-1); - QueryCreateVoxel(v.xID, v.yID-1, v.zID-1); + QueryCreateVoxel(v.xID, v.yID + 1, v.zID - 1); + QueryCreateVoxel(v.xID, v.yID, v.zID - 1); + QueryCreateVoxel(v.xID, v.yID - 1, v.zID - 1); - QueryCreateVoxel(v.xID+1, v.yID-1, v.zID-1); - QueryCreateVoxel(v.xID+1, v.yID, v.zID-1); - QueryCreateVoxel(v.xID+1, v.yID+1, v.zID-1); + QueryCreateVoxel(v.xID + 1, v.yID - 1, v.zID - 1); + QueryCreateVoxel(v.xID + 1, v.yID, v.zID - 1); + QueryCreateVoxel(v.xID + 1, v.yID + 1, v.zID - 1); v.neighborsCreated = true; } } } - /** - * Calculate the UV coordinates for a triangle. - * @param ia first triangle vertex index - * @param ib second triangle vertex index - * @param ix third triangle vertex index - */ - void CalculateUVs(int ia, int ib, int ic) { - //likely bug, if it winds down to the last face - //it forces it to be valid, which will alter - //an existing face without checking that face - //may not be resolvable without doing a full - //3-color graph solver - - if(m_uvs[ia] == uvOptions[0]){ - if(m_uvs[ib] == uvOptions[0]){ - if(m_uvs[ic] == uvOptions[0]){ + /// + /// Calculate the UV coordinates for a triangle. + /// + /// First triangle vertex index. + /// Second triangle vertex index. + /// Third triangle vertex index. + private void CalculateUVs(int ia, int ib, int ic) + { + // likely bug, if it winds down to the last face + // it forces it to be valid, which will alter + // an existing face without checking that face + // may not be resolvable without doing a full + // 3-color graph solver + if (m_uvs[ia] == uvOptions[0]) + { + if (m_uvs[ib] == uvOptions[0]) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ia] = uvOptions[1]; m_uvs[ib] = uvOptions[2]; m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[1]){ + else if (m_uvs[ic] == uvOptions[1]) + { m_uvs[ia] = uvOptions[2]; m_uvs[ib] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[2]){ + else if (m_uvs[ic] == uvOptions[2]) + { m_uvs[ia] = uvOptions[1]; m_uvs[ib] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[3]){ + else if (m_uvs[ic] == uvOptions[3]) + { m_uvs[ia] = uvOptions[1]; m_uvs[ib] = uvOptions[2]; } } - else if(m_uvs[ib] == uvOptions[1]){ - if(m_uvs[ic] == uvOptions[0]){ + else if (m_uvs[ib] == uvOptions[1]) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ia] = uvOptions[2]; m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[2]){ + else if (m_uvs[ic] == uvOptions[2]) + { m_uvs[ia] = uvOptions[1]; } - else if(m_uvs[ic] == uvOptions[3]){ + else if (m_uvs[ic] == uvOptions[3]) + { m_uvs[ia] = uvOptions[2]; } } - else if(m_uvs[ib] == uvOptions[2]){ - if(m_uvs[ic] == uvOptions[0]){ + else if (m_uvs[ib] == uvOptions[2]) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ia] = uvOptions[1]; m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[1]){ + else if (m_uvs[ic] == uvOptions[1]) + { m_uvs[ia] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[3]){ + else if (m_uvs[ic] == uvOptions[3]) + { m_uvs[ia] = uvOptions[1]; } } - else if(m_uvs[ib] == uvOptions[3]){ - if(m_uvs[ic] == uvOptions[0]){ + else if (m_uvs[ib] == uvOptions[3]) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ia] = uvOptions[1]; m_uvs[ic] = uvOptions[2]; } - else if(m_uvs[ic] == uvOptions[1]){ + else if (m_uvs[ic] == uvOptions[1]) + { m_uvs[ia] = uvOptions[2]; } - else if(m_uvs[ic] == uvOptions[2]){ + else if (m_uvs[ic] == uvOptions[2]) + { m_uvs[ia] = uvOptions[1]; } } } - else if(m_uvs[ia] == uvOptions[1]){ - if((m_uvs[ib] == uvOptions[0])||(m_uvs[ib] == uvOptions[1])){ - if(m_uvs[ic] == uvOptions[0]){ + else if (m_uvs[ia] == uvOptions[1]) + { + if ((m_uvs[ib] == uvOptions[0]) || (m_uvs[ib] == uvOptions[1])) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ib] = uvOptions[2]; m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[2]){ + else if (m_uvs[ic] == uvOptions[2]) + { m_uvs[ib] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[3]){ + else if (m_uvs[ic] == uvOptions[3]) + { m_uvs[ib] = uvOptions[2]; } } - else if(m_uvs[ib] == uvOptions[2]){ + else if (m_uvs[ib] == uvOptions[2]) + { m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ib] == uvOptions[3]){ + else if (m_uvs[ib] == uvOptions[3]) + { m_uvs[ic] = uvOptions[2]; } } - else if(m_uvs[ia] == uvOptions[2]){ - if((m_uvs[ib] == uvOptions[0])||(m_uvs[ib] == uvOptions[2])){ - if(m_uvs[ic] == uvOptions[0]){ + else if (m_uvs[ia] == uvOptions[2]) + { + if ((m_uvs[ib] == uvOptions[0]) || (m_uvs[ib] == uvOptions[2])) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ib] = uvOptions[1]; m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[1]){ + else if (m_uvs[ic] == uvOptions[1]) + { m_uvs[ib] = uvOptions[3]; } - else if(m_uvs[ic] == uvOptions[3]){ + else if (m_uvs[ic] == uvOptions[3]) + { m_uvs[ib] = uvOptions[1]; } } - else if(m_uvs[ib] == uvOptions[1]){ + else if (m_uvs[ib] == uvOptions[1]) + { m_uvs[ic] = uvOptions[3]; } - else if(m_uvs[ib] == uvOptions[3]){ + else if (m_uvs[ib] == uvOptions[3]) + { m_uvs[ic] = uvOptions[1]; } } - if(m_uvs[ia] == uvOptions[3]){ - if((m_uvs[ib] == uvOptions[0])||(m_uvs[ib] == uvOptions[3])){ - if(m_uvs[ic] == uvOptions[0]){ + if (m_uvs[ia] == uvOptions[3]) + { + if ((m_uvs[ib] == uvOptions[0]) || (m_uvs[ib] == uvOptions[3])) + { + if (m_uvs[ic] == uvOptions[0]) + { m_uvs[ib] = uvOptions[1]; m_uvs[ic] = uvOptions[2]; } - else if(m_uvs[ic] == uvOptions[1]){ + else if (m_uvs[ic] == uvOptions[1]) + { m_uvs[ib] = uvOptions[2]; } - else if(m_uvs[ic] == uvOptions[2]){ + else if (m_uvs[ic] == uvOptions[2]) + { m_uvs[ib] = uvOptions[1]; } } - else if(m_uvs[ib] == uvOptions[1]){ + else if (m_uvs[ib] == uvOptions[1]) + { m_uvs[ic] = uvOptions[2]; } - else if(m_uvs[ib] == uvOptions[2]){ + else if (m_uvs[ib] == uvOptions[2]) + { m_uvs[ic] = uvOptions[1]; } } } - /** - * For a given voxel, execute the polygonization algorithm to generate mesh vertices, triangles, normals, and UVs. - * @param v the voxel to mesh - * @return number of created triangles - */ - int Polygonize(Voxel v) { + /// + /// For a given voxel, execute the polygonization algorithm to generate mesh vertices, triangles, normals, and UVs. + /// + /// The voxel to mesh. + /// Number of created triangles. + private int Polygonize(Voxel v) + { if (v == null) + { return 0; + } - //allows us to track if the mesh is dirty and needs updating - //needs to be above the early exit checks, otherwise voxels - //keep getting marked as dirty + // allows us to track if the mesh is dirty and needs updating + // needs to be above the early exit checks, otherwise voxels + // keep getting marked as dirty v.lastMeshedValue = v.value; - //keep the meshing within the volume bounds + // keep the meshing within the volume bounds if (v.xID >= m_voxelResolution) + { return 0; + } if (v.yID >= m_voxelResolution) + { return 0; + } if (v.zID >= m_voxelResolution) + { return 0; + } if (v.xID < 0) + { return 0; + } if (v.yID < 0) + { return 0; + } if (v.zID < 0) + { return 0; + } Voxel v0 = v; - //this conditions te input to the polygonize, and make sure all the neighbors have valid entries - //if all input voxels are gauranteed to not be edge voxels, this may not be necessary. + // this conditions te input to the polygonize, and make sure all the neighbors have valid entries + // if all input voxels are gauranteed to not be edge voxels, this may not be necessary. - //OPIMTIZATION - voxel can store meshing neighbors, rather than query each - //skip if they are null - Voxel v1 = QueryVoxel(v.xID+1, v.yID, v.zID); + // OPIMTIZATION - voxel can store meshing neighbors, rather than query each + // skip if they are null + Voxel v1 = QueryVoxel(v.xID + 1, v.yID, v.zID); if (v1 == null) + { return 0; - Voxel v2 = QueryVoxel(v.xID+1, v.yID+1, v.zID); + } + Voxel v2 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID); if (v2 == null) + { return 0; - Voxel v3 = QueryVoxel(v.xID, v.yID+1, v.zID); + } + Voxel v3 = QueryVoxel(v.xID, v.yID + 1, v.zID); if (v3 == null) + { return 0; - Voxel v4 = QueryVoxel(v.xID, v.yID, v.zID+1); + } + Voxel v4 = QueryVoxel(v.xID, v.yID, v.zID + 1); if (v4 == null) + { return 0; - Voxel v5 = QueryVoxel(v.xID+1, v.yID, v.zID+1); + } + Voxel v5 = QueryVoxel(v.xID + 1, v.yID, v.zID + 1); if (v5 == null) + { return 0; - Voxel v6 = QueryVoxel(v.xID+1, v.yID+1, v.zID+1); + } + Voxel v6 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID + 1); if (v6 == null) + { return 0; - Voxel v7 = QueryVoxel(v.xID, v.yID+1, v.zID+1); + } + Voxel v7 = QueryVoxel(v.xID, v.yID + 1, v.zID + 1); if (v7 == null) + { return 0; + } int triangleStart = m_triangles.Count; int createdTriangles = Polygonizer.Process(m_meshingIsolevel, - v0.value, - v1.value, - v2.value, - v3.value, - v4.value, - v5.value, - v6.value, - v7.value, - v0.anchor, - v1.anchor, - v2.anchor, - v3.anchor, - v4.anchor, - v5.anchor, - v6.anchor, - v7.anchor, - ref m_vertices,ref m_triangles); - - //compute per vertex normal + v0.value, + v1.value, + v2.value, + v3.value, + v4.value, + v5.value, + v6.value, + v7.value, + v0.anchor, + v1.anchor, + v2.anchor, + v3.anchor, + v4.anchor, + v5.anchor, + v6.anchor, + v7.anchor, + ref m_vertices, + ref m_triangles); + + // compute per vertex normal int addedVertCount = 0; - while (m_normals.Count < m_vertices.Count) { - m_normals.Add(new Vector3(0,1,0)); - m_uvs.Add (new Vector2 (-1, -1)); + while (m_normals.Count < m_vertices.Count) + { + m_normals.Add(new Vector3(0, 1, 0)); + m_uvs.Add(new Vector2(-1, -1)); addedVertCount++; } - for (int i = triangleStart; i < m_triangles.Count; i += 3) { - v.trianglesIndicies.Add(i);//add it to each voxel this impacted? + for (int i = triangleStart; i < m_triangles.Count; i += 3) + { + v.trianglesIndicies.Add(i); // add it to each voxel this impacted? int ia = m_triangles[i]; - int ib = m_triangles[i+1]; - int ic = m_triangles[i+2]; + int ib = m_triangles[i + 1]; + int ic = m_triangles[i + 2]; Vector3 a = m_vertices[ia]; Vector3 b = m_vertices[ib]; Vector3 c = m_vertices[ic]; - Vector3 n = Vector3.Cross(a-b,b-c).normalized; + Vector3 n = Vector3.Cross(a - b, b - c).normalized; m_normals[ia] = n; m_normals[ib] = n; m_normals[ic] = n; - CalculateUVs(ia,ib,ic); + CalculateUVs(ia, ib, ic); } - //adjust per voxel normal - + // adjust per voxel normal return createdTriangles; } - - /** - * EXPERIMENTAL - simplfying planar sections of the mesh - */ - public void SimplifyPlanarGroup(Voxel v0, Voxel v1, Voxel v2, Voxel v3) { - - Voxel[] voxels = new Voxel[4]; - voxels [0] = v0; - voxels [1] = v1; - voxels [2] = v2; - voxels [3] = v3; - - int totalTriangles = 0; - Vector3 averageNormal = new Vector3 (0, 0, 0); - List triIndicies = new List(); - foreach (Voxel v in voxels) { - if(v == null) - return; - if(v.trianglesIndicies.Count != 2)//only do planar groups right now - return; - totalTriangles += v.trianglesIndicies.Count; - foreach(int triIndex in v.trianglesIndicies) - averageNormal += m_normals[m_triangles[triIndex]]; - } - - averageNormal /= totalTriangles; - - //too contentious - if (averageNormal.magnitude < 0.75f) - return; - - //we have 4 voxel neighors with triangles - //see if the normals are within tolernace - - float variance = 0; - foreach (Voxel v in voxels) { - foreach(int triIndex in v.trianglesIndicies) { - variance += Vector3.SqrMagnitude(m_normals[m_triangles[triIndex]]-averageNormal); - triIndicies.Add(triIndex); - } - } - variance /= totalTriangles; - - if (variance > 0.05) - return; - - //we have triangles in a plane - - Vector3 avg = new Vector3 (); - foreach (int index in triIndicies) { - avg += m_vertices[m_triangles[index]]; - avg += m_vertices[m_triangles[index+1]]; - avg += m_vertices[m_triangles[index+2]]; - } - avg /= totalTriangles * 3; - - foreach (int index in triIndicies) { - bool remove = false; - if(Vector3.SqrMagnitude(m_vertices[m_triangles[index]]-avg) < 0.05f) { - remove = true; - } - if(Vector3.SqrMagnitude(m_vertices[m_triangles[index+1]]-avg) < 0.05f) { - remove = true; - } - if(Vector3.SqrMagnitude(m_vertices[m_triangles[index+2]]-avg) < 0.05f) { - remove = true; - } - - if(remove) { - m_triangles.RemoveAt(index); - m_triangles.RemoveAt(index+1); - m_triangles.RemoveAt(index+2); - } - } - - DebugDrawing.CrossX(avg + transform.position, 0.01f, Color.magenta); - - //lets create the neighbor graph - - } - - /** - * EXPERIMENTAL - simpligy planar parts of the mesh - */ - public void SimplifyByVoxel(Voxel v) { - //this conditions te input to the polygonize, and make sure all the neighbors have valid entries - //if all input voxels are gauranteed to not be edge voxels, this may not be necessary. - Voxel v0 = v; - Voxel v1 = QueryVoxel(v.xID+1, v.yID, v.zID); - Voxel v2 = QueryVoxel(v.xID+1, v.yID+1, v.zID); - Voxel v3 = QueryVoxel(v.xID, v.yID+1, v.zID); - Voxel v4 = QueryVoxel(v.xID, v.yID, v.zID+1); - Voxel v5 = QueryVoxel(v.xID+1, v.yID, v.zID+1); - Voxel v6 = QueryVoxel(v.xID, v.yID+1, v.zID+1); - - //three planar directions.. diagonals aren't necessary? - SimplifyPlanarGroup (v0, v1, v2, v3); - SimplifyPlanarGroup (v0, v1, v4, v5); - SimplifyPlanarGroup (v0, v2, v3, v6); - } - - /** - * Rebuild the Unity mesh - * @return 1 if successful, -1 if there was an error - */ - - public int RegenerateMesh() { - - if (!isDirty) - return 0; - if (m_isRegenerating) - return 0; - - if (m_meshFilter == null) { - Debug.Log ("mesh filter is null"); - return -1; - } - - Mesh mesh = m_meshFilter.sharedMesh; - if (mesh == null){ - Debug.Log ("shared mesh was null, creating new"); - m_meshFilter.mesh = new Mesh(); - mesh = m_meshFilter.sharedMesh; - } - - if (mesh == null) { - Debug.Log("mesh is null"); - return -1; - } - - m_isRegenerating = true; - - mesh.Clear (); - m_vertices.Clear (); - m_triangles.Clear (); - m_normals.Clear (); - m_uvs.Clear (); - - PrepareVoxels (); - - foreach (VoxelHashTree t in voxelStorage.GetEnumerable()) { - if (t.Voxel == null) { - Debug.Log ("Error: VoxelTree has null voxel"); - continue; - } - - if(Polygonize(t.Voxel) == 0) { - //no triangles were created, consider deleting this voxel? - //just delecting, causes a lot of re-creation. need o be smarter - } - } - - SetMesh(); - isDirty = false; - m_isRegenerating = false; - - return 1; - } - - /** - * Update the Unity Meshfilter data. - */ - - public void SetMesh() { - if (m_vertices == null) { - Debug.Log("vertices null"); - return; - } - if (m_normals == null) { - Debug.Log("normals null"); - return; - } - if (m_uvs == null) { - Debug.Log("uvs null"); - return; - } - if (m_triangles == null) { - Debug.Log("triangles null"); - return; - } - - if (m_meshFilter == null) { - Debug.Log("mf is null"); - return; - } - - Mesh mesh = m_meshFilter.sharedMesh; - if (mesh == null){ - m_meshFilter.mesh = new Mesh(); - mesh = m_meshFilter.sharedMesh; - } - - if (mesh == null) { - Debug.Log("mesh is null"); - return; - } - mesh.Clear (); - mesh.MarkDynamic(); - mesh.vertices = m_vertices.ToArray(); - mesh.normals = m_normals.ToArray(); - mesh.uv = m_uvs.ToArray (); - - if (mesh.vertices == null) { - Debug.Log("mesh vertices null"); - return; - } - - if (mesh.normals == null) { - Debug.Log("mesh normals null"); - return; - } - - if (mesh.uv == null) { - Debug.Log("mesh uv null"); - return; - } - - mesh.triangles = m_triangles.ToArray(); - - if (mesh.triangles == null) { - Debug.Log("mesh triangles null"); - return; - } - - mesh.RecalculateBounds (); - mesh.Optimize (); - - GetComponent().sharedMesh = null; - GetComponent().sharedMesh = mesh; - } - - /** - * Debug Draw the normals - */ - - public void DebugDrawNormals() { - for (int i =0; i < m_vertices.Count; i++) { - Vector3 p = transform.position + m_vertices[i]; - Debug.DrawLine (p,p + m_normals[i]*m_voxelSize,Color.red); - } - } - - /** - * Update called once per frame - */ - void Update () { + /// + /// Update called once per frame. + /// + private void Update() + { } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshManager.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshManager.cs index 19b5a278..ed72994c 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshManager.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/DynamicMeshManager.cs @@ -1,325 +1,359 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; -/** - * DynamicMeshManager - * This class handles all of the administrative work of inserting points, creating new meshes, - * queueing meshes to be regenerated. Meshing volumes are allocated dynamically in a unit cube grid. - * When points are inserted into the mesh manager, it creates and updates the appropriate mesh cube. - * Mesh cubes that are marked dirty, at processed in the queue each frame. If the user spends a lot - * of time in the same space, the number of meshing cubes that need to be updated should slowly approach zero. - * The mesh geometery is available to any other Unity tool such as hit testing of path planning. - */ -public class DynamicMeshManager : MonoBehaviour { - - /** - * Prefab that gets instantiated when new cube volumes are needed. - * It has the DynamicMeshingCube script - */ +using UnityEngine; + +/// +/// This class handles all of the administrative work of inserting points, creating new meshes, +/// queueing meshes to be regenerated. Meshing volumes are allocated dynamically in a unit cube grid. +/// When points are inserted into the mesh manager, it creates and updates the appropriate mesh cube. +/// Mesh cubes that are marked dirty, at processed in the queue each frame. If the user spends a lot +/// of time in the same space, the number of meshing cubes that need to be updated should slowly approach zero. +/// The mesh geometery is available to any other Unity tool such as hit testing of path planning. +/// +public class DynamicMeshManager : MonoBehaviour +{ + /// + /// Prefab that gets instantiated when new cube volumes are needed. + /// It has the DynamicMeshingCube script. + /// public GameObject m_meshingCubePrefab; - /** - * Resolution of the cube meshes. Specifies divisions per meter. - */ + /// + /// Resolution of the cube meshes. Specifies divisions per meter. + /// public int m_voxelResolution = 10; - /** - * The amount of time per frame allowed to be spend on mesh regeneration. - */ + /// + /// The amount of time per frame allowed to be spend on mesh regeneration. + /// public float m_meshingTimeBudgetMS = 10; + + /// + /// Handle for the main camera, primarily to set position when in dataset playback. + /// + public Camera m_mainCamera; - /** - * Keeps track of total vertices in the mesh system. - */ + /// + /// Flag for raycast development testing. + /// + public bool m_raycastTesting; + + /// + /// Keeps track of total vertices in the mesh system. + /// private int m_totalVertices = 0; - /** - * Keeps track of the total triangles in the system. - */ + /// + /// Keeps track of the total triangles in the system. + /// private int m_totalTriangles = 0; - /** - * Keeps track of the total points that have been inserted. - */ + /// + /// Keeps track of the total points that have been inserted. + /// private int m_insertCount = 0; - /** - * Keeps track of the total number of meshing cubes created. - */ + /// + /// Keeps track of the total number of meshing cubes created. + /// private int m_totalMeshCubes = 0; - /** - * Flag to let the update and insertion threads know it is being cleared. - */ + /// + /// Flag to let the update and insertion threads know it is being cleared. + /// private bool m_isClearing = false; - /** - * Queue for tracking which meshing cubes need to be regenerated. - */ - private Queue m_regenerationQueue = new Queue (); + /// + /// Queue for tracking which meshing cubes need to be regenerated. + /// + private Queue m_regenerationQueue = new Queue(); - /** - * HashTree datastructure for storing the meshing cubes. - */ + /// + /// HashTree datastructure for storing the meshing cubes. + /// private VolumetricHashTree m_meshStorage = new VolumetricHashTree(null, 0); - /** - * Keeps track of how long was spent remeshing each frame. - */ + /// + /// Keeps track of how long was spent remeshing each frame. + /// private float m_remeshingTime = 0; - /** - * Limit on the number of meshes that can be remeshed each frame. - */ + /// + /// Limit on the number of meshes that can be remeshed each frame. + /// private int m_maximumRemeshingCountPerFrame = 1; - /** - * Keeps track of the time spend inserting points each depth frame update - */ + /// + /// Keeps track of the time spend inserting points each depth frame update. + /// private float m_pointInsertionTime = 0; - /** - * Smoothing variable for FPS-like measurements - */ + /// + /// Smoothing variable for FPS-like measurements. + /// private float m_frameRateSmoothing = 0.97f; - /** - * Keeps track of the last time the meshing system receive an Update - */ + /// + /// Keeps track of the last time the meshing system receive an Update. + /// private float m_lastUpdateTime = 0; - /** - * Keeps track of the number of rendering frames updated. - */ + /// + /// Keeps track of the number of rendering frames updated. + /// private int m_frameCount = 0; - /** - * Handle for the main camera, primarily to set position when in dataset playback. - */ - public Camera m_mainCamera; - - /** - * Storage of the voxels that are intersected with a raycast test. - */ - List m_raycastHits = null; - - /** - * Flag for raycast development testing. - */ - public bool m_raycastTesting; - - /** - * Testing for raycast development. - */ - Vector3 m_raycastStart; + /// + /// Storage of the voxels that are intersected with a raycast test. + /// + private List m_raycastHits = null; - /** - * Testing for raycast development. - */ - Vector3 m_raycastStop; + /// + /// Testing for raycast development. + /// + private Vector3 m_raycastStart; + /// + /// Testing for raycast development. + /// + private Vector3 m_raycastStop; - float m_meshingStart = 0; - float m_meshingStop = 0; - - /** - * Used for initialization. - */ - void Start () { + private float m_meshingStart = 0; + private float m_meshingStop = 0; + /// + /// Used for initialization. + /// + public void Start() + { } - /** - * Gets the time smoothing parameter. - */ - public float TimeSmoothing { - get { - return m_frameRateSmoothing; - } - set { - m_frameRateSmoothing = value; - } + /// + /// Gets the time smoothing parameter. + /// + /// The time smoothing. + public float TimeSmoothing + { + get { return m_frameRateSmoothing; } + set { m_frameRateSmoothing = value; } } - /** - * Gets the point insertion time. - */ - public float InsertionTime { - get { - return m_pointInsertionTime; - } - set { - m_pointInsertionTime = value; - } + /// + /// Gets the point insertion time. + /// + /// The insertion time. + public float InsertionTime + { + get { return m_pointInsertionTime; } + set { m_pointInsertionTime = value; } } - /** - * Insert a point into the meshing volumes. - * @param p the 3D point to be inserted - * @param obs the direction of the observation vector from the camera toward the point - * @param w weight of the observation - */ - public void InsertPoint(Vector3 p, Vector3 obs, float weight) { + /// + /// Insert a point into the meshing volumes. + /// + /// The 3D point to be inserted. + /// The direction of the observation vector from the camera toward the point. + /// Weight of the observation. + public void InsertPoint(Vector3 p, Vector3 obs, float weight) + { if (m_isClearing) + { return; - m_meshStorage.InsertPoint(p,obs,weight, m_meshingCubePrefab, transform, m_voxelResolution); + } + m_meshStorage.InsertPoint(p, obs, weight, m_meshingCubePrefab, transform, m_voxelResolution); m_insertCount++; } - /** - * Searches for meshing cubes that have been mark dirty and adds them to the queue for remeshing. - */ - public void QueueDirtyMeshesForRegeneration() { + /// + /// Searches for meshing cubes that have been mark dirty and adds them to the queue for remeshing. + /// + public void QueueDirtyMeshesForRegeneration() + { if (m_isClearing) + { return; + } - //enque dirty meshes + // enque dirty meshes int count = 0; - foreach (VolumetricHashTree o in m_meshStorage.GetEnumerable()) { + foreach (VolumetricHashTree o in m_meshStorage.GetEnumerable()) + { count += 1; - if(o.DynamicMeshCube == null) + if (o.DynamicMeshCube == null) + { continue; + } - if(o.DynamicMeshCube.IsDirty) { - if(!m_regenerationQueue.Contains(o.DynamicMeshCube)) + if (o.DynamicMeshCube.IsDirty) + { + if (!m_regenerationQueue.Contains(o.DynamicMeshCube)) + { m_regenerationQueue.Enqueue(o.DynamicMeshCube); + } } } } - /** - * Print out debug information for each of the meshing cubes. - */ - public void PrintDebugInfo() { - foreach (VolumetricHashTree o in m_meshStorage.GetEnumerable()) { - if(o.DynamicMeshCube == null) + /// + /// Print out debug information for each of the meshing cubes. + /// + public void PrintDebugInfo() + { + foreach (VolumetricHashTree o in m_meshStorage.GetEnumerable()) + { + if (o.DynamicMeshCube == null) + { continue; + } o.DynamicMeshCube.PrintDebugInfo(); } } - /** - * Recompute statistics about the meshing cubes. - */ - public void UpdateStats() { + /// + /// Recompute statistics about the meshing cubes. + /// + public void UpdateStats() + { m_totalVertices = 0; m_totalTriangles = 0; m_totalMeshCubes = 0; - m_meshStorage.ComputeStats (ref m_totalVertices, ref m_totalTriangles, ref m_totalMeshCubes); + m_meshStorage.ComputeStats(ref m_totalVertices, ref m_totalTriangles, ref m_totalMeshCubes); } - - /** - * Clears all meshing data. - */ - public void Clear() { - //i think this causes a thread contention because we are updating the mesh in the Update call + /// + /// Clears all meshing data. + /// + public void Clear() + { + // i think this causes a thread contention because we are updating the mesh in the Update call m_isClearing = true; m_insertCount = 0; - m_regenerationQueue.Clear (); - m_meshStorage.Clear (); + m_regenerationQueue.Clear(); + m_meshStorage.Clear(); m_isClearing = false; } - /** - * Displays statistics and diagnostics information about the meshing cubes - */ - void OnGUI() + /// + /// Displays statistics and diagnostics information about the meshing cubes. + /// + public void OnGUI() { - GUI.Label(new Rect(10,20,1000,30), "Persistent Path: " + Application.persistentDataPath); - GUI.Label(new Rect(10,40,1000,30), "Total Verts/Triangles: " + m_totalVertices + "/" + m_totalTriangles + " Volumes: " + m_totalMeshCubes + " UpdateQueue:" + m_regenerationQueue.Count); - GUI.Label(new Rect(10,60,1000,30), "Insert Count: " + m_insertCount); - GUI.Label(new Rect(10,80,1000,30), "RemeshingTime: " + m_remeshingTime.ToString("F6") + " Remeshing Count: " + m_maximumRemeshingCountPerFrame); - GUI.Label(new Rect(10,100,1000,30), "InsertionTime: " + m_pointInsertionTime.ToString("F6")); - GUI.Label(new Rect(10,120,1000,30), "Last Update Time: " + m_lastUpdateTime.ToString("F6")); - GUI.Label(new Rect(10,140,1000,30), "Version: " + "15.06.05"); - - if (GUI.Button (new Rect (Screen.width - 160, 20, 140, 80), "Clear")) { + GUI.Label(new Rect(10, 20, 1000, 30), "Persistent Path: " + Application.persistentDataPath); + GUI.Label(new Rect(10, 40, 1000, 30), "Total Verts/Triangles: " + m_totalVertices + "/" + m_totalTriangles + " Volumes: " + m_totalMeshCubes + " UpdateQueue:" + m_regenerationQueue.Count); + GUI.Label(new Rect(10, 60, 1000, 30), "Insert Count: " + m_insertCount); + GUI.Label(new Rect(10, 80, 1000, 30), "RemeshingTime: " + m_remeshingTime.ToString("F6") + " Remeshing Count: " + m_maximumRemeshingCountPerFrame); + GUI.Label(new Rect(10, 100, 1000, 30), "InsertionTime: " + m_pointInsertionTime.ToString("F6")); + GUI.Label(new Rect(10, 120, 1000, 30), "Last Update Time: " + m_lastUpdateTime.ToString("F6")); + GUI.Label(new Rect(10, 140, 1000, 30), "Version: " + "15.06.05"); + + if (GUI.Button(new Rect(Screen.width - 160, 20, 140, 80), "Clear")) + { Clear(); } } - /** - * Update is called once per frame and progressively remeshes volumes that are in the queue. - */ - void Update () { + /// + /// Update is called once per frame and progressively remeshes volumes that are in the queue. + /// + public void Update() + { m_frameCount++; - int meshUpdateCount = 0; - //update 1 cell in the top of queue + // update 1 cell in the top of queue if (m_maximumRemeshingCountPerFrame < 1) + { m_maximumRemeshingCountPerFrame = 1; + } if (m_maximumRemeshingCountPerFrame > 10) + { m_maximumRemeshingCountPerFrame = 10; + } { - for(int i = 0; i < m_maximumRemeshingCountPerFrame; i++) { - if(m_regenerationQueue.Count == 0) { - if((m_meshingStart != 0)&&(m_meshingStop == 0)) { + for (int i = 0; i < m_maximumRemeshingCountPerFrame; i++) + { + if (m_regenerationQueue.Count == 0) + { + if ((m_meshingStart != 0) && (m_meshingStop == 0)) + { m_meshingStop = UnityEngine.Time.realtimeSinceStartup; Debug.Log("Meshing time: " + (m_meshingStop - m_meshingStart)); } break; } - if(m_meshingStart == 0) + if (m_meshingStart == 0) + { m_meshingStart = UnityEngine.Time.realtimeSinceStartup; + } float start = Time.realtimeSinceStartup; - ((DynamicMeshCube)m_regenerationQueue.Dequeue ()).RegenerateMesh(); + ((DynamicMeshCube)m_regenerationQueue.Dequeue()).RegenerateMesh(); float stop = Time.realtimeSinceStartup; - m_remeshingTime = m_frameRateSmoothing*m_remeshingTime + (1.0f-m_frameRateSmoothing)*(stop - start); + m_remeshingTime = (m_frameRateSmoothing * m_remeshingTime) + ((1.0f - m_frameRateSmoothing) * (stop - start)); meshUpdateCount++; } - if(m_remeshingTime > float.Epsilon) - m_maximumRemeshingCountPerFrame = (int)(m_meshingTimeBudgetMS*0.001f / m_remeshingTime); - UpdateStats (); + if (m_remeshingTime > float.Epsilon) + { + m_maximumRemeshingCountPerFrame = (int)(m_meshingTimeBudgetMS * 0.001f / m_remeshingTime); + } + UpdateStats(); } - if (m_raycastTesting) { + if (m_raycastTesting) + { m_raycastStart = m_mainCamera.transform.position; - m_raycastStop = m_mainCamera.transform.position + m_mainCamera.transform.forward*5; + m_raycastStop = m_mainCamera.transform.position + (m_mainCamera.transform.forward * 5); m_raycastHits = m_meshStorage.RaycastVoxelHitlist(m_raycastStart, m_raycastStop); - if(m_raycastHits == null) { + if (m_raycastHits == null) + { Debug.Log("Error Dynamic Mesh - Raycast returned null"); } - if(m_raycastHits.Count == 0) { - Debug.DrawLine(m_raycastStart, m_raycastStop,Color.red); - }else { - foreach(Voxel v in m_raycastHits) { - Vector3 voxelSize = new Vector3(v.size,v.size,v.size)/2; + if (m_raycastHits.Count == 0) + { + Debug.DrawLine(m_raycastStart, m_raycastStop, Color.red); + } + else + { + foreach (Voxel v in m_raycastHits) + { + Vector3 voxelSize = new Vector3(v.size, v.size, v.size) / 2; Vector3 min = v.anchor + v.parent.position - voxelSize; Vector3 max = v.anchor + v.parent.position + voxelSize; - DebugDrawing.Box(min, max,Color.green); + DebugDrawing.Box(min, max, Color.green); } - Debug.DrawLine(m_raycastStart, m_raycastStop,Color.green); + Debug.DrawLine(m_raycastStart, m_raycastStop, Color.green); } } - if (Input.GetKeyDown (KeyCode.C)) - Clear (); - + if (Input.GetKeyDown(KeyCode.C)) + { + Clear(); + } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/MeshBuilderPoseController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/MeshBuilderPoseController.cs index 7efc73d7..8c5eb52e 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/MeshBuilderPoseController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/MeshBuilderPoseController.cs @@ -1,31 +1,59 @@ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- +using System; using System.Collections; +using UnityEngine; using Tango; -using System; -public class MeshBuilderPoseController : MonoBehaviour , ITangoPose { +/// +/// Pose controller for this sample. +/// +public class MeshBuilderPoseController : MonoBehaviour, ITangoPose +{ private TangoApplication m_tangoApplication; // Instance for Tango Client private Vector3 m_tangoPosition; // Position from Pose Callback private Quaternion m_tangoRotation; // Rotation from Pose Callback private Vector3 m_startPosition; // Start Position of the camera - - // Matrix for Tango coordinate frame to Unity coordinate frame conversion. - // Start of service frame with respect to Unity world frame. + /// + /// Matrix for Tango coordinate frame to Unity coordinate frame conversion. + /// Start of service frame with respect to Unity world frame. + /// private Matrix4x4 m_uwTss; - // Unity camera frame with respect to device frame. + + /// + /// Unity camera frame with respect to device frame. + /// private Matrix4x4 m_dTuc; - - // Use this for initialization - void Start () + /// + /// Use this for initialization. + /// + public void Start() { // Initialize some variables - m_tangoRotation = Quaternion.Euler(90,0,0); + m_tangoRotation = Quaternion.Euler(90, 0, 0); m_tangoPosition = Vector3.zero; m_startPosition = transform.position; m_tangoApplication = FindObjectOfType(); - if(m_tangoApplication != null) + if (m_tangoApplication != null) { // Request Tango permissions m_tangoApplication.RegisterPermissionsCallback(PermissionsCallback); @@ -38,38 +66,24 @@ void Start () } m_uwTss = new Matrix4x4(); - m_uwTss.SetColumn (0, new Vector4 (1.0f, 0.0f, 0.0f, 0.0f)); - m_uwTss.SetColumn (1, new Vector4 (0.0f, 0.0f, 1.0f, 0.0f)); - m_uwTss.SetColumn (2, new Vector4 (0.0f, 1.0f, 0.0f, 0.0f)); - m_uwTss.SetColumn (3, new Vector4 (0.0f, 0.0f, 0.0f, 1.0f)); + m_uwTss.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + m_uwTss.SetColumn(1, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); + m_uwTss.SetColumn(2, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + m_uwTss.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); m_dTuc = new Matrix4x4(); - m_dTuc.SetColumn (0, new Vector4 (1.0f, 0.0f, 0.0f, 0.0f)); - m_dTuc.SetColumn (1, new Vector4 (0.0f, 1.0f, 0.0f, 0.0f)); - m_dTuc.SetColumn (2, new Vector4 (0.0f, 0.0f, -1.0f, 0.0f)); - m_dTuc.SetColumn (3, new Vector4 (0.0f, 0.0f, 0.0f, 1.0f)); - + m_dTuc.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + m_dTuc.SetColumn(1, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + m_dTuc.SetColumn(2, new Vector4(0.0f, 0.0f, -1.0f, 0.0f)); + m_dTuc.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); Application.targetFrameRate = 60; - - } - - // Permissions callback - private void PermissionsCallback(bool success) - { - if(success) - { - m_tangoApplication.InitApplication(); // Initialize Tango Client - m_tangoApplication.InitProviders(string.Empty); // Initialize listeners - m_tangoApplication.ConnectToService(); // Connect to Tango Service - } - else - { - AndroidHelper.ShowAndroidToastMessage("Motion Tracking Permissions Needed", true); - } } - // Pose callbacks from Project Tango + /// + /// Pose callbacks from Project Tango. + /// + /// Tango pose. public void OnTangoPoseAvailable(Tango.TangoPoseData pose) { // Do nothing if we don't get a pose @@ -78,59 +92,79 @@ public void OnTangoPoseAvailable(Tango.TangoPoseData pose) Debug.Log("TangoPoseData is null."); return; } + // The callback pose is for device with respect to start of service pose. if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) { if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) { - // Cache the position and rotation to be set in the update function. - m_tangoPosition = new Vector3((float)pose.translation [0], - (float)pose.translation [1], - (float)pose.translation [2]); + m_tangoPosition = new Vector3((float)pose.translation[0], + (float)pose.translation[1], + (float)pose.translation[2]); - m_tangoRotation = new Quaternion((float)pose.orientation [0], - (float)pose.orientation [1], - (float)pose.orientation [2], - (float)pose.orientation [3]); -// Debug.Log("Tango VALID pose: " + m_tangoPosition + " " + m_tangoRotation); + m_tangoRotation = new Quaternion((float)pose.orientation[0], + (float)pose.orientation[1], + (float)pose.orientation[2], + (float)pose.orientation[3]); +//// Debug.Log("Tango VALID pose: " + m_tangoPosition + " " + m_tangoRotation); } } } - + /// - /// Transforms the Tango pose which is in Start of Service to Device frame to Unity coordinate system. + /// Update is called once per frame. /// - /// The Tango Pose in unity coordinate system. - /// Translation. - /// Rotation. - /// Scale. - Matrix4x4 TransformTangoPoseToUnityCoordinateSystem(Vector3 translation, Quaternion rotation, Vector3 scale) + public void Update() { - Matrix4x4 ssTd = Matrix4x4.TRS(translation, rotation, scale); - return m_uwTss * ssTd * m_dTuc; - } - - // Update is called once per frame - void Update() - { -// Debug.Log("Tango update: " + m_tangoPosition + " " + m_tangoRotation); - + //// Debug.Log("Tango update: " + m_tangoPosition + " " + m_tangoRotation); + #if UNITY_EDITOR PoseProvider.GetMouseEmulation(ref m_tangoPosition, ref m_tangoRotation); transform.position = m_tangoPosition + m_startPosition; transform.rotation = m_tangoRotation; -#else + #else Matrix4x4 uwTuc = TransformTangoPoseToUnityCoordinateSystem(m_tangoPosition, m_tangoRotation, Vector3.one); + // Extract new local position - transform.position = (uwTuc.GetColumn(3)); + transform.position = uwTuc.GetColumn(3); transform.position = transform.position + m_startPosition; // Extract new local rotation transform.rotation = Quaternion.LookRotation(uwTuc.GetColumn(2), uwTuc.GetColumn(1)); -#endif + #endif + } + /// + /// Permissions callback. + /// + /// If set to true permissions are granted. + private void PermissionsCallback(bool success) + { + if (success) + { + m_tangoApplication.InitApplication(); // Initialize Tango Client + m_tangoApplication.InitProviders(string.Empty); // Initialize listeners + m_tangoApplication.ConnectToService(); // Connect to Tango Service + } + else + { + AndroidHelper.ShowAndroidToastMessage("Motion Tracking Permissions Needed", true); + } + } + + /// + /// Transforms the Tango pose which is in Start of Service to Device frame to Unity coordinate system. + /// + /// The Tango Pose in unity coordinate system. + /// Translation. + /// Rotation. + /// Scale. + private Matrix4x4 TransformTangoPoseToUnityCoordinateSystem(Vector3 translation, Quaternion rotation, Vector3 scale) + { + Matrix4x4 ssTd = Matrix4x4.TRS(translation, rotation, scale); + return m_uwTss * ssTd * m_dTuc; } } \ No newline at end of file diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Polygonizer.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Polygonizer.cs index 61f65b3b..3342affb 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Polygonizer.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Polygonizer.cs @@ -1,19 +1,3 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - // ------------------------------------------------------------------------------ // // This code was generated by a tool. diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/TopDownFollow.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/TopDownFollow.cs index 01394081..9029c18a 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/TopDownFollow.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/TopDownFollow.cs @@ -1,31 +1,56 @@ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; - -/** - * Follows that target from above, for top down view of the main camera - */ -public class TopDownFollow : MonoBehaviour { - +/// +/// Follows that target from above, for top down view of the main camera. +/// +public class TopDownFollow : MonoBehaviour +{ public GameObject followTarget; public bool followYaw = false; private Vector3 pos; private Vector3 rotation; - // Use this for initialization - void Start () { + /// + /// Use this for initialization. + /// + public void Start() + { transform.parent = null; pos = transform.position; } - // Update is called once per frame - void Update () { + /// + /// Update is called once per frame. + /// + public void Update() + { pos.x = followTarget.transform.position.x; pos.z = followTarget.transform.position.z; transform.position = pos; - if (followYaw) { + if (followYaw) + { rotation = followTarget.transform.rotation.eulerAngles; rotation.x = 90; rotation.z = 0; diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VolumetricHashTree.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VolumetricHashTree.cs index 1f41a7c8..29f393cc 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VolumetricHashTree.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VolumetricHashTree.cs @@ -1,418 +1,508 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; +using UnityEngine; - -/** - * Volumetric Hash Tree - * A binary tree datastructure that uses a hashkey based on the 3D coordinates. - * Space surrounding the origin is divided into 1 meter cubes. The hashkey is a - * reversible index into that volume. allows quick indexing, and ray marching - * through space. Supports a 1000m x 1000m x 1000m volume centered at the origin. - */ -public class VolumetricHashTree { - - /** - * Left subtree. - */ +/// +/// A binary tree datastructure that uses a hashkey based on the 3D coordinates. +/// Space surrounding the origin is divided into 1 meter cubes. The hashkey is a +/// reversible index into that volume. allows quick indexing, and ray marching +/// through space. Supports a 1000m x 1000m x 1000m volume centered at the origin. +/// +public class VolumetricHashTree +{ + /// + /// Left subtree. + /// private VolumetricHashTree m_leftHashTree = null; - /** - * Right subtree. - */ + /// + /// Right subtree. + /// private VolumetricHashTree m_rightHashTree = null; - /** - * Pointer to the root node of the tree. - */ + /// + /// Pointer to the root node of the tree. + /// private VolumetricHashTree m_rootHashTree = null; - /** - * Prefab that will be instantiated for each tree node - */ + /// + /// Prefab that will be instantiated for each tree node. + /// private GameObject m_meshPrefab = null; - /** - * Dynamic Meshing class that will handle the data processing - */ + /// + /// Dynamic Meshing class that will handle the data processing. + /// private DynamicMeshCube m_dynamicMeshCube = null; - /** - * Unpacked spatial volume index of the position of this tree node - */ + /// + /// Unpacked spatial volume index of the position of this tree node. + /// private int[] m_volumeIndex = new int[3]; - /** - * HashKey of the position of this tree node - */ + /// + /// HashKey of the position of this tree node. + /// private int m_hashKey = 0; - /** - * Maximum dimension of 3D the hashkey space - */ - private int m_maximumVolumeIndexDimension = 1000;//supports +/- 500m from origin along each axis + /// + /// Maximum dimension of 3D the hashkey space. + /// + private int m_maximumVolumeIndexDimension = 1000; // supports +/- 500m from origin along each axis - /** - * Epsilon tolerance for boundary insertions - */ + /// + /// Epsilon tolerance for boundary insertions. + /// private float m_epsilon = 0.01f; - /** - * Create a new tree node with a specified parent and hashkey - * @param parent The parent tree node. - * @param hashkey The spatial hashkey for this tree node. - */ - public VolumetricHashTree(VolumetricHashTree parent, int hashkey) { + /// + /// Create a new tree node with a specified parent and hashkey. + /// + /// The parent tree node. + /// The spatial hashkey for this tree node. + public VolumetricHashTree(VolumetricHashTree parent, int hashkey) + { if (parent == null) + { m_rootHashTree = this; + } else + { m_rootHashTree = parent; + } m_hashKey = hashkey; } - /** - * Get the DynamicMeshCube that contains the mesh data - */ - public DynamicMeshCube DynamicMeshCube { - get { - return m_dynamicMeshCube; - } - } - - /** - * Instantiate the Unity Prefab that will exist at this node location - * @param hashkey The spatial hashkey for this tree node. - * @param prefab The Unity Prefab object. - * @param parent The Unity transform of the GameObject parent of the prefab. - * @param voxelResolution The voxel resolution of the meshing cube. - * @return void - */ - private void InstantiatePrefab(int hashkey, GameObject prefab, Transform parent, int voxelResolution) { - int x, y, z; - ReverseHashKey(hashkey, out x, out y, out z); - m_meshPrefab = (GameObject)GameObject.Instantiate (prefab); - m_meshPrefab.transform.position = new Vector3 (x, y, z); - m_meshPrefab.transform.parent = parent; - m_dynamicMeshCube = m_meshPrefab.GetComponent (); - if (m_meshPrefab == null) - Debug.LogError ("Game Object does not have the dynamic mesh component"); - m_dynamicMeshCube.SetProperties (voxelResolution); - m_dynamicMeshCube.Key = hashkey; + /// + /// Get the DynamicMeshCube that contains the mesh data. + /// + /// The dynamic mesh cube. + public DynamicMeshCube DynamicMeshCube + { + get { return m_dynamicMeshCube; } } - - /** - * Enumeration function for iterating through the entire tree structure - */ + /// + /// Enumeration function for iterating through the entire tree structure. + /// + /// The enumerable. public IEnumerable GetEnumerable() { if (m_leftHashTree != null) - foreach(VolumetricHashTree n in m_leftHashTree.GetEnumerable()) + { + foreach (VolumetricHashTree n in m_leftHashTree.GetEnumerable()) + { yield return n; + } + } yield return this; if (m_rightHashTree != null) + { foreach (VolumetricHashTree n in m_rightHashTree.GetEnumerable()) + { yield return n; - } - - /** - * Computes the spatial hashkey given a 3D point - * @param p Point for hashing into the key space. - * @return the hashkey value for the point. - */ - public int GetHashKey(Vector3 p) { - return (int)Mathf.Floor (p.x) + (int)(m_maximumVolumeIndexDimension * Mathf.Floor (p.y)) + (int)(m_maximumVolumeIndexDimension*m_maximumVolumeIndexDimension * Mathf.Floor (p.z)); + } + } } - /** - * Computes the new spatial hashkey given an integer offset in the 3D volume - * @return the hashkey value for the new position - */ - public int OffsetHashKey(int startKey, int xOffset, int yOffset, int zOffset) + /// + /// Computes the spatial hashkey given a 3D point. + /// + /// The hashkey value for the point. + /// Point for hashing into the key space. + public int GetHashKey(Vector3 p) { - return startKey + xOffset + m_maximumVolumeIndexDimension * yOffset + m_maximumVolumeIndexDimension*m_maximumVolumeIndexDimension * zOffset; + return Mathf.FloorToInt(p.x) + (int)(m_maximumVolumeIndexDimension * Mathf.Floor(p.y)) + (int)(m_maximumVolumeIndexDimension * m_maximumVolumeIndexDimension * Mathf.Floor(p.z)); } - /** - * Computes the x, y, z integer coordinates that coorespond to a given hashkey - * @param hashKey the key to reverse - * @param x the output x position - * @param y the output y position - * @param z the output z position - * @return void - */ - private void ReverseHashKey(int hashKey, out int x, out int y, out int z) + /// + /// Computes the new spatial hashkey given an integer offset in the 3D volume. + /// + /// The hashkey value for the new position. + /// Start key. + /// X offset. + /// Y offset. + /// Z offset. + public int OffsetHashKey(int startKey, int xOffset, int yOffset, int zOffset) { - int flipLimit = m_maximumVolumeIndexDimension / 2; - int temp = hashKey; - - x = temp % m_maximumVolumeIndexDimension; - if (x > flipLimit) //x is negative, but opposite sign of y - x = x - m_maximumVolumeIndexDimension; - if (x < -flipLimit) //x is positive, but opposite sign of y - x = m_maximumVolumeIndexDimension + x; - temp -= x; - temp /= m_maximumVolumeIndexDimension; - - y = temp % m_maximumVolumeIndexDimension; - if (y > flipLimit) - y = y - m_maximumVolumeIndexDimension;//y is negative, but opposite sign of z - if (y < -flipLimit) - y = m_maximumVolumeIndexDimension + y;//y is positive, but opposite sign of z - - temp -= y; - z = temp/m_maximumVolumeIndexDimension; + return startKey + xOffset + (m_maximumVolumeIndexDimension * yOffset) + (m_maximumVolumeIndexDimension * m_maximumVolumeIndexDimension * zOffset); } - /** - * Insert 3D point into the hash storage. Creates a new meshing cube at the location if needed. - * @param p the 3D point - * @param obs observation vector from the camera to the point - * @param weight weight of the observation - * @param prefab Unity Prefab to be instantiated at this node location if needed - * @param tranform Unity transform of the parent object for the prefab created at this node location - * @param voxelResolution Resolution of the voxels for this meshing cube - * @return the value of the voxel that received the insertion - */ - public float InsertPoint(Vector3 p, Vector3 obs, float weight, GameObject prefab, Transform parent, int voxelResolution) { + /// + /// Insert 3D point into the hash storage. Creates a new meshing cube at the location if needed. + /// + /// The value of the voxel that received the insertion. + /// The 3D point. + /// Observation vector from the camera to the point. + /// Weight of the observation. + /// Unity Prefab to be instantiated at this node location if needed. + /// Unity transform of the parent object for the prefab created at this node location. + /// Resolution of the voxels for this meshing cube. + public float InsertPoint(Vector3 p, Vector3 obs, float weight, GameObject prefab, Transform parent, int voxelResolution) + { int hashKey = GetHashKey(p); - return InsertPoint (hashKey, p, obs, weight, prefab, parent, voxelResolution); + return InsertPoint(hashKey, p, obs, weight, prefab, parent, voxelResolution); } - - /** - * Insert 3D point into the hash storage. Creates a new meshing cube at the location if needed. - * @param hashkey hashkey index of the target node - * @param p the 3D point - * @param obs observation vector from the camera to the point - * @param weight weight of the observation - * @param prefab Unity Prefab to be instantiated at this node location if needed - * @param tranform Unity transform of the parent object for the prefab created at this node location - * @param voxelResolution Resolution of the voxels for this meshing cube - * @return the value of the voxel that received the insertion - */ - private float InsertPoint(int hashkey, Vector3 p, Vector3 obs, float weight, GameObject prefab, Transform parent, int voxelResolution) - { - if (m_hashKey == hashkey) - { - if(m_meshPrefab == null) { - InstantiatePrefab(hashkey, prefab, parent, voxelResolution); - } - - if(m_meshPrefab == null) - m_dynamicMeshCube = m_meshPrefab.GetComponent (); - if(m_meshPrefab == null) { - Debug.Log ("Error: cannot find DynamicMeshVolume"); - return 0; - } - - if(m_dynamicMeshCube.IsRegenerating) - return 0; - - //adjust weight of mutiple voxels along observation ray - float result = m_dynamicMeshCube.InsertPoint(p, obs, weight, ref m_volumeIndex); - Vector3 closerPoint = p-obs*m_dynamicMeshCube.VoxelSize; - Vector3 furtherPoint = p+obs*m_dynamicMeshCube.VoxelSize; - //voxel was inside the surface, back out one, and insert in the next closest voxel - if(result > 0) - m_dynamicMeshCube.InsertPoint(closerPoint, p, obs, weight); - else - m_dynamicMeshCube.InsertPoint(furtherPoint, p, obs, weight); - - - if(m_volumeIndex[0] == 0) { - int neighborHashKey = hashkey - 1; - result = m_rootHashTree.InsertPoint(neighborHashKey, p,obs,weight,prefab,parent,voxelResolution); - } - if(m_volumeIndex[1] == 0) { - int neighborHashKey = hashkey - m_maximumVolumeIndexDimension; - result = m_rootHashTree.InsertPoint(neighborHashKey, p,obs,weight,prefab,parent,voxelResolution); - } - if(m_volumeIndex[2] == 0) { - int neighborHashKey = hashkey - m_maximumVolumeIndexDimension*m_maximumVolumeIndexDimension; - result = m_rootHashTree.InsertPoint(neighborHashKey, p,obs,weight,prefab,parent,voxelResolution); - } - - return result; - } - - if(hashkey < m_hashKey) { - if(m_leftHashTree == null) - m_leftHashTree = new VolumetricHashTree(m_rootHashTree, hashkey); - return m_leftHashTree.InsertPoint(hashkey, p, obs, weight, prefab, parent, voxelResolution); - } else { - if(m_rightHashTree == null) - m_rightHashTree = new VolumetricHashTree(m_rootHashTree, hashkey); - return m_rightHashTree.InsertPoint(hashkey, p, obs, weight, prefab, parent, voxelResolution); - } - } - - /** - * Raycast through the volume to quickly determine the list of voxels intersected. - * @param start start point of the ray. - * @param stop stop point of the ray. - * @return list of populated voxels the ray intersects. - */ - public List RaycastVoxelHitlist(Vector3 start, Vector3 stop) + + /// + /// Raycast through the volume to quickly determine the list of voxels intersected. + /// + /// List of populated voxels the ray intersects. + /// Start point of the ray. + /// Stop point of the ray. + public List RaycastVoxelHitlist(Vector3 start, Vector3 stop) { Vector3 dir = (stop - start).normalized; List volumeHitKeys = new List(); volumeHitKeys.Add(GetHashKey(start)); - - //x crosses + // x crosses if (dir.x > 0) { - for (float x = Mathf.Ceil(start.x)+m_epsilon; x < stop.x; x += 1) { + for (float x = Mathf.Ceil(start.x) + m_epsilon; x < stop.x; x += 1) + { float scale = (x - start.x) / dir.x; - volumeHitKeys.Add (GetHashKey (start + scale * dir)); + volumeHitKeys.Add(GetHashKey(start + (scale * dir))); } } else { - for (float x = Mathf.Floor(start.x)-m_epsilon; x > stop.x; x -= 1) { + for (float x = Mathf.Floor(start.x) - m_epsilon; x > stop.x; x -= 1) + { float scale = (x - start.x) / dir.x; - volumeHitKeys.Add (GetHashKey (start + scale * dir)); + volumeHitKeys.Add(GetHashKey(start + (scale * dir))); } } - //y crosses + // y crosses if (dir.y > 0) { - for (float y = Mathf.Ceil(start.y)+m_epsilon; y < stop.y; y += 1) { + for (float y = Mathf.Ceil(start.y) + m_epsilon; y < stop.y; y += 1) + { float scale = (y - start.y) / dir.y; - volumeHitKeys.Add (GetHashKey (start + scale * dir)); + volumeHitKeys.Add(GetHashKey(start + (scale * dir))); } } else { - for (float y = Mathf.Floor(start.y)-m_epsilon; y > stop.y; y -= 1) { + for (float y = Mathf.Floor(start.y) - m_epsilon; y > stop.y; y -= 1) + { float scale = (y - start.y) / dir.y; - volumeHitKeys.Add (GetHashKey (start + scale * dir)); + volumeHitKeys.Add(GetHashKey(start + (scale * dir))); } } - //z crosses + // z crosses if (dir.z > 0) { - for (float z = Mathf.Ceil(start.z)+m_epsilon; z < stop.z; z += 1) { + for (float z = Mathf.Ceil(start.z) + m_epsilon; z < stop.z; z += 1) + { float scale = (z - start.z) / dir.z; - volumeHitKeys.Add (GetHashKey (start + scale * dir)); + volumeHitKeys.Add(GetHashKey(start + (scale * dir))); } } else { - for (float z = Mathf.Floor(start.z)-m_epsilon; z > stop.z; z -= 1) { + for (float z = Mathf.Floor(start.z) - m_epsilon; z > stop.z; z -= 1) + { float scale = (z - start.z) / dir.z; - volumeHitKeys.Add (GetHashKey (start + scale * dir)); + volumeHitKeys.Add(GetHashKey(start + (scale * dir))); } } - List voxelHits = new List (); + List voxelHits = new List(); - foreach (int volumeKey in volumeHitKeys) { + foreach (int volumeKey in volumeHitKeys) + { VolumetricHashTree result = Query(volumeKey); - if(result == null) + if (result == null) + { continue; - if(result.m_meshPrefab == null) + } + if (result.m_meshPrefab == null) + { continue; + } List voxels = result.m_dynamicMeshCube.RayCastVoxelHitlist(start, stop, dir); - foreach(Voxel v in voxels){ + foreach (Voxel v in voxels) + { voxelHits.Add(v); } } return voxelHits; } - - /** - * Query for the existence of a node at a hashKey location - * @return the node if it exists, null if it does not. - */ - public VolumetricHashTree Query(int hashKey) { - if (hashKey == m_hashKey) { + + /// + /// Query for the existence of a node at a hashKey location. + /// + /// Hash key. + /// The node if it exists, null if it does not. + public VolumetricHashTree Query(int hashKey) + { + if (hashKey == m_hashKey) + { return this; } - if(hashKey < m_hashKey) { - if(m_leftHashTree != null) + if (hashKey < m_hashKey) + { + if (m_leftHashTree != null) + { return m_leftHashTree.Query(hashKey); - } else { - if(m_rightHashTree != null) + } + } + else + { + if (m_rightHashTree != null) + { return m_rightHashTree.Query(hashKey); + } } return null; } - - /** - * Clears the contents of this tree node and its subtrees - */ - - public void Clear() { - if (m_leftHashTree != null) { - m_leftHashTree.Clear (); + + /// + /// Clears the contents of this tree node and its subtrees. + /// + public void Clear() + { + if (m_leftHashTree != null) + { + m_leftHashTree.Clear(); m_leftHashTree = null; } - if (m_rightHashTree != null) { - m_rightHashTree.Clear (); + if (m_rightHashTree != null) + { + m_rightHashTree.Clear(); m_rightHashTree = null; } - if (m_dynamicMeshCube != null) { - m_dynamicMeshCube.Clear (); + if (m_dynamicMeshCube != null) + { + m_dynamicMeshCube.Clear(); } - if (m_meshPrefab != null) { - GameObject.DestroyImmediate (m_meshPrefab); + if (m_meshPrefab != null) + { + GameObject.DestroyImmediate(m_meshPrefab); m_meshPrefab = null; } } - - /** - * Calculates statistics about this tree node and its subtrees - * @param vertCount vertex counter - * @param triangleCount triangle counter - * @param nodeCount tree node counter - */ - public void ComputeStats(ref int vertCount, ref int triangleCount, ref int nodeCount) { + + /// + /// Calculates statistics about this tree node and its subtrees. + /// + /// Vertex counter. + /// Triangle counter. + /// Tree node counter. + public void ComputeStats(ref int vertCount, ref int triangleCount, ref int nodeCount) + { if (m_leftHashTree != null) + { m_leftHashTree.ComputeStats(ref vertCount, ref triangleCount, ref nodeCount); - if (m_meshPrefab != null) { + } + if (m_meshPrefab != null) + { vertCount += m_dynamicMeshCube.Vertices.Count; triangleCount += m_dynamicMeshCube.Triangles.Count; } nodeCount++; if (m_rightHashTree != null) + { m_rightHashTree.ComputeStats(ref vertCount, ref triangleCount, ref nodeCount); + } } - - /** - * Debug Draw will draw debug lines outlining the populated volumes - */ - public void DebugDraw() { + + /// + /// Debug Draw will draw debug lines outlining the populated volumes. + /// + public void DebugDraw() + { if (m_leftHashTree != null) + { m_leftHashTree.DebugDraw(); - if (m_dynamicMeshCube != null) { + } + if (m_dynamicMeshCube != null) + { m_dynamicMeshCube.DebugDrawNormals(); } if (m_rightHashTree != null) + { m_rightHashTree.DebugDraw(); + } + } + + /// + /// Instantiate the Unity Prefab that will exist at this node location. + /// + /// The spatial hashkey for this tree node. + /// The Unity Prefab object. + /// The Unity transform of the GameObject parent of the prefab. + /// The voxel resolution of the meshing cube. + private void InstantiatePrefab(int hashkey, GameObject prefab, Transform parent, int voxelResolution) + { + int x, y, z; + ReverseHashKey(hashkey, out x, out y, out z); + m_meshPrefab = (GameObject)GameObject.Instantiate(prefab); + m_meshPrefab.transform.position = new Vector3(x, y, z); + m_meshPrefab.transform.parent = parent; + m_dynamicMeshCube = m_meshPrefab.GetComponent(); + if (m_meshPrefab == null) + { + Debug.LogError("Game Object does not have the dynamic mesh component"); + } + m_dynamicMeshCube.SetProperties(voxelResolution); + m_dynamicMeshCube.Key = hashkey; + } + + /// + /// Computes the x, y, z integer coordinates that coorespond to a given hashkey. + /// + /// The key to reverse. + /// The output x position. + /// The output y position. + /// The output z position. + private void ReverseHashKey(int hashKey, out int x, out int y, out int z) + { + int flipLimit = m_maximumVolumeIndexDimension / 2; + int temp = hashKey; + + x = temp % m_maximumVolumeIndexDimension; + if (x > flipLimit) + { + // x is negative, but opposite sign of y + x = x - m_maximumVolumeIndexDimension; + } + if (x < -flipLimit) + { + // x is positive, but opposite sign of y + x = m_maximumVolumeIndexDimension + x; + } + temp -= x; + temp /= m_maximumVolumeIndexDimension; + + y = temp % m_maximumVolumeIndexDimension; + if (y > flipLimit) + { + // y is negative, but opposite sign of z + y = y - m_maximumVolumeIndexDimension; + } + if (y < -flipLimit) + { + // y is positive, but opposite sign of z + y = m_maximumVolumeIndexDimension + y; + } + + temp -= y; + z = temp / m_maximumVolumeIndexDimension; + } + + /// + /// Insert 3D point into the hash storage. Creates a new meshing cube at the location if needed. + /// + /// The value of the voxel that received the insertion. + /// Hashkey index of the target node. + /// The 3D point. + /// Observation vector from the camera to the point. + /// Weight of the observation. + /// Unity Prefab to be instantiated at this node location if needed. + /// Unity transform of the parent object for the prefab created at this node location. + /// Resolution of the voxels for this meshing cube. + private float InsertPoint(int hashkey, Vector3 p, Vector3 obs, float weight, GameObject prefab, Transform parent, int voxelResolution) + { + if (m_hashKey == hashkey) + { + if (m_meshPrefab == null) + { + InstantiatePrefab(hashkey, prefab, parent, voxelResolution); + } + + if (m_meshPrefab == null) + { + m_dynamicMeshCube = m_meshPrefab.GetComponent(); + } + if (m_meshPrefab == null) + { + Debug.Log("Error: cannot find DynamicMeshVolume"); + return 0; + } + + if (m_dynamicMeshCube.IsRegenerating) + { + return 0; + } + + // adjust weight of mutiple voxels along observation ray + float result = m_dynamicMeshCube.InsertPoint(p, obs, weight, ref m_volumeIndex); + Vector3 closerPoint = p - (obs * m_dynamicMeshCube.VoxelSize); + Vector3 furtherPoint = p + (obs * m_dynamicMeshCube.VoxelSize); + + // voxel was inside the surface, back out one, and insert in the next closest voxel + if (result > 0) + { + m_dynamicMeshCube.InsertPoint(closerPoint, p, obs, weight); + } + else + { + m_dynamicMeshCube.InsertPoint(furtherPoint, p, obs, weight); + } + + if (m_volumeIndex[0] == 0) + { + int neighborHashKey = hashkey - 1; + result = m_rootHashTree.InsertPoint(neighborHashKey, p, obs, weight, prefab, parent, voxelResolution); + } + if (m_volumeIndex[1] == 0) + { + int neighborHashKey = hashkey - m_maximumVolumeIndexDimension; + result = m_rootHashTree.InsertPoint(neighborHashKey, p, obs, weight, prefab, parent, voxelResolution); + } + if (m_volumeIndex[2] == 0) + { + int neighborHashKey = hashkey - (m_maximumVolumeIndexDimension * m_maximumVolumeIndexDimension); + result = m_rootHashTree.InsertPoint(neighborHashKey, p, obs, weight, prefab, parent, voxelResolution); + } + + return result; + } + + if (hashkey < m_hashKey) + { + if (m_leftHashTree == null) + { + m_leftHashTree = new VolumetricHashTree(m_rootHashTree, hashkey); + } + return m_leftHashTree.InsertPoint(hashkey, p, obs, weight, prefab, parent, voxelResolution); + } + else + { + if (m_rightHashTree == null) + { + m_rightHashTree = new VolumetricHashTree(m_rootHashTree, hashkey); + } + return m_rightHashTree.InsertPoint(hashkey, p, obs, weight, prefab, parent, voxelResolution); + } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Voxel.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Voxel.cs index 4b7437e7..6cd833f3 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Voxel.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/Voxel.cs @@ -1,92 +1,92 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; +using UnityEngine; -/** - * Voxel class for storing voxel data and state - */ - +/// +/// Voxel class for storing voxel data and state. +/// public class Voxel { - /** - * x position index within the hash volume - */ + /// + /// X position index within the hash volume. + /// public int xID; - /** - * y position index within the hash volume - */ + /// + /// Y position index within the hash volume. + /// public int yID; - /** - * z position index within the hash volume - */ + /// + /// Z position index within the hash volume. + /// public int zID; - /** - * signed distance value of the voxel - */ + /// + /// Signed distance value of the voxel. + /// public float value; - /** - * signed distance weight of the voxel - */ + /// + /// Signed distance weight of the voxel. + /// public float weight; - /** - * previous signed distance wieght of the voxel - */ + /// + /// Previous signed distance wieght of the voxel. + /// public float lastMeshedValue; - /** - * 3D point position of the voxel - */ + /// + /// 3D point position of the voxel. + /// public Vector3 anchor; - /** - * size of the voxel - */ + /// + /// Size of the voxel. + /// public float size; - /** - * estaimte normal of the voxel surface - */ + /// + /// Estaimte normal of the voxel surface. + /// public Vector3 normal; - /** - * Unity object that own this voxel - */ + /// + /// Unity object that own this voxel. + /// public Transform parent; - /** - * flags for preprocessing neighbors - */ + /// + /// Flags for preprocessing neighbors. + /// public bool neighborsCreated; - /** - * indices of triangles this voxel participated in - */ + /// + /// Indices of triangles this voxel participated in. + /// public List trianglesIndicies = new List(); - /** - * neighbor voxels for faster meshing - */ + // neighbor voxels for faster meshing public Voxel v1; public Voxel v2; public Voxel v3; @@ -94,5 +94,4 @@ public class Voxel public Voxel v5; public Voxel v6; public Voxel v7; - } \ No newline at end of file diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VoxelHashTree.cs b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VoxelHashTree.cs index 47595ae4..c8398da0 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VoxelHashTree.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalMeshBuilder/Scripts/VoxelHashTree.cs @@ -1,191 +1,236 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; +using UnityEngine; - -/** - * Voxel Hash Tree - * A binary tree datastructure that uses a hashkey based on the 3D coordinates. - * Space with within the cube is divided into a regular grid of voxels. The hashkey is a - * reversible index into that volume. allows quick indexing, and ray marching - * through the cube. - */ - -public class VoxelHashTree { - - /** - * hashkey for this tree node - */ +/// +/// A binary tree datastructure that uses a hashkey based on the 3D coordinates. +/// Space with within the cube is divided into a regular grid of voxels. The hashkey is a +/// reversible index into that volume. allows quick indexing, and ray marching +/// through the cube. +/// +public class VoxelHashTree +{ + /// + /// Hashkey for this tree node. + /// private int m_hashKey = int.MinValue; - /** - * voxel data at this node - */ + /// + /// Voxel data at this node. + /// private Voxel m_voxel = null; - /** - * Left subtree. - */ + /// + /// Left subtree. + /// private VoxelHashTree m_leftHashTree = null; - /** - * Right subtree. - */ + /// + /// Right subtree. + /// private VoxelHashTree m_rightHashTree = null; - /** - * Parent tree. - */ + /// + /// Parent tree. + /// private VoxelHashTree m_parentHashTree = null; - /** - * Initalize the tree - */ - public VoxelHashTree() {} + /// + /// Initalize the tree. + /// + public VoxelHashTree() + { + } - /** - * Clear the tree and subtrees - */ - public void Clear() { + /// + /// Clear the tree and subtrees. + /// + public void Clear() + { m_hashKey = int.MinValue; m_voxel = null; m_parentHashTree = null; - if(m_leftHashTree != null) { + if (m_leftHashTree != null) + { m_leftHashTree.Clear(); m_leftHashTree = null; } - if(m_rightHashTree != null) { + if (m_rightHashTree != null) + { m_rightHashTree.Clear(); m_rightHashTree = null; } } - /** - * Gets the voxel at this node - */ - public Voxel Voxel { - get { - return m_voxel; - } + /// + /// Gets the voxel at this node. + /// + /// The voxel. + public Voxel Voxel + { + get { return m_voxel; } } - /** - * Gets the hashkey of this node - */ - public int Key { - get { - return m_hashKey; - } + /// + /// Gets the hashkey of this node. + /// + /// The key. + public int Key + { + get { return m_hashKey; } } - /** - * Allows iterating through all nodes in the tree - */ - public IEnumerable GetEnumerable() { + /// + /// Allows iterating through all nodes in the tree. + /// + /// The enumerable. + public IEnumerable GetEnumerable() + { if (m_leftHashTree != null) - foreach(VoxelHashTree n in m_leftHashTree.GetEnumerable()) + { + foreach (VoxelHashTree n in m_leftHashTree.GetEnumerable()) + { yield return n; + } + } yield return this; if (m_rightHashTree != null) + { foreach (VoxelHashTree n in m_rightHashTree.GetEnumerable()) + { yield return n; + } + } } - /** - * gets the minimum key value in the tree - */ - VoxelHashTree GetMinKey() { - if (m_leftHashTree == null) { + /// + /// Gets the minimum key value in the tree. + /// + /// The minimum key. + public VoxelHashTree GetMinKey() + { + if (m_leftHashTree == null) + { return this; - } else { - return m_leftHashTree.GetMinKey (); + } + else + { + return m_leftHashTree.GetMinKey(); } } - /** - * Delete this node from tree. - */ - public bool Delete() { - return Delete (m_hashKey); + /// + /// Delete this node from tree. + /// + /// True. + public bool Delete() + { + return Delete(m_hashKey); } - /** - * Delete node with specific haskey from tree. - */ - public bool Delete(int hashkey) { - - if (hashkey == m_hashKey) { - if((m_leftHashTree != null)&&(m_rightHashTree != null)) { - //we have left and right trees, - //copy the right's minimum tree into this tree - //delete from right tree + /// + /// Delete node with specific haskey from tree. + /// + /// Hashkey. + /// If it found a node to delete. + public bool Delete(int hashkey) + { + if (hashkey == m_hashKey) + { + if ((m_leftHashTree != null) && (m_rightHashTree != null)) + { + // we have left and right trees, + // copy the right's minimum tree into this tree + // delete from right tree VoxelHashTree target = m_rightHashTree.GetMinKey(); m_voxel = target.m_voxel; m_hashKey = target.m_hashKey; m_rightHashTree.Delete(m_hashKey); - } else if(m_parentHashTree.m_leftHashTree == this) { - //point parent directly at child - //depends on GC to remove this? + } + else if (m_parentHashTree.m_leftHashTree == this) + { + // point parent directly at child + // depends on GC to remove this? m_parentHashTree.m_leftHashTree = (m_leftHashTree != null) ? m_leftHashTree : m_rightHashTree; - } else if(m_parentHashTree.m_rightHashTree == this) { - //point parent directly at child - //depends on GC to remove this? + } + else if (m_parentHashTree.m_rightHashTree == this) + { + // point parent directly at child + // depends on GC to remove this? m_parentHashTree.m_rightHashTree = (m_leftHashTree != null) ? m_leftHashTree : m_rightHashTree; } return true; } - if (hashkey < m_hashKey) { + if (hashkey < m_hashKey) + { if (m_leftHashTree == null) + { return false; + } return m_leftHashTree.Delete(hashkey); - } else { + } + else + { if (m_rightHashTree == null) + { return false; + } return m_rightHashTree.Delete(hashkey); } } - /** - * Insert new voxel with hashkey into the hashtree - * @param voxel voxel to be inserted - * @param hashkey hashkey of the voxel - */ - public void Insert(Voxel voxel, int hashkey) { - if (m_hashKey == int.MinValue) { + /// + /// Insert new voxel with hashkey into the hashtree. + /// + /// Voxel to be inserted. + /// Hashkey of the voxel. + public void Insert(Voxel voxel, int hashkey) + { + if (m_hashKey == int.MinValue) + { m_hashKey = hashkey; this.m_voxel = voxel; return; } - if (m_hashKey == hashkey) { + if (m_hashKey == hashkey) + { this.m_voxel = voxel; return; } - if(hashkey < m_hashKey) { - if(m_leftHashTree == null) { + if (hashkey < m_hashKey) + { + if (m_leftHashTree == null) + { m_leftHashTree = new VoxelHashTree(); m_leftHashTree.m_parentHashTree = this; } m_leftHashTree.Insert(voxel, hashkey); - } else { - if(m_rightHashTree == null){ + } + else + { + if (m_rightHashTree == null) + { m_rightHashTree = new VoxelHashTree(); m_rightHashTree.m_parentHashTree = this; } @@ -193,24 +238,38 @@ public void Insert(Voxel voxel, int hashkey) { } } - /** - * Query for spefici voxel using hashkey - * @param hashkey haskey of the target voxel - * @return the voxel if it exsits, otherwise null - */ - public Voxel Query(int hashkey) { - if(hashkey == m_hashKey) + /// + /// Query for spefici voxel using hashkey. + /// + /// Haskey of the target voxel. + /// The voxel if it exsits, otherwise null. + public Voxel Query(int hashkey) + { + if (hashkey == m_hashKey) + { return m_voxel; - if(hashkey < m_hashKey) { - if(m_leftHashTree == null) + } + if (hashkey < m_hashKey) + { + if (m_leftHashTree == null) + { return null; + } else + { return m_leftHashTree.Query(hashkey); - } else { - if(m_rightHashTree == null) + } + } + else + { + if (m_rightHashTree == null) + { return null; + } else + { return m_rightHashTree.Query(hashkey); + } } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/BuildingController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/BuildingController.cs index 1b5d3935..9472266c 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/BuildingController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/BuildingController.cs @@ -1,35 +1,52 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class BuildingController : MonoBehaviour { +/// +/// Building controller. +/// +public class BuildingController : MonoBehaviour +{ public GameObject buildingOutfit; - // Use this for initialization - void Start () { - + /// + /// Use this for initialization. + /// + public void Start() + { } - // Update is called once per frame - void Update () { - + /// + /// Update is called once per frame. + /// + public void Update() + { } - public void SetBuildingOutfitColor (Color color) { + /// + /// Sets the drawing color of the building outfit. + /// + /// Color. + public void SetBuildingOutfitColor(Color color) + { buildingOutfit.GetComponent().material.color = color; } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/CustomPoseController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/CustomPoseController.cs index ea9a697c..84f8d16d 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/CustomPoseController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/CustomPoseController.cs @@ -1,37 +1,50 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- +using System; using System.Collections; +using UnityEngine; using Tango; -using System; -public class CustomPoseController : MonoBehaviour, ITangoPose { +/// +/// Custom pose controller. +/// +public class CustomPoseController : MonoBehaviour, ITangoPose +{ public Vector3 positionOffest = new Vector3(0.0f, 1.35f, 0.0f); - TangoApplication tangoApplication; - Quaternion rotationFix = Quaternion.Euler(90.0f, 0.0f, 0.0f); - Quaternion startingRotation; + private TangoApplication tangoApplication; + private Quaternion rotationFix = Quaternion.Euler(90.0f, 0.0f, 0.0f); + private Quaternion startingRotation; - TangoPoseStates preTangoState; - // Use this for initialization - void Start () { + private TangoPoseStates preTangoState; + + /// + /// Use this for initialization. + /// + public void Start() + { Statics.currentTangoState = TangoPoseStates.Connecting; tangoApplication = FindObjectOfType(); - if (tangoApplication == null) { + if (tangoApplication == null) + { tangoApplication = FindObjectOfType(); } tangoApplication.InitProviders(Statics.curADFId); @@ -40,36 +53,55 @@ void Start () { startingRotation = transform.rotation; } - - public void OnTangoPoseAvailable(TangoPoseData pose) { + + /// + /// Tango pose event. + /// + /// Pose. + public void OnTangoPoseAvailable(TangoPoseData pose) + { if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION && - pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) { - if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) { + pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) + { + if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) + { Statics.currentTangoState = TangoPoseStates.Running; UpdateTransform(pose); return; - } else { + } + else + { Statics.currentTangoState = TangoPoseStates.Relocalizing; } - } else if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && - pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) { - if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) { + } + else if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && + pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) + { + if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) + { UpdateTransform(pose); } - } else { + } + else + { return; } } - - private void UpdateTransform(TangoPoseData pose) { - Vector3 tangoPosition = new Vector3((float)pose.translation [0], - (float)pose.translation [2], - (float)pose.translation [1]); + + /// + /// Updates the transform from a Tango pose data. + /// + /// Tango pose. + private void UpdateTransform(TangoPoseData pose) + { + Vector3 tangoPosition = new Vector3((float)pose.translation[0], + (float)pose.translation[2], + (float)pose.translation[1]); - Quaternion tangoRotation = new Quaternion((float)pose.orientation [0], - (float)pose.orientation [2], // these rotation values are swapped on purpose - (float)pose.orientation [1], - (float)pose.orientation [3]); + Quaternion tangoRotation = new Quaternion((float)pose.orientation[0], + (float)pose.orientation[2], // these rotation values are swapped on purpose + (float)pose.orientation[1], + (float)pose.orientation[3]); Quaternion axisFix = Quaternion.Euler(-tangoRotation.eulerAngles.x, -tangoRotation.eulerAngles.z, @@ -79,13 +111,18 @@ private void UpdateTransform(TangoPoseData pose) { transform.position = (startingRotation * tangoPosition) + positionOffest; // Fire the state change event. - if (preTangoState != Statics.currentTangoState) { - EventManager.instance.TangoPoseStateChanged(Statics.currentTangoState); + if (preTangoState != Statics.currentTangoState) + { + EventManager.Instance.SendTangoPoseStateChanged(Statics.currentTangoState); } preTangoState = Statics.currentTangoState; } - - private void OnDestroy() { + + /// + /// Called when the game object is destroyed. + /// + private void OnDestroy() + { tangoApplication.Shutdown(); } } \ No newline at end of file diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/DataSavingController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/DataSavingController.cs index 6caa3085..a5c8b1bd 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/DataSavingController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/DataSavingController.cs @@ -1,35 +1,68 @@ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; using Tango; -public class DataSavingController : MonoBehaviour { +/// +/// Controls saving and loading ADFs. +/// +public class DataSavingController : MonoBehaviour +{ private static TouchScreenKeyboard keyboard; private static string keyboardString; private static UUIDUnityHolder savedAdfHolder; private static bool startedSaving = false; - void Update () { - if (startedSaving) { - if(keyboard.done) { + /// + /// Start the saving process. + /// + public static void SaveData() + { + keyboard = TouchScreenKeyboard.Open(keyboardString, TouchScreenKeyboardType.Default, false); + startedSaving = true; + } + + /// + /// Update is called once per frame. + /// + public void Update() + { + if (startedSaving) + { + if (keyboard.done) + { savedAdfHolder = new UUIDUnityHolder(); keyboardString = keyboard.text; - PoseProvider.SaveAreaDescription (savedAdfHolder); + PoseProvider.SaveAreaDescription(savedAdfHolder); PoseProvider.GetAreaDescriptionMetaData(savedAdfHolder); - PoseProvider.AreaDescriptionMetaData_set(Common.MetaDataKeyType.KEY_NAME, keyboardString,savedAdfHolder); + PoseProvider.AreaDescriptionMetaData_set(Common.MetaDataKeyType.KEY_NAME, keyboardString, savedAdfHolder); PoseProvider.SaveAreaDescriptionMetaData(savedAdfHolder); // Null terminator will cause invalid argument in the file system. - string uuid = savedAdfHolder.GetStringDataUUID().Replace("\0",""); + string uuid = savedAdfHolder.GetStringDataUUID().Replace("\0", string.Empty); string path = Application.persistentDataPath + "/" + uuid; - FileParser.SaveBuildingDataToPath(BuildingManager.instance.buildingList, path); - EventManager.instance.GameDataSaved(true); + FileParser.SaveBuildingDataToPath(BuildingManager.Instance.buildingList, path); + EventManager.Instance.SendGameDataSaved(true); startedSaving = false; } } } - - public static void SaveData() { - keyboard = TouchScreenKeyboard.Open(keyboardString,TouchScreenKeyboardType.Default, false); - startedSaving = true; - } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/GameCameraEffectController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/GameCameraEffectController.cs index f663de6a..fb421657 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/GameCameraEffectController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/GameCameraEffectController.cs @@ -1,62 +1,84 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class GameCameraEffectController : MonoBehaviour { +/// +/// Controls camera effects. +/// +public class GameCameraEffectController : MonoBehaviour +{ public Vignetting vignetting; public DepthOfField34 depthOfField; - // Use this for initialization - void Start () { - - } - float counter = 0.0f; - float totalTime = 1.0f; - bool savedStartStateOfEffects = false; + private float counter = 0.0f; + private float totalTime = 1.0f; + private bool savedStartStateOfEffects = false; + + private float chromaticAberration; + private float blury; + + /// + /// Use this for initialization. + /// + public void Start() + { + } - float chromaticAberration; - float blury; - // Update is called once per frame - void Update () { - if (Statics.currentTangoState == TangoPoseStates.Connecting || Statics.currentTangoState == TangoPoseStates.Relocalizing) { + /// + /// Update is called once per frame. + /// + public void Update() + { + if (Statics.currentTangoState == TangoPoseStates.Connecting || Statics.currentTangoState == TangoPoseStates.Relocalizing) + { depthOfField.smoothness = 0.1f; counter += Time.deltaTime; - if (counter <= totalTime) { - vignetting.chromaticAberration = Mathf.Lerp(-36.0f, 36.0f, counter/totalTime); + if (counter <= totalTime) + { + vignetting.chromaticAberration = Mathf.Lerp(-36.0f, 36.0f, counter / totalTime); } - if (counter > totalTime && counter <= 2*totalTime) { - vignetting.chromaticAberration = Mathf.Lerp(36.0f, -36.0f, (counter-totalTime)/totalTime); + if (counter > totalTime && counter <= 2 * totalTime) + { + vignetting.chromaticAberration = Mathf.Lerp(36.0f, -36.0f, (counter - totalTime) / totalTime); } - if (counter > 2*totalTime) { + if (counter > 2 * totalTime) + { counter = 0.0f; } savedStartStateOfEffects = false; } - else { - if (!savedStartStateOfEffects) { + else + { + if (!savedStartStateOfEffects) + { counter = 0.0f; savedStartStateOfEffects = true; chromaticAberration = vignetting.chromaticAberration; blury = depthOfField.smoothness; } counter += Time.deltaTime; - if (counter <= 2.0f) { - vignetting.chromaticAberration = Mathf.Lerp(chromaticAberration, 0.2f, counter/2.0f); - depthOfField.smoothness = Mathf.Lerp(blury, 3.84f, counter/2.0f); + if (counter <= 2.0f) + { + vignetting.chromaticAberration = Mathf.Lerp(chromaticAberration, 0.2f, counter / 2.0f); + depthOfField.smoothness = Mathf.Lerp(blury, 3.84f, counter / 2.0f); } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/StartSceneCameraController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/StartSceneCameraController.cs index ae7f3767..1da22f5e 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/StartSceneCameraController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Controllers/StartSceneCameraController.cs @@ -1,46 +1,71 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class StartSceneCameraController : MonoBehaviour { +/// +/// Updates a simple chromatic effect. +/// +public class StartSceneCameraController : MonoBehaviour +{ public float spinningSpeed; public Vignetting vignetting; - // Use this for initialization - void Start () { + + private float counter = 0.0f; + private float totalTime = 1.0f; + + /// + /// Use this for initialization. + /// + public void Start() + { StartCoroutine(ColorChromEffect()); } - // Update is called once per frame - void Update () { + /// + /// Update is called once per frame. + /// + public void Update() + { gameObject.transform.Rotate(new Vector3(0.0f, spinningSpeed, 0.0f)); } - float counter = 0.0f; - float totalTime = 1.0f; - IEnumerator ColorChromEffect () { - while (true) { + /// + /// Coroutine for updating the chromatic effect. + /// + /// Coroutine enumerator. + private IEnumerator ColorChromEffect() + { + while (true) + { counter += Time.deltaTime; - if (counter <= totalTime) { - vignetting.chromaticAberration = Mathf.Lerp(-6.0f, 6.0f, counter/totalTime); + if (counter <= totalTime) + { + vignetting.chromaticAberration = Mathf.Lerp(-6.0f, 6.0f, counter / totalTime); } - if (counter > totalTime && counter <= 2*totalTime) { - vignetting.chromaticAberration = Mathf.Lerp(6.0f, -6.0f, (counter-totalTime)/totalTime); + if (counter > totalTime && counter <= 2 * totalTime) + { + vignetting.chromaticAberration = Mathf.Lerp(6.0f, -6.0f, (counter - totalTime) / totalTime); } - if (counter > 2*totalTime) { + if (counter > 2 * totalTime) + { counter = 0.0f; } yield return null; diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Debug/DebugString.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Debug/DebugString.cs index 33649c28..9e68d4bf 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Debug/DebugString.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Debug/DebugString.cs @@ -1,31 +1,44 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class DebugString : MonoBehaviour { +/// +/// Updates a debug string. +/// +public class DebugString : MonoBehaviour +{ public TextMesh textMesh; - // Use this for initialization - void Start () { - + /// + /// Use this for initialization. + /// + public void Start() + { } - // Update is called once per frame - void Update () { + /// + /// Update is called once per frame. + /// + public void Update() + { textMesh.text = Statics.debugString; } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/BuildingManager.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/BuildingManager.cs index 1827abb1..cbad9248 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/BuildingManager.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/BuildingManager.cs @@ -1,179 +1,198 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; +using UnityEngine; -public class Building : MonoBehaviour { - public GameObject buildingObject; - public int buildingId; - - public Building() { - } - - public void SetBuildingActive (bool isActive) { - buildingObject.SetActive(isActive); - } - - ~Building() { - DestroyObject(buildingObject); - } -} - -public class BuildingManager : MonoBehaviour { - private static BuildingManager _instance; - - public static BuildingManager instance { - get { - if(_instance == null) { - _instance = GameObject.FindObjectOfType(); - DontDestroyOnLoad(_instance.gameObject); - } - - return _instance; - } - } - - public GameObject[] buildingPrototypes; +/// +/// Singleton building manager. +/// +public class BuildingManager : MonoBehaviour +{ + public GameObject[] buildingPrototypes; public List buildingList = new List(); - + public GameObject goundObject; public Camera mainCamera; public Camera uiCamera; public Building curBuldingObject; - + public Color buildingErrorColor; public Color buildingCorrectColor; - + public GameObject placeBuildingButton; public GameObject cancelBuildingButton; + + private static BuildingManager m_instance; private bool[] occupancyIndex = new bool[400 * 400]; - void Awake () { - if(_instance == null) { - _instance = this; + /// + /// Gets the singleton instance. + /// + /// The instance. + public static BuildingManager Instance + { + get + { + if (m_instance == null) + { + m_instance = GameObject.FindObjectOfType(); + DontDestroyOnLoad(m_instance.gameObject); + } + + return m_instance; + } + } + + /// + /// Called before Start(). + /// + public void Awake() + { + if (m_instance == null) + { + m_instance = this; DontDestroyOnLoad(this); } - else { - if(this != _instance) { + else + { + if (this != m_instance) + { Destroy(this.gameObject); } } } - // Use this for initialization - void Start () { - EventManager.tangoPoseStatedChanged += TangoStateChanged; + /// + /// Use this for initialization. + /// + public void Start() + { + EventManager.TangoPoseStateChanged += TangoStateChanged; + // Null terminator cause problem in the file system. - Statics.curADFId = Statics.curADFId.Replace ("\0", ""); + Statics.curADFId = Statics.curADFId.Replace("\0", string.Empty); string path = Application.persistentDataPath + "/" + Statics.curADFId; - FileParser.GetVectorListFromPath (out buildingList, path); + FileParser.GetVectorListFromPath(out buildingList, path); SetAllBuildingActive(false); } - Vector2 hitPoint = new Vector2(); - int index = 0; - // Update is called once per frame - void Update () { - if (Statics.isPlacingObject) { - if (Input.GetKey(KeyCode.Mouse0)) { + private Vector2 hitPoint = new Vector2(); + private int index = 0; + + /// + /// Update is called once per frame. + /// + public void Update() + { + if (Statics.isPlacingObject) + { + if (Input.GetKey(KeyCode.Mouse0)) + { if (RayCastGroud(out hitPoint)) { hitPoint = FindContainningGrid(out index, hitPoint.x, hitPoint.y); curBuldingObject.buildingObject.transform.position = new Vector3(hitPoint.x, 0.0f, hitPoint.y); } } - if (!occupancyIndex[index]) { + if (!occupancyIndex[index]) + { // make the building red. curBuldingObject.buildingObject.GetComponent().SetBuildingOutfitColor(buildingCorrectColor); } - else { + else + { // make building green. curBuldingObject.buildingObject.GetComponent().SetBuildingOutfitColor(buildingErrorColor); } } } - Vector2 FindContainningGrid (out int index, float x, float z) { - float iterX = -50.0f; - float iterY = -50.0f; - int indexX = 0; - int indexY = 0; - while (iterX < x) { - iterX += 0.25f; - indexX++; - } - iterX = iterX - 0.125f; - while (iterY < z) { - iterY += 0.25f; - indexY++; - } - iterY = iterY - 0.125f; - - index = indexY * 400 + indexX; - return new Vector2(iterX, iterY); - } - - void TangoStateChanged(TangoPoseStates curState) { - if (curState == TangoPoseStates.Running) { - SetAllBuildingActive(true); - } else { - SetAllBuildingActive(false); - } - } - - public void SetAllBuildingActive(bool isActive) { - foreach(Building building in buildingList) { + /// + /// Sets all buildings' active state. + /// + /// If set to true is active. + public void SetAllBuildingActive(bool isActive) + { + foreach (Building building in buildingList) + { building.SetBuildingActive(isActive); } } - public void PlaceBuilding() { - if (occupancyIndex [index]) { + /// + /// Place a new building. + /// + public void PlaceBuilding() + { + if (occupancyIndex[index]) + { // not placeable. return; } - occupancyIndex [index] = true; - curBuldingObject.buildingObject.GetComponent ().buildingOutfit.SetActive (false); + occupancyIndex[index] = true; + curBuldingObject.buildingObject.GetComponent().buildingOutfit.SetActive(false); Statics.isPlacingObject = false; - placeBuildingButton.SetActive (false); - cancelBuildingButton.SetActive (false); + placeBuildingButton.SetActive(false); + cancelBuildingButton.SetActive(false); buildingList.Add(curBuldingObject); } - public void CancelBuildingPlacement() { + /// + /// Cancel the placement of a building. + /// + public void CancelBuildingPlacement() + { Statics.isPlacingObject = false; - placeBuildingButton.SetActive (false); - cancelBuildingButton.SetActive (false); + placeBuildingButton.SetActive(false); + cancelBuildingButton.SetActive(false); DestroyImmediate(curBuldingObject.buildingObject); } - public void CreateBulding(int index) { - if (Statics.isPlacingObject) { + /// + /// Create a building in one place. + /// + /// Index. + public void CreateBulding(int index) + { + if (Statics.isPlacingObject) + { // place on bulding at a time. return; } - curBuldingObject = InstantiateBuilding (index, 0.0f, 0.0f); + curBuldingObject = InstantiateBuilding(index, 0.0f, 0.0f); Statics.isPlacingObject = true; - placeBuildingButton.SetActive (true); - cancelBuildingButton.SetActive (true); + placeBuildingButton.SetActive(true); + cancelBuildingButton.SetActive(true); } - public Building InstantiateBuilding(int index, float x, float z) { + /// + /// Get a new building object at a specific index / coordinate. + /// + /// The building. + /// Index. + /// The x coordinate. + /// The z coordinate. + public Building InstantiateBuilding(int index, float x, float z) + { GameObject buildingObj = (GameObject)Instantiate(buildingPrototypes[index]); Building building = new Building(); building.buildingObject = buildingObj; @@ -182,20 +201,79 @@ public Building InstantiateBuilding(int index, float x, float z) { return building; } - public void ResetBuildingManager() { + /// + /// Clear all buildings. + /// + public void ResetBuildingManager() + { buildingList = new List(); } + + /// + /// Finds the correct grid cell for this position. + /// + /// The containning grid cell. + /// Index of the grid cell. + /// The x coordinate. + /// The z coordinate. + private Vector2 FindContainningGrid(out int index, float x, float z) + { + float iterX = -50.0f; + float iterY = -50.0f; + int indexX = 0; + int indexY = 0; + while (iterX < x) + { + iterX += 0.25f; + indexX++; + } + iterX = iterX - 0.125f; + while (iterY < z) + { + iterY += 0.25f; + indexY++; + } + iterY = iterY - 0.125f; + + index = (indexY * 400) + indexX; + return new Vector2(iterX, iterY); + } + + /// + /// Called up update the Tango state. + /// + /// Current state. + private void TangoStateChanged(TangoPoseStates curState) + { + if (curState == TangoPoseStates.Running) + { + SetAllBuildingActive(true); + } + else + { + SetAllBuildingActive(false); + } + } - private bool RayCastGroud(out Vector2 outHitPoint) { + /// + /// Raycast from the "mouse" to the ground. + /// + /// true, if cast groud was rayed, false otherwise. + /// Out hit point. + private bool RayCastGroud(out Vector2 outHitPoint) + { RaycastHit hit = new RaycastHit(); Vector3 screenPosition = Input.mousePosition; - if (Physics.Raycast(uiCamera.ScreenPointToRay(screenPosition), out hit, Mathf.Infinity)) { + if (Physics.Raycast(uiCamera.ScreenPointToRay(screenPosition), out hit, Mathf.Infinity)) + { outHitPoint = new Vector2(); return false; } - if (Physics.Raycast(mainCamera.ScreenPointToRay(screenPosition), out hit, Mathf.Infinity)) { + if (Physics.Raycast(mainCamera.ScreenPointToRay(screenPosition), out hit, Mathf.Infinity)) + { Debug.DrawRay(mainCamera.transform.position, hit.point - mainCamera.transform.position, Color.red); - if (hit.transform.gameObject == goundObject) { + if (hit.transform.gameObject == goundObject) + { outHitPoint = new Vector2(hit.point.x, hit.point.z); return true; } @@ -204,3 +282,37 @@ private bool RayCastGroud(out Vector2 outHitPoint) { return false; } } + +/// +/// A single building. +/// +public class Building : MonoBehaviour +{ + public GameObject buildingObject; + public int buildingId; + + /// + /// Initializes a new instance of the class. + /// + public Building() + { + } + + /// + /// Sets the building active. + /// + /// If set to true is active. + public void SetBuildingActive(bool isActive) + { + buildingObject.SetActive(isActive); + } + + /// + /// Releases unmanaged resources and performs other cleanup operations before the is + /// reclaimed by garbage collection. + /// + ~Building() + { + DestroyObject(buildingObject); + } +} diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/EventManager.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/EventManager.cs index ac69cf36..80226708 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/EventManager.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/EventManager.cs @@ -1,72 +1,133 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class EventManager : MonoBehaviour { - private static EventManager _instance; +/// +/// Singleton event manager. +/// +public class EventManager : MonoBehaviour +{ + private static EventManager m_instance; - public static EventManager instance { - get { - if(_instance == null) { - _instance = GameObject.FindObjectOfType(); - DontDestroyOnLoad(_instance.gameObject); + /// + /// Gets the singleton instance. + /// + /// The instance. + public static EventManager Instance + { + get + { + if (m_instance == null) + { + m_instance = GameObject.FindObjectOfType(); + DontDestroyOnLoad(m_instance.gameObject); } - - return _instance; + + return m_instance; } } + /// + /// Called when the Tango service is initialized. + /// public delegate void TangoServiceInitilizedHandler(); - public static event TangoServiceInitilizedHandler tangoServiceInitilized; + /// + /// Called when the Tango service is initialized. + /// + public static event TangoServiceInitilizedHandler TangoServiceInitialized; + + /// + /// Called when a save is requested. + /// + /// If the save succeded or not. public delegate void GameDataSavedHandler(bool successed); - public static event GameDataSavedHandler gameDataSaved; + /// + /// Called when a save is requested. + /// + public static event GameDataSavedHandler GameDataSaved; + + /// + /// Called when a pose state update happens. + /// + /// The current pose state. public delegate void TangoPoseStateHandler(TangoPoseStates currentState); - public static event TangoPoseStateHandler tangoPoseStatedChanged; - void Awake () { - if(_instance == null) { - _instance = this; + /// + /// Called when a pose update happens. + /// + public static event TangoPoseStateHandler TangoPoseStateChanged; + + /// + /// Called before Start. + /// + public void Awake() + { + if (m_instance == null) + { + m_instance = this; DontDestroyOnLoad(this); } - else { - if(this != _instance) + else + { + if (this != m_instance) { Destroy(this.gameObject); } } } - public void TangoServiceInitializd () { - if (tangoServiceInitilized != null) { - tangoServiceInitilized(); + /// + /// Fire the TangoServiceInitilized event. + /// + public void SendTangoServiceInitialized() + { + if (TangoServiceInitialized != null) + { + TangoServiceInitialized(); } } - public void GameDataSaved(bool successed) { - if (gameDataSaved != null) { - gameDataSaved(successed); + /// + /// Fire the GameDataSaved event. + /// + /// If set to true successed. + public void SendGameDataSaved(bool successed) + { + if (GameDataSaved != null) + { + GameDataSaved(successed); } } - public void TangoPoseStateChanged(TangoPoseStates currentState) { - if (tangoPoseStatedChanged != null) { - tangoPoseStatedChanged(currentState); + /// + /// Fire the TangoPoseStateChanged event. + /// + /// Current state. + public void SendTangoPoseStateChanged(TangoPoseStates currentState) + { + if (TangoPoseStateChanged != null) + { + TangoPoseStateChanged(currentState); } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/FileParser.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/FileParser.cs index 84dfa5d2..2a646674 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/FileParser.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/FileParser.cs @@ -1,28 +1,43 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; +using UnityEngine; -public class FileParser : MonoBehaviour { - public static void SaveBuildingDataToPath(List buildingList, string path) { +/// +/// Misc File utilities. +/// +public class FileParser : MonoBehaviour +{ + /// + /// Saves all buildings to a file. + /// + /// Building list. + /// File path to save to. + public static void SaveBuildingDataToPath(List buildingList, string path) + { StringBuilder strBuilder = new StringBuilder(); - foreach(Building iter in buildingList) { + foreach (Building iter in buildingList) + { strBuilder.Append(iter.buildingId.ToString() + ","); strBuilder.Append(iter.buildingObject.transform.position.x.ToString() + ","); strBuilder.Append(iter.buildingObject.transform.position.z.ToString() + "\n"); @@ -30,16 +45,24 @@ public static void SaveBuildingDataToPath(List buildingList, string pa System.IO.File.WriteAllText(path, strBuilder.ToString()); } - public static void GetVectorListFromPath(out List buildList, string path) { - string line = ""; + /// + /// Load buildings from a file. + /// + /// Buildings loaded. + /// File path to load. + public static void GetVectorListFromPath(out List buildList, string path) + { + string line = string.Empty; buildList = new List(); + // Null terminator causes problem in the file syste. StreamReader file = new StreamReader(path); - while ((line = file.ReadLine()) != null) { + while ((line = file.ReadLine()) != null) + { Building b = new Building(); string[] ints = line.Split(','); - b = BuildingManager.instance.InstantiateBuilding(int.Parse(ints[0]), float.Parse(ints[1]), float.Parse(ints[2])); - b.buildingObject.GetComponent ().buildingOutfit.SetActive (false); + b = BuildingManager.Instance.InstantiateBuilding(int.Parse(ints[0]), float.Parse(ints[1]), float.Parse(ints[2])); + b.buildingObject.GetComponent().buildingOutfit.SetActive(false); buildList.Add(b); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/StartSceneUIManager.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/StartSceneUIManager.cs index 8083cf03..48e6cae0 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/StartSceneUIManager.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/StartSceneUIManager.cs @@ -1,27 +1,38 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class StartSceneUIManager : MonoBehaviour { +/// +/// Simple script to update UI text. +/// +public class StartSceneUIManager : MonoBehaviour +{ public TextMesh curADFId; public TextMesh curADFName; - // Update is called once per frame - void Update () { + /// + /// Update is called once per frame. + /// + public void Update() + { curADFId.text = Statics.curADFId; curADFName.text = Statics.curADFName; } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/Statics.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/Statics.cs index a92a43ee..6adbd6a0 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/Statics.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/Statics.cs @@ -1,29 +1,41 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public enum TangoPoseStates { +/// +/// Tango pose states. +/// +public enum TangoPoseStates +{ Connecting, Relocalizing, // Relocalizing means running under motion tracking mode. Running, Unknown } -public class Statics { +/// +/// Stores global state. +/// +public class Statics +{ // Game states. public static bool isPlacingObject = false; @@ -31,8 +43,8 @@ public class Statics { public static TangoPoseStates currentTangoState; // String consts. - public static string curADFId = ""; - public static string curADFName = ""; + public static string curADFId = string.Empty; + public static string curADFName = string.Empty; public static string debugString = "statics"; public static string uiPanelConnectingService = "Connecting Tango Service"; public static string uiPanelRelocalizing = "Walk around to relocalize"; diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/TangoInitializer.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/TangoInitializer.cs index ba0cedf4..c4306e82 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/TangoInitializer.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/GameData/TangoInitializer.cs @@ -1,63 +1,88 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; -using Tango; using System.IO; +using Tango; +using UnityEngine; -public class TangoInitializer : MonoBehaviour { +/// +/// Script to connect to the Tango service. +/// +public class TangoInitializer : MonoBehaviour +{ public TangoApplication tangoApplication; private bool isInitialized = false; private bool shouldInitTango = false; - void Start () { + /// + /// Use this to initialize. + /// + private void Start() + { tangoApplication = FindObjectOfType(); - if(tangoApplication != null) { - if(AndroidHelper.IsTangoCorePresent()) { + if (tangoApplication != null) + { + if (AndroidHelper.IsTangoCorePresent()) + { // Request Tango permissions tangoApplication.RegisterPermissionsCallback(_OnTangoApplicationPermissionsEvent); tangoApplication.RequestNecessaryPermissionsAndConnect(); } - } else { + } + else + { Debug.Log("No Tango Manager found in scene."); } } + /// + /// Update is called once per frame. + /// private void Update() { - if(shouldInitTango) { + if (shouldInitTango) + { tangoApplication.InitApplication(); isInitialized = true; shouldInitTango = false; } } - private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { - if(permissionsGranted && !isInitialized) { + /// + /// Tango permissions event callback. + /// + /// If set to true permissions granted. + private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) + { + if (permissionsGranted && !isInitialized) + { isInitialized = true; shouldInitTango = true; tangoApplication.InitApplication(); - EventManager.instance.TangoServiceInitializd(); + EventManager.Instance.SendTangoServiceInitialized(); } else if (!permissionsGranted) { AndroidHelper.ShowAndroidToastMessage("Motion Tracking Permissions Needed", true); } } - } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPicker.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPicker.cs index 722da08c..2c081dab 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPicker.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPicker.cs @@ -1,54 +1,80 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; using Tango; +using UnityEngine; -public class ADFPicker : MonoBehaviour { +/// +/// An ADF picker button. +/// +public class ADFPicker : MonoBehaviour +{ public Vector3 buttonOffsets; public GameObject adfPickerButtonPrototype; - // Use this for initialization - void Awake () { - EventManager.tangoServiceInitilized += HandleEventTangoInitialized; + /// + /// Use this for initialization. + /// + public void Awake() + { + EventManager.TangoServiceInitialized += HandleEventTangoInitialized; } - void HandleEventTangoInitialized() { + /// + /// Callback when the Tango service is initialized. + /// + private void HandleEventTangoInitialized() + { PoseProvider.RefreshADFList(); RefreshADFPickerList(PoseProvider.GetCachedADFList()); } - void RefreshADFPickerList(UUID_list list) { - foreach (Transform child in transform) { + /// + /// Refreshs the ADF picker list UI. + /// + /// List to use. + private void RefreshADFPickerList(UUID_list list) + { + foreach (Transform child in transform) + { Destroy(transform.gameObject); } int numberOfADFs = list.Count; Vector3 startPosition = transform.position; - for (int i = 0; i < numberOfADFs; i++) { + for (int i = 0; i < numberOfADFs; i++) + { UUIDUnityHolder adf = list.GetADFAtIndex(i); Dictionary adfMeta = adf.uuidMetaData.GetMetaDataKeyValues(); string uuid = adfMeta["id"]; string name = adfMeta["name"]; - GameObject button = (GameObject) Instantiate(adfPickerButtonPrototype, startPosition+i*buttonOffsets, Quaternion.identity); + GameObject button = (GameObject)Instantiate(adfPickerButtonPrototype, startPosition + (i * buttonOffsets), Quaternion.identity); button.GetComponent().SetTitles(name, uuid); } } - void OnDestory () { - EventManager.tangoServiceInitilized -= HandleEventTangoInitialized; + /// + /// Called when this game object is destroyed. + /// + private void OnDestory() + { + EventManager.TangoServiceInitialized -= HandleEventTangoInitialized; } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPickerButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPickerButton.cs index 70cb5b67..d5fa6f38 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPickerButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/ADFPickerButton.cs @@ -1,18 +1,22 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using UnityEngine; @@ -30,43 +34,74 @@ public class ADFPickerButton : TouchableObject private Vector3 touchScaleSize; private Vector3 untouchedScaleSize; - void Start() { + /// + /// Use this to initialize. + /// + public void Start() + { m_raycastCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent(); touchScaleSize = normaledScaleFactor * content.transform.localScale; untouchedScaleSize = content.transform.localScale; } - protected override void OnTouch() { + /// + /// Sets the titles. + /// + /// Title. + /// Subtitle. + public void SetTitles(string title, string subtitle) + { + titleTextObj.text = title; + subtitleTextObj.text = subtitle; + } + + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { content.gameObject.transform.localScale = touchScaleSize; } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { content.gameObject.transform.localScale = untouchedScaleSize; } - protected override void TouchUp() { + /// + /// Called every frame. + /// + protected override void TouchUp() + { content.gameObject.transform.localScale = untouchedScaleSize; - if (Statics.curADFId == subtitleTextObj.text) { - Statics.curADFId = ""; - Statics.curADFName = ""; - } else { + if (Statics.curADFId == subtitleTextObj.text) + { + Statics.curADFId = string.Empty; + Statics.curADFName = string.Empty; + } + else + { Statics.curADFId = subtitleTextObj.text; Statics.curADFName = titleTextObj.text; } } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); - if (Statics.curADFId != subtitleTextObj.text) { + if (Statics.curADFId != subtitleTextObj.text) + { checkerObject.SetActive(false); } - else { + else + { checkerObject.SetActive(true); } } - - public void SetTitles(string title, string subtitle) { - titleTextObj.text = title; - subtitleTextObj.text = subtitle; - } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/AddBuildingPickerButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/AddBuildingPickerButton.cs index 979e94a6..3ae29ed9 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/AddBuildingPickerButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/AddBuildingPickerButton.cs @@ -1,21 +1,28 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; +/// +/// UI for picking a building. +/// public class AddBuildingPickerButton : TouchableObject { public GameObject buildingPickerBar; @@ -24,54 +31,84 @@ public class AddBuildingPickerButton : TouchableObject private Vector3 touchScaleSize; private Vector3 untouchedScaleSize; - bool isPickerOpened = false; + private bool isPickerOpened = false; - void Start() { + /// + /// Use this to initialize. + /// + public void Start() + { m_raycastCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent(); touchScaleSize = normaledScaleFactor * content.transform.localScale; untouchedScaleSize = content.transform.localScale; + // Reset the picker position. buildingPickerBar.transform.position = new Vector3(Statics.buildingPickerSlideOutPosX, buildingPickerBar.transform.position.y, buildingPickerBar.transform.position.z); } - protected override void OnTouch() { + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { content.gameObject.transform.localScale = touchScaleSize; } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { content.gameObject.transform.localScale = untouchedScaleSize; } - protected override void TouchUp() { + /// + /// Called every frame. + /// + protected override void TouchUp() + { content.gameObject.transform.localScale = untouchedScaleSize; StartCoroutine(ButtonRotationAnimation()); } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); } - float counter = 0.0f; - float totalTime = 0.25f; - IEnumerator ButtonRotationAnimation () { - while(counter< totalTime) { + private float counter = 0.0f; + private float totalTime = 0.25f; + + /// + /// Coroutine to show a rotation animation. + /// + /// The coroutine enumerator. + private IEnumerator ButtonRotationAnimation() + { + while (counter < totalTime) + { counter += Time.deltaTime; float rotValue; float posValue; - if (isPickerOpened) { - rotValue = Mathf.Lerp(-45.0f, 0.0f, counter/totalTime); + if (isPickerOpened) + { + rotValue = Mathf.Lerp(-45.0f, 0.0f, counter / totalTime); posValue = Mathf.Lerp(Statics.buildingPickerSlideInPosX, Statics.buildingPickerSlideOutPosX, - counter/totalTime); - - } else { - rotValue = Mathf.Lerp(0.0f, -45.0f, counter/totalTime); + counter / totalTime); + } + else + { + rotValue = Mathf.Lerp(0.0f, -45.0f, counter / totalTime); posValue = Mathf.Lerp(Statics.buildingPickerSlideOutPosX, Statics.buildingPickerSlideInPosX, - counter/totalTime); + counter / totalTime); } transform.rotation = Quaternion.Euler(new Vector3(0, 0, rotValue)); buildingPickerBar.transform.position = new Vector3(posValue, diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/BuildingPickerButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/BuildingPickerButton.cs index cd9863ca..9e114979 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/BuildingPickerButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/BuildingPickerButton.cs @@ -1,38 +1,62 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class BuildingPickerButton : TouchableObject { - +/// +/// Building picker button. +/// +public class BuildingPickerButton : TouchableObject +{ public int buildingId; - - protected override void OnTouch() { + + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { if (!Statics.isPlacingObject) - BuildingManager.instance.CreateBulding(buildingId); + { + BuildingManager.Instance.CreateBulding(buildingId); + } } - protected override void TouchUp() { - + /// + /// Called every frame. + /// + protected override void TouchUp() + { } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/CancelBuildingButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/CancelBuildingButton.cs index 248581e6..798b4763 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/CancelBuildingButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/CancelBuildingButton.cs @@ -1,47 +1,75 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class CancelBuildingButton : TouchableObject { +/// +/// Cancel building button. +/// +public class CancelBuildingButton : TouchableObject +{ public GameObject content; public float normaledScaleFactor = 0.95f; private Vector3 touchScaleSize; private Vector3 untouchedScaleSize; - - void Start() { + + /// + /// Use this to initialize. + /// + public void Start() + { m_raycastCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent(); touchScaleSize = normaledScaleFactor * content.transform.localScale; untouchedScaleSize = content.transform.localScale; } - protected override void OnTouch() { + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { content.gameObject.transform.localScale = touchScaleSize; } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { content.gameObject.transform.localScale = untouchedScaleSize; } - protected override void TouchUp() { + /// + /// Called every frame. + /// + protected override void TouchUp() + { content.gameObject.transform.localScale = untouchedScaleSize; - BuildingManager.instance.CancelBuildingPlacement (); + BuildingManager.Instance.CancelBuildingPlacement(); } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/LoadMapButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/LoadMapButton.cs index d146bab9..7a5e2197 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/LoadMapButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/LoadMapButton.cs @@ -1,30 +1,41 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class LoadMapButton : MonoBehaviour { - - // Use this for initialization - void Start () { - +/// +/// Load map button. +/// +public class LoadMapButton : MonoBehaviour +{ + /// + /// Use this for initialization. + /// + public void Start() + { } - // Update is called once per frame - void Update () { - + /// + /// Update is called once per frame. + /// + public void Update() + { } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/PlaceBuildingButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/PlaceBuildingButton.cs index 8c1ca3ab..052bc39c 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/PlaceBuildingButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/PlaceBuildingButton.cs @@ -1,48 +1,75 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class PlaceBuildingButton : TouchableObject { +/// +/// Place building button. +/// +public class PlaceBuildingButton : TouchableObject +{ public GameObject content; public float normaledScaleFactor = 0.95f; private Vector3 touchScaleSize; private Vector3 untouchedScaleSize; - void Start() { + /// + /// Initialize this component. + /// + public void Start() + { m_raycastCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent(); touchScaleSize = normaledScaleFactor * content.transform.localScale; untouchedScaleSize = content.transform.localScale; } - protected override void OnTouch() { + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { content.gameObject.transform.localScale = touchScaleSize; } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { content.gameObject.transform.localScale = untouchedScaleSize; } - protected override void TouchUp() { + /// + /// Called every frame. + /// + protected override void TouchUp() + { content.gameObject.transform.localScale = untouchedScaleSize; - BuildingManager.instance.PlaceBuilding (); - + BuildingManager.Instance.PlaceBuilding(); } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/SaveGameButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/SaveGameButton.cs index 1cfe39d6..b28b20c9 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/SaveGameButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/SaveGameButton.cs @@ -1,47 +1,75 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class SaveGameButton : TouchableObject { +/// +/// Save game button. +/// +public class SaveGameButton : TouchableObject +{ public GameObject content; public float normaledScaleFactor = 0.95f; private Vector3 touchScaleSize; private Vector3 untouchedScaleSize; - - void Start() { + + /// + /// Initialize this component. + /// + public void Start() + { m_raycastCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent(); touchScaleSize = normaledScaleFactor * content.transform.localScale; untouchedScaleSize = content.transform.localScale; } - protected override void OnTouch() { + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { content.gameObject.transform.localScale = touchScaleSize; } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { content.gameObject.transform.localScale = untouchedScaleSize; } - protected override void TouchUp() { + /// + /// Called every frame. + /// + protected override void TouchUp() + { content.gameObject.transform.localScale = untouchedScaleSize; - DataSavingController.SaveData (); + DataSavingController.SaveData(); } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/StartGameButton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/StartGameButton.cs index b1ece758..de3b9e72 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/StartGameButton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/StartGameButton.cs @@ -1,48 +1,75 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; +/// +/// Start game button. +/// public class StartGameButton : TouchableObject { public GameObject content; public float normaledScaleFactor = 0.95f; private Vector3 touchScaleSize; private Vector3 untouchedScaleSize; - - void Start() { + + /// + /// Start this instance. + /// + public void Start() + { m_raycastCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent(); touchScaleSize = normaledScaleFactor * content.transform.localScale; untouchedScaleSize = content.transform.localScale; } - protected override void OnTouch() { + /// + /// Touch event similar to key hold. + /// + protected override void OnTouch() + { content.gameObject.transform.localScale = touchScaleSize; } - protected override void OutTouch() { + /// + /// Called every frame. + /// + protected override void OutTouch() + { content.gameObject.transform.localScale = untouchedScaleSize; } - protected override void TouchUp() { + /// + /// Called every frame. + /// + protected override void TouchUp() + { content.gameObject.transform.localScale = untouchedScaleSize; Application.LoadLevel("ExperimentalPersistentState_GameScene"); } - protected override void Update() { + /// + /// Called every frame. + /// + protected override void Update() + { base.Update(); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/TouchableObject.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/TouchableObject.cs index 8e55ce03..ba198997 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/TouchableObject.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/TouchableObject.cs @@ -1,18 +1,22 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; using UnityEngine; @@ -22,10 +26,10 @@ /// public class TouchableObject : MonoBehaviour { - // camera which detects button touch through raycast + // camera which detects button touch through raycast public Camera m_raycastCamera; - // Flag for Editor mode testing + // Flag for Editor mode testing private bool m_isOutTouch = true; /// diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/UIInfoPanelController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/UIInfoPanelController.cs index 6921b6d5..472443e0 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/UIInfoPanelController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/UI/UIInfoPanelController.cs @@ -1,72 +1,113 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class UIInfoPanelController : MonoBehaviour { +/// +/// User interface info panel controller. +/// +public class UIInfoPanelController : MonoBehaviour +{ public GameObject background; public TextMesh textMesh; - // Use this for initialization - void Start () { - EventManager.gameDataSaved += GameDataSaved; - EventManager.tangoPoseStatedChanged += TangoPoseStateChanged; + + /// + /// Use this for initialization. + /// + public void Start() + { + EventManager.GameDataSaved += GameDataSaved; + EventManager.TangoPoseStateChanged += TangoPoseStateChanged; } - // Update is called once per frame - void Update () { + /// + /// Update is called once per frame. + /// + public void Update() + { } - void GameDataSaved(bool successed) { - if (successed) { + /// + /// Callback for when GameData is saved. + /// + /// If set to true successed. + private void GameDataSaved(bool successed) + { + if (successed) + { StartCoroutine(ShowText("Game Saved", 1.5f)); } } - void TangoPoseStateChanged(TangoPoseStates curState) { - if (curState == TangoPoseStates.Connecting) { + /// + /// Callback for when the Tango pose state changes. + /// + /// Current state. + private void TangoPoseStateChanged(TangoPoseStates curState) + { + if (curState == TangoPoseStates.Connecting) + { SetPanelShown(true); textMesh.text = Statics.uiPanelConnectingService; } - else if (curState == TangoPoseStates.Relocalizing) { + else if (curState == TangoPoseStates.Relocalizing) + { SetPanelShown(true); textMesh.text = Statics.uiPanelRelocalizing; } - else if (curState == TangoPoseStates.Running) { + else if (curState == TangoPoseStates.Running) + { SetPanelShown(false); } } - void SetPanelShown(bool isShowing) { + /// + /// Set the panel visibility. + /// + /// If set to true is showing. + private void SetPanelShown(bool isShowing) + { background.GetComponent().enabled = isShowing; textMesh.gameObject.SetActive(isShowing); } - float counter = 0.0f; - IEnumerator ShowText(string text, float timeLength) { + private float counter = 0.0f; + + /// + /// Coroutine for showing text. + /// + /// Coroutine enumerator. + /// Text to show. + /// How long to show the text. + private IEnumerator ShowText(string text, float timeLength) + { textMesh.text = text; - while (counter <= timeLength) { + while (counter <= timeLength) + { SetPanelShown(true); counter += Time.deltaTime; yield return null; } SetPanelShown(false); - textMesh.text = ""; + textMesh.text = string.Empty; counter = 0.0f; yield return null; } - - } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Utils/ManagerSingleton.cs b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Utils/ManagerSingleton.cs index d70b7ab2..e06ba911 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Utils/ManagerSingleton.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalPersistentState/Scripts/Utils/ManagerSingleton.cs @@ -1,30 +1,63 @@ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class ManagerSingleton : MonoBehaviour { - private static ManagerSingleton _instance; - - public static ManagerSingleton instance - { - get - { - if(_instance == null) - { - _instance = GameObject.FindObjectOfType(); - DontDestroyOnLoad(_instance.gameObject); +/// +/// Manager singleton. +/// +public class ManagerSingleton : MonoBehaviour +{ + private static ManagerSingleton m_instance; + + /// + /// The singleton instance. + /// + /// The instance. + public static ManagerSingleton Instance + { + get + { + if (m_instance == null) + { + m_instance = GameObject.FindObjectOfType(); + DontDestroyOnLoad(m_instance.gameObject); } - return _instance; + return m_instance; } } - void Awake () { - if(_instance == null) { - _instance = this; - DontDestroyOnLoad(this); - } - else { - if(this != _instance) + /// + /// Do initialization here. + /// + public void Awake() + { + if (m_instance == null) + { + m_instance = this; + DontDestroyOnLoad(this); + } + else + { + if (this != m_instance) { Destroy(this.gameObject); } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CreateHeadsetGeometery.cs b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CreateHeadsetGeometery.cs index 3206c68f..eaf09b4e 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CreateHeadsetGeometery.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CreateHeadsetGeometery.cs @@ -1,97 +1,121 @@ -using UnityEngine; +//----------------------------------------------------------------------- +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class CreateHeadsetGeometery : MonoBehaviour { - - +/// +/// Creates geometry to model a headset. +/// +public class CreateHeadsetGeometery : MonoBehaviour +{ public GameObject leftCamera; public GameObject rightCamera; + public Vector2 screenSizeInMM = new Vector2(150, 95); + public Vector3 screenOffsetInMM = new Vector3(0, -60, 0); + + public Vector3 headOffsetInMM = new Vector3(0, -60, -110); + private GameObject tangoPoseCenter; private GameObject leftEyeBall; private GameObject rightEyeBall; private GameObject headCenter; -// private GameObject leftCamNearClip; -// private GameObject rightCamNearClip; +//// private GameObject leftCamNearClip; +//// private GameObject rightCamNearClip; private GameObject deviceScreen; - public Vector2 screenSizeInMM = new Vector2(150, 95); - public Vector3 screenOffsetInMM = new Vector3(0,-60,0); - public Vector3 headOffsetInMM = new Vector3(0,-60,-110); - -// private Camera leftCameraComponent; -// private Camera rightCameraComponent; +//// private Camera leftCameraComponent; +//// private Camera rightCameraComponent; private float eyeBallSizeInMM = 24; private float worldScale; private Color color = Color.gray; private float headBallSizeInMM = 140; - // Use this for initialization - void Start () { - - worldScale = GetComponent ().m_metersToWorldUnitsScaler; + /// + /// Use this for initialization. + /// + public void Start() + { + worldScale = GetComponent().m_metersToWorldUnitsScaler; -// leftCameraComponent = leftCamera.GetComponent (); -// rightCameraComponent = rightCamera.GetComponent (); +//// leftCameraComponent = leftCamera.GetComponent (); +//// rightCameraComponent = rightCamera.GetComponent (); - tangoPoseCenter = GameObject.CreatePrimitive(PrimitiveType.Cube); + tangoPoseCenter = GameObject.CreatePrimitive(PrimitiveType.Cube); tangoPoseCenter.transform.parent = transform; - tangoPoseCenter.transform.localScale = new Vector3 (0.02f, 0.02f, 0.02f)*worldScale; - tangoPoseCenter.transform.localPosition = new Vector3 (); + tangoPoseCenter.transform.localScale = new Vector3(0.02f, 0.02f, 0.02f) * worldScale; + tangoPoseCenter.transform.localPosition = new Vector3(); tangoPoseCenter.GetComponent().material.shader = Shader.Find("Diffuse"); tangoPoseCenter.GetComponent().material.SetColor("_Color", color); - leftEyeBall = GameObject.CreatePrimitive(PrimitiveType.Sphere); + leftEyeBall = GameObject.CreatePrimitive(PrimitiveType.Sphere); leftEyeBall.transform.parent = leftCamera.transform; - leftEyeBall.transform.localPosition = new Vector3 (); - leftEyeBall.transform.localScale = new Vector3 (eyeBallSizeInMM, eyeBallSizeInMM,eyeBallSizeInMM)*worldScale/1000.0f; + leftEyeBall.transform.localPosition = new Vector3(); + leftEyeBall.transform.localScale = new Vector3(eyeBallSizeInMM, eyeBallSizeInMM, eyeBallSizeInMM) * worldScale / 1000.0f; leftEyeBall.GetComponent().material.shader = Shader.Find("Diffuse"); leftEyeBall.GetComponent().material.SetColor("_Color", color); - - headCenter = GameObject.CreatePrimitive(PrimitiveType.Sphere); + headCenter = GameObject.CreatePrimitive(PrimitiveType.Sphere); headCenter.transform.parent = transform; - headCenter.transform.localPosition = headOffsetInMM*worldScale/1000.0f; - headCenter.transform.localScale = new Vector3 (headBallSizeInMM, headBallSizeInMM, headBallSizeInMM)*worldScale/1000.0f; + headCenter.transform.localPosition = headOffsetInMM * worldScale / 1000.0f; + headCenter.transform.localScale = new Vector3(headBallSizeInMM, headBallSizeInMM, headBallSizeInMM) * worldScale / 1000.0f; headCenter.GetComponent().material.shader = Shader.Find("Diffuse"); headCenter.GetComponent().material.SetColor("_Color", color); +//// leftCamNearClip = GameObject.CreatePrimitive(PrimitiveType.Cube); +//// leftCamNearClip.transform.parent = leftCamera.transform; +//// leftCamNearClip.transform.localPosition = new Vector3 (0,0,leftCameraComponent.nearClipPlane); +//// leftCamNearClip.GetComponent().material.shader = Shader.Find("Diffuse"); +//// leftCamNearClip.GetComponent().material.SetColor("_Color", color); -// leftCamNearClip = GameObject.CreatePrimitive(PrimitiveType.Cube); -// leftCamNearClip.transform.parent = leftCamera.transform; -// leftCamNearClip.transform.localPosition = new Vector3 (0,0,leftCameraComponent.nearClipPlane); -// leftCamNearClip.GetComponent().material.shader = Shader.Find("Diffuse"); -// leftCamNearClip.GetComponent().material.SetColor("_Color", color); - - deviceScreen = GameObject.CreatePrimitive(PrimitiveType.Cube); + deviceScreen = GameObject.CreatePrimitive(PrimitiveType.Cube); deviceScreen.transform.parent = transform; - deviceScreen.transform.localScale = new Vector3 (screenSizeInMM.x*worldScale/1000.0f,screenSizeInMM.y*worldScale/1000.0f,worldScale/1000.0f); + deviceScreen.transform.localScale = new Vector3(screenSizeInMM.x * worldScale / 1000.0f, screenSizeInMM.y * worldScale / 1000.0f, worldScale / 1000.0f); deviceScreen.transform.localPosition = screenOffsetInMM * worldScale / 1000.0f; deviceScreen.GetComponent().material.shader = Shader.Find("Diffuse"); deviceScreen.GetComponent().material.SetColor("_Color", color); - rightEyeBall = GameObject.CreatePrimitive(PrimitiveType.Sphere); + rightEyeBall = GameObject.CreatePrimitive(PrimitiveType.Sphere); rightEyeBall.transform.parent = rightCamera.transform; - rightEyeBall.transform.localPosition = new Vector3 (); - rightEyeBall.transform.localScale = new Vector3 (eyeBallSizeInMM, eyeBallSizeInMM,eyeBallSizeInMM)*worldScale/1000.0f; + rightEyeBall.transform.localPosition = new Vector3(); + rightEyeBall.transform.localScale = new Vector3(eyeBallSizeInMM, eyeBallSizeInMM, eyeBallSizeInMM) * worldScale / 1000.0f; rightEyeBall.GetComponent().material.shader = Shader.Find("Diffuse"); rightEyeBall.GetComponent().material.SetColor("_Color", color); -// rightCamNearClip = GameObject.CreatePrimitive(PrimitiveType.Cube); -// rightCamNearClip.transform.parent = rightCamera.transform; -// rightCamNearClip.transform.localPosition = new Vector3 (0,0,rightCameraComponent.nearClipPlane); -// rightCamNearClip.GetComponent().material.shader = Shader.Find("Diffuse"); -// rightCamNearClip.GetComponent().material.SetColor("_Color", color); - +//// rightCamNearClip = GameObject.CreatePrimitive(PrimitiveType.Cube); +//// rightCamNearClip.transform.parent = rightCamera.transform; +//// rightCamNearClip.transform.localPosition = new Vector3 (0,0,rightCameraComponent.nearClipPlane); +//// rightCamNearClip.GetComponent().material.shader = Shader.Find("Diffuse"); +//// rightCamNearClip.GetComponent().material.SetColor("_Color", color); } - // Update is called once per frame - void Update () { -// float horzSize = Mathf.Tan (leftCameraComponent.fieldOfView * Mathf.Deg2Rad/2) * leftCameraComponent.nearClipPlane; -// leftCamNearClip.transform.localScale = new Vector3 (horzSize, horzSize, 0.01f); -// rightCamNearClip.transform.localScale = new Vector3 (horzSize, horzSize, 0.01f); + /// + /// Update is called once per frame. + /// + public void Update() + { +//// float horzSize = Mathf.Tan (leftCameraComponent.fieldOfView * Mathf.Deg2Rad/2) * leftCameraComponent.nearClipPlane; +//// leftCamNearClip.transform.localScale = new Vector3 (horzSize, horzSize, 0.01f); +//// rightCamNearClip.transform.localScale = new Vector3 (horzSize, horzSize, 0.01f); } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CubeGenerator.cs b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CubeGenerator.cs index 692ec0c3..8f90ee4b 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CubeGenerator.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CubeGenerator.cs @@ -1,32 +1,59 @@ -using UnityEngine; +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class CubeGenerator : MonoBehaviour { +/// +/// Generate the cube world. +/// +public class CubeGenerator : MonoBehaviour +{ + public GameObject prefab; - public GameObject prefab; + public float size = 1; + public int gridSize = 4; - public float size = 1; - public int gridSize = 4; + /// + /// Use this for initialization. + /// + public void Start() + { + float gridStep = 5 * size; + for (int x = -gridSize; x <= gridSize; x++) + { + for (int y = -gridSize; y <= gridSize; y++) + { + for (int z = -gridSize; z <= gridSize; z++) + { + GameObject obj = (GameObject)GameObject.Instantiate(prefab); + obj.transform.parent = transform; + obj.transform.localScale = new Vector3(size, size, size); + obj.transform.position = new Vector3(x * gridStep, y * gridStep, z * gridStep); + } + } + } + } - - // Use this for initialization - void Start () { - - float gridStep = 5*size; - for (int x = -gridSize; x <= gridSize; x++) { - for (int y = -gridSize; y <= gridSize; y++) { - for (int z = -gridSize; z <= gridSize; z++) { - GameObject obj = (GameObject)GameObject.Instantiate (prefab); - obj.transform.parent = transform; - obj.transform.localScale = new Vector3 (size, size, size); - obj.transform.position = new Vector3(x*gridStep,y*gridStep,z*gridStep); - } - } - } - } - - // Update is called once per frame - void Update () { - - } + /// + /// Update is called once per frame. + /// + public void Update() + { + } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CustomTangoController.cs b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CustomTangoController.cs index a974ed4f..1ae126c4 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CustomTangoController.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/CustomTangoController.cs @@ -1,29 +1,35 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- +using System; using System.Collections; -using UnityEngine; using Tango; -using System; +using UnityEngine; /// /// This is a basic movement controller based on /// pose estimation returned from the Tango Service. /// -public class CustomTangoController : MonoBehaviour , ITangoPose +public class CustomTangoController : MonoBehaviour, ITangoPose { + /// + /// Tracking state of Tango. + /// public enum TrackingTypes { NONE, @@ -31,8 +37,6 @@ public enum TrackingTypes ADF, RELOCALIZED } - - [HideInInspector] public float m_metersToWorldUnitsScaler = 1.0f; @@ -50,6 +54,38 @@ public enum TrackingTypes private TangoPoseData prevPose = new TangoPoseData(); private TangoPoseData currPose = new TangoPoseData(); private float unityTimestampOffset = 0; + + /// + /// Handle the callback sent by the Tango Service + /// when a new pose is sampled. + /// + /// Pose. + public void OnTangoPoseAvailable(Tango.TangoPoseData pose) + { + // The callback pose is for device with respect to start of service pose. + if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && + pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) + { + if (pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) + { + popManager.tangoInitialized = true; + popManager.TriggerAPICallbackFPS(); + + UpdateInterpolationData(pose); + if (enableInterpolation) + { + if (unityTimestampOffset > float.Epsilon) + { + UpdateUsingInterpolatedPose(Time.realtimeSinceStartup + unityTimestampOffset); + } + } + else + { + UpdateUsingInterpolatedPose(currPose.timestamp); + } + } + } + } /// /// Initialize the controller. @@ -59,7 +95,7 @@ private void Awake() m_startPosition = transform.position; m_startRotation = transform.rotation; - popManager = GetComponent (); + popManager = GetComponent(); } /// @@ -71,9 +107,9 @@ private void Start() m_tangoApplication = FindObjectOfType(); - if(m_tangoApplication != null) + if (m_tangoApplication != null) { - if(AndroidHelper.IsTangoCorePresent()) + if (AndroidHelper.IsTangoCorePresent()) { // Request Tango permissions m_tangoApplication.RegisterPermissionsCallback(_OnTangoApplicationPermissionsEvent); @@ -95,6 +131,7 @@ private void Start() /// /// Informs the user that they should install Tango Core via Android toast. /// + /// Coroutine enumerator. private IEnumerator _InformUserNoTangoCore() { AndroidHelper.ShowAndroidToastMessage("Please install Tango Core", false); @@ -128,17 +165,25 @@ private void Update() Quaternion tempRotation = transform.rotation; PoseProvider.GetMouseEmulation(ref tempPosition, ref tempRotation); transform.rotation = tempRotation; - transform.position = transform.position + (tempPosition - transform.position)*m_metersToWorldUnitsScaler; + transform.position = transform.position + ((tempPosition - transform.position) * m_metersToWorldUnitsScaler); #endif popManager.debugText = "Interpolation: " + enableInterpolation; } - - void UpdateUsingInterpolatedPose(double t) { - float dt = (float)((t - prevPose.timestamp)/(currPose.timestamp - prevPose.timestamp)); - //restrict this, so it isn't doesn't swing out of control - if(dt > 4) + + /// + /// Updates the using interpolated pose. + /// + /// Current time. + private void UpdateUsingInterpolatedPose(double t) + { + float dt = (float)((t - prevPose.timestamp) / (currPose.timestamp - prevPose.timestamp)); + + // restrict this, so it isn't doesn't swing out of control + if (dt > 4) + { dt = 4; + } Vector3 currPos = new Vector3(); Vector3 prevPos = new Vector3(); @@ -148,36 +193,44 @@ void UpdateUsingInterpolatedPose(double t) { ComputeTransformUsingPose(out currPos, out currRot, currPose); ComputeTransformUsingPose(out prevPos, out prevRot, prevPose); - //hack for rotation, should be a slerp - transform.rotation = m_startRotation*(new Quaternion(dt*(currRot[0] - prevRot[0])+prevRot[0], - dt*(currRot[1] - prevRot[1])+prevRot[1], - dt*(currRot[2] - prevRot[2])+prevRot[2], - dt*(currRot[3] - prevRot[3])+prevRot[3])); - transform.position = m_startRotation*((new Vector3 (dt * (currPos [0] - prevPos [0]) + prevPos [0], - dt * (currPos [1] - prevPos [1]) + prevPos [1], - dt * (currPos [2] - prevPos [2]) + prevPos [2])) - m_zeroPosition)*m_metersToWorldUnitsScaler + m_startPosition; + // hack for rotation, should be a slerp + transform.rotation = m_startRotation * new Quaternion((dt * (currRot[0] - prevRot[0])) + prevRot[0], + (dt * (currRot[1] - prevRot[1])) + prevRot[1], + (dt * (currRot[2] - prevRot[2])) + prevRot[2], + (dt * (currRot[3] - prevRot[3])) + prevRot[3]); + transform.position = (m_startRotation * (new Vector3((dt * (currPos[0] - prevPos[0])) + prevPos[0], + (dt * (currPos[1] - prevPos[1])) + prevPos[1], + (dt * (currPos[2] - prevPos[2])) + prevPos[2]) - m_zeroPosition) * m_metersToWorldUnitsScaler) + m_startPosition; } - - - void ComputeTransformUsingPose(out Vector3 position, out Quaternion rot, TangoPoseData pose) { - position = new Vector3((float)pose.translation [0], - (float)pose.translation [2], - (float)pose.translation [1]); - - rot = new Quaternion((float)pose.orientation [0], - (float)pose.orientation [2], // these rotation values are swapped on purpose - (float)pose.orientation [1], - (float)pose.orientation [3]); - + + /// + /// Extract the position, rotation for a Tango pose. + /// + /// Output position. + /// Output rotation. + /// Tango Pose. + private void ComputeTransformUsingPose(out Vector3 position, out Quaternion rot, TangoPoseData pose) + { + position = new Vector3((float)pose.translation[0], + (float)pose.translation[2], + (float)pose.translation[1]); + rot = new Quaternion((float)pose.orientation[0], + (float)pose.orientation[2], // these rotation values are swapped on purpose + (float)pose.orientation[1], + (float)pose.orientation[3]); + // This rotation needs to be put into Unity coordinate space. - Quaternion axisFix = Quaternion.Euler(-rot.eulerAngles.x, - -rot.eulerAngles.z, - rot.eulerAngles.y); + Quaternion axisFix = Quaternion.Euler(-rot.eulerAngles.x, -rot.eulerAngles.z, rot.eulerAngles.y); Quaternion rotationFix = Quaternion.Euler(90.0f, 0.0f, 0.0f); rot = rotationFix * axisFix; } + /// + /// Return a clone of a Tango pose. + /// + /// The cloned tango pose. + /// Tango pose. private TangoPoseData DeepCopyTangoPose(TangoPoseData other) { TangoPoseData poseCopy = new TangoPoseData(); @@ -192,51 +245,37 @@ private TangoPoseData DeepCopyTangoPose(TangoPoseData other) poseCopy.accuracy = other.accuracy; return poseCopy; } - - private void UpdateInterpolationData(TangoPoseData pose) { + + /// + /// Update the timestamp offset. + /// + /// Tango pose to update for. + private void UpdateInterpolationData(TangoPoseData pose) + { prevPose = currPose; + // We need to make sure to deep copy the pose because it is // only guaranteed to be valid for the duration of our callback. currPose = DeepCopyTangoPose(pose); float timestampSmoothing = 0.95f; - if(unityTimestampOffset < float.Epsilon) + if (unityTimestampOffset < float.Epsilon) + { unityTimestampOffset = (float)pose.timestamp - Time.realtimeSinceStartup; + } else - unityTimestampOffset = timestampSmoothing*unityTimestampOffset + (1-timestampSmoothing)*((float)pose.timestamp - Time.realtimeSinceStartup); - } - - /// - /// Handle the callback sent by the Tango Service - /// when a new pose is sampled. - /// - /// Callback context. - /// Pose. - public void OnTangoPoseAvailable(Tango.TangoPoseData pose) - { - // The callback pose is for device with respect to start of service pose. - if (pose.framePair.baseFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE && - pose.framePair.targetFrame == TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE) { - if(pose.status_code == TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) - { - popManager.tangoInitialized = true; - popManager.TriggerAPICallbackFPS(); - - UpdateInterpolationData(pose); - if (enableInterpolation){ - if(unityTimestampOffset > float.Epsilon) - UpdateUsingInterpolatedPose(Time.realtimeSinceStartup + unityTimestampOffset); - } else { - UpdateUsingInterpolatedPose(currPose.timestamp); - } - } + unityTimestampOffset = (timestampSmoothing * unityTimestampOffset) + ((1 - timestampSmoothing) * ((float)pose.timestamp - Time.realtimeSinceStartup)); } } - + + /// + /// Callback for tango permissions. + /// + /// If set to true permissions granted. private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { popManager.StartApiFailCheck(); - if(permissionsGranted) + if (permissionsGranted) { m_tangoApplication.InitApplication(); m_tangoApplication.InitProviders(String.Empty); @@ -248,11 +287,17 @@ private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) } } - void OnGUI() { + /// + /// Unity 2D GUI. + /// + private void OnGUI() + { // TODO(jason): temporarily comment out this part, to do is to move this button to someother debug functionality class. - if (isShowingDebugButton) { - if (GUI.Button (new Rect (Screen.width - 200, 50, 150, 80), "Reset Position")) { - ComputeTransformUsingPose (out m_zeroPosition, out m_zeroRotation, currPose); + if (isShowingDebugButton) + { + if (GUI.Button(new Rect(Screen.width - 200, 50, 150, 80), "Reset Position")) + { + ComputeTransformUsingPose(out m_zeroPosition, out m_zeroRotation, currPose); } } } diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/PopupManager.cs b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/PopupManager.cs index c282b75f..ea4069b7 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/PopupManager.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/PopupManager.cs @@ -1,22 +1,47 @@ -using UnityEngine; +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class PopupManager : MonoBehaviour { - +/// +/// Manage the API-based popups. +/// +public class PopupManager : MonoBehaviour +{ [HideInInspector] public string debugText; - [HideInInspector] public bool tangoInitialized = false; public bool showText = true; - public Vector2 textPosition = new Vector2 (230, 30); + public Vector2 textPosition = new Vector2(230, 30); public GameObject viewController; - public Vector3 chartPosition = new Vector3 (-0.5f, 0, 1); + public Vector3 chartPosition = new Vector3(-0.5f, 0, 1); - private float FPSSmoothing = 0.95f; + public bool showPlots = true; + public GameObject tangoServiceTroublePopup; + public GameObject tangoInitializePopup; + public bool isShowingDebugButton = false; + + private float fpsSmoothing = 0.95f; private float updateFPS = 60; private float apiFPS = 0; private float lastUpdateTime = 0; @@ -26,81 +51,107 @@ public class PopupManager : MonoBehaviour { private LineChart baselineChart; private bool isApiFailCheckingStarted = false; - public bool showPlots = true; - public GameObject tangoServiceTroublePopup; - public GameObject tangoInitializePopup; - public bool isShowingDebugButton = false; - - // Use this for initialization - void Start () { + /// + /// Use this for initialization. + /// + public void Start() + { tangoServiceTroublePopup.SetActive(false); tangoInitializePopup.SetActive(false); - apiChart = new LineChart (viewController, chartPosition, Color.red, 100); - renderChart = new LineChart (viewController, chartPosition, Color.green, 100); - baselineChart = new LineChart (viewController, chartPosition, Color.gray, 100); + apiChart = new LineChart(viewController, chartPosition, Color.red, 100); + renderChart = new LineChart(viewController, chartPosition, Color.green, 100); + baselineChart = new LineChart(viewController, chartPosition, Color.gray, 100); apiChart.line.enabled = showPlots; renderChart.line.enabled = showPlots; baselineChart.line.enabled = showPlots; } - // Update is called once per frame - void Update () { - //timeout popup if we are running without getting any data from the service + /// + /// Update is called once per frame. + /// + public void Update() + { + // timeout popup if we are running without getting any data from the service #if UNITY_ANDROID && !UNITY_EDITOR tangoInitializePopup.SetActive (!tangoInitialized); tangoServiceTroublePopup.SetActive(((lastUpdateTime - lastApiTime) > 5)); #endif - apiChart.Update (); - renderChart.Update (); - baselineChart.Update (); + apiChart.Update(); + renderChart.Update(); + baselineChart.Update(); } - public void TriggerUpdateFPS() { - if (isApiFailCheckingStarted) { + /// + /// Update the fps calculation. + /// + public void TriggerUpdateFPS() + { + if (isApiFailCheckingStarted) + { float now = Time.realtimeSinceStartup; float dt = now - lastUpdateTime; lastUpdateTime = now; - if (dt < float.Epsilon) { + if (dt < float.Epsilon) + { return; } if (renderChart != null) - renderChart.AddData (10 * dt); - updateFPS = updateFPS * FPSSmoothing + (1.0f - FPSSmoothing) / dt; + { + renderChart.AddData(10 * dt); + } + updateFPS = (updateFPS * fpsSmoothing) + ((1.0f - fpsSmoothing) / dt); } } - - public void StartApiFailCheck() { + + /// + /// Start checking for the API failure. + /// + public void StartApiFailCheck() + { isApiFailCheckingStarted = true; } - public void TriggerAPICallbackFPS() { + /// + /// Update the API fps. + /// + public void TriggerAPICallbackFPS() + { float now = Time.realtimeSinceStartup; float dt = now - lastApiTime; lastApiTime = now; - if(dt < float.Epsilon) { + if (dt < float.Epsilon) + { return; } - if(apiChart != null) - apiChart.AddData (10*dt); - apiFPS = apiFPS*FPSSmoothing + (1.0f-FPSSmoothing)/dt; + if (apiChart != null) + { + apiChart.AddData(10 * dt); + } + apiFPS = (apiFPS * fpsSmoothing) + ((1.0f - fpsSmoothing) / dt); } - void OnGUI() + /// + /// Unity GUI callback. + /// + public void OnGUI() { - if (showText) { + if (showText) + { int textLineSpacing = 20; - GUI.Label(new Rect(textPosition.x, textPosition.y,1000,30), "Update FPS: " + updateFPS.ToString("F2")); - GUI.Label(new Rect(textPosition.x, textPosition.y + textLineSpacing*1,1000,30), "API FPS: " + apiFPS.ToString("F2")); - GUI.Label(new Rect(textPosition.x, textPosition.y + textLineSpacing*2,1000,30), "Position: " + transform.position.ToString("F3")); - GUI.Label(new Rect(textPosition.x, textPosition.y + textLineSpacing*3,1000,30), "Debug: " + debugText); + GUI.Label(new Rect(textPosition.x, textPosition.y, 1000, 30), "Update FPS: " + updateFPS.ToString("F2")); + GUI.Label(new Rect(textPosition.x, textPosition.y + (textLineSpacing * 1), 1000, 30), "API FPS: " + apiFPS.ToString("F2")); + GUI.Label(new Rect(textPosition.x, textPosition.y + (textLineSpacing * 2), 1000, 30), "Position: " + transform.position.ToString("F3")); + GUI.Label(new Rect(textPosition.x, textPosition.y + (textLineSpacing * 3), 1000, 30), "Debug: " + debugText); } // TODO(jason): temporarily comment out this part, to do is to move this button to someother debug functionality class. - if (isShowingDebugButton) { - if (GUI.Button (new Rect (Screen.width - 200, 250, 150, 80), "Toggle Time Plots")) { + if (isShowingDebugButton) + { + if (GUI.Button(new Rect(Screen.width - 200, 250, 150, 80), "Toggle Time Plots")) + { showPlots = !showPlots; apiChart.line.enabled = showPlots; renderChart.line.enabled = showPlots; diff --git a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/StereoCameraManager.cs b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/StereoCameraManager.cs index 2908a637..522bfb84 100644 --- a/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/StereoCameraManager.cs +++ b/UnityExamples/Assets/TangoExamples/ExperimentalVirtualReality/Scripts/StereoCameraManager.cs @@ -1,42 +1,66 @@ -using UnityEngine; +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System.Collections; +using UnityEngine; -public class StereoCameraManager : MonoBehaviour { - +/// +/// Updates two cameras to provide a stereo view. +/// +public class StereoCameraManager : MonoBehaviour +{ public GameObject leftCamera; public GameObject rightCamera; - public bool enableStereo = false; - + public float FOV = 80.0f; public float IPDInMM = 65; public float screenWidthInMM = 152.4f; - private float worldScale = 1.0f; public float nearClippingPlaneInMM = 150; public float farClippingPlaneInMM = 10000; - public Vector3 eyeOffsetInMM = new Vector3 (0, -50, -50); + public Vector3 eyeOffsetInMM = new Vector3(0, -50, -50); + + public bool isPoseIndependentCamera = false; + public bool isShowingDebugButton = false; + + private float worldScale = 1.0f; private Camera leftCameraComponent; private Camera rightCameraComponent; private int frameCount = 0; private GameObject blackPanel; - private Vector3 rightVector = new Vector3(1,0,0); - - public bool isPoseIndependentCamera = false; - public bool isShowingDebugButton = false; - - // Use this for initialization - void Start () { + private Vector3 rightVector = new Vector3(1, 0, 0); + /// + /// Use this for initialization. + /// + public void Start() + { Application.targetFrameRate = 60; - if (!isPoseIndependentCamera) { + if (!isPoseIndependentCamera) + { // TODO(jason): I think have world scale relatve the movement scale is wrong. worldScale = 1.0f; -// worldScale = GetComponent ().m_metersToWorldUnitsScaler; +//// worldScale = GetComponent ().m_metersToWorldUnitsScaler; } leftCameraComponent = leftCamera.GetComponent(); @@ -45,69 +69,91 @@ void Start () { SetupCameras(enableStereo); } - void SetupCameras(bool enable) { - - rightCameraComponent.enabled = enable; - if(enable) { - if(IPDInMM/2 > screenWidthInMM/4) { - float viewPortWidth = 2*(screenWidthInMM/2 - IPDInMM/2)/screenWidthInMM; - //screen is too small, put a gap in the middle - leftCameraComponent.rect = new Rect(0, 0,viewPortWidth, 1); - rightCameraComponent.rect = new Rect(1.0f - viewPortWidth, 0, viewPortWidth, 1); - } else { - //screen is too large, put a gap on the sides - float viewPortWidth = IPDInMM/screenWidthInMM; - leftCameraComponent.rect = new Rect(0.5f-viewPortWidth, 0,viewPortWidth, 1); - rightCameraComponent.rect = new Rect(0.5f, 0,viewPortWidth, 1); - } - - leftCameraComponent.nearClipPlane = nearClippingPlaneInMM*worldScale/1000.0f; - leftCameraComponent.farClipPlane = farClippingPlaneInMM*worldScale/1000.0f; - leftCameraComponent.fieldOfView = FOV; - rightCameraComponent.fieldOfView = leftCameraComponent.fieldOfView; - rightCameraComponent.backgroundColor = leftCameraComponent.backgroundColor; - rightCameraComponent.nearClipPlane = leftCameraComponent.nearClipPlane; - rightCameraComponent.farClipPlane = leftCameraComponent.farClipPlane; - } else { - leftCameraComponent.rect = new Rect(0, 0, 1, 1); - } - - } - - // Update is called once per frame - void Update () { + /// + /// Update is called once per frame. + /// + public void Update() + { frameCount += 1; - if(frameCount < 10) { - //needed to clear the frame buffers + if (frameCount < 10) + { + // needed to clear the frame buffers SetupCameras(false); } - if(frameCount == 11) { + if (frameCount == 11) + { SetupCameras(enableStereo); } - if (enableStereo) { - Vector3 lateralCameraOffset = 0.5f*rightVector*(IPDInMM/1000.0f)*worldScale; - Vector3 offset = eyeOffsetInMM*worldScale/1000.0f; + if (enableStereo) + { + Vector3 lateralCameraOffset = 0.5f * rightVector * (IPDInMM / 1000.0f) * worldScale; + Vector3 offset = eyeOffsetInMM * worldScale / 1000.0f; leftCamera.transform.localPosition = -lateralCameraOffset + offset; leftCamera.transform.rotation = transform.rotation; rightCamera.transform.localPosition = lateralCameraOffset + offset; rightCamera.transform.rotation = transform.rotation; } - else { + else + { leftCamera.transform.position = transform.position; leftCamera.transform.rotation = transform.rotation; } } - void OnGUI() { + /// + /// Unity GUI callback. + /// + public void OnGUI() + { // TODO(jason): temporarily checking off this part, to do is to move this button to someother debug functionality class. - if (isShowingDebugButton) { - if (GUI.Button (new Rect (Screen.width - 200, 150, 150, 80), "Toggle Stereo")) { + if (isShowingDebugButton) + { + if (GUI.Button(new Rect(Screen.width - 200, 150, 150, 80), "Toggle Stereo")) + { frameCount = 0; enableStereo = !enableStereo; } } } - + + /// + /// Setup the cameras for the left and right eye to display in stereo. + /// + /// If set to true enable. + private void SetupCameras(bool enable) + { + rightCameraComponent.enabled = enable; + if (enable) + { + if (IPDInMM / 2 > screenWidthInMM / 4) + { + float viewPortWidth = 2 * (screenWidthInMM - IPDInMM) / 2 / screenWidthInMM; + + // screen is too small, put a gap in the middle + leftCameraComponent.rect = new Rect(0, 0, viewPortWidth, 1); + rightCameraComponent.rect = new Rect(1.0f - viewPortWidth, 0, viewPortWidth, 1); + } + else + { + // screen is too large, put a gap on the sides + float viewPortWidth = IPDInMM / screenWidthInMM; + leftCameraComponent.rect = new Rect(0.5f - viewPortWidth, 0, viewPortWidth, 1); + rightCameraComponent.rect = new Rect(0.5f, 0, viewPortWidth, 1); + } + + leftCameraComponent.nearClipPlane = nearClippingPlaneInMM * worldScale / 1000.0f; + leftCameraComponent.farClipPlane = farClippingPlaneInMM * worldScale / 1000.0f; + leftCameraComponent.fieldOfView = FOV; + rightCameraComponent.fieldOfView = leftCameraComponent.fieldOfView; + rightCameraComponent.backgroundColor = leftCameraComponent.backgroundColor; + rightCameraComponent.nearClipPlane = leftCameraComponent.nearClipPlane; + rightCameraComponent.farClipPlane = leftCameraComponent.farClipPlane; + } + else + { + leftCameraComponent.rect = new Rect(0, 0, 1, 1); + } + } } diff --git a/UnityExamples/Assets/TangoExamples/MotionTracking/Scripts/MotionTrackingGUIController.cs b/UnityExamples/Assets/TangoExamples/MotionTracking/Scripts/MotionTrackingGUIController.cs index 2c48d743..31b23592 100644 --- a/UnityExamples/Assets/TangoExamples/MotionTracking/Scripts/MotionTrackingGUIController.cs +++ b/UnityExamples/Assets/TangoExamples/MotionTracking/Scripts/MotionTrackingGUIController.cs @@ -1,27 +1,30 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; +using UnityEngine; using Tango; /// /// FPS counter. /// -public class MotionTrackingGUIController : MonoBehaviour { - +public class MotionTrackingGUIController : MonoBehaviour +{ public const float UI_LABEL_START_X = 15.0f; public const float UI_LABEL_START_Y = 15.0f; public const float UI_LABEL_SIZE_X = 1920.0f; @@ -52,8 +55,8 @@ public class MotionTrackingGUIController : MonoBehaviour { public const float SECOND_TO_MILLISECOND = 1000.0f; public TangoPoseController m_tangoPoseController; - private const float m_updateFrequency = 1.0f; - private string m_FPSText; + private const float UPDATE_FREQUENCY = 1.0f; + private string m_fpsText; private int m_currentFPS; private int m_framesSinceUpdate; private float m_accumulation; @@ -62,39 +65,85 @@ public class MotionTrackingGUIController : MonoBehaviour { private Rect m_label; private TangoApplication m_tangoApplication; - // Use this for initialization - void Start () + /// + /// Use this for initialization. + /// + public void Start() { m_currentFPS = 0; m_framesSinceUpdate = 0; m_currentTime = 0.0f; - m_FPSText = "FPS = Calculating"; - m_label = new Rect(Screen.width * 0.025f - 50, Screen.height * 0.96f - 25, 600.0f, 50.0f); + m_fpsText = "FPS = Calculating"; + m_label = new Rect((Screen.width * 0.025f) - 50, (Screen.height * 0.96f) - 25, 600.0f, 50.0f); m_tangoApplication = FindObjectOfType(); } - // Update is called once per frame - void Update () + /// + /// Update is called once per frame. + /// + public void Update() { m_currentTime += Time.deltaTime; ++m_framesSinceUpdate; m_accumulation += Time.timeScale / Time.deltaTime; - if(m_currentTime >= m_updateFrequency) + if (m_currentTime >= UPDATE_FREQUENCY) { - m_currentFPS = (int)(m_accumulation/m_framesSinceUpdate); + m_currentFPS = (int)(m_accumulation / m_framesSinceUpdate); m_currentTime = 0.0f; m_framesSinceUpdate = 0; m_accumulation = 0.0f; - m_FPSText = "FPS: " + m_currentFPS; + m_fpsText = "FPS: " + m_currentFPS; + } + } + + /// + /// Unity GUI callback. + /// + public void OnGUI() + { + if (m_tangoApplication.HasRequestedPermissions()) + { + Color oldColor = GUI.color; + GUI.color = Color.white; + + if (GUI.Button(new Rect(UI_BUTTON_GAP_X, + Screen.height - (UI_BUTTON_SIZE_Y + UI_LABEL_GAP_Y), + UI_BUTTON_SIZE_X + 100, + UI_BUTTON_SIZE_Y), "Reset motion tracking")) + { + PoseProvider.ResetMotionTracking(); + } + + GUI.color = Color.black; + GUI.Label(new Rect(UI_LABEL_START_X, UI_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TANGO_SERVICE_VERSION, m_tangoPoseController.m_tangoServiceVersionName) + ""); + + GUI.Label(new Rect(UI_LABEL_START_X, UI_FPS_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + m_fpsText + ""); + + // MOTION TRACKING + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y - UI_LABEL_OFFSET, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, "Device", "Start") + ""); + + string logString = String.Format(UX_STATUS, + _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status), + _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount), + _GetLoggingStringFromVec3(m_tangoPoseController.transform.position), + _GetLoggingStringFromQuaternion(m_tangoPoseController.transform.rotation)); + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + logString + ""); + GUI.color = oldColor; } } /// /// Construct readable string from TangoPoseStatusType. /// + /// Printable string. + /// Tango pose status. private string _GetLoggingStringFromPoseStatus(TangoEnums.TangoPoseStatusType status) { - string statusString = ""; + string statusString = string.Empty; switch (status) { case TangoEnums.TangoPoseStatusType.TANGO_POSE_INITIALIZING: @@ -119,9 +168,11 @@ private string _GetLoggingStringFromPoseStatus(TangoEnums.TangoPoseStatusType st /// /// Reformat string from vector3 type for data logging. /// + /// Printable string. + /// A vector. private string _GetLoggingStringFromVec3(Vector3 vec) { - if(vec == Vector3.zero) + if (vec == Vector3.zero) { return "N/A"; } @@ -137,9 +188,11 @@ private string _GetLoggingStringFromVec3(Vector3 vec) /// /// Reformat string from quaternion type for data logging. /// + /// Printable string. + /// A quaternion. private string _GetLoggingStringFromQuaternion(Quaternion quat) { - if(quat == Quaternion.identity) + if (quat == Quaternion.identity) { return "N/A"; } @@ -160,7 +213,7 @@ private string _GetLoggingStringFromQuaternion(Quaternion quat) /// Frame count. private string _GetLoggingStringFromFrameCount(int frameCount) { - if(frameCount == -1.0) + if (frameCount == -1.0) { return "N/A"; } @@ -171,13 +224,13 @@ private string _GetLoggingStringFromFrameCount(int frameCount) } /// - /// Return a string to get logging of FrameDeltaTime + /// Return a string to get logging of FrameDeltaTime. /// /// The get loggin string from frame delta time. /// Frame delta time. private string _GetLogginStringFromFrameDeltaTime(float frameDeltaTime) { - if(frameDeltaTime == -1.0) + if (frameDeltaTime == -1.0) { return "N/A"; } @@ -186,49 +239,4 @@ private string _GetLogginStringFromFrameDeltaTime(float frameDeltaTime) return (frameDeltaTime * SECOND_TO_MILLISECOND).ToString(UI_FLOAT_FORMAT); } } - - void OnGUI() - { - if(m_tangoApplication.HasRequestedPermissions()) - { - Color oldColor = GUI.color; - GUI.color = Color.white; - - if (GUI.Button(new Rect(UI_BUTTON_GAP_X, - Screen.height - (UI_BUTTON_SIZE_Y + UI_LABEL_GAP_Y), - UI_BUTTON_SIZE_X + 100, - UI_BUTTON_SIZE_Y), "Reset motion tracking")) - { - PoseProvider.ResetMotionTracking(); - } - - GUI.color = Color.black; - GUI.Label(new Rect(UI_LABEL_START_X, - UI_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TANGO_SERVICE_VERSION, m_tangoPoseController.m_tangoServiceVersionName) + ""); - - GUI.Label(new Rect(UI_LABEL_START_X, - UI_FPS_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + m_FPSText + ""); - // MOTION TRACKING - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y - UI_LABEL_OFFSET, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, - "Device", - "Start") + ""); - - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_STATUS, - _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status), - _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount), - _GetLoggingStringFromVec3(m_tangoPoseController.transform.position), - _GetLoggingStringFromQuaternion(m_tangoPoseController.transform.rotation)) + ""); - GUI.color = oldColor; - } - } } diff --git a/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudFPSCounter.cs b/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudFPSCounter.cs index 39d79415..ece4eb4e 100644 --- a/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudFPSCounter.cs +++ b/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudFPSCounter.cs @@ -1,25 +1,29 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using UnityEngine; using Tango; /// /// FPS counter. /// -public class PointCloudFPSCounter : MonoBehaviour { +public class PointCloudFPSCounter : MonoBehaviour +{ public float m_updateFrequency = 1.0f; public string m_FPSText; @@ -31,44 +35,49 @@ public class PointCloudFPSCounter : MonoBehaviour { private Rect m_label; private TangoApplication m_tangoApplication; - // Use this for initialization - void Start () + /// + /// Use this for initialization. + /// + public void Start() { m_currentFPS = 0; m_framesSinceUpdate = 0; m_currentTime = 0.0f; m_FPSText = "FPS = Calculating"; - m_label = new Rect(Screen.width * 0.025f - 50, Screen.height * 0.96f - 25, 600.0f, 50.0f); + m_label = new Rect((Screen.width * 0.025f) - 50, (Screen.height * 0.96f) - 25, 600.0f, 50.0f); m_tangoApplication = FindObjectOfType(); } - // Update is called once per frame - void Update () + /// + /// Update is called once per frame. + /// + public void Update() { m_currentTime += Time.deltaTime; ++m_framesSinceUpdate; m_accumulation += Time.timeScale / Time.deltaTime; - if(m_currentTime >= m_updateFrequency) + if (m_currentTime >= m_updateFrequency) { - m_currentFPS = (int)(m_accumulation/m_framesSinceUpdate); + m_currentFPS = (int)(m_accumulation / m_framesSinceUpdate); m_currentTime = 0.0f; m_framesSinceUpdate = 0; m_accumulation = 0.0f; m_FPSText = "FPS: " + m_currentFPS; } } - - void OnGUI() + + /// + /// Unity GUI callback. + /// + public void OnGUI() { - if(m_tangoApplication.HasRequestedPermissions()) + if (m_tangoApplication.HasRequestedPermissions()) { Color oldColor = GUI.color; GUI.color = Color.black; - GUI.Label(new Rect(Common.UI_LABEL_START_X, - Common.UI_FPS_LABEL_START_Y, - Common.UI_LABEL_SIZE_X , - Common.UI_LABEL_SIZE_Y), Common.UI_FONT_SIZE + m_FPSText + ""); + GUI.Label(new Rect(Common.UI_LABEL_START_X, Common.UI_FPS_LABEL_START_Y, Common.UI_LABEL_SIZE_X, Common.UI_LABEL_SIZE_Y), + Common.UI_FONT_SIZE + m_FPSText + ""); GUI.color = oldColor; } diff --git a/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudGUIController.cs b/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudGUIController.cs index 3c0caa7a..2f2f63e1 100644 --- a/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudGUIController.cs +++ b/UnityExamples/Assets/TangoExamples/PointCloud/Scripts/PointCloudGUIController.cs @@ -1,28 +1,30 @@ -/* - * Copyright 2014 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using UnityEngine; +// +// +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +//----------------------------------------------------------------------- using System; +using UnityEngine; using Tango; /// /// FPS counter. /// -public class PointCloudGUIController : MonoBehaviour { - - +public class PointCloudGUIController : MonoBehaviour +{ public const float UI_LABEL_START_X = 15.0f; public const float UI_LABEL_START_Y = 15.0f; public const float UI_LABEL_SIZE_X = 1920.0f; @@ -54,8 +56,8 @@ public class PointCloudGUIController : MonoBehaviour { public TangoPoseController m_tangoPoseController; public TangoPointCloud m_pointcloud; - private const float m_updateFrequency = 1.0f; - private string m_FPSText; + private const float UPDATE_FREQUENCY = 1.0f; + private string m_fpsText; private int m_currentFPS; private int m_framesSinceUpdate; private float m_accumulation; @@ -64,39 +66,86 @@ public class PointCloudGUIController : MonoBehaviour { private Rect m_label; private TangoApplication m_tangoApplication; - // Use this for initialization - void Start () + /// + /// Use this for initialization. + /// + public void Start() { m_currentFPS = 0; m_framesSinceUpdate = 0; m_currentTime = 0.0f; - m_FPSText = "FPS = Calculating"; - m_label = new Rect(Screen.width * 0.025f - 50, Screen.height * 0.96f - 25, 600.0f, 50.0f); + m_fpsText = "FPS = Calculating"; + m_label = new Rect((Screen.width * 0.025f) - 50, (Screen.height * 0.96f) - 25, 600.0f, 50.0f); m_tangoApplication = FindObjectOfType(); } - // Update is called once per frame - void Update () + /// + /// Update is called once per frame. + /// + public void Update() { m_currentTime += Time.deltaTime; ++m_framesSinceUpdate; m_accumulation += Time.timeScale / Time.deltaTime; - if(m_currentTime >= m_updateFrequency) + if (m_currentTime >= UPDATE_FREQUENCY) { - m_currentFPS = (int)(m_accumulation/m_framesSinceUpdate); + m_currentFPS = (int)(m_accumulation / m_framesSinceUpdate); m_currentTime = 0.0f; m_framesSinceUpdate = 0; m_accumulation = 0.0f; - m_FPSText = "FPS: " + m_currentFPS; + m_fpsText = "FPS: " + m_currentFPS; + } + } + + /// + /// Unity GUI callback. + /// + public void OnGUI() + { + if (m_tangoApplication.HasRequestedPermissions()) + { + Color oldColor = GUI.color; + GUI.color = Color.black; + + GUI.Label(new Rect(UI_LABEL_START_X, UI_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TANGO_SERVICE_VERSION, m_tangoPoseController.m_tangoServiceVersionName) + ""); + + GUI.Label(new Rect(UI_LABEL_START_X, UI_FPS_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + m_fpsText + ""); + + // MOTION TRACKING + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y - UI_LABEL_OFFSET, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, "Device", "Start") + ""); + + string logString = String.Format(UX_STATUS, + _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status), + _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount), + _GetLoggingStringFromVec3(m_tangoPoseController.transform.position), + _GetLoggingStringFromQuaternion(m_tangoPoseController.transform.rotation)); + GUI.Label(new Rect(UI_LABEL_START_X, UI_POSE_LABEL_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + logString + ""); + + GUI.Label(new Rect(UI_LABEL_START_X, UI_DEPTH_LABLE_START_Y, UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + "Average depth (m): " + m_pointcloud.m_overallZ.ToString() + ""); + + GUI.Label(new Rect(UI_LABEL_START_X, UI_DEPTH_LABLE_START_Y + (UI_LABEL_OFFSET * 1.0f), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + "Point count: " + m_pointcloud.m_pointsCount.ToString() + ""); + + GUI.Label(new Rect(UI_LABEL_START_X, UI_DEPTH_LABLE_START_Y + (UI_LABEL_OFFSET * 2.0f), UI_LABEL_SIZE_X, UI_LABEL_SIZE_Y), + UI_FONT_SIZE + "Frame delta time (ms): " + m_pointcloud.m_depthDeltaTime.ToString(UI_FLOAT_FORMAT) + ""); + + GUI.color = oldColor; } } /// /// Construct readable string from TangoPoseStatusType. /// + /// Printable string. + /// A Tango pose status. private string _GetLoggingStringFromPoseStatus(TangoEnums.TangoPoseStatusType status) { - string statusString = ""; + string statusString = string.Empty; switch (status) { case TangoEnums.TangoPoseStatusType.TANGO_POSE_INITIALIZING: @@ -121,9 +170,11 @@ private string _GetLoggingStringFromPoseStatus(TangoEnums.TangoPoseStatusType st /// /// Reformat string from vector3 type for data logging. /// + /// Printable string. + /// A vector. private string _GetLoggingStringFromVec3(Vector3 vec) { - if(vec == Vector3.zero) + if (vec == Vector3.zero) { return "N/A"; } @@ -139,9 +190,11 @@ private string _GetLoggingStringFromVec3(Vector3 vec) /// /// Reformat string from quaternion type for data logging. /// + /// Printable string. + /// A quaternion. private string _GetLoggingStringFromQuaternion(Quaternion quat) { - if(quat == Quaternion.identity) + if (quat == Quaternion.identity) { return "N/A"; } @@ -162,7 +215,7 @@ private string _GetLoggingStringFromQuaternion(Quaternion quat) /// Frame count. private string _GetLoggingStringFromFrameCount(int frameCount) { - if(frameCount == -1.0) + if (frameCount == -1.0) { return "N/A"; } @@ -173,13 +226,13 @@ private string _GetLoggingStringFromFrameCount(int frameCount) } /// - /// Return a string to get logging of FrameDeltaTime + /// Return a string to get logging of FrameDeltaTime. /// /// The get loggin string from frame delta time. /// Frame delta time. private string _GetLogginStringFromFrameDeltaTime(float frameDeltaTime) { - if(frameDeltaTime == -1.0) + if (frameDeltaTime == -1.0) { return "N/A"; } @@ -188,61 +241,4 @@ private string _GetLogginStringFromFrameDeltaTime(float frameDeltaTime) return (frameDeltaTime * SECOND_TO_MILLISECOND).ToString(UI_FLOAT_FORMAT); } } - - void OnGUI() - { - if(m_tangoApplication.HasRequestedPermissions()) - { - Color oldColor = GUI.color; - GUI.color = Color.black; - - - - GUI.Label(new Rect(UI_LABEL_START_X, - UI_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TANGO_SERVICE_VERSION, m_tangoPoseController.m_tangoServiceVersionName) + ""); - - GUI.Label(new Rect(UI_LABEL_START_X, - UI_FPS_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + m_FPSText + ""); - - // MOTION TRACKING - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y - UI_LABEL_OFFSET, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_TARGET_TO_BASE_FRAME, - "Device", - "Start") + ""); - - GUI.Label( new Rect(UI_LABEL_START_X, - UI_POSE_LABEL_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + String.Format(UX_STATUS, - _GetLoggingStringFromPoseStatus(m_tangoPoseController.m_status), - _GetLoggingStringFromFrameCount(m_tangoPoseController.m_frameCount), - _GetLoggingStringFromVec3(m_tangoPoseController.transform.position), - _GetLoggingStringFromQuaternion(m_tangoPoseController.transform.rotation)) + ""); - - GUI.Label(new Rect(UI_LABEL_START_X, - UI_DEPTH_LABLE_START_Y, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + "Average depth (m): " + m_pointcloud.m_overallZ.ToString() + ""); - - GUI.Label(new Rect(UI_LABEL_START_X, - UI_DEPTH_LABLE_START_Y + UI_LABEL_OFFSET * 1.0f, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + "Point count: " + m_pointcloud.m_pointsCount.ToString() + ""); - - - GUI.Label(new Rect(UI_LABEL_START_X, - UI_DEPTH_LABLE_START_Y + UI_LABEL_OFFSET * 2.0f, - UI_LABEL_SIZE_X , - UI_LABEL_SIZE_Y), UI_FONT_SIZE + "Frame delta time (ms): " + m_pointcloud.m_depthDeltaTime.ToString(UI_FLOAT_FORMAT) + ""); - - - GUI.color = oldColor; - } - } } diff --git a/UnityExamples/Assets/TangoPrefabs/Scripts/TangoGestureCamera.cs b/UnityExamples/Assets/TangoPrefabs/Scripts/TangoGestureCamera.cs index c23960eb..2173f61d 100644 --- a/UnityExamples/Assets/TangoPrefabs/Scripts/TangoGestureCamera.cs +++ b/UnityExamples/Assets/TangoPrefabs/Scripts/TangoGestureCamera.cs @@ -1,13 +1,24 @@ -//----------------------------------------------------------------------- -// -// +// +// // Copyright 2015 Google Inc. All Rights Reserved. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // //----------------------------------------------------------------------- using System.Collections; -using UnityEngine; using Tango; +using UnityEngine; /// /// Pointcloud orbit camera. diff --git a/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPointCloud.cs b/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPointCloud.cs index b9113fcf..425b1ac8 100644 --- a/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPointCloud.cs +++ b/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPointCloud.cs @@ -1,12 +1,24 @@ -//----------------------------------------------------------------------- -// -// +// +// // Copyright 2015 Google Inc. All Rights Reserved. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // //----------------------------------------------------------------------- using System; using System.Collections; +using System.Collections.Generic; using UnityEngine; using Tango; @@ -56,11 +68,12 @@ public class TangoPointCloud : MonoBehaviour, ITangoDepth // Matrices for transforming pointcloud to world coordinates. // This equation will take account of the camera sensors extrinsic. // Full equation is: - // Matrix4x4 uwTc = m_uwTss * m_ssTd * Matrix4x4.Inverse(m_imuTd) * m_imuTc - private Matrix4x4 m_uwTss = new Matrix4x4 (); - private Matrix4x4 m_ssTd = new Matrix4x4 (); - private Matrix4x4 m_imuTd = new Matrix4x4 (); - private Matrix4x4 m_imuTc = new Matrix4x4(); + // Matrix4x4 unityWorldTDepthCamera = + // m_unityWorldTStartService * m_startServiceTDevice * Matrix4x4.Inverse(m_imuTDevice) * m_imuTDepthCamera; + private Matrix4x4 m_unityWorldTStartService = new Matrix4x4(); + private Matrix4x4 m_startServiceTDevice = new Matrix4x4(); + private Matrix4x4 m_imuTDevice = new Matrix4x4(); + private Matrix4x4 m_imuTDepthCamera = new Matrix4x4(); /// /// Mesh this script will modify. @@ -72,6 +85,7 @@ public class TangoPointCloud : MonoBehaviour, ITangoDepth private bool m_isExtrinsicQuerable = false; private Renderer m_renderer; + private System.Random m_rand; /// /// Use this for initialization. @@ -81,10 +95,10 @@ public void Start() m_tangoApplication = FindObjectOfType(); m_tangoApplication.Register(this); - m_uwTss.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); - m_uwTss.SetColumn(1, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); - m_uwTss.SetColumn(2, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); - m_uwTss.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); + m_unityWorldTStartService.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + m_unityWorldTStartService.SetColumn(1, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); + m_unityWorldTStartService.SetColumn(2, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + m_unityWorldTStartService.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); // Assign triangles, note: this is just for visualizing point in the mesh data. m_points = new Vector3[MAX_POINT_COUNT]; @@ -93,6 +107,7 @@ public void Start() m_mesh.Clear(); m_renderer = GetComponent(); + m_rand = new System.Random(); } /// @@ -128,9 +143,11 @@ public void OnTangoDepthAvailable(TangoUnityDepth tangoDepth) pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE; pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE; PoseProvider.GetPoseAtTime(poseData, m_previousDepthDeltaTime, pair); - if (poseData.status_code != TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) { + if (poseData.status_code != TangoEnums.TangoPoseStatusType.TANGO_POSE_VALID) + { return; } + Vector3 position = new Vector3((float)poseData.translation[0], (float)poseData.translation[1], (float)poseData.translation[2]); @@ -138,15 +155,15 @@ public void OnTangoDepthAvailable(TangoUnityDepth tangoDepth) (float)poseData.orientation[1], (float)poseData.orientation[2], (float)poseData.orientation[3]); - m_ssTd = Matrix4x4.TRS(position, quat, Vector3.one); + m_startServiceTDevice = Matrix4x4.TRS(position, quat, Vector3.one); // The transformation matrix that represents the pointcloud's pose. // Explanation: - // The pointcloud which is in RGB's camera frame, is put in unity world's - // coordinate system(wrt unit camera). + // The pointcloud which is in Depth camera's frame, is put in unity world's + // coordinate system(wrt unity world). // Then we are extracting the position and rotation from uwTuc matrix and applying it to // the PointCloud's transform. - Matrix4x4 uwTc = m_uwTss * m_ssTd * Matrix4x4.Inverse(m_imuTd) * m_imuTc; + Matrix4x4 unityWorldTDepthCamera = m_unityWorldTStartService * m_startServiceTDevice * Matrix4x4.Inverse(m_imuTDevice) * m_imuTDepthCamera; transform.position = Vector3.zero; transform.rotation = Quaternion.identity; @@ -158,7 +175,7 @@ public void OnTangoDepthAvailable(TangoUnityDepth tangoDepth) float y = tangoDepth.m_points[(i * 3) + 1]; float z = tangoDepth.m_points[(i * 3) + 2]; - m_points[i] = uwTc.MultiplyPoint(new Vector3(x, y, z)); + m_points[i] = unityWorldTDepthCamera.MultiplyPoint(new Vector3(x, y, z)); m_overallZ += z; } m_overallZ = m_overallZ / m_pointsCount; @@ -178,7 +195,7 @@ public void OnTangoDepthAvailable(TangoUnityDepth tangoDepth) } // The color should be pose relative, we need to store enough info to go back to pose values. - m_renderer.material.SetMatrix("ucTuw", uwTc.inverse); + m_renderer.material.SetMatrix("depthCameraTUnityWorld", unityWorldTDepthCamera.inverse); } else { @@ -223,6 +240,211 @@ public int FindClosestPoint(Camera cam, Vector2 pos, int maxDist) return bestIndex; } + /// + /// Finds all points within a certain radius of a point on the screen. + /// + /// NOTE: This is slow because it looks at every single point in the point cloud. Avoid + /// calling this more than once a frame. + /// + /// A list of point indices for points within the radius. + /// The current camera. + /// Position on screen (in pixels). + /// The maximum pixel distance to allow. + public List FindPointsWithinDistance(Camera cam, Vector2 pos, float maxDist) + { + List closePoints = new List(); + float sqMaxDist = maxDist * maxDist; + + for (int it = 0; it < m_pointsCount; ++it) + { + Vector3 screenPos3 = cam.WorldToScreenPoint(m_points[it]); + Vector2 screenPos = new Vector2(screenPos3.x, screenPos3.y); + + float distSqr = Vector2.SqrMagnitude(screenPos - pos); + if (distSqr > sqMaxDist) + { + continue; + } + closePoints.Add(it); + } + + return closePoints; + } + + /// + /// Finds the average point from a set of point indices. + /// + /// The average point value. + /// The points to compute the average for. + public Vector3 GetAverageFromFilteredPoints(List points) + { + Vector3 averagePoint = new Vector3(0, 0, 0); + + for (int i = 0; i < points.Count; i++) + { + averagePoint += m_points[points[i]]; + } + + averagePoint /= points.Count; + + return averagePoint; + } + + /// + /// Given a screen coordinate and search radius, finds a plane that most closely + /// fits depth values in that area. + /// + /// True if a plane was found, false otherwise. + /// The Unity camera. + /// The point in screen space to perform detection on. + /// The search radius to use in pixels. + /// The minimum percentage for inliers when fitting a plane. + /// Filled in with the center of the plane in Unity world space. + /// Filled in with a model of the plane in Unity world space. + public bool FindPlane(Camera cam, Vector2 pos, + float maxPixelDist, float minInlierPercentage, + out Vector3 planeCenter, out Plane plane) + { + List closestPoints = FindPointsWithinDistance(cam, pos, maxPixelDist); + planeCenter = GetAverageFromFilteredPoints(closestPoints); + List inliers; + if (!GetPlaneUsingRANSAC(cam, closestPoints, minInlierPercentage, out inliers, out plane)) + { + return false; + } + return true; + } + + /// + /// Given a set of points find the best fit plane with RANSAC. + /// TODO(@eitanm): refine with SVD after this. + /// + /// True if the plane fit succeeds, false otherwise. + /// The unity camera. + /// The points to compute the plane for. + /// The minimum percentage of inliers to be considered a plane. + /// Filled in with the indices of the plane's inliers. + /// Filled in with the model of the best fit plane. + public bool GetPlaneUsingRANSAC(Camera cam, List points, double minPercentage, + out List inliers, out Plane plane) + { + inliers = new List(); + plane = new Plane(); + + if (points.Count < 3) + { + return false; + } + + // Max number of iterations + int maxIterations = 50; + + // Threshold to define if a point belongs to a plane or not + // Distance in meters from point to plane + double threshold = 0.02; + + int maxFittedPoints = 0; + double percentageFitted = 0; + + // RANSAC algorithm to determine inliers + for (int i = 0; i < maxIterations; i++) + { + List candidateInliers = new List(); + + Plane candidatePlane = MakeRandomPlane(cam, points); + + // See for every point if it belongs to that Plane or not + for (int j = 0; j < points.Count; j++) + { + float distToPlane = candidatePlane.GetDistanceToPoint(m_points[points[j]]); + if (distToPlane < threshold) + { + candidateInliers.Add(points[j]); + } + } + if (candidateInliers.Count > maxFittedPoints) + { + maxFittedPoints = candidateInliers.Count; + inliers = candidateInliers; + plane = candidatePlane; + } + + percentageFitted = maxFittedPoints / points.Count; + if (percentageFitted > minPercentage) + { + break; + } + } + + // If we couldn't reach the minimum points to be fitted with RANSAC, return false + if (percentageFitted < minPercentage) + { + return false; + } + return true; + } + + /// + /// Create a plane from a list of points at random. + /// + /// A random plane. + /// The Unity camera so we can make sure the plane orientation is correct. + /// The points to compute a random plane from. + private Plane MakeRandomPlane(Camera cam, List points) + { + if (points.Count < 3) + { + return new Plane(); + } + + // Choose 3 points randomly. + int r0 = m_rand.Next(points.Count); + int r1 = m_rand.Next(points.Count - 1); + + // Make sure we handle collisions. + if (r1 == r0) + { + r1++; + } + else if (r1 < r0) + { + // We'll make sure to keep r0 and r1 in sorted order. + int temp = r0; + r0 = r1; + r1 = temp; + } + + int r2 = m_rand.Next(points.Count - 2); + + // Handle collisions. + if (r2 == r0) + { + ++r2; + } + if (r2 == r1) + { + ++r2; + } + + int idx0 = points[r0]; + int idx1 = points[r1]; + int idx2 = points[r2]; + + Vector3 p0 = m_points[idx0]; + Vector3 p1 = m_points[idx1]; + Vector3 p2 = m_points[idx2]; + + // Define the plane + Plane plane = new Plane(p0, p1, p2); + + // Make sure that the normal of the plane points towards the camera. + if (Vector3.Dot(cam.transform.forward, plane.normal) > 0) + { + plane.SetNormalAndPosition(plane.normal * -1.0f, p0); + } + return plane; + } + /// /// Sets up extrinsic matrixces for this hardware. /// @@ -243,11 +465,11 @@ private void _SetUpExtrinsics() (float)poseData.orientation[1], (float)poseData.orientation[2], (float)poseData.orientation[3]); - m_imuTd = Matrix4x4.TRS(position, quat, new Vector3(1.0f, 1.0f, 1.0f)); - + m_imuTDevice = Matrix4x4.TRS(position, quat, new Vector3(1.0f, 1.0f, 1.0f)); + // Query the extrinsics between IMU and color camera frame. pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_IMU; - pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_CAMERA_COLOR; + pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_CAMERA_DEPTH; PoseProvider.GetPoseAtTime(poseData, timestamp, pair); position = new Vector3((float)poseData.translation[0], (float)poseData.translation[1], @@ -256,6 +478,6 @@ private void _SetUpExtrinsics() (float)poseData.orientation[1], (float)poseData.orientation[2], (float)poseData.orientation[3]); - m_imuTc = Matrix4x4.TRS(position, quat, new Vector3(1.0f, 1.0f, 1.0f)); + m_imuTDepthCamera = Matrix4x4.TRS(position, quat, new Vector3(1.0f, 1.0f, 1.0f)); } } diff --git a/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPoseController.cs b/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPoseController.cs index 2005d1e2..281db469 100644 --- a/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPoseController.cs +++ b/UnityExamples/Assets/TangoPrefabs/Scripts/TangoPoseController.cs @@ -1,11 +1,21 @@ -//----------------------------------------------------------------------- // -// +// // Copyright 2015 Google Inc. All Rights Reserved. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // //----------------------------------------------------------------------- - using System.Collections; using System; using UnityEngine; @@ -213,6 +223,14 @@ private void Update() #endif } + /// + /// Unity callback when this object is destroyed. + /// + private void OnDestroy() + { + m_tangoApplication.Shutdown(); + } + /// /// Unity callback when application is paused. /// diff --git a/UnityExamples/Assets/TangoPrefabs/Shaders/PointCloud.shader b/UnityExamples/Assets/TangoPrefabs/Shaders/PointCloud.shader index 7b59eb1c..edc87c6a 100644 --- a/UnityExamples/Assets/TangoPrefabs/Shaders/PointCloud.shader +++ b/UnityExamples/Assets/TangoPrefabs/Shaders/PointCloud.shader @@ -4,7 +4,7 @@ GLSLPROGRAM #ifdef VERTEX - uniform mat4 ucTuw; + uniform mat4 depthCameraTUnityWorld; varying vec4 v_color; void main() { @@ -12,7 +12,7 @@ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // Color should be based on pose relative info - v_color = ucTuw * gl_Vertex; + v_color = depthCameraTUnityWorld * gl_Vertex; } #endif diff --git a/UnityExamples/Assets/TangoSDK.meta b/UnityExamples/Assets/TangoSDK.meta index 475cb6da..7e3eb154 100644 --- a/UnityExamples/Assets/TangoSDK.meta +++ b/UnityExamples/Assets/TangoSDK.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 9feced8d9e81e4cb8aa69a8a67a3f6bc folderAsset: yes -timeCreated: 1437161479 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core.meta b/UnityExamples/Assets/TangoSDK/Core.meta index 094011f3..9fae13bb 100644 --- a/UnityExamples/Assets/TangoSDK/Core.meta +++ b/UnityExamples/Assets/TangoSDK/Core.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: b80c15ce37a1447f69e465cf133f71b6 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Prefabs.meta b/UnityExamples/Assets/TangoSDK/Core/Prefabs.meta index 3039c118..646dc028 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Prefabs.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Prefabs.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: ceb5ea0e0a3d4435a8173d62c903e8b3 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Prefabs/Tango Manager.prefab b/UnityExamples/Assets/TangoSDK/Core/Prefabs/Tango Manager.prefab index 26f69d76..cfa99502 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Prefabs/Tango Manager.prefab +++ b/UnityExamples/Assets/TangoSDK/Core/Prefabs/Tango Manager.prefab @@ -9,7 +9,7 @@ GameObject: m_Component: - 4: {fileID: 400000} - 114: {fileID: 11400006} - - 114: {fileID: 11475042} + - 114: {fileID: 11435600} m_Layer: 0 m_Name: Tango Manager m_TagString: Untagged @@ -47,7 +47,7 @@ MonoBehaviour: m_enableAreaLearning: 0 m_useExperimentalVideoOverlay: 1 m_useExperimentalADF: 0 ---- !u!114 &11475042 +--- !u!114 &11435600 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts.meta b/UnityExamples/Assets/TangoSDK/Core/Scripts.meta index 021e40a1..9a3d74cb 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 8e63f857443034fb6b291e8ff42a6c60 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts/Common.meta b/UnityExamples/Assets/TangoSDK/Core/Scripts/Common.meta index 88b83c3a..d4d6b6fb 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts/Common.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts/Common.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: a96639d914c7d4c11aa8634e9e475b09 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoAndroidHelper.cs b/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoAndroidHelper.cs index decd78e1..bf6de0e4 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoAndroidHelper.cs +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoAndroidHelper.cs @@ -21,6 +21,16 @@ /// public partial class AndroidHelper { + /// + /// Holds the current and default offset of the + /// current Tango device. + /// + public struct TangoDeviceOrientation + { + public DeviceOrientation defaultRotation; + public DeviceOrientation currentRotation; + } + private const string PERMISSION_REQUESTER = "com.projecttango.permissionrequester.RequestManagerActivity"; #pragma warning disable 414 @@ -94,7 +104,27 @@ public static bool ApplicationHasTangoPermissions(string permissionType) return false; } + /// + /// Gets the current and default device orientation. + /// + /// The current and default tango device orientation. + public static TangoDeviceOrientation GetTangoDeviceOrientation() + { + AndroidJavaObject tangoObject = GetTangoHelperObject(); + TangoDeviceOrientation deviceOrientation; + deviceOrientation.defaultRotation = DeviceOrientation.Unknown; + deviceOrientation.currentRotation = DeviceOrientation.Unknown; + + if(tangoObject != null) + { + AndroidJavaObject rotationInfo = tangoObject.Call("showTranslatedOrientation"); + deviceOrientation.defaultRotation = (DeviceOrientation)rotationInfo.Get("defaultRotation"); + deviceOrientation.currentRotation = (DeviceOrientation)rotationInfo.Get("currentRotation"); + } + + return deviceOrientation; + } /// /// Determines if is tango core present. diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoTypes.cs b/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoTypes.cs index 71193311..e7b63ac8 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoTypes.cs +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts/Common/TangoTypes.cs @@ -145,7 +145,7 @@ public class TangoImageBuffer } /// - /// /// The TangoCameraIntrinsics struct contains intrinsic parameters for a camera. + /// The TangoCameraIntrinsics struct contains intrinsic parameters for a camera. /// For image coordinates, the obervations, [u, v]^T in pixels. /// Normalized image plane coordinates refer to: /// diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts/Interfaces.meta b/UnityExamples/Assets/TangoSDK/Core/Scripts/Interfaces.meta index 19954c2a..336f5967 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts/Interfaces.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts/Interfaces.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: f5d37fb7ce64947f28ab06d0dbf90ce4 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts/Listeners.meta b/UnityExamples/Assets/TangoSDK/Core/Scripts/Listeners.meta index 4afbdda3..25f8567c 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts/Listeners.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts/Listeners.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: f2e1e806634414f10ad59d9b84c3130c folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Scripts/TangoWrappers.meta b/UnityExamples/Assets/TangoSDK/Core/Scripts/TangoWrappers.meta index c0486891..4b01f5ba 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Scripts/TangoWrappers.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Scripts/TangoWrappers.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 4fc55f6870f0443b986d0ef797cec697 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Core/Tango.dat b/UnityExamples/Assets/TangoSDK/Core/Tango.dat index 8621bfc7..a4f0ccf9 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Tango.dat +++ b/UnityExamples/Assets/TangoSDK/Core/Tango.dat @@ -1 +1 @@ - undefined14e386114e3861) \ No newline at end of file + undefined10aa264!fix/release-buildrelease-urquhart \ No newline at end of file diff --git a/UnityExamples/Assets/TangoSDK/Core/Tango.dat.meta b/UnityExamples/Assets/TangoSDK/Core/Tango.dat.meta index a53a6706..f09babd9 100644 --- a/UnityExamples/Assets/TangoSDK/Core/Tango.dat.meta +++ b/UnityExamples/Assets/TangoSDK/Core/Tango.dat.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c3a52d965c53d459ba119306dd314475 +guid: 26d5948e8e2234b25b5c0f9e4e6cf44a DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/Editor.meta b/UnityExamples/Assets/TangoSDK/Editor.meta index 998bcd17..9196f0c6 100644 --- a/UnityExamples/Assets/TangoSDK/Editor.meta +++ b/UnityExamples/Assets/TangoSDK/Editor.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: 78f7df302e5d14d179d4c2a81857cab4 folderAsset: yes -timeCreated: 1438114372 -licenseType: Pro +timeCreated: 1439506105 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX.meta b/UnityExamples/Assets/TangoSDK/TangoUX.meta index 06004989..27d68d99 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 guid: ab41d32a0a64440748e605a044b13387 folderAsset: yes -timeCreated: 1437161548 -licenseType: Pro +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts.meta index 5a22b7c9..32d93607 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts.meta @@ -1,5 +1,9 @@ fileFormatVersion: 2 guid: dd9505c88c48745c8bc7a16f712938f5 folderAsset: yes +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common.meta index 2c1a56ec..f88bfb77 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common.meta @@ -1,5 +1,9 @@ fileFormatVersion: 2 guid: e29d70e17a9154895b257ee30b296791 folderAsset: yes +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs index 81ef3f48..43e9c09c 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs @@ -67,21 +67,23 @@ public static void ParseTangoDepthPointCount(int pointCount) } } - /// - /// Initialize tango ux library. - /// - public static void InitTangoUx(bool isMotionTrackingEnabled) - { - AndroidJavaObject tangoUxObject = GetTangoUxHelperObject(); - if(tangoUxObject != null) - { - tangoUxObject.Call("initTangoUx", isMotionTrackingEnabled); - } - } + /// + /// Initialize tango ux library. + /// + /// A flag to indicate if motion tracking is enabled. + public static void InitTangoUx(bool isMotionTrackingEnabled) + { + AndroidJavaObject tangoUxObject = GetTangoUxHelperObject(); + if(tangoUxObject != null) + { + tangoUxObject.Call("initTangoUx", isMotionTrackingEnabled); + } + } /// /// Shows the standard tango exceptions UI. /// + /// A flag to indicate if default TangoUx UI is enabled. public static void ShowStandardTangoExceptionsUI(bool shouldUseDefaultUi) { AndroidJavaObject tangoUxObject = GetTangoUxHelperObject(); @@ -125,7 +127,7 @@ public static void SetUxExceptionEventListener() AndroidJavaObject tangoUxObject = GetTangoUxHelperObject(); if(tangoUxObject != null) { - tangoUxObject.Call("setUxExceptionEventListener", UxExceptionEventListener.GetInstance); + tangoUxObject.Call("setUxExceptionEventListener", UxExceptionEventListener.GetInstance); } } } diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs.meta index 6767fdde..29cae8b5 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/AndroidHelper.cs.meta @@ -6,3 +6,5 @@ MonoImporter: executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxEnums.cs b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxEnums.cs index 7fa7d35a..e7d73dcc 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxEnums.cs +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxEnums.cs @@ -18,37 +18,37 @@ namespace Tango { - /// - /// Enumerations used by the Tango Ux. - /// - public class TangoUxEnums - { - /// - /// Possible types for a UX Exception Event. - /// - public enum UxExceptionEventType - { - TYPE_OVER_EXPOSED, /**< Camera is over exposed */ - TYPE_UNDER_EXPOSED, /**< Camera is under exposed */ - TYPE_MOVING_TOO_FAST, /**< Device is being moved too fast */ - TYPE_FEW_FEATURES, /**< Too few features */ - TYPE_FEW_DEPTH_POINTS, /**< Unable to detect any surface */ - TYPE_LYING_ON_SURFACE, /**< Device is lying on a surface */ - TYPE_MOTION_TRACK_INVALID, /**< Motion tracking is invalid */ - TYPE_TANGO_SERVICE_NOT_RESPONDING, /**< Tango Service stopped responding */ - TYPE_INCOMPATIBLE_VM, /**< Incompatible vm is found */ - TYPE_TANGO_UPDATE_NEEDED, /**< Tango version update is needed */ - NA /*** + /// Enumerations used by TangoUx. + /// + public class TangoUxEnums + { + /// + /// Possible types for a UX Exception Event. + /// + public enum UxExceptionEventType + { + TYPE_OVER_EXPOSED, /**< Camera is over exposed */ + TYPE_UNDER_EXPOSED, /**< Camera is under exposed */ + TYPE_MOVING_TOO_FAST, /**< Device is being moved too fast */ + TYPE_FEW_FEATURES, /**< Too few features */ + TYPE_FEW_DEPTH_POINTS, /**< Unable to detect any surface */ + TYPE_LYING_ON_SURFACE, /**< Device is lying on a surface */ + TYPE_MOTION_TRACK_INVALID, /**< Motion tracking is invalid */ + TYPE_TANGO_SERVICE_NOT_RESPONDING, /**< Tango Service stopped responding */ + TYPE_INCOMPATIBLE_VM, /**< Incompatible vm is found */ + TYPE_TANGO_UPDATE_NEEDED, /**< Tango version update is needed */ + NA /*** - /// Possible states for the exception status - /// - public enum UxExceptionEventStatus - { - STATUS_RESOLVED, /**< The exception was resolved */ - STATUS_DETECTED, /**< The exception was detected */ - NA /*** + /// Possible status for exceptions. + /// + public enum UxExceptionEventStatus + { + STATUS_RESOLVED, /**< The exception was resolved */ + STATUS_DETECTED, /**< The exception was detected */ + NA /*** - /// Represents a Tango Ux Exception. - /// - [StructLayout(LayoutKind.Sequential)] - public class UxExceptionEvent - { - [MarshalAs(UnmanagedType.I4)] - public TangoUxEnums.UxExceptionEventType type; - - [MarshalAs(UnmanagedType.R4)] - public float value; - - [MarshalAs(UnmanagedType.I4)] - public TangoUxEnums.UxExceptionEventStatus status; + /// + /// Represents a Tango Ux Exception Event. + /// + [StructLayout(LayoutKind.Sequential)] + public class UxExceptionEvent + { + /// + /// The type for this Ux Exception Event. + /// + [MarshalAs(UnmanagedType.I4)] + public TangoUxEnums.UxExceptionEventType type; - public UxExceptionEvent() - { - type = TangoUxEnums.UxExceptionEventType.NA; - value = float.NaN; - status = TangoUxEnums.UxExceptionEventStatus.NA; - } + /// + /// The event value for this Ux Exception Event. + /// + [MarshalAs(UnmanagedType.R4)] + public float value; - } + /// + /// The status for this Ux Exception Event. + /// + [MarshalAs(UnmanagedType.I4)] + public TangoUxEnums.UxExceptionEventStatus status; + + /// + /// Initialize a new instance of Tango.UxExceptionEvent. + /// + public UxExceptionEvent() + { + type = TangoUxEnums.UxExceptionEventType.NA; + value = float.NaN; + status = TangoUxEnums.UxExceptionEventStatus.NA; + } + } } diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxTypes.cs.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxTypes.cs.meta index 4c3d2d88..e9b50f04 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxTypes.cs.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Common/TangoUxTypes.cs.meta @@ -6,3 +6,5 @@ MonoImporter: executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces.meta index 57f55460..198e94cd 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces.meta @@ -1,5 +1,9 @@ fileFormatVersion: 2 guid: 8c7c0ebacfab24a0cbe5503a4bc5fa07 folderAsset: yes +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs index 5d4f9f82..4e7a8751 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs @@ -21,5 +21,9 @@ /// public interface ITangoUX { - void onUxExceptionEventHandler(Tango.UxExceptionEvent exceptionEvent); + /// + /// Called when a Tango.UxExceptionEvent is dispatched. + /// + /// Event containing information about the exception + void onUxExceptionEventHandler(Tango.UxExceptionEvent exceptionEvent); } diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs.meta index 9a109773..b43293b1 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Interfaces/ITangoUX.cs.meta @@ -6,3 +6,5 @@ MonoImporter: executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners.meta index c13432eb..b7ec8af3 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners.meta @@ -1,5 +1,9 @@ fileFormatVersion: 2 guid: acb9e1dbfe50d40808cb4061f03790d9 folderAsset: yes +timeCreated: 1439506118 +licenseType: Free DefaultImporter: userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs index 3bfdec95..9e81c020 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs @@ -23,63 +23,64 @@ /// public class UxExceptionEventListener : AndroidJavaProxy { - private static UxExceptionEventListener m_instance; + private static UxExceptionEventListener m_instance; - /// - /// Initializes a new instance of the class. - /// - private UxExceptionEventListener (): base("com.google.atap.tango.ux.UxExceptionEventListener") - { - } + /// + /// Initializes a new instance of the class. + /// + private UxExceptionEventListener (): base("com.google.atap.tango.ux.UxExceptionEventListener") + { + } - private event onUxExceptionEventHandler m_onUxExceptionEvent; + private event onUxExceptionEventHandler m_onUxExceptionEvent; + /// + /// Gets the get instance. + /// + /// The get instance. + public static UxExceptionEventListener GetInstance { + get { + if (m_instance == null) { + m_instance = new UxExceptionEventListener (); + } + return m_instance; + } + } + /// + /// Registers ux exception events. + /// + /// Handler. + public void RegisterOnUxExceptionEventHandler (onUxExceptionEventHandler handler) + { + if (handler != null) { + m_onUxExceptionEvent += handler; + } + } - /// - /// Gets the get instance. - /// - /// The get instance. - public static UxExceptionEventListener GetInstance { - get { - if (m_instance == null) { - m_instance = new UxExceptionEventListener (); - } - return m_instance; - } - } + /// + /// Unregisters the on too few points. + /// + /// Handler. + public void UnregisterOnUxExceptionEventHandler (onUxExceptionEventHandler handler) + { + if (handler != null) { + m_onUxExceptionEvent -= handler; + } + } - /// - /// Registers ux exception events. - /// - /// Handler. - public void RegisterOnUxExceptionEventHandler (onUxExceptionEventHandler handler) - { - if (handler != null) { - m_onUxExceptionEvent += handler; - } - } - - /// - /// Unregisters the on too few points. - /// - /// Handler. - public void UnregisterOnUxExceptionEventHandler (onUxExceptionEventHandler handler) - { - if (handler != null) { - m_onUxExceptionEvent -= handler; - } - } - - void onUxExceptionEvent(AndroidJavaObject tangoUxEvent) - { - if (m_onUxExceptionEvent != null) { - Tango.UxExceptionEvent uxEvent = new Tango.UxExceptionEvent(); - uxEvent.type = (Tango.TangoUxEnums.UxExceptionEventType) tangoUxEvent.Call ("getType"); - uxEvent.value = tangoUxEvent.Call ("getValue"); - uxEvent.status = (Tango.TangoUxEnums.UxExceptionEventStatus) tangoUxEvent.Call ("getStatus"); - m_onUxExceptionEvent (uxEvent); - } - } - + /// + /// Called when a Ux Exception Event is dispatched. + /// + /// A AndroidJavaObject containing information about the exception + void onUxExceptionEvent(AndroidJavaObject tangoUxEvent) + { + if (m_onUxExceptionEvent != null) { + Tango.UxExceptionEvent uxEvent = new Tango.UxExceptionEvent(); + uxEvent.type = (Tango.TangoUxEnums.UxExceptionEventType) tangoUxEvent.Call ("getType"); + uxEvent.value = tangoUxEvent.Call ("getValue"); + uxEvent.status = (Tango.TangoUxEnums.UxExceptionEventStatus) tangoUxEvent.Call ("getStatus"); + m_onUxExceptionEvent (uxEvent); + } + } } diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs.meta index 2522aac7..dcce5c35 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/Listeners/UxExceptionEventListener.cs.meta @@ -6,3 +6,5 @@ MonoImporter: executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs index 9194bd8d..16bcd901 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs @@ -26,18 +26,18 @@ public class TangoUx : MonoBehaviour, ITangoPose, ITangoEvent, ITangoDepth private TangoApplication m_tangoApplication; - /// + /// /// Start this instance. /// - void Start () + void Start () { m_tangoApplication = GetComponent(); m_tangoApplication.RegisterPermissionsCallback(_OnTangoPermissionsEvent); m_tangoApplication.RegisterOnTangoConnect(_OnTangoServiceConnected); m_tangoApplication.RegisterOnTangoDisconnect(_OnTangoServiceDisconnected); m_tangoApplication.Register(this); - AndroidHelper.InitTangoUx(m_tangoApplication.m_enableMotionTracking); - } + AndroidHelper.InitTangoUx(m_tangoApplication.m_enableMotionTracking); + } /// /// Raises the destroy event. @@ -65,7 +65,7 @@ public void Register(Object tangoObject) if(tangoUX != null) { - UxExceptionEventListener.GetInstance.RegisterOnUxExceptionEventHandler(tangoUX.onUxExceptionEventHandler); + UxExceptionEventListener.GetInstance.RegisterOnUxExceptionEventHandler(tangoUX.onUxExceptionEventHandler); } } } @@ -82,7 +82,7 @@ public void Unregister(Object tangoObject) if(tangoUX != null) { - UxExceptionEventListener.GetInstance.UnregisterOnUxExceptionEventHandler(tangoUX.onUxExceptionEventHandler); + UxExceptionEventListener.GetInstance.UnregisterOnUxExceptionEventHandler(tangoUX.onUxExceptionEventHandler); } } } @@ -133,7 +133,7 @@ public void OnTangoDepthAvailable(Tango.TangoUnityDepth tangoDepth) private IEnumerator _StartExceptionsListener() { AndroidHelper.ShowStandardTangoExceptionsUI(m_drawDefaultUXExceptions); - AndroidHelper.SetUxExceptionEventListener (); + AndroidHelper.SetUxExceptionEventListener (); yield return 0; } diff --git a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs.meta b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs.meta index f7b4b4f4..67349643 100644 --- a/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs.meta +++ b/UnityExamples/Assets/TangoSDK/TangoUX/Scripts/TangoUx.cs.meta @@ -6,3 +6,5 @@ MonoImporter: executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityExamples/ProjectSettings/EditorBuildSettings.asset b/UnityExamples/ProjectSettings/EditorBuildSettings.asset index 799239ca..6b20106f 100644 --- a/UnityExamples/ProjectSettings/EditorBuildSettings.asset +++ b/UnityExamples/ProjectSettings/EditorBuildSettings.asset @@ -5,11 +5,11 @@ EditorBuildSettings: m_ObjectHideFlags: 0 serializedVersion: 2 m_Scenes: - - enabled: 0 + - enabled: 1 path: Assets/Scenes/AreaLearning.unity - enabled: 1 path: Assets/Scenes/MotionTracking.unity - - enabled: 0 + - enabled: 1 path: Assets/Scenes/PointCloud.unity - enabled: 0 path: Assets/Scenes/ExperimentalAugmentedReality.unity diff --git a/UnityExamples/ProjectSettings/ProjectSettings.asset b/UnityExamples/ProjectSettings/ProjectSettings.asset index 4ff5112c..f942b489 100644 --- a/UnityExamples/ProjectSettings/ProjectSettings.asset +++ b/UnityExamples/ProjectSettings/ProjectSettings.asset @@ -72,14 +72,14 @@ PlayerSettings: 16:9: 1 Others: 1 bundleIdentifier: com.projecttango.unityexamples - bundleVersion: 1.19 + bundleVersion: 1.20 preloadedAssets: [] metroEnableIndependentInputSource: 0 metroEnableLowLatencyPresentationAPI: 0 xboxOneDisableKinectGpuReservation: 0 virtualRealitySupported: 0 productGUID: c6391136f507d40acbbba7382166aeb8 - AndroidBundleVersionCode: 19 + AndroidBundleVersionCode: 20 AndroidMinSdkVersion: 17 AndroidPreferredInstallLocation: 1 aotOptions: @@ -139,17 +139,17 @@ PlayerSettings: m_Size: 128 - m_BuildTarget: Android m_Icons: - - m_Icon: {fileID: 0} + - m_Icon: {fileID: 2800000, guid: 87944d11c2cdb43679e685502eff846c, type: 3} m_Size: 192 - - m_Icon: {fileID: 0} + - m_Icon: {fileID: 2800000, guid: 87944d11c2cdb43679e685502eff846c, type: 3} m_Size: 144 - - m_Icon: {fileID: 0} + - m_Icon: {fileID: 2800000, guid: 87944d11c2cdb43679e685502eff846c, type: 3} m_Size: 96 - - m_Icon: {fileID: 0} + - m_Icon: {fileID: 2800000, guid: 87944d11c2cdb43679e685502eff846c, type: 3} m_Size: 72 - - m_Icon: {fileID: 0} + - m_Icon: {fileID: 2800000, guid: 87944d11c2cdb43679e685502eff846c, type: 3} m_Size: 48 - - m_Icon: {fileID: 0} + - m_Icon: {fileID: 2800000, guid: 87944d11c2cdb43679e685502eff846c, type: 3} m_Size: 36 m_BuildTargetBatching: [] m_BuildTargetGraphicsAPIs: diff --git a/UnityExamples/Settings.StyleCop b/UnityExamples/Settings.StyleCop index a1b64675..3de6ff9f 100644 --- a/UnityExamples/Settings.StyleCop +++ b/UnityExamples/Settings.StyleCop @@ -119,7 +119,7 @@ Google - Copyright 2015 Google Inc. All Rights Reserved. + Copyright 2015 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. False @@ -200,12 +200,27 @@ False + + + False + + ar + c + d + imu is m_ + ss + ui + uv + uw + x + y + z