Merge branch 'master' of http://192.168.31.100:8088/framework/xosmopluginlibrary
This commit is contained in:
@@ -11,6 +11,7 @@ stages:
|
||||
- 07.RKTools
|
||||
- 08.UniTask
|
||||
- 09.CodeChecker
|
||||
- 99.imdk_unity
|
||||
# 00.StaryEvo
|
||||
job_StaryEvo:
|
||||
only:
|
||||
@@ -27,6 +28,9 @@ job_StaryEvo:
|
||||
- cd Assets/00.StaryEvo
|
||||
# 获取当前版本
|
||||
- CURRENT_VERSION=$(node -p "require('./package.json').version")
|
||||
|
||||
|
||||
|
||||
- echo "registry=http://${SERVER_HOST}/npm" > .npmrc
|
||||
- echo "//${SERVER_HOST}/:_authToken=${AuthToken}" >> .npmrc
|
||||
- npm publish
|
||||
@@ -226,5 +230,25 @@ job_CodeChecker:
|
||||
allow_failure: true
|
||||
when: 'on_success'
|
||||
|
||||
# 99.imdk_unity
|
||||
job_CodeChecker:
|
||||
only:
|
||||
- master
|
||||
stage: 99.imdk_unity
|
||||
tags:
|
||||
- xosmoPlugin
|
||||
before_script:
|
||||
- echo '开始发布'
|
||||
- node -v # 验证 Node.js 版本
|
||||
script:
|
||||
- cd Assets/99.imdk_unity
|
||||
# 获取当前版本
|
||||
- CURRENT_VERSION=$(node -p "require('./package.json').version")
|
||||
- echo "registry=http://${SERVER_HOST}/npm" > .npmrc
|
||||
- echo "//${SERVER_HOST}/:_authToken=${AuthToken}" >> .npmrc
|
||||
- npm publish
|
||||
- echo '99.imdk_unity构建完成'
|
||||
allow_failure: true
|
||||
when: 'on_success'
|
||||
after_script:
|
||||
- echo "====== 发布完成 ========="
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Stary.Evo.Editor
|
||||
|
||||
[ShowIf("@ buildAssetType== BuildAssetType.Login")] [BoxGroup("Login", showLabel: false)]
|
||||
public string ip, userName, password;
|
||||
|
||||
|
||||
[ShowIf("@ buildAssetType== BuildAssetType.Login")]
|
||||
[BoxGroup("Login", showLabel: false)]
|
||||
[Button("登录", ButtonSizes.Large)]
|
||||
@@ -161,7 +161,7 @@ namespace Stary.Evo.Editor
|
||||
#region HyBridCLRBuild
|
||||
|
||||
[BoxGroup("Build", showLabel: false)]
|
||||
[HideIf("@ packageName== \"Main\" || buildAssetType!= BuildAssetType.Build")]
|
||||
[HideIf("@ buildAssetType!= BuildAssetType.Build")]
|
||||
[Title("打包dll(子包仅打一次)", titleAlignment: TitleAlignments.Centered)]
|
||||
[HorizontalGroup("Build/HyBridClrBuildEntity"), HideLabel]
|
||||
public BuildAssetEntity hyBridClrBuildEntity =
|
||||
@@ -274,23 +274,11 @@ namespace Stary.Evo.Editor
|
||||
[HideLabel]
|
||||
public BuildAssetEntity onBuildPipelineEntity;
|
||||
|
||||
// [BoxGroup("Build", showLabel: false)]
|
||||
// [TitleGroup("Build/UpdateAssetButton", alignment: TitleAlignments.Centered)]
|
||||
// // [ShowIf("@ BuildAssetDataSetting.environmentType== EnvironmentType.Release ", true)]
|
||||
// [ReadOnly]
|
||||
// [InfoBox("服务器资源盘位未存在", InfoMessageType.Error, "@ _isCheckDriveExist==false")]
|
||||
// [InfoBox("1、映射网络驱动器\n2、添加http://192.168.31.100:5005/alist/HotRefresh地址\n3、设置盘符为Z盘", InfoMessageType.Info,
|
||||
// "@ _isCheckDriveExist==false")]
|
||||
// [HideIf(
|
||||
// "@ selectedPackageNames==\"Main\" ||BuildAssetDataSetting.environmentType!= EnvironmentType.Release || buildAssetType!= BuildAssetType.Build")]
|
||||
// public string updateServerPath;
|
||||
|
||||
|
||||
[BoxGroup("Build", showLabel: false)]
|
||||
[Title("上传资源", titleAlignment: TitleAlignments.Centered)]
|
||||
[HideLabel]
|
||||
[ShowIf(
|
||||
"@ BuildAssetDataSetting.environmentType== EnvironmentType.Release&&selectedPackageNames!=\"Main\" && buildAssetType== BuildAssetType.Build")]
|
||||
"@ BuildAssetDataSetting.environmentType== EnvironmentType.Release && buildAssetType== BuildAssetType.Build")]
|
||||
public BuildAssetEntity onUpdateBuildPipelineEntity;
|
||||
|
||||
|
||||
@@ -385,7 +373,14 @@ namespace Stary.Evo.Editor
|
||||
|
||||
public static async Task UpdateFileDataResDomain(BuildAssetDataSetting setting, string zipFilePath)
|
||||
{
|
||||
string ip = PlayerPrefs.GetString("LoginIp");
|
||||
//初始化读取资源配置表
|
||||
HotfixMainResDomain hotfixMainResDomain = Resources.Load<HotfixMainResDomain>("HotfixMainResDomain");
|
||||
if (hotfixMainResDomain == null)
|
||||
{
|
||||
Debug.LogError($"UnityEvo:读取资源配置表失败【HotfixMainResDomain】...表不存在");
|
||||
return;
|
||||
}
|
||||
var ip = hotfixMainResDomain.hotfixMainResDomainEntity.ipconfig;
|
||||
var messageEntity = await WebRequestSystem.PostFile(ip + "/FileLoad/UpLoadFile", new[] { zipFilePath });
|
||||
EditorUtility.DisplayProgressBar("提示", $"开始上传{setting.packageName}(上传zip文件)", 0.5f);
|
||||
if (messageEntity.code == 200)
|
||||
@@ -444,9 +439,6 @@ namespace Stary.Evo.Editor
|
||||
/// </summary>
|
||||
private async void GetHostBuildPackageVersion(BuildAssetDataSetting setting)
|
||||
{
|
||||
if (selectedPackageNames == "Main")
|
||||
|
||||
return;
|
||||
var resDmainAddRequst = new ResDmainRequst()
|
||||
{
|
||||
ProductName = Application.identifier,
|
||||
|
||||
@@ -123,10 +123,10 @@ namespace Stary.Evo.Editor
|
||||
public virtual void ExecuteBuild()
|
||||
{
|
||||
// GetPackageVersion();
|
||||
if (dataSetting.packageName == "Main")
|
||||
{
|
||||
dataSetting.GetBuildPackageVersion(true);
|
||||
}
|
||||
// if (dataSetting.packageName == "Main")
|
||||
// {
|
||||
// dataSetting.GetBuildPackageVersion(true);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -67,7 +67,14 @@ namespace Stary.Evo.Editor
|
||||
$"Assets/Domain/{oneKeyBUildEntity.DomainName}/Conf/BuildAssetDataSetting.asset");
|
||||
if (buildAssetDataSetting != null)
|
||||
{
|
||||
string ip = PlayerPrefs.GetString("LoginIp");
|
||||
//初始化读取资源配置表
|
||||
HotfixMainResDomain hotfixMainResDomain = Resources.Load<HotfixMainResDomain>("HotfixMainResDomain");
|
||||
if (hotfixMainResDomain == null)
|
||||
{
|
||||
Debug.LogError($"UnityEvo:读取资源配置表失败【HotfixMainResDomain】...表不存在");
|
||||
continue;
|
||||
}
|
||||
var ip = hotfixMainResDomain.hotfixMainResDomainEntity.ipconfig;
|
||||
string url = $"{ip}/ResDomain/GetResDomainByDomain";
|
||||
var resDmainRequst = new ResDmainRequst()
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace Stary.Evo.Editor
|
||||
{
|
||||
private static AssetBundleCollectorPackage package;
|
||||
private static string packageName;
|
||||
|
||||
|
||||
|
||||
public static string DomainRoot
|
||||
@@ -23,10 +22,6 @@ namespace Stary.Evo.Editor
|
||||
get { return Application.dataPath + "/Domain"; }
|
||||
}
|
||||
|
||||
public static string MainDomainRoot
|
||||
{
|
||||
get { return Application.dataPath + "/Main"; }
|
||||
}
|
||||
|
||||
// public static string SpriteRemotedAtlas
|
||||
// {
|
||||
@@ -65,7 +60,8 @@ namespace Stary.Evo.Editor
|
||||
{
|
||||
if (oneKeyBUildEntity.isRaw)
|
||||
{
|
||||
CopyDllHotUpdateAssembly(oneKeyBUildEntity.DomainName, $"{DomainRoot}/{oneKeyBUildEntity.DomainName}/AddressableRes");
|
||||
CopyDllHotUpdateAssembly(oneKeyBUildEntity.DomainName,
|
||||
$"{DomainRoot}/{oneKeyBUildEntity.DomainName}/AddressableRes");
|
||||
CopyDllStrippedAOTDllOutputRootDir($"{DomainRoot}/{oneKeyBUildEntity.DomainName}/AddressableRes");
|
||||
}
|
||||
}
|
||||
@@ -137,15 +133,10 @@ namespace Stary.Evo.Editor
|
||||
AssetDatabase.LoadAssetAtPath<DomainConfig>(configPath);
|
||||
packageName = domainConfig.domain;
|
||||
Mark();
|
||||
if (!oneKeyBUildEntity.DomainName.Equals("Main"))
|
||||
CreateRes(packageName,
|
||||
$"{DomainRoot}/{oneKeyBUildEntity.DomainName}/AddressableRes",
|
||||
$"{DomainRoot}/{oneKeyBUildEntity.DomainName}/HotUpdate");
|
||||
else
|
||||
CreateRes(packageName,
|
||||
$"{DomainRoot}/{oneKeyBUildEntity.DomainName}/AddressableRes",
|
||||
$"{MainDomainRoot}/Script/Runtime/HotUpdate");
|
||||
|
||||
CreateRes(packageName,
|
||||
$"{DomainRoot}/{oneKeyBUildEntity.DomainName}/AddressableRes",
|
||||
$"{DomainRoot}/{oneKeyBUildEntity.DomainName}/HotUpdate");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,8 +147,8 @@ namespace Stary.Evo.Editor
|
||||
// //清空主包旧数据
|
||||
AssetBundleCollectorPackage assetBundleCollectorPackage = null;
|
||||
//copydll
|
||||
if (!BuildAssetWindow.GetBuildPackageName().Equals("Main"))
|
||||
AddHotfixAddressableDll();
|
||||
|
||||
AddHotfixAddressableDll();
|
||||
//清空用户旧数据
|
||||
|
||||
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
|
||||
@@ -179,14 +170,11 @@ namespace Stary.Evo.Editor
|
||||
AssetDatabase.LoadAssetAtPath<DomainConfig>(configPath);
|
||||
packageName = domainConfig.domain;
|
||||
Mark();
|
||||
if (!BuildAssetWindow.GetBuildPackageName().Equals("Main"))
|
||||
CreateRes(packageName,
|
||||
$"{DomainRoot}/{BuildAssetWindow.GetBuildPackageName()}/AddressableRes",
|
||||
$"{DomainRoot}/{BuildAssetWindow.GetBuildPackageName()}/HotUpdate");
|
||||
else
|
||||
CreateRes(packageName,
|
||||
$"{DomainRoot}/{BuildAssetWindow.GetBuildPackageName()}/AddressableRes",
|
||||
$"{MainDomainRoot}/Script/Runtime/HotUpdate");
|
||||
|
||||
CreateRes(packageName,
|
||||
$"{DomainRoot}/{BuildAssetWindow.GetBuildPackageName()}/AddressableRes",
|
||||
$"{DomainRoot}/{BuildAssetWindow.GetBuildPackageName()}/HotUpdate");
|
||||
|
||||
EditorUtility.DisplayDialog("自动标记", "自动标记成功", "确定");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Stary.Evo
|
||||
{
|
||||
@@ -24,6 +25,9 @@ namespace Stary.Evo
|
||||
[Sirenix.OdinInspector.ReadOnly] public string className;
|
||||
|
||||
public LoadResType loadResType;
|
||||
|
||||
|
||||
|
||||
|
||||
[Sirenix.OdinInspector.ReadOnly] [ShowIf("loadResType", LoadResType.Prefab)]
|
||||
/// <summary>
|
||||
@@ -33,34 +37,13 @@ namespace Stary.Evo
|
||||
|
||||
[ShowIf("loadResType", LoadResType.Scene)]
|
||||
public string mainScene;
|
||||
|
||||
|
||||
// [ShowIfGroup("loadResType", LoadResType.Prefab)]
|
||||
// public PonitPrefabType ponitPrefabType;
|
||||
|
||||
// [ShowIfGroup("loadResType", LoadResType.Prefab)]
|
||||
// [ShowIf("ponitPrefabType", PonitPrefabType.Plural)]
|
||||
// [OnCollectionChanged("OnPointConfDichChanged")]
|
||||
// public Dictionary<string, string> PonitConfDic = new Dictionary<string, string>();
|
||||
|
||||
|
||||
// private void OnPointConfDichChanged(CollectionChangeInfo info, object value)
|
||||
// {
|
||||
// Debug.Log("Received callback BEFORE CHANGE with the following info: " + info +
|
||||
// ", and the following collection instance: " + value);
|
||||
// }
|
||||
|
||||
|
||||
[ShowIf("loadResType", LoadResType.Scene)]
|
||||
public LoadSceneMode loadSceneMode;
|
||||
public enum LoadResType
|
||||
{
|
||||
Prefab,
|
||||
Scene
|
||||
}
|
||||
|
||||
// public enum PonitPrefabType
|
||||
// {
|
||||
// Single,
|
||||
// Plural
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "com.staryevo.main",
|
||||
"version": "1.2.16",
|
||||
"version": "1.3.2",
|
||||
"displayName": "00.StaryEvo",
|
||||
"description": "This is an Framework package(后台服务器版本,端口9527)",
|
||||
"unity": "2021.3",
|
||||
|
||||
8
Assets/99.imdk_unity/Editor.meta
Normal file
8
Assets/99.imdk_unity/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f441e4b77db3b4f9ba98e2ae40142506
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
70
Assets/99.imdk_unity/Editor/DeviceLocalizationEditor.cs
Normal file
70
Assets/99.imdk_unity/Editor/DeviceLocalizationEditor.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(DeviceLocalization))]
|
||||
public class DeviceLocalizationEditor : Editor
|
||||
{
|
||||
private SerializedProperty configurationMode;
|
||||
private SerializedProperty solverTypeProperty;
|
||||
|
||||
private SerializedProperty priorNNCountProperty;
|
||||
private SerializedProperty priorScaleProperty;
|
||||
private SerializedProperty priorRadiusProperty;
|
||||
|
||||
private SerializedProperty onProgressEventProperty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
configurationMode = serializedObject.FindProperty("m_ConfigurationMode");
|
||||
solverTypeProperty = serializedObject.FindProperty("m_SolverType");
|
||||
|
||||
priorNNCountProperty = serializedObject.FindProperty("m_PriorNNCount");
|
||||
priorRadiusProperty = serializedObject.FindProperty("m_PriorRadius");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// Configuration mode
|
||||
|
||||
EditorGUILayout.HelpBox(configurationMode.enumValueIndex == (int)ConfigurationMode.Always ? "This localization method will be active even if there are no maps configured to use it." : "This localization method will only be active if there are maps configured to use it.", MessageType.Info);
|
||||
|
||||
configurationMode.enumValueIndex = EditorGUILayout.Popup("Configuration mode", configurationMode.enumValueIndex, configurationMode.enumNames);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (solverTypeProperty.enumValueIndex is (int)SolverType.Prior or (int)SolverType.Lean)
|
||||
{
|
||||
EditorGUILayout.HelpBox("This Solver type is experimental. Extensive testing is advised.", MessageType.Warning);
|
||||
}
|
||||
|
||||
// SolverType
|
||||
solverTypeProperty.enumValueIndex = EditorGUILayout.Popup("Solver type", solverTypeProperty.enumValueIndex, solverTypeProperty.enumNames);
|
||||
|
||||
if (solverTypeProperty.enumValueIndex == (int)SolverType.Prior)
|
||||
{
|
||||
EditorGUILayout.PropertyField(priorNNCountProperty, new GUIContent("Nearest neighbour min"));
|
||||
EditorGUILayout.PropertyField(priorRadiusProperty, new GUIContent("Radius"));
|
||||
}
|
||||
|
||||
// Apply
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/DeviceLocalizationEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/DeviceLocalizationEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 486b4a0e3043f44b7aa3217d7cff1f65
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
81
Assets/99.imdk_unity/Editor/GeoLocalizationEditor.cs
Normal file
81
Assets/99.imdk_unity/Editor/GeoLocalizationEditor.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(GeoLocalization))]
|
||||
public class GeoLocalizationEditor : Editor
|
||||
{
|
||||
private SerializedProperty configurationMode;
|
||||
private SerializedProperty solverTypeProperty;
|
||||
|
||||
private SerializedProperty priorNNCountMinProperty;
|
||||
private SerializedProperty priorNNCountMaxProperty;
|
||||
private SerializedProperty priorScaleProperty;
|
||||
private SerializedProperty priorRadiusProperty;
|
||||
|
||||
private SerializedProperty onProgressEventProperty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
configurationMode = serializedObject.FindProperty("m_ConfigurationMode");
|
||||
solverTypeProperty = serializedObject.FindProperty("m_SolverType");
|
||||
|
||||
priorNNCountMinProperty = serializedObject.FindProperty("m_PriorNNCountMin");
|
||||
priorNNCountMaxProperty = serializedObject.FindProperty("m_PriorNNCountMax");
|
||||
priorScaleProperty = serializedObject.FindProperty("m_PriorScale");
|
||||
priorRadiusProperty = serializedObject.FindProperty("m_PriorRadius");
|
||||
|
||||
onProgressEventProperty = serializedObject.FindProperty("OnProgress");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// Configuration mode
|
||||
|
||||
EditorGUILayout.HelpBox(configurationMode.enumValueIndex == (int)ConfigurationMode.Always ? "This localization method will be active even if there are no maps configured to use it." : "This localization method will only be active if there are maps configured to use it.", MessageType.Info);
|
||||
|
||||
configurationMode.enumValueIndex = EditorGUILayout.Popup("Configuration mode", configurationMode.enumValueIndex, configurationMode.enumNames);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (solverTypeProperty.enumValueIndex is (int)SolverType.Prior or (int)SolverType.Lean)
|
||||
{
|
||||
EditorGUILayout.HelpBox("This Solver type is experimental. Extensive testing is advised.", MessageType.Warning);
|
||||
}
|
||||
|
||||
// SolverType
|
||||
solverTypeProperty.enumValueIndex = EditorGUILayout.Popup("Solver type", solverTypeProperty.enumValueIndex, solverTypeProperty.enumNames);
|
||||
|
||||
if (solverTypeProperty.enumValueIndex == (int)SolverType.Prior)
|
||||
{
|
||||
EditorGUILayout.PropertyField(priorNNCountMinProperty, new GUIContent("Nearest neighbour min"));
|
||||
EditorGUILayout.PropertyField(priorNNCountMaxProperty, new GUIContent("Nearest neighbour max"));
|
||||
EditorGUILayout.PropertyField(priorScaleProperty, new GUIContent("Scale"));
|
||||
EditorGUILayout.PropertyField(priorRadiusProperty, new GUIContent("Radius"));
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.PropertyField(onProgressEventProperty, new GUIContent("Upload progress"));
|
||||
|
||||
// Apply
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/GeoLocalizationEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/GeoLocalizationEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e1bea21e32424fe78db71c1f7435af4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/99.imdk_unity/Editor/Immersal.Core.Editor.asmdef
Normal file
27
Assets/99.imdk_unity/Editor/Immersal.Core.Editor.asmdef
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "Immersal.Core.Editor",
|
||||
"references": [
|
||||
"Immersal.Core",
|
||||
"Unity.EditorCoroutines.Editor",
|
||||
"Unity.XR.Management",
|
||||
"Unity.XR.Management.Editor",
|
||||
"Unity.RenderPipelines.Universal.Runtime"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.magicleap.unitysdk",
|
||||
"expression": "1.7.0",
|
||||
"define": "IMMERSAL_MAGIC_LEAP_ENABLED"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6084709da3b1941e0b68429c7e238813
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
772
Assets/99.imdk_unity/Editor/ImmersalProjectValidation.cs
Normal file
772
Assets/99.imdk_unity/Editor/ImmersalProjectValidation.cs
Normal file
@@ -0,0 +1,772 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.XR.Management;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
internal enum ProjectValidationState
|
||||
{
|
||||
Uninitialized = 0,
|
||||
Issues = 1,
|
||||
NoIssues = 2
|
||||
}
|
||||
|
||||
internal class ImmersalProjectValidationWindow : EditorWindow, IActiveBuildTargetChanged
|
||||
{
|
||||
private static ImmersalProjectValidationWindow window = null;
|
||||
|
||||
private Vector2 m_ScrollViewPos = Vector2.zero;
|
||||
|
||||
private static ProjectValidationState SavedValidationState
|
||||
{
|
||||
get => (ProjectValidationState)PlayerPrefs.GetInt(ImmersalProjectValidation.PlayerPrefsStateString, 0);
|
||||
set => PlayerPrefs.SetInt(ImmersalProjectValidation.PlayerPrefsStateString, (int)value);
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
internal static void InitializeOnLoad()
|
||||
{
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (SavedValidationState is ProjectValidationState.Uninitialized or ProjectValidationState.Issues)
|
||||
{
|
||||
SavedValidationState = ProjectValidationState.Issues;
|
||||
ShowWindow();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[MenuItem("Immersal SDK/Project Validation")]
|
||||
private static void MenuItem()
|
||||
{
|
||||
ShowWindow();
|
||||
}
|
||||
|
||||
private static void ShowWindow(BuildTargetGroup buildTargetGroup = BuildTargetGroup.Unknown)
|
||||
{
|
||||
if (window == null)
|
||||
{
|
||||
window = (ImmersalProjectValidationWindow) GetWindow(typeof(ImmersalProjectValidationWindow));
|
||||
window.titleContent = Content.Title;
|
||||
window.minSize = new Vector2(500.0f, 300.0f);
|
||||
}
|
||||
window.UpdateIssues();
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private static void InitStyles()
|
||||
{
|
||||
if (Styles.s_ListLabel != null)
|
||||
return;
|
||||
|
||||
Styles.s_ListLabel = new GUIStyle(Styles.s_SelectionStyle)
|
||||
{
|
||||
border = new RectOffset(0, 0, 0, 0),
|
||||
padding = new RectOffset(5, 5, 5, 5),
|
||||
margin = new RectOffset(5, 5, 5, 5)
|
||||
};
|
||||
|
||||
Styles.s_TargetPlatformLabel = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
fontSize = 9,
|
||||
fontStyle = FontStyle.Normal,
|
||||
padding = new RectOffset(10, 10, 0, 0),
|
||||
};
|
||||
|
||||
Styles.s_IssuesTitleLabel = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
fontSize = 16,
|
||||
fontStyle = FontStyle.Bold,
|
||||
padding = new RectOffset(10, 10, 0, 0),
|
||||
};
|
||||
|
||||
Styles.s_Wrap = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
wordWrap = true,
|
||||
alignment = TextAnchor.MiddleLeft,
|
||||
padding = new RectOffset(0, 5, 5, 5)
|
||||
};
|
||||
|
||||
Styles.s_Icon = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
margin = new RectOffset(10, 10, 8, 0),
|
||||
fixedWidth = Content.IconSize.x * 2
|
||||
};
|
||||
|
||||
Styles.s_InfoBanner = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
padding = new RectOffset(10, 10, 15, 5)
|
||||
};
|
||||
|
||||
Styles.s_Fix = new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
stretchWidth = false,
|
||||
fixedWidth = 80,
|
||||
margin = new RectOffset(0, 0, 8, 5)
|
||||
};
|
||||
|
||||
Styles.s_FixAll = new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
stretchWidth = false,
|
||||
fixedWidth = 80,
|
||||
margin = new RectOffset(0, 10, 5, 8)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private readonly List<ImmersalProjectIssue> projectIssues = new List<ImmersalProjectIssue>();
|
||||
private List<ImmersalProjectIssue> fixAllIssues = new List<ImmersalProjectIssue>();
|
||||
|
||||
private double lastUpdate;
|
||||
private const double updateInterval = 1.0;
|
||||
private const double backgroundUpdateInterval = 1.0;
|
||||
|
||||
private static class Content
|
||||
{
|
||||
public static readonly GUIContent Title = new GUIContent("Immersal Project Validation", "");
|
||||
public static readonly GUIContent WarningIcon = EditorGUIUtility.IconContent("Warning@2x");
|
||||
public static readonly GUIContent ErrorIcon = EditorGUIUtility.IconContent("Error@2x");
|
||||
public static readonly GUIContent FixButton = new GUIContent("Fix", "");
|
||||
public static readonly GUIContent PlayMode = new GUIContent("Exit play mode", EditorGUIUtility.IconContent("console.infoicon").image);
|
||||
public static readonly Vector2 IconSize = new Vector2(16.0f, 16.0f);
|
||||
}
|
||||
|
||||
private static class Styles
|
||||
{
|
||||
public static GUIStyle s_SelectionStyle = "TV Selection";
|
||||
public static GUIStyle s_IssuesBackground = "ScrollViewAlt";
|
||||
public static GUIStyle s_ListLabel;
|
||||
public static GUIStyle s_TargetPlatformLabel;
|
||||
public static GUIStyle s_IssuesTitleLabel;
|
||||
public static GUIStyle s_Wrap;
|
||||
public static GUIStyle s_Icon;
|
||||
public static GUIStyle s_InfoBanner;
|
||||
public static GUIStyle s_Fix;
|
||||
public static GUIStyle s_FixAll;
|
||||
}
|
||||
|
||||
protected void OnFocus() => UpdateIssues(true);
|
||||
|
||||
protected void Update() => UpdateIssues();
|
||||
|
||||
private void UpdateIssues(bool force = false)
|
||||
{
|
||||
var interval = EditorWindow.focusedWindow == this ? updateInterval : backgroundUpdateInterval;
|
||||
if (!force && EditorApplication.timeSinceStartup - lastUpdate < interval)
|
||||
return;
|
||||
|
||||
// Fix all
|
||||
foreach (ImmersalProjectIssue issue in fixAllIssues)
|
||||
{
|
||||
issue.Fix?.Invoke();
|
||||
}
|
||||
fixAllIssues.Clear();
|
||||
|
||||
ImmersalProjectValidation.CheckIssues(projectIssues);
|
||||
Repaint();
|
||||
|
||||
if (projectIssues.Count > 0)
|
||||
{
|
||||
if(SavedValidationState != ProjectValidationState.Uninitialized)
|
||||
SavedValidationState = ProjectValidationState.Issues;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
SavedValidationState = ProjectValidationState.NoIssues;
|
||||
}
|
||||
|
||||
lastUpdate = EditorApplication.timeSinceStartup;
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
InitStyles();
|
||||
|
||||
EditorGUIUtility.SetIconSize(Content.IconSize);
|
||||
|
||||
using (new EditorGUI.DisabledScope(fixAllIssues.Count > 0))
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
if (EditorApplication.isPlaying && projectIssues.Count > 0)
|
||||
{
|
||||
GUILayout.Label(Content.PlayMode, Styles.s_InfoBanner);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
bool fixableIssues = projectIssues.Any(f => f.Fix != null);
|
||||
|
||||
EditorGUILayout.LabelField($"Target platform: {ImmersalProjectValidation.ActiveBuildTarget.ToString()}", Styles.s_TargetPlatformLabel);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
using (new EditorGUI.DisabledScope(EditorApplication.isPlaying))
|
||||
{
|
||||
EditorGUILayout.LabelField($"Project issues ({projectIssues.Count}):", Styles.s_IssuesTitleLabel);
|
||||
}
|
||||
|
||||
if (fixableIssues)
|
||||
{
|
||||
using (new EditorGUI.DisabledScope(EditorApplication.isPlaying))
|
||||
{
|
||||
if (GUILayout.Button("Fix All", Styles.s_FixAll))
|
||||
{
|
||||
fixAllIssues = new List<ImmersalProjectIssue>();
|
||||
foreach (ImmersalProjectIssue issue in projectIssues)
|
||||
{
|
||||
if (!issue.RequiresManualFix)
|
||||
fixAllIssues.Add(issue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
m_ScrollViewPos = EditorGUILayout.BeginScrollView(m_ScrollViewPos, Styles.s_IssuesBackground,
|
||||
GUILayout.ExpandHeight(true));
|
||||
|
||||
using (new EditorGUI.DisabledScope(EditorApplication.isPlaying))
|
||||
{
|
||||
foreach (ImmersalProjectIssue issue in projectIssues)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal(Styles.s_ListLabel);
|
||||
|
||||
GUILayout.Label(issue.Error ? Content.ErrorIcon : Content.WarningIcon, Styles.s_Icon,
|
||||
GUILayout.Width(Content.IconSize.x));
|
||||
GUILayout.Label(issue.Message(), Styles.s_Wrap);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("", GUILayout.Width(Content.IconSize.x * 1.5f));
|
||||
|
||||
if (issue.Fix != null)
|
||||
{
|
||||
if (GUILayout.Button(Content.FixButton, Styles.s_Fix))
|
||||
{
|
||||
issue.Fix();
|
||||
}
|
||||
}
|
||||
else if (fixableIssues)
|
||||
{
|
||||
GUILayout.Label("", GUILayout.Width(80.0f));
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
|
||||
{
|
||||
UpdateIssues(true);
|
||||
}
|
||||
|
||||
public int callbackOrder => 0;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public interface IImmersalProjectIssueProvider
|
||||
{
|
||||
public string Name { get; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool DisableDefaultIssues { get; }
|
||||
public IEnumerable<ImmersalProjectIssue> Issues { get; }
|
||||
}
|
||||
|
||||
public class ImmersalProjectIssue
|
||||
{
|
||||
public Func<string> Message;
|
||||
public Func<bool> Check;
|
||||
public Action Fix;
|
||||
public bool Error;
|
||||
public bool RequiresManualFix;
|
||||
}
|
||||
|
||||
public static class ImmersalProjectValidation
|
||||
{
|
||||
public static string PlayerPrefsStateString = "ImmersalProjectValidationState";
|
||||
|
||||
private static IImmersalProjectIssueProvider m_DefaultIssueProvider = new DefaultImmersalProjectIssueProvider();
|
||||
private static Dictionary<string, IImmersalProjectIssueProvider> m_IssueProviders = new Dictionary<string, IImmersalProjectIssueProvider>();
|
||||
|
||||
public static BuildTargetGroup ActiveBuildTargetGroup = ActiveBuildTarget switch
|
||||
{
|
||||
BuildTarget.iOS => BuildTargetGroup.iOS,
|
||||
BuildTarget.Android => BuildTargetGroup.Android,
|
||||
BuildTarget.StandaloneOSX => BuildTargetGroup.Standalone,
|
||||
BuildTarget.StandaloneWindows => BuildTargetGroup.Standalone,
|
||||
BuildTarget.StandaloneWindows64 => BuildTargetGroup.Standalone,
|
||||
BuildTarget.StandaloneLinux64 => BuildTargetGroup.Standalone,
|
||||
BuildTarget.WSAPlayer => BuildTargetGroup.WSA,
|
||||
_ => BuildTargetGroup.Unknown
|
||||
};
|
||||
|
||||
public static BuildTarget ActiveBuildTarget => EditorUserBuildSettings.activeBuildTarget;
|
||||
|
||||
public static void RegisterIssueProvider(IImmersalProjectIssueProvider provider)
|
||||
{
|
||||
m_IssueProviders[provider.Name] = provider;
|
||||
}
|
||||
|
||||
public static void CheckIssues(List<ImmersalProjectIssue> issues)
|
||||
{
|
||||
issues.Clear();
|
||||
|
||||
if (m_IssueProviders.Count > 1)
|
||||
{
|
||||
issues.Add(new ImmersalProjectIssue
|
||||
{
|
||||
Check = () => false,
|
||||
Message = () => "Multiple packages affecting project issues.",
|
||||
Error = false
|
||||
});
|
||||
}
|
||||
|
||||
foreach (IImmersalProjectIssueProvider provider in m_IssueProviders.Values)
|
||||
{
|
||||
if (provider.DisableDefaultIssues)
|
||||
m_DefaultIssueProvider.Enabled = false;
|
||||
if (provider.Enabled)
|
||||
issues.AddRange(provider.Issues);
|
||||
}
|
||||
|
||||
if (m_DefaultIssueProvider.Enabled)
|
||||
issues.AddRange(m_DefaultIssueProvider.Issues);
|
||||
|
||||
issues.RemoveAll(issue => issue.Check?.Invoke() ?? false);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DefaultImmersalProjectIssueProvider : IImmersalProjectIssueProvider
|
||||
{
|
||||
public string Name => "Default";
|
||||
public bool DisableDefaultIssues => false;
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public IEnumerable<ImmersalProjectIssue> Issues => DefaultProjectIssues;
|
||||
|
||||
// ReSharper disable once HeapView.ObjectAllocation
|
||||
private static readonly ImmersalProjectIssue[] DefaultProjectIssues =
|
||||
{
|
||||
// Graphics API
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () =>
|
||||
{
|
||||
return ImmersalProjectValidation.ActiveBuildTarget switch
|
||||
{
|
||||
BuildTarget.iOS => "Graphics API must be set to Metal",
|
||||
BuildTarget.Android => "Graphics API must be set to OpenGLES3",
|
||||
BuildTarget.StandaloneWindows => "Graphics API must set to OpenGLCore",
|
||||
_ => "Unsupported GraphicsAPI for current build target."
|
||||
};
|
||||
},
|
||||
Check = () =>
|
||||
{
|
||||
GraphicsDeviceType[] graphicAPIs = PlayerSettings.GetGraphicsAPIs(ImmersalProjectValidation.ActiveBuildTarget);
|
||||
return ImmersalProjectValidation.ActiveBuildTarget switch
|
||||
{
|
||||
BuildTarget.iOS => graphicAPIs.Length == 1 && graphicAPIs[0] == GraphicsDeviceType.Metal,
|
||||
BuildTarget.Android => graphicAPIs.Length == 1 && graphicAPIs[0] == GraphicsDeviceType.OpenGLES3,
|
||||
BuildTarget.StandaloneWindows => graphicAPIs.Length == 1 && graphicAPIs[0] == GraphicsDeviceType.OpenGLCore,
|
||||
_ => true
|
||||
};
|
||||
},
|
||||
Fix = () =>
|
||||
{
|
||||
GraphicsDeviceType[] cga = PlayerSettings.GetGraphicsAPIs(ImmersalProjectValidation.ActiveBuildTarget);
|
||||
var autoGraphicAPI = PlayerSettings.GetUseDefaultGraphicsAPIs(ImmersalProjectValidation.ActiveBuildTarget);
|
||||
if (autoGraphicAPI)
|
||||
PlayerSettings.SetUseDefaultGraphicsAPIs(ImmersalProjectValidation.ActiveBuildTarget, false);
|
||||
|
||||
GraphicsDeviceType[] graphicAPIs = ImmersalProjectValidation.ActiveBuildTarget switch
|
||||
{
|
||||
BuildTarget.iOS => new GraphicsDeviceType[] { GraphicsDeviceType.Metal },
|
||||
BuildTarget.Android => new GraphicsDeviceType[] { GraphicsDeviceType.OpenGLES3 },
|
||||
BuildTarget.StandaloneWindows => new GraphicsDeviceType[] { GraphicsDeviceType.OpenGLCore },
|
||||
_ => PlayerSettings.GetGraphicsAPIs(ImmersalProjectValidation.ActiveBuildTarget)
|
||||
};
|
||||
|
||||
PlayerSettings.SetGraphicsAPIs(ImmersalProjectValidation.ActiveBuildTarget, graphicAPIs);
|
||||
},
|
||||
Error = true,
|
||||
},
|
||||
// IL2CPP
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "IL2CPP must be enabled.",
|
||||
Check = () => PlayerSettings.GetScriptingBackend(ImmersalProjectValidation.ActiveBuildTargetGroup) == ScriptingImplementation.IL2CPP,
|
||||
Fix = () => { PlayerSettings.SetScriptingBackend(ImmersalProjectValidation.ActiveBuildTargetGroup, ScriptingImplementation.IL2CPP); },
|
||||
Error = true,
|
||||
},
|
||||
// Allow unsafe code
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Allow 'unsafe' code must be enabled.",
|
||||
Check = () => PlayerSettings.allowUnsafeCode,
|
||||
Fix = () => { PlayerSettings.allowUnsafeCode = true; },
|
||||
Error = true,
|
||||
},
|
||||
// Camera usage description
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Camera Usage Description must be defined.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.iOS || PlayerSettings.iOS.cameraUsageDescription != "",
|
||||
Fix = () => { PlayerSettings.iOS.cameraUsageDescription = "Required for augmented reality support."; },
|
||||
Error = true,
|
||||
},
|
||||
// Location usage description
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Location Usage Description must be defined.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.iOS || PlayerSettings.iOS.locationUsageDescription != "",
|
||||
Fix = () => { PlayerSettings.iOS.locationUsageDescription = "Required for satellite positioning support."; },
|
||||
Error = true,
|
||||
},
|
||||
// minimum ios version 12.0
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Target minimum iOS Version must be 12.0 or higher.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.iOS || (float.TryParse(PlayerSettings.iOS.targetOSVersionString, out float minVersion) && minVersion >= 12.0f),
|
||||
Fix = () => { PlayerSettings.iOS.targetOSVersionString = "12.0"; },
|
||||
Error = true,
|
||||
},
|
||||
// minimum android api version 26
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Minimum Android API Level must be 26 or higher.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.Android ||
|
||||
PlayerSettings.Android.minSdkVersion >= AndroidSdkVersions.AndroidApiLevel26,
|
||||
Fix = () => { PlayerSettings.Android.minSdkVersion = AndroidSdkVersions.AndroidApiLevel26; },
|
||||
Error = true,
|
||||
},
|
||||
// ARM64
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "ARM64 Target Architecture must be enabled.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.Android ||
|
||||
(PlayerSettings.Android.targetArchitectures & AndroidArchitecture.ARM64) != 0,
|
||||
Fix = () => { PlayerSettings.Android.targetArchitectures |= AndroidArchitecture.ARM64; },
|
||||
Error = true,
|
||||
},
|
||||
// ARKit loader
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "ARKit XR-Plugin Provider must be enabled.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.iOS || IsPluginLoaderEnabled("AR Kit Loader") ,
|
||||
Fix = () =>
|
||||
{
|
||||
EditorUserBuildSettings.selectedBuildTargetGroup = ImmersalProjectValidation.ActiveBuildTargetGroup;
|
||||
SettingsService.OpenProjectSettings("Project/XR Plug-in Management");
|
||||
},
|
||||
Error = true,
|
||||
RequiresManualFix = true
|
||||
},
|
||||
// ARCore loader
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "ARCore XR-Plugin Provider must be enabled.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.Android || IsPluginLoaderEnabled("AR Core Loader"),
|
||||
Fix = () =>
|
||||
{
|
||||
EditorUserBuildSettings.selectedBuildTargetGroup = ImmersalProjectValidation.ActiveBuildTargetGroup;
|
||||
SettingsService.OpenProjectSettings("Project/XR Plug-in Management");
|
||||
},
|
||||
Error = true,
|
||||
RequiresManualFix = true
|
||||
},
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Universal Render Pipeline is recommended",
|
||||
Check = () => GraphicsSettings.defaultRenderPipeline != null,
|
||||
Fix = SetupRenderPipeline,
|
||||
Error = false,
|
||||
RequiresManualFix = false
|
||||
},
|
||||
// android manifest exists
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Custom Android Manifest is required.",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.Android || CheckManifestExists(),
|
||||
Fix = CreateManifest,
|
||||
Error = true,
|
||||
},
|
||||
// android manifest has necessary attributes
|
||||
new ImmersalProjectIssue()
|
||||
{
|
||||
Message = () => "Android Manifest should include network permissions",
|
||||
Check = () => ImmersalProjectValidation.ActiveBuildTarget != BuildTarget.Android || CheckManifestContent(),
|
||||
Fix = ConfigureManifest,
|
||||
Error = false,
|
||||
},
|
||||
};
|
||||
|
||||
private static bool IsPluginLoaderEnabled(string loaderName)
|
||||
{
|
||||
XRGeneralSettings generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(ImmersalProjectValidation.ActiveBuildTargetGroup);
|
||||
if (generalSettings == null)
|
||||
return false;
|
||||
|
||||
XRManagerSettings managerSettings = generalSettings.AssignedSettings;
|
||||
|
||||
string loaderNameNoWhitespace = loaderName.Replace(" ", "");
|
||||
return managerSettings != null && managerSettings.activeLoaders.Any(loader => (loader.name == loaderName || loader.name == loaderNameNoWhitespace));
|
||||
}
|
||||
|
||||
private static void SetupRenderPipeline()
|
||||
{
|
||||
string destinationPath = Application.dataPath;
|
||||
|
||||
// Renderer and RenderPipelineAsset
|
||||
if (CopyFromPackage("Editor/ImmersalURPAsset_Renderer.asset", Path.Combine(destinationPath, "ImmersalURPAsset_Renderer.asset"), true))
|
||||
{
|
||||
// Load RendererData
|
||||
string rendererDataPath = Path.Combine("Assets", "ImmersalURPAsset_Renderer.asset");
|
||||
UniversalRendererData rendererData =
|
||||
(UniversalRendererData)AssetDatabase.LoadAssetAtPath(rendererDataPath, typeof(UniversalRendererData));
|
||||
|
||||
if (rendererData != null)
|
||||
{
|
||||
// Create / load RenderPipelineAsset
|
||||
UniversalRenderPipelineAsset rpa = UniversalRenderPipelineAsset.Create(rendererData);
|
||||
|
||||
// Save to file
|
||||
string rpaSavePath = Path.Combine("Assets", "ImmersalURPAsset.asset");
|
||||
AssetDatabase.CreateAsset(rpa, rpaSavePath);
|
||||
|
||||
// Configure
|
||||
ConfigureRenderPipelineAsset(rpa);
|
||||
|
||||
// Set in settings
|
||||
GraphicsSettings.defaultRenderPipeline = rpa;
|
||||
QualitySettings.renderPipeline = rpa;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Global Settings
|
||||
if (CopyFromPackage("Editor/ImmersalURPGlobalSettings.asset", Path.Combine(destinationPath, "ImmersalURPGlobalSettings.asset"), true))
|
||||
{
|
||||
string settingsPath = Path.Combine("Assets", "ImmersalURPGlobalSettings.asset");
|
||||
RenderPipelineGlobalSettings settings =
|
||||
(RenderPipelineGlobalSettings)AssetDatabase.LoadAssetAtPath(settingsPath,
|
||||
typeof(RenderPipelineGlobalSettings));
|
||||
|
||||
if (settings != null)
|
||||
{
|
||||
GraphicsSettings.RegisterRenderPipelineSettings<UniversalRenderPipeline>(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ConfigureRenderPipelineAsset(UniversalRenderPipelineAsset asset)
|
||||
{
|
||||
asset.supportsHDR = false;
|
||||
asset.cascadeBorder = 0.1f;
|
||||
}
|
||||
|
||||
private static bool CopyFromPackage(string packageRelativePath, string destinationPath, bool refreshDatabase = true)
|
||||
{
|
||||
string sourcePath = Path.Combine("Packages/com.immersal.core/", packageRelativePath);
|
||||
string absolutePath = FixWindowsPath(Path.GetFullPath(sourcePath));
|
||||
destinationPath = FixWindowsPath(destinationPath);
|
||||
|
||||
if (File.Exists(absolutePath))
|
||||
{
|
||||
if (File.Exists(destinationPath))
|
||||
{
|
||||
ImmersalLogger.LogWarning(
|
||||
$"Attempting to copy file from Immersal package but destination already exists: {destinationPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have to manually create directories or CopyFileOrDirectory will error on Windows
|
||||
string dirName = Path.GetDirectoryName(destinationPath);
|
||||
if (dirName == null)
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(dirName))
|
||||
Directory.CreateDirectory(dirName);
|
||||
|
||||
FileUtil.CopyFileOrDirectory(absolutePath, destinationPath);
|
||||
}
|
||||
if (refreshDatabase)
|
||||
AssetDatabase.Refresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
ImmersalLogger.LogWarning($"Could not locate {packageRelativePath} in Immersal package.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unity API expects forward-slashes everywhere, but .NET methods produce paths with back-slashes on Windows
|
||||
private static string FixWindowsPath(string path)
|
||||
{
|
||||
return path.Replace("\\", "/");
|
||||
}
|
||||
|
||||
private static bool CheckManifestExists()
|
||||
{
|
||||
return File.Exists(GetManifestPath());
|
||||
}
|
||||
|
||||
private static bool CheckManifestContent()
|
||||
{
|
||||
if (CheckManifestExists())
|
||||
{
|
||||
AndroidManifest manifest = new AndroidManifest(GetManifestPath());
|
||||
bool internet = manifest.CheckPermission("android.permission.INTERNET");
|
||||
bool network = manifest.CheckPermission("android.permission.ACCESS_NETWORK_STATE");
|
||||
return internet && network;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetManifestPath()
|
||||
{
|
||||
return Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml");
|
||||
}
|
||||
|
||||
private static void CreateManifest()
|
||||
{
|
||||
CopyFromPackage("Editor/SampleAndroidManifest.xml", GetManifestPath());
|
||||
}
|
||||
|
||||
private static void ConfigureManifest()
|
||||
{
|
||||
if (CheckManifestExists())
|
||||
{
|
||||
AndroidManifest manifest = new AndroidManifest(GetManifestPath());
|
||||
manifest.AddPermission("android.permission.INTERNET");
|
||||
manifest.AddPermission("android.permission.ACCESS_NETWORK_STATE");
|
||||
manifest.Save();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class AndroidXmlDocument : XmlDocument
|
||||
{
|
||||
private string m_Path;
|
||||
protected XmlNamespaceManager nsMgr;
|
||||
public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
|
||||
public AndroidXmlDocument(string path)
|
||||
{
|
||||
m_Path = path;
|
||||
using (var reader = new XmlTextReader(m_Path))
|
||||
{
|
||||
reader.Read();
|
||||
Load(reader);
|
||||
}
|
||||
nsMgr = new XmlNamespaceManager(NameTable);
|
||||
nsMgr.AddNamespace("android", AndroidXmlNamespace);
|
||||
}
|
||||
|
||||
public string Save()
|
||||
{
|
||||
return SaveAs(m_Path);
|
||||
}
|
||||
|
||||
public string SaveAs(string path)
|
||||
{
|
||||
using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
|
||||
{
|
||||
writer.Formatting = Formatting.Indented;
|
||||
Save(writer);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
internal class AndroidManifest : AndroidXmlDocument
|
||||
{
|
||||
private readonly XmlElement ApplicationElement;
|
||||
|
||||
public AndroidManifest(string path) : base(path)
|
||||
{
|
||||
ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
|
||||
}
|
||||
|
||||
private XmlAttribute CreateAndroidAttribute(string key, string value)
|
||||
{
|
||||
XmlAttribute attr = CreateAttribute("android", key, AndroidXmlNamespace);
|
||||
attr.Value = value;
|
||||
return attr;
|
||||
}
|
||||
|
||||
private XmlElement CreatePermissionElement(string permissionName)
|
||||
{
|
||||
XmlElement elem = CreateElement("uses-permission");
|
||||
XmlAttribute attr = CreateAttribute("android", "name", AndroidXmlNamespace);
|
||||
attr.Value = permissionName;
|
||||
elem.Attributes.Append(attr);
|
||||
return elem;
|
||||
}
|
||||
|
||||
internal XmlNode GetActivityWithLaunchIntent()
|
||||
{
|
||||
return SelectSingleNode("/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and " +
|
||||
"intent-filter/category/@android:name='android.intent.category.LAUNCHER']", nsMgr);
|
||||
}
|
||||
|
||||
internal void SetApplicationTheme(string appTheme)
|
||||
{
|
||||
ApplicationElement.Attributes.Append(CreateAndroidAttribute("theme", appTheme));
|
||||
}
|
||||
|
||||
internal void SetStartingActivityName(string activityName)
|
||||
{
|
||||
GetActivityWithLaunchIntent().Attributes.Append(CreateAndroidAttribute("name", activityName));
|
||||
}
|
||||
|
||||
internal void AddPermission(string permissionName)
|
||||
{
|
||||
XmlElement ManifestElement = SelectSingleNode("/manifest") as XmlElement;
|
||||
XmlElement permissionElement = CreatePermissionElement(permissionName);
|
||||
ManifestElement?.AppendChild(permissionElement);
|
||||
}
|
||||
|
||||
internal bool CheckPermission(string permissionName)
|
||||
{
|
||||
XmlElement ManifestElement = SelectSingleNode("/manifest") as XmlElement;
|
||||
XmlNodeList children = ManifestElement?.ChildNodes;
|
||||
if (children == null) return false;
|
||||
foreach (XmlNode child in children)
|
||||
{
|
||||
if (child.Name != "uses-permission") continue;
|
||||
if (child.Attributes == null) continue;
|
||||
XmlAttribute attr = child.Attributes?["android:name"];
|
||||
if (attr == null) continue;
|
||||
if (attr.Value == permissionName) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39d80592149a7480bbaa221e6c227a34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
164
Assets/99.imdk_unity/Editor/ImmersalSDKEditor.cs
Normal file
164
Assets/99.imdk_unity/Editor/ImmersalSDKEditor.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Immersal.XR;
|
||||
using Unity.EditorCoroutines.Editor;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.Networking;
|
||||
using Immersal.REST;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
[CustomEditor(typeof(ImmersalSDK))]
|
||||
public class ImmersalSDKEditor : Editor, IPreprocessBuildWithReport
|
||||
{
|
||||
private SerializedProperty immersalServer;
|
||||
private SerializedProperty immersalServerUrl;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
immersalServer = serializedObject.FindProperty("ImmersalServer");
|
||||
immersalServerUrl = serializedObject.FindProperty("m_CustomServerUrl");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
ImmersalSDK obj = (ImmersalSDK)target;
|
||||
|
||||
EditorGUILayout.HelpBox("Immersal SDK v" + ImmersalSDK.sdkVersion, MessageType.Info);
|
||||
|
||||
EditorGUILayout.LabelField("Cloud configuration", EditorStyles.boldLabel);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
ImmersalSDK.APIServer serverSelection = (ImmersalSDK.APIServer)EditorGUILayout.EnumPopup("Immersal Server", (ImmersalSDK.APIServer)immersalServer.enumValueIndex);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
immersalServer.enumValueIndex = (int)serverSelection;
|
||||
}
|
||||
|
||||
if (serverSelection == ImmersalSDK.APIServer.CustomServer && immersalServerUrl != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(immersalServerUrl);
|
||||
}
|
||||
|
||||
DrawPropertiesExcluding(serializedObject, "m_Script", "ImmersalServer", "m_CustomServerUrl");
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
// Preprocess builds
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
// ARMaps
|
||||
XRMap[] maps = FindObjectsOfType<XRMap>();
|
||||
foreach (XRMap map in maps)
|
||||
{
|
||||
if (!map.PreBuildCheck(out string msg))
|
||||
{
|
||||
throw new BuildFailedException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LoginWindow: EditorWindow
|
||||
{
|
||||
private string myEmail = "";
|
||||
private string myPassword = "";
|
||||
private string myToken = "";
|
||||
private ImmersalSDK sdk = null;
|
||||
|
||||
private static UnityWebRequest request;
|
||||
|
||||
[MenuItem("Immersal SDK/Login")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
EditorWindow.GetWindow<LoginWindow>("Immersal Login");
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
GUILayout.Label("Credentials", EditorStyles.boldLabel);
|
||||
myEmail = EditorGUILayout.TextField("Email", myEmail);
|
||||
myPassword = EditorGUILayout.PasswordField("Password", myPassword);
|
||||
|
||||
if (GUILayout.Button("Login"))
|
||||
{
|
||||
SDKLoginRequest loginRequest = new SDKLoginRequest();
|
||||
loginRequest.login = myEmail;
|
||||
loginRequest.password = myPassword;
|
||||
|
||||
EditorCoroutineUtility.StartCoroutine(Login(loginRequest), this);
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
myToken = EditorGUILayout.TextField("Token", myToken);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.LabelField("(C) 2023 Immersal - Part of Hexagon. All Right Reserved.");
|
||||
}
|
||||
|
||||
void OnInspectorUpdate()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
IEnumerator Login(SDKLoginRequest loginRequest)
|
||||
{
|
||||
string jsonString = JsonUtility.ToJson(loginRequest);
|
||||
sdk = ImmersalSDK.Instance;
|
||||
using (UnityWebRequest request = UnityWebRequest.Put(string.Format(ImmersalHttp.URL_FORMAT, sdk.localizationServer, SDKLoginRequest.endpoint), jsonString))
|
||||
{
|
||||
request.method = UnityWebRequest.kHttpVerbPOST;
|
||||
request.useHttpContinue = false;
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
request.SetRequestHeader("Accept", "application/json");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (request.isNetworkError || request.isHttpError)
|
||||
#endif
|
||||
{
|
||||
Debug.LogError(request.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDKLoginResult loginResult = JsonUtility.FromJson<SDKLoginResult>(request.downloadHandler.text);
|
||||
if (loginResult.error == "none")
|
||||
{
|
||||
myToken = loginResult.token;
|
||||
sdk.developerToken = myToken;
|
||||
|
||||
// Apply override to the prefab instance
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(sdk);
|
||||
|
||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/ImmersalSDKEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/ImmersalSDKEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0b763741518b4f588fd56817d8bf5ee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
71
Assets/99.imdk_unity/Editor/ImmersalURPAsset_Renderer.asset
Normal file
71
Assets/99.imdk_unity/Editor/ImmersalURPAsset_Renderer.asset
Normal file
@@ -0,0 +1,71 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-6306797109214245143
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0ae4d376c05df421b98c5b39b25b0d29, type: 3}
|
||||
m_Name: ARBackgroundRendererFeature
|
||||
m_EditorClassIdentifier:
|
||||
m_Active: 1
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: de640fe3d0db1804a85f9fc8f5cadab6, type: 3}
|
||||
m_Name: ImmersalURPAsset_Renderer
|
||||
m_EditorClassIdentifier:
|
||||
debugShaders:
|
||||
debugReplacementPS: {fileID: 4800000, guid: cf852408f2e174538bcd9b7fda1c5ae7, type: 3}
|
||||
hdrDebugViewPS: {fileID: 4800000, guid: 573620ae32aec764abd4d728906d2587, type: 3}
|
||||
m_RendererFeatures:
|
||||
- {fileID: -6306797109214245143}
|
||||
m_RendererFeatureMap: e90ed3aa71c179a8
|
||||
m_UseNativeRenderPass: 0
|
||||
postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2}
|
||||
xrSystemData: {fileID: 11400000, guid: 60e1133243b97e347b653163a8c01b64, type: 2}
|
||||
shaders:
|
||||
blitPS: {fileID: 4800000, guid: c17132b1f77d20942aa75f8429c0f8bc, type: 3}
|
||||
copyDepthPS: {fileID: 4800000, guid: d6dae50ee9e1bfa4db75f19f99355220, type: 3}
|
||||
screenSpaceShadowPS: {fileID: 4800000, guid: 0f854b35a0cf61a429bd5dcfea30eddd, type: 3}
|
||||
samplingPS: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3}
|
||||
stencilDeferredPS: {fileID: 4800000, guid: e9155b26e1bc55942a41e518703fe304, type: 3}
|
||||
fallbackErrorPS: {fileID: 4800000, guid: e6e9a19c3678ded42a3bc431ebef7dbd, type: 3}
|
||||
fallbackLoadingPS: {fileID: 4800000, guid: 7f888aff2ac86494babad1c2c5daeee2, type: 3}
|
||||
materialErrorPS: {fileID: 4800000, guid: 5fd9a8feb75a4b5894c241777f519d4e, type: 3}
|
||||
coreBlitPS: {fileID: 4800000, guid: 93446b5c5339d4f00b85c159e1159b7c, type: 3}
|
||||
coreBlitColorAndDepthPS: {fileID: 4800000, guid: d104b2fc1ca6445babb8e90b0758136b, type: 3}
|
||||
blitHDROverlay: {fileID: 4800000, guid: a89bee29cffa951418fc1e2da94d1959, type: 3}
|
||||
cameraMotionVector: {fileID: 4800000, guid: c56b7e0d4c7cb484e959caeeedae9bbf, type: 3}
|
||||
objectMotionVector: {fileID: 4800000, guid: 7b3ede40266cd49a395def176e1bc486, type: 3}
|
||||
dataDrivenLensFlare: {fileID: 4800000, guid: 6cda457ac28612740adb23da5d39ea92, type: 3}
|
||||
m_AssetVersion: 2
|
||||
m_OpaqueLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_TransparentLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_DefaultStencilState:
|
||||
overrideStencilState: 0
|
||||
stencilReference: 0
|
||||
stencilCompareFunction: 8
|
||||
passOperation: 0
|
||||
failOperation: 0
|
||||
zFailOperation: 0
|
||||
m_ShadowTransparentReceive: 1
|
||||
m_RenderingMode: 0
|
||||
m_DepthPrimingMode: 0
|
||||
m_CopyDepthMode: 0
|
||||
m_AccurateGbufferNormals: 0
|
||||
m_IntermediateTextureMode: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 939f6cfbed10c417bb69bff14fa799bd
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/99.imdk_unity/Editor/ImmersalURPGlobalSettings.asset
Normal file
41
Assets/99.imdk_unity/Editor/ImmersalURPGlobalSettings.asset
Normal file
@@ -0,0 +1,41 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2ec995e51a6e251468d2a3fd8a686257, type: 3}
|
||||
m_Name: ImmersalURPGlobalSettings
|
||||
m_EditorClassIdentifier:
|
||||
k_AssetVersion: 3
|
||||
m_RenderingLayerNames:
|
||||
- Light Layer default
|
||||
- Light Layer 1
|
||||
- Light Layer 2
|
||||
- Light Layer 3
|
||||
- Light Layer 4
|
||||
- Light Layer 5
|
||||
- Light Layer 6
|
||||
- Light Layer 7
|
||||
m_ValidRenderingLayers: 255
|
||||
lightLayerName0: Light Layer default
|
||||
lightLayerName1: Light Layer 1
|
||||
lightLayerName2: Light Layer 2
|
||||
lightLayerName3: Light Layer 3
|
||||
lightLayerName4: Light Layer 4
|
||||
lightLayerName5: Light Layer 5
|
||||
lightLayerName6: Light Layer 6
|
||||
lightLayerName7: Light Layer 7
|
||||
m_StripDebugVariants: 1
|
||||
m_StripUnusedPostProcessingVariants: 0
|
||||
m_StripUnusedVariants: 1
|
||||
m_StripUnusedLODCrossFadeVariants: 1
|
||||
m_StripScreenCoordOverrideVariants: 1
|
||||
supportRuntimeDebugDisplay: 0
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_ExportShaderVariants: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95b35ca7c5dee41ae911d5ac6a1c665a
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
93
Assets/99.imdk_unity/Editor/InterfaceDrawer.cs
Normal file
93
Assets/99.imdk_unity/Editor/InterfaceDrawer.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(InterfaceAttribute))]
|
||||
public class InterfaceDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
InterfaceAttribute att = attribute as InterfaceAttribute;
|
||||
|
||||
if (property.propertyType != SerializedPropertyType.ObjectReference)
|
||||
{
|
||||
EditorGUI.LabelField(position, label.text, "InterfaceType Attribute can only be used with MonoBehaviour Components!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Pick a specific component
|
||||
MonoBehaviour oldComp = property.objectReferenceValue as MonoBehaviour;
|
||||
|
||||
GameObject temp = null;
|
||||
string oldName = "";
|
||||
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
if (oldComp == null)
|
||||
{
|
||||
temp = new GameObject("None [" + att.TypeOfInterface.Name + "]");
|
||||
oldComp = temp.AddComponent<MonoInterface>();
|
||||
}
|
||||
else
|
||||
{
|
||||
oldName = oldComp.name;
|
||||
oldComp.name = oldName + " [" + att.TypeOfInterface.Name + "]";
|
||||
}
|
||||
}
|
||||
|
||||
MonoBehaviour comp = EditorGUI.ObjectField(position, label, oldComp, typeof(MonoBehaviour), true) as MonoBehaviour;
|
||||
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
if (temp != null)
|
||||
GameObject.DestroyImmediate(temp);
|
||||
else
|
||||
oldComp.name = oldName;
|
||||
}
|
||||
|
||||
// Make sure something changed.
|
||||
if (oldComp == comp) return;
|
||||
|
||||
// If a component is assigned, make sure it is the interface we are looking for.
|
||||
if (comp != null)
|
||||
{
|
||||
// Make sure component is of the right interface
|
||||
if (comp.GetType() != att.TypeOfInterface)
|
||||
// Component failed. Check game object.
|
||||
comp = comp.gameObject.GetComponent(att.TypeOfInterface) as MonoBehaviour;
|
||||
|
||||
// Item failed test. Do not override old component
|
||||
if (comp == null)
|
||||
{
|
||||
var previousColor = GUI.color;
|
||||
GUI.color = Color.red;
|
||||
EditorGUI.LabelField(position, label, new GUIContent("Assigned Property does not implement required interface!"));
|
||||
GUI.color = previousColor;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
property.objectReferenceValue = comp;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public class MonoInterface : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/InterfaceDrawer.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/InterfaceDrawer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6d3fafdb9a614dfe9e84a3f6e45f652
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/99.imdk_unity/Editor/PoseFilterEditor.cs
Normal file
68
Assets/99.imdk_unity/Editor/PoseFilterEditor.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(PoseFilter))]
|
||||
public class PoseFilterEditor : Editor
|
||||
{
|
||||
private SerializedProperty filterMethodProperty;
|
||||
private SerializedProperty historySizeProperty;
|
||||
private SerializedProperty useConfidenceProperty;
|
||||
private SerializedProperty confidenceMaxProperty;
|
||||
private SerializedProperty confidenceImpactProperty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
filterMethodProperty = serializedObject.FindProperty("m_FilterMethod");
|
||||
historySizeProperty = serializedObject.FindProperty("m_HistorySize");
|
||||
useConfidenceProperty = serializedObject.FindProperty("m_UseConfidence");
|
||||
confidenceMaxProperty = serializedObject.FindProperty("m_ConfidenceMax");
|
||||
confidenceImpactProperty = serializedObject.FindProperty("m_ConfidenceImpact");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
if (filterMethodProperty.enumValueIndex == (int)FilterMethod.Legacy)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Legacy filtering method is can cause issues with large maps and offsets. The simple filtering method is recommended instead.", MessageType.Warning);
|
||||
}
|
||||
else if (filterMethodProperty.enumValueIndex == (int)FilterMethod.Advanced)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Using advanced features and parameters can decrease the quality of filtering in some configurations. Some features are experimental. Extensive testing is advised.", MessageType.Info);
|
||||
}
|
||||
|
||||
// Method
|
||||
filterMethodProperty.enumValueIndex = EditorGUILayout.Popup("Filter method", filterMethodProperty.enumValueIndex, filterMethodProperty.enumNames);
|
||||
|
||||
if (filterMethodProperty.enumValueIndex == (int)FilterMethod.Advanced)
|
||||
{
|
||||
EditorGUILayout.PropertyField(historySizeProperty, new GUIContent("History size"));
|
||||
EditorGUILayout.PropertyField(useConfidenceProperty, new GUIContent("Apply confidence"));
|
||||
if (useConfidenceProperty.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(confidenceImpactProperty, new GUIContent("Confidence impact"));
|
||||
EditorGUILayout.PropertyField(confidenceMaxProperty, new GUIContent("Confidence max value"));
|
||||
}
|
||||
}
|
||||
|
||||
// Apply
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/PoseFilterEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/PoseFilterEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bd069f80548a47a69f5abff37f19afe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/99.imdk_unity/Editor/ReadOnlyDrawer.cs
Normal file
34
Assets/99.imdk_unity/Editor/ReadOnlyDrawer.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
|
||||
public class ReadOnlyDrawer : PropertyDrawer
|
||||
{
|
||||
public override float GetPropertyHeight(SerializedProperty property,
|
||||
GUIContent label)
|
||||
{
|
||||
return EditorGUI.GetPropertyHeight(property, label, true);
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position,
|
||||
SerializedProperty property,
|
||||
GUIContent label)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/ReadOnlyDrawer.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/ReadOnlyDrawer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3050b4a46d51a4a1c96ed495132603bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/99.imdk_unity/Editor/SampleAndroidManifest.xml
Normal file
18
Assets/99.imdk_unity/Editor/SampleAndroidManifest.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
|
||||
<application android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name" android:usesCleartextTraffic="true">
|
||||
<activity android:name="com.unity3d.player.UnityPlayerActivity"
|
||||
android:theme="@style/UnityThemeSelector"
|
||||
android:label="@string/app_name"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
</manifest>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b052e1bcf916a43a5a8e011d0276f7cb
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
81
Assets/99.imdk_unity/Editor/ServerLocalizationEditor.cs
Normal file
81
Assets/99.imdk_unity/Editor/ServerLocalizationEditor.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(ServerLocalization))]
|
||||
public class ServerLocalizationEditor : Editor
|
||||
{
|
||||
private SerializedProperty configurationMode;
|
||||
private SerializedProperty solverTypeProperty;
|
||||
|
||||
private SerializedProperty priorNNCountMinProperty;
|
||||
private SerializedProperty priorNNCountMaxProperty;
|
||||
private SerializedProperty priorScaleProperty;
|
||||
private SerializedProperty priorRadiusProperty;
|
||||
|
||||
private SerializedProperty onProgressEventProperty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
configurationMode = serializedObject.FindProperty("m_ConfigurationMode");
|
||||
solverTypeProperty = serializedObject.FindProperty("m_SolverType");
|
||||
|
||||
priorNNCountMinProperty = serializedObject.FindProperty("m_PriorNNCountMin");
|
||||
priorNNCountMaxProperty = serializedObject.FindProperty("m_PriorNNCountMax");
|
||||
priorScaleProperty = serializedObject.FindProperty("m_PriorScale");
|
||||
priorRadiusProperty = serializedObject.FindProperty("m_PriorRadius");
|
||||
|
||||
onProgressEventProperty = serializedObject.FindProperty("OnProgress");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// Configuration mode
|
||||
|
||||
EditorGUILayout.HelpBox(configurationMode.enumValueIndex == (int)ConfigurationMode.Always ? "This localization method will be active even if there are no maps configured to use it." : "This localization method will only be active if there are maps configured to use it.", MessageType.Info);
|
||||
|
||||
configurationMode.enumValueIndex = EditorGUILayout.Popup("Configuration mode", configurationMode.enumValueIndex, configurationMode.enumNames);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (solverTypeProperty.enumValueIndex is (int)SolverType.Prior or (int)SolverType.Lean)
|
||||
{
|
||||
EditorGUILayout.HelpBox("This Solver type is experimental. Extensive testing is advised.", MessageType.Warning);
|
||||
}
|
||||
|
||||
// SolverType
|
||||
solverTypeProperty.enumValueIndex = EditorGUILayout.Popup("Solver type", solverTypeProperty.enumValueIndex, solverTypeProperty.enumNames);
|
||||
|
||||
if (solverTypeProperty.enumValueIndex == (int)SolverType.Prior)
|
||||
{
|
||||
EditorGUILayout.PropertyField(priorNNCountMinProperty, new GUIContent("Nearest neighbour min"));
|
||||
EditorGUILayout.PropertyField(priorNNCountMaxProperty, new GUIContent("Nearest neighbour max"));
|
||||
EditorGUILayout.PropertyField(priorScaleProperty, new GUIContent("Scale"));
|
||||
EditorGUILayout.PropertyField(priorRadiusProperty, new GUIContent("Radius"));
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.PropertyField(onProgressEventProperty, new GUIContent("Upload progress"));
|
||||
|
||||
// Apply
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/ServerLocalizationEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/ServerLocalizationEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2f45c072c48b493a87a8158bee264f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
580
Assets/99.imdk_unity/Editor/XRMapEditor.cs
Normal file
580
Assets/99.imdk_unity/Editor/XRMapEditor.cs
Normal file
@@ -0,0 +1,580 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Networking;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.EditorCoroutines.Editor;
|
||||
using Immersal.REST;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(XRMap))]
|
||||
public class XRMapEditor : Editor
|
||||
{
|
||||
private ImmersalSDK sdk;
|
||||
private GameObject sceneParentObj;
|
||||
private ISceneUpdateable sceneParent;
|
||||
private int userEnteredMapId = -1;
|
||||
private bool[] downloadSelections = { true, false, false };
|
||||
|
||||
// Localization method requires some extra variables
|
||||
private static ILocalizationMethod[] availableMethods;
|
||||
private static string[] availableMethodNames;
|
||||
private int selectedTypeIndex; // Current selection
|
||||
|
||||
// Other properties
|
||||
private SerializedProperty mapFileProperty;
|
||||
private SerializedProperty mapIdProperty;
|
||||
private SerializedProperty mapNameProperty;
|
||||
private SerializedProperty privacyProperty;
|
||||
private SerializedProperty alignmentProperty;
|
||||
private SerializedProperty wgs84Property;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
XRMap map = (XRMap)target;
|
||||
mapFileProperty = serializedObject.FindProperty("mapFile");
|
||||
mapIdProperty = serializedObject.FindProperty("m_MapId");
|
||||
mapNameProperty = serializedObject.FindProperty("m_MapName");
|
||||
privacyProperty = serializedObject.FindProperty("privacy");
|
||||
alignmentProperty = serializedObject.FindProperty("mapAlignment");
|
||||
wgs84Property = serializedObject.FindProperty("wgs84");
|
||||
|
||||
// Localization method
|
||||
if (!CheckAvailableLocalizationMethods())
|
||||
{
|
||||
RefreshAvailableLocalizationMethods();
|
||||
}
|
||||
|
||||
// Check for null
|
||||
if (map.LocalizationMethod.IsNullOrDead())
|
||||
{
|
||||
ImmersalLogger.LogWarning($"Map {map.name} has invalid localization method, resetting to DeviceLocalization.");
|
||||
if (!TrySetLocalizationMethod(map, typeof(DeviceLocalization)))
|
||||
{
|
||||
ImmersalLogger.LogError($"Failed. Uninitializing map {map.name}");
|
||||
map.Uninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
// Get current index
|
||||
if (!map.LocalizationMethod.IsNullOrDead() && availableMethodNames != null)
|
||||
{
|
||||
selectedTypeIndex = Array.IndexOf(availableMethodNames, map.LocalizationMethod.GetType().Name);
|
||||
if (selectedTypeIndex == -1) selectedTypeIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckAvailableLocalizationMethods()
|
||||
{
|
||||
if (availableMethods == null || availableMethodNames == null)
|
||||
return false;
|
||||
|
||||
foreach (ILocalizationMethod localizationMethod in availableMethods)
|
||||
{
|
||||
if (localizationMethod.IsNullOrDead())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RefreshAvailableLocalizationMethods()
|
||||
{
|
||||
ILocalizationMethod[] methods = MapManager.AvailableLocalizationMethods;
|
||||
if (methods != null)
|
||||
{
|
||||
availableMethods = methods;
|
||||
availableMethodNames = availableMethods.Select(m => m.GetType().Name).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void ClearAvailableLocalizationMethodTypes()
|
||||
{
|
||||
availableMethods = null;
|
||||
availableMethodNames = null;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (BuildPipeline.isBuildingPlayer)
|
||||
return;
|
||||
|
||||
serializedObject.Update();
|
||||
XRMap obj = (XRMap)target;
|
||||
|
||||
// Configure styles
|
||||
GUIStyle centeredBoldLabel = new GUIStyle(EditorStyles.boldLabel);
|
||||
centeredBoldLabel.alignment = TextAnchor.MiddleCenter;
|
||||
GUIStyle bigLabel = new GUIStyle(EditorStyles.boldLabel);
|
||||
bigLabel.fontSize = 16;
|
||||
|
||||
// The Custom Editor has two states
|
||||
|
||||
// Map is configured
|
||||
if (obj.IsConfigured)
|
||||
{
|
||||
Color oldColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(0.5f, 1f, 0.6f);
|
||||
EditorGUILayout.HelpBox("Map configured!", MessageType.Info);
|
||||
GUI.backgroundColor = oldColor;
|
||||
|
||||
// Reconfigure
|
||||
if (GUILayout.Button("Reconfigure map"))
|
||||
{
|
||||
obj.Uninitialize();
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Localization method
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
if (availableMethods != null && availableMethodNames.Length > 0)
|
||||
{
|
||||
selectedTypeIndex =
|
||||
EditorGUILayout.Popup("Localization method", selectedTypeIndex, availableMethodNames);
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
TrySetLocalizationMethod(obj, availableMethods[selectedTypeIndex]);
|
||||
}
|
||||
|
||||
// Map options
|
||||
MapOptionsSection(obj);
|
||||
|
||||
// Metadata
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Map Metadata", EditorStyles.boldLabel);
|
||||
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.PropertyField(mapIdProperty);
|
||||
EditorGUILayout.PropertyField(mapNameProperty);
|
||||
EditorGUILayout.PropertyField(privacyProperty);
|
||||
EditorGUILayout.PropertyField(wgs84Property);
|
||||
EditorGUILayout.PropertyField(alignmentProperty);
|
||||
GUI.enabled = true;
|
||||
|
||||
// Map Alignment controls
|
||||
EditorGUILayout.HelpBox("Alignment metadata stored in right-handed coordinate system. Captured (default) alignment is in ECEF coordinates", MessageType.Info);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button(new GUIContent("Load Alignment", "Loads alignment from map metadata. Coordinate system is unknown (ECEF or Unity's)")))
|
||||
{
|
||||
EditorCoroutineUtility.StartCoroutine(MapAlignmentLoad(), this);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Save Alignment", "Saves current (local transform) alignment to map metadata")))
|
||||
{
|
||||
EditorCoroutineUtility.StartCoroutine(MapAlignmentSave(), this);
|
||||
}
|
||||
|
||||
oldColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(1f, 0.5f, 0.6f);
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Reset Alignment", "Fetches the original captured alignment metadata in ECEF coordinates")))
|
||||
{
|
||||
EditorCoroutineUtility.StartCoroutine(MapAlignmentReset(), this);
|
||||
}
|
||||
|
||||
GUI.backgroundColor = oldColor;
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// Visualization
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Visualization", EditorStyles.boldLabel);
|
||||
|
||||
if (obj.Visualization != null)
|
||||
{
|
||||
if (GUILayout.Button("Select visualization"))
|
||||
{
|
||||
Selection.SetActiveObjectWithContext(obj.Visualization.gameObject, null);
|
||||
}
|
||||
if (GUILayout.Button("Remove visualization"))
|
||||
{
|
||||
obj.RemoveVisualization();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("Add visualization"))
|
||||
{
|
||||
obj.CreateVisualization();
|
||||
Selection.SetActiveObjectWithContext(obj.Visualization.gameObject, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map unconfigured
|
||||
else
|
||||
{
|
||||
// Check that a parent implements ISceneUpdateable
|
||||
ISceneUpdateable sceneUpdateable = obj.transform.GetComponentInParent<ISceneUpdateable>(true);
|
||||
|
||||
if (sceneUpdateable != null)
|
||||
{
|
||||
// Configuration instructions and options
|
||||
|
||||
Color oldColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(1f, 0.5f, 0.6f);
|
||||
EditorGUILayout.HelpBox("Map has not been configured! Add or download map data below.", MessageType.Warning);
|
||||
GUI.backgroundColor = oldColor;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Local map file", bigLabel);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Drag and drop your map file (.bytes) here or use the selector to find one.", EditorStyles.wordWrappedLabel);
|
||||
|
||||
// Mapfile option
|
||||
|
||||
EditorGUILayout.PropertyField(mapFileProperty);
|
||||
|
||||
//currentMapFile = obj.mapFile;
|
||||
TextAsset mapFile = mapFileProperty.objectReferenceValue as TextAsset;
|
||||
if (mapFile != null)
|
||||
{
|
||||
string bytesPath = AssetDatabase.GetAssetPath(mapFile);
|
||||
if (bytesPath.EndsWith(".bytes"))
|
||||
{
|
||||
if (TrySetLocalizationMethod(obj, typeof(DeviceLocalization)))
|
||||
{
|
||||
obj.Configure(mapFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImmersalLogger.Log($"{AssetDatabase.GetAssetPath(mapFile)} is not a valid map file");
|
||||
obj.mapFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Download options
|
||||
|
||||
EditorGUILayout.Space(12f);
|
||||
EditorGUILayout.LabelField("OR", centeredBoldLabel, GUILayout.ExpandWidth(true));
|
||||
EditorGUILayout.Space(12f);
|
||||
EditorGUILayout.LabelField("Download from cloud", bigLabel);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Input your map id and select which data to download. You can configure the save path in the ImmersalSDK configuration.", EditorStyles.wordWrappedLabel);
|
||||
|
||||
userEnteredMapId = EditorGUILayout.IntField("Map id: ", userEnteredMapId);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Section for selecting data types to download
|
||||
DownloadSelectionSection();
|
||||
|
||||
// Download
|
||||
|
||||
if (GUILayout.Button("Download"))
|
||||
{
|
||||
// metadata is always downloaded
|
||||
EditorCoroutineUtility.StartCoroutine(
|
||||
MapManager.DownloadMapMetadata(userEnteredMapId, metadata =>
|
||||
{
|
||||
// apply meta
|
||||
obj.SetMetadata(metadata, true);
|
||||
|
||||
// mapfile
|
||||
if (downloadSelections[1])
|
||||
{
|
||||
EditorCoroutineUtility.StartCoroutine(MapManager.DownloadMapFile(
|
||||
obj.mapId, obj.mapName, (result, mapFileAsset) =>
|
||||
{
|
||||
if (TrySetLocalizationMethod(obj, typeof(DeviceLocalization)))
|
||||
{
|
||||
// apply map file and process
|
||||
obj.Configure(mapFileAsset);
|
||||
}
|
||||
}), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TrySetLocalizationMethod(obj, typeof(ServerLocalization)))
|
||||
{
|
||||
obj.Configure();
|
||||
}
|
||||
}
|
||||
|
||||
// vis
|
||||
if (downloadSelections[2])
|
||||
{
|
||||
EditorCoroutineUtility.StartCoroutine(MapManager.DownloadSparseFile(
|
||||
obj.mapId, obj.mapName, (result, path) =>
|
||||
{
|
||||
// apply bytes and process
|
||||
obj.CreateVisualization();
|
||||
obj.Visualization.LoadPly(path);
|
||||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||||
|
||||
}), this);
|
||||
}
|
||||
}), this);
|
||||
}
|
||||
}
|
||||
// Invalid parent
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("Scene parent does not implement ISceneUpdateable.", MessageType.Error, true);
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private bool TrySetLocalizationMethod(XRMap map, Type localizationMethodType)
|
||||
{
|
||||
ILocalizationMethod method = availableMethods.FirstOrDefault(m => m.GetType() == localizationMethodType);
|
||||
return TrySetLocalizationMethod(map, method);
|
||||
}
|
||||
|
||||
private bool TrySetLocalizationMethod(XRMap map, ILocalizationMethod localizationMethod)
|
||||
{
|
||||
if (localizationMethod.IsNullOrDead())
|
||||
{
|
||||
ImmersalLogger.LogError("Invalid localization method assignment.");
|
||||
MapManager.RefreshLocalizationMethods();
|
||||
RefreshAvailableLocalizationMethods();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure index is also updated when call is not originating from direct index change
|
||||
selectedTypeIndex = Array.IndexOf(availableMethodNames, localizationMethod.GetType().Name);
|
||||
if (selectedTypeIndex == -1) selectedTypeIndex = 0;
|
||||
|
||||
//map.LocalizationMethodType = localizationMethodType;
|
||||
map.LocalizationMethod = localizationMethod;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
map.UpdateMapOptions();
|
||||
EditorUtility.SetDirty(map);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Render map configurations
|
||||
private void MapOptionsSection(XRMap map)
|
||||
{
|
||||
if (map.MapOptions == null)
|
||||
return;
|
||||
|
||||
if (map.MapOptions.Count == 0)
|
||||
return;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField($"{availableMethodNames[selectedTypeIndex]} options", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
foreach (IMapOption configuration in map.MapOptions)
|
||||
{
|
||||
configuration.DrawEditorGUI(map);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
map.SerializeMapOptions();
|
||||
EditorUtility.SetDirty(map);
|
||||
}
|
||||
}
|
||||
|
||||
// Render download options
|
||||
private void DownloadSelectionSection()
|
||||
{
|
||||
string[] labels = { "Metadata", "Mapfile", "Visualization" };
|
||||
string[] minis = {
|
||||
"The map metadata contains information about the map alignment, privacy, etc. It is the minimum requirement for configuring maps.",
|
||||
"The map file is a binary representation of the map. This is required for embedding maps for offline use.",
|
||||
"This is the sparse point cloud of the map that can be used to visualize the map."
|
||||
};
|
||||
bool[] enabled = { false, true, true };
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
// Left column
|
||||
GUILayout.BeginVertical();
|
||||
for (int i = 0; i < labels.Length; i++)
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Label(labels[i]);
|
||||
GUILayout.Label(minis[i], EditorStyles.wordWrappedMiniLabel);
|
||||
GUILayout.EndVertical();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
// Right column
|
||||
GUILayout.BeginVertical();
|
||||
for (int i = 0; i < downloadSelections.Length; i++)
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUI.enabled = enabled[i];
|
||||
downloadSelections[i] = EditorGUILayout.Toggle(downloadSelections[i]); //, GUILayout.ExpandWidth(true));
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
GUI.enabled = true;
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#region Alignment methods
|
||||
|
||||
private IEnumerator MapAlignmentLoad()
|
||||
{
|
||||
//
|
||||
// Loads map metadata, updates XR Map metadata info, extracts the alignment, converts it to Unity's coordinate system and sets the map transform
|
||||
//
|
||||
|
||||
XRMap obj = (XRMap)target;
|
||||
sdk = ImmersalSDK.Instance;
|
||||
|
||||
// Check if metadata file exists already
|
||||
string destinationFolder = MapManager.GetDirectoryPath();
|
||||
string existingFilePath = Path.Combine(destinationFolder, $"{obj.mapId}-{obj.mapName}-metadata.json");
|
||||
if (File.Exists(existingFilePath))
|
||||
{
|
||||
XRMap.MetadataFile metadataFile = JsonUtility.FromJson<XRMap.MetadataFile>(File.ReadAllText(existingFilePath));
|
||||
obj.SetMetadata(metadataFile, true);
|
||||
obj.ApplyAlignment();
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Download
|
||||
EditorCoroutineUtility.StartCoroutine(MapManager.DownloadMapMetadata(obj.mapId, result =>
|
||||
{
|
||||
obj.SetMetadata(result, false);
|
||||
obj.ApplyAlignment();
|
||||
}), this);
|
||||
}
|
||||
|
||||
private IEnumerator MapAlignmentSave()
|
||||
{
|
||||
//
|
||||
// Updates map metadata to the Cloud Service and reloads to keep local files in sync
|
||||
//
|
||||
|
||||
XRMap obj = (XRMap)target;
|
||||
sdk = ImmersalSDK.Instance;
|
||||
|
||||
Vector3 pos = obj.transform.localPosition;
|
||||
Quaternion rot = obj.transform.localRotation;
|
||||
float scl = (obj.transform.localScale.x + obj.transform.localScale.y + obj.transform.localScale.z) / 3f; // Only uniform scale metadata is supported
|
||||
|
||||
// IMPORTANT
|
||||
// Switching coordinate system handedness from Unity's left-handed system to Immersal Cloud Service's default right-handed system
|
||||
Matrix4x4 b = Matrix4x4.TRS(pos, rot, obj.transform.localScale);
|
||||
Matrix4x4 a = b.SwitchHandedness();
|
||||
pos = a.GetColumn(3);
|
||||
rot = a.rotation;
|
||||
|
||||
// Update map alignment metadata to Immersal Cloud Service
|
||||
SDKMapAlignmentSetRequest r = new SDKMapAlignmentSetRequest();
|
||||
r.token = sdk.developerToken;
|
||||
r.id = obj.mapId;
|
||||
r.tx = pos.x;
|
||||
r.ty = pos.y;
|
||||
r.tz = pos.z;
|
||||
r.qx = rot.x;
|
||||
r.qy = rot.y;
|
||||
r.qz = rot.z;
|
||||
r.qw = rot.w;
|
||||
r.scale = scl;
|
||||
|
||||
string jsonString = JsonUtility.ToJson(r);
|
||||
UnityWebRequest request = UnityWebRequest.Put(string.Format(ImmersalHttp.URL_FORMAT, ImmersalSDK.Instance.localizationServer, SDKMapAlignmentSetRequest.endpoint), jsonString);
|
||||
request.method = UnityWebRequest.kHttpVerbPOST;
|
||||
request.useHttpContinue = false;
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
request.SetRequestHeader("Accept", "application/json");
|
||||
request.SendWebRequest();
|
||||
|
||||
while (!request.isDone)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (request.isNetworkError || request.isHttpError)
|
||||
#endif
|
||||
{
|
||||
ImmersalLogger.LogError($"Failed to save alignment for map id {obj.mapId}\n{request.error}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SDKMapAlignmentSetResult result = JsonUtility.FromJson<SDKMapAlignmentSetResult>(request.downloadHandler.text);
|
||||
if (result.error == "none")
|
||||
{
|
||||
// Reload the metadata from Immersal Cloud Service to keep local files in sync
|
||||
EditorCoroutineUtility.StartCoroutine(MapAlignmentLoad(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator MapAlignmentReset()
|
||||
{
|
||||
//
|
||||
// Reset map alignment to the original captured data and reload metadata from the Immersal Cloud Service to keep local files in sync
|
||||
//
|
||||
|
||||
XRMap obj = (XRMap)target;
|
||||
sdk = ImmersalSDK.Instance;
|
||||
|
||||
// Reset alignment on Immersal Cloud Service
|
||||
SDKMapAlignmentResetRequest r = new SDKMapAlignmentResetRequest();
|
||||
r.token = sdk.developerToken;
|
||||
r.id = obj.mapId;
|
||||
|
||||
string jsonString = JsonUtility.ToJson(r);
|
||||
UnityWebRequest request = UnityWebRequest.Put(string.Format(ImmersalHttp.URL_FORMAT, ImmersalSDK.Instance.localizationServer, SDKMapAlignmentResetRequest.endpoint), jsonString);
|
||||
request.method = UnityWebRequest.kHttpVerbPOST;
|
||||
request.useHttpContinue = false;
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
request.SetRequestHeader("Accept", "application/json");
|
||||
request.SendWebRequest();
|
||||
|
||||
while (!request.isDone)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (request.isNetworkError || request.isHttpError)
|
||||
#endif
|
||||
{
|
||||
ImmersalLogger.LogError($"Failed to reset alignment for map id {obj.mapId}\n{request.error}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SDKMapAlignmentResetResult result = JsonUtility.FromJson<SDKMapAlignmentResetResult>(request.downloadHandler.text);
|
||||
if (result.error == "none")
|
||||
{
|
||||
// Reload the metadata from Immersal Cloud Service to keep local files in sync
|
||||
EditorCoroutineUtility.StartCoroutine(MapAlignmentLoad(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion'
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/XRMapEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/XRMapEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b38c61e43b9434129bf029ea93c69cea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
116
Assets/99.imdk_unity/Editor/XRMapVisualizationEditor.cs
Normal file
116
Assets/99.imdk_unity/Editor/XRMapVisualizationEditor.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sdk@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.IO;
|
||||
using Unity.EditorCoroutines.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(XRMapVisualization))]
|
||||
public class XRMapVisualizationEditor : Editor
|
||||
{
|
||||
// visualization
|
||||
private SerializedProperty renderModeProperty;
|
||||
private SerializedProperty pointColorProperty;
|
||||
|
||||
private static float pointSizeSliderValue = 0.33f;
|
||||
private static bool renderAs3dPointsToggle = true;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
pointSizeSliderValue = EditorPrefs.GetFloat("pointSizeSliderValue", pointSizeSliderValue);
|
||||
renderAs3dPointsToggle = EditorPrefs.GetBool("pointSizeSliderValue", renderAs3dPointsToggle);
|
||||
renderModeProperty = serializedObject.FindProperty("renderMode");
|
||||
pointColorProperty = serializedObject.FindProperty("m_PointColor");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (BuildPipeline.isBuildingPlayer)
|
||||
return;
|
||||
|
||||
XRMapVisualization obj = (XRMapVisualization)target;
|
||||
|
||||
obj.UpdateMaterial();
|
||||
|
||||
if (obj.IsVisualized)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
if (GUILayout.Button("Reset visualization"))
|
||||
{
|
||||
obj.ClearVisualization();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(renderModeProperty);
|
||||
EditorGUILayout.PropertyField(pointColorProperty);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
pointSizeSliderValue = EditorGUILayout.Slider("Point Size", pointSizeSliderValue, 0f, 1f);
|
||||
renderAs3dPointsToggle = EditorGUILayout.Toggle("Render as 3D Points", renderAs3dPointsToggle);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
XRMapVisualization.pointSize = pointSizeSliderValue;
|
||||
XRMapVisualization.renderAs3dPoints = renderAs3dPointsToggle;
|
||||
|
||||
EditorPrefs.SetFloat("pointSizeSliderValue", pointSizeSliderValue);
|
||||
EditorPrefs.SetBool("pointSizeSliderValue", renderAs3dPointsToggle);
|
||||
|
||||
obj.UpdateMaterial();
|
||||
|
||||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("To visualize the ARMap in the Editor, load either the sparse or dense PLY file.", MessageType.Warning);
|
||||
|
||||
// Ply loading
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
if (GUILayout.Button("Load local sparse ply file"))
|
||||
{
|
||||
PickAndLoadPly(obj);
|
||||
}
|
||||
if (GUILayout.Button("Download sparse ply file"))
|
||||
{
|
||||
EditorCoroutineUtility.StartCoroutine(MapManager.DownloadSparseFile(
|
||||
obj.Map.mapId, obj.Map.mapName,
|
||||
(result, path) =>
|
||||
{
|
||||
// apply bytes and process
|
||||
obj.LoadPly(path);
|
||||
|
||||
}), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void PickAndLoadPly(XRMapVisualization obj)
|
||||
{
|
||||
string path = EditorUtility.OpenFilePanel("Select Ply", "", "ply");
|
||||
|
||||
if (path.Length != 0)
|
||||
{
|
||||
obj.LoadPly(path);
|
||||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/XRMapVisualizationEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/XRMapVisualizationEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6462ada5e0cb43e1a7572ad1fc02ccb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Assets/99.imdk_unity/Editor/XRSpaceEditor.cs
Normal file
32
Assets/99.imdk_unity/Editor/XRSpaceEditor.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
[CustomEditor(typeof(XRSpace))]
|
||||
public class XRSpaceEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Place XR Maps and all content under this object.\n(you can also use a custom implementation of ISceneParent)", MessageType.Info);
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("DataProcessors added at runtime are not serialized and thus do not show up in the inspector.", MessageType.Warning);
|
||||
}
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Editor/XRSpaceEditor.cs.meta
Normal file
11
Assets/99.imdk_unity/Editor/XRSpaceEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4db60c4a514e4af982813880c0ddae7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime.meta
Normal file
8
Assets/99.imdk_unity/Runtime.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 666ab8dba47f544338191598ba6454f2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/99.imdk_unity/Runtime/Immersal.Core.asmdef
Normal file
18
Assets/99.imdk_unity/Runtime/Immersal.Core.asmdef
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Immersal.Core",
|
||||
"references": [
|
||||
"Unity.XR.ARFoundation",
|
||||
"Unity.XR.ARSubsystems",
|
||||
"Unity.XR.CoreUtils",
|
||||
"Unity.TextMeshPro"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/99.imdk_unity/Runtime/Immersal.Core.asmdef.meta
Normal file
7
Assets/99.imdk_unity/Runtime/Immersal.Core.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e7d06324bb40437f864b52eb770c3c5
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebb9a2aa61c1c4adfa46fdb884506587
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins/Android.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins/Android.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbddf664aa7a14ace8ba3d4ed402b232
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/99.imdk_unity/Runtime/Plugins/Android/nativebindings.aar
Normal file
BIN
Assets/99.imdk_unity/Runtime/Plugins/Android/nativebindings.aar
Normal file
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0cb792fbfeed43ac9c56884627eaa0d
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/99.imdk_unity/Runtime/Plugins/Android/poseplugin.aar
Normal file
BIN
Assets/99.imdk_unity/Runtime/Plugins/Android/poseplugin.aar
Normal file
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ff5eb1b694e9493c81a4e7cefc3fa40
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins/Android/x86_64.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins/Android/x86_64.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e8a5e52ef86f4c60981bff8a85d6016
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75b23102b03aa4e37862216603fe6cca
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 1
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 0
|
||||
Exclude Editor: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: X86_64
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
129
Assets/99.imdk_unity/Runtime/Plugins/NativeBindings.cs
Normal file
129
Assets/99.imdk_unity/Runtime/Plugins/NativeBindings.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
#if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
public class NativeBindings
|
||||
{
|
||||
#if UNITY_IOS
|
||||
[DllImport("__Internal")]
|
||||
public static extern void startLocation();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void stopLocation();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern double getLatitude();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern double getLongitude();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern double getAltitude();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern double getHorizontalAccuracy();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern double getVerticalAccuracy();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern bool locationServicesEnabled();
|
||||
|
||||
#elif PLATFORM_ANDROID
|
||||
static AndroidJavaClass obj = new AndroidJavaClass("com.immersal.nativebindings.Main");
|
||||
#endif
|
||||
|
||||
public static bool StartLocation()
|
||||
{
|
||||
if (!Input.location.isEnabledByUser)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UNITY_IOS
|
||||
startLocation();
|
||||
#elif PLATFORM_ANDROID
|
||||
obj.CallStatic("startLocation");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void StopLocation()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
stopLocation();
|
||||
#elif PLATFORM_ANDROID
|
||||
obj.CallStatic("stopLocation");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static double GetLatitude()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return getLatitude();
|
||||
#elif PLATFORM_ANDROID
|
||||
return obj.CallStatic<double>("getLatitude");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static double GetLongitude()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return getLongitude();
|
||||
#elif PLATFORM_ANDROID
|
||||
return obj.CallStatic<double>("getLongitude");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static double GetAltitude()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return getAltitude();
|
||||
#elif PLATFORM_ANDROID
|
||||
return obj.CallStatic<double>("getAltitude");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static double GetHorizontalAccuracy()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return getHorizontalAccuracy();
|
||||
#elif PLATFORM_ANDROID
|
||||
return obj.CallStatic<double>("getHorizontalAccuracy");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static double GetVerticalAccuracy()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return getVerticalAccuracy();
|
||||
#elif PLATFORM_ANDROID
|
||||
return obj.CallStatic<double>("getVerticalAccuracy");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool LocationServicesEnabled()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return locationServicesEnabled();
|
||||
#elif PLATFORM_ANDROID
|
||||
return obj.CallStatic<bool>("locationServicesEnabled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/99.imdk_unity/Runtime/Plugins/NativeBindings.cs.meta
Normal file
11
Assets/99.imdk_unity/Runtime/Plugins/NativeBindings.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d5ebb2a7d1c34821bfc011129e06e21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins/WSA.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins/WSA.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 315d898c8a9b741e2abf8ebf066826e5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins/WSA/ARM64.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins/WSA/ARM64.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a372d43f1ea534be097e7631d0b49a2c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/99.imdk_unity/Runtime/Plugins/WSA/ARM64/PosePlugin.dll
Normal file
BIN
Assets/99.imdk_unity/Runtime/Plugins/WSA/ARM64/PosePlugin.dll
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 304d68efbb95e42698724e8c83b2d707
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 1
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d110880cd997a4cd0aca0eabf4284cde
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins/iOS.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins/iOS.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e61930de07ae54862bde5a3e16380735
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/99.imdk_unity/Runtime/Plugins/iOS/NativeLocation.h
Normal file
18
Assets/99.imdk_unity/Runtime/Plugins/iOS/NativeLocation.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// NativeLocation.h
|
||||
// Immersal SDK
|
||||
//
|
||||
// Created by Mikko on 29/05/2020.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface NativeLocation : NSObject <CLLocationManagerDelegate>
|
||||
|
||||
- (NativeLocation *)init;
|
||||
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3047a557b77d947608c98b823c7d4d5b
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
132
Assets/99.imdk_unity/Runtime/Plugins/iOS/NativeLocation.mm
Normal file
132
Assets/99.imdk_unity/Runtime/Plugins/iOS/NativeLocation.mm
Normal file
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// NativeLocation.m
|
||||
// Immersal SDK
|
||||
//
|
||||
// Created by Mikko on 29/05/2020.
|
||||
//
|
||||
//
|
||||
|
||||
#import "NativeLocation.h"
|
||||
|
||||
double latitude;
|
||||
double longitude;
|
||||
double altitude;
|
||||
double haccuracy;
|
||||
double vaccuracy;
|
||||
|
||||
@implementation NativeLocation
|
||||
|
||||
CLLocationManager *locationManager;
|
||||
static bool isEnabled = NO;
|
||||
|
||||
- (NativeLocation *)init
|
||||
{
|
||||
locationManager = [[CLLocationManager alloc] init];
|
||||
locationManager.delegate = self;
|
||||
locationManager.distanceFilter = kCLDistanceFilterNone;
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
|
||||
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
|
||||
[locationManager requestWhenInUseAuthorization];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
|
||||
{
|
||||
/* switch (status) {
|
||||
case kCLAuthorizationStatusAuthorizedWhenInUse:
|
||||
case kCLAuthorizationStatusAuthorizedAlways:
|
||||
isEnabled = YES; break;
|
||||
default:
|
||||
isEnabled = NO; break;
|
||||
}*/
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error;
|
||||
{
|
||||
isEnabled = NO;
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
|
||||
{
|
||||
CLLocation *location = [locations lastObject];
|
||||
latitude = location.coordinate.latitude;
|
||||
longitude = location.coordinate.longitude;
|
||||
altitude = location.altitude;
|
||||
haccuracy = location.horizontalAccuracy;
|
||||
vaccuracy = location.verticalAccuracy;
|
||||
|
||||
isEnabled = YES;
|
||||
|
||||
//NSLog(@"lat: %f long: %f alt: %f", latitude, longitude, altitude);
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
if (locationManager != NULL) {
|
||||
[locationManager startUpdatingLocation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stop
|
||||
{
|
||||
if (locationManager != NULL) {
|
||||
[locationManager stopUpdatingLocation];
|
||||
}
|
||||
|
||||
isEnabled = NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static NativeLocation* locationDelegate = NULL;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void startLocation()
|
||||
{
|
||||
if (locationDelegate == NULL) {
|
||||
locationDelegate = [[NativeLocation alloc] init];
|
||||
}
|
||||
|
||||
[locationDelegate start];
|
||||
}
|
||||
|
||||
void stopLocation()
|
||||
{
|
||||
if (locationDelegate != NULL) {
|
||||
[locationDelegate stop];
|
||||
}
|
||||
}
|
||||
|
||||
double getLatitude()
|
||||
{
|
||||
return latitude;
|
||||
}
|
||||
|
||||
double getLongitude()
|
||||
{
|
||||
return longitude;
|
||||
}
|
||||
|
||||
double getAltitude()
|
||||
{
|
||||
return altitude;
|
||||
}
|
||||
|
||||
double getHorizontalAccuracy()
|
||||
{
|
||||
return haccuracy;
|
||||
}
|
||||
|
||||
double getVerticalAccuracy()
|
||||
{
|
||||
return vaccuracy;
|
||||
}
|
||||
|
||||
bool locationServicesEnabled()
|
||||
{
|
||||
return isEnabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d437760fb73c64fbea6c103e65c7b46a
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/99.imdk_unity/Runtime/Plugins/iOS/libPosePlugin.a
Normal file
BIN
Assets/99.imdk_unity/Runtime/Plugins/iOS/libPosePlugin.a
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e5497290e47344189a08bc45a2d4ec6
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies: Security;
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Plugins/x86_64.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Plugins/x86_64.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c47c562ad1e504ce5bbc75ec607a6979
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f2fc1147aedf422eb4fc088c5bb4290
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 1
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 0
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: OSX
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>23D56</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>PosePlugin</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.immersal.PosePlugin</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>PosePlugin</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string></string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>macosx</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>14.2</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>23C53</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx14.2</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1520</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>15C500b</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2022 Immersal - Part of Hexagon. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict/>
|
||||
<key>files2</key>
|
||||
<dict/>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^Resources/</key>
|
||||
<true/>
|
||||
<key>^Resources/.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Resources/Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^Resources/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Resources/Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^[^/]+$</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Assets/99.imdk_unity/Runtime/Plugins/x86_64/PosePlugin.dll
Normal file
BIN
Assets/99.imdk_unity/Runtime/Plugins/x86_64/PosePlugin.dll
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf35b419ea46d43e291ce52433f69fab
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 1
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 0
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
DefaultValueInitialized: true
|
||||
OS: Windows
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/99.imdk_unity/Runtime/Plugins/x86_64/opencv_world453.dll
Normal file
BIN
Assets/99.imdk_unity/Runtime/Plugins/x86_64/opencv_world453.dll
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c97dcf0869d9843e3b51c44c38f6c532
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 0
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AndroidSharedLibraryType: Executable
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
DefaultValueInitialized: true
|
||||
OS: Windows
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Resources.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Resources.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73c6a3909744c47c1a172adf16bfb53e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Resources/Prefabs.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Resources/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2aad495dd66e94cf0b2f8e6aa0e76ad2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,440 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &1434895627878410
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4682760393691964}
|
||||
- component: {fileID: 4876485604010972054}
|
||||
m_Layer: 0
|
||||
m_Name: ImmersalSDK
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4682760393691964
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1434895627878410}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 4358890709939687853}
|
||||
- {fileID: 5728853109968807875}
|
||||
- {fileID: 542854591214680858}
|
||||
- {fileID: 3561577978855217239}
|
||||
- {fileID: 8846418124030723115}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &4876485604010972054
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1434895627878410}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 22271c1298ba444ffacf4138cd9ef2eb, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
defaultServer: 0
|
||||
developerToken:
|
||||
m_Session: {fileID: 4858077625584781203}
|
||||
m_Platform: {fileID: 6469108069241648846}
|
||||
m_Localizer: {fileID: 4174534150879381888}
|
||||
m_SceneUpdater: {fileID: 2545414792828475238}
|
||||
m_TrackingAnalyzer: {fileID: 6509155160601367522}
|
||||
m_TargetFrameRate: 60
|
||||
m_Downsample: 1
|
||||
m_LoggingLevel: 2
|
||||
m_DownloadDirectory: Map Data
|
||||
OnInitializationComplete:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnReset:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &1624132911465332519
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3561577978855217239}
|
||||
- component: {fileID: 2545414792828475238}
|
||||
m_Layer: 0
|
||||
m_Name: SceneUpdater
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3561577978855217239
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1624132911465332519}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4682760393691964}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2545414792828475238
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1624132911465332519}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 10b6f3f5d6c78474d867465b74b8a539, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &4025295615373336692
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6323821621449692113}
|
||||
- component: {fileID: 3150119538342652997}
|
||||
m_Layer: 0
|
||||
m_Name: DeviceLocalization
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6323821621449692113
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4025295615373336692}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 542854591214680858}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &3150119538342652997
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4025295615373336692}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d8be42d7c34a64923aa637c8abcaeb7d, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_ConfigurationMode: 1
|
||||
m_SolverType: 0
|
||||
--- !u!1 &4483478919481266077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5728853109968807875}
|
||||
- component: {fileID: 6469108069241648846}
|
||||
m_Layer: 0
|
||||
m_Name: ARFoundationSupport
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &5728853109968807875
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4483478919481266077}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4682760393691964}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &6469108069241648846
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4483478919481266077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ff1599bedf7cb4f2bb03770be4930ce8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_MaxConfigurationAttempts: 10
|
||||
m_MsBetweenConfigurationAttempts: 100
|
||||
m_AndroidResolution: 2
|
||||
m_iOSResolution: 0
|
||||
--- !u!1 &5513217393547005349
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8846418124030723115}
|
||||
- component: {fileID: 6509155160601367522}
|
||||
m_Layer: 0
|
||||
m_Name: TrackingAnalyzer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8846418124030723115
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5513217393547005349}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4682760393691964}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &6509155160601367522
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5513217393547005349}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d3670ede57ef84f68845b3bb411d4a87, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_SecondsToDecayPose: 2
|
||||
m_SeparateLocalizationResults: 0
|
||||
OnPlatformTrackingLost:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 4876485604010972054}
|
||||
m_TargetAssemblyTypeName: Immersal.ImmersalSDK, Immersal.Core
|
||||
m_MethodName: TriggerSoftReset
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
OnTrackingWell:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnTrackingLost:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &6218135140821756341
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4358890709939687853}
|
||||
- component: {fileID: 4858077625584781203}
|
||||
m_Layer: 0
|
||||
m_Name: ImmersalSession
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4358890709939687853
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6218135140821756341}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4682760393691964}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &4858077625584781203
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6218135140821756341}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1998a90ed503d46ffa5a88d3c7505c28, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_AutoStart: 1
|
||||
m_UpdateContinuously: 1
|
||||
m_SessionUpdateInterval: 2
|
||||
m_BurstMode: 1
|
||||
m_ResetOnPause: 0
|
||||
m_ProcessData: 0
|
||||
m_SessionDataProcessors: []
|
||||
OnPause:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnResume:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnReset:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &8087551170109127229
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1533780097516228215}
|
||||
- component: {fileID: 4803580791226008317}
|
||||
m_Layer: 0
|
||||
m_Name: ServerLocalization
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1533780097516228215
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8087551170109127229}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 542854591214680858}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &4803580791226008317
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8087551170109127229}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 82ac8f41066bd43cca7a925e70116602, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_ConfigurationMode: 0
|
||||
m_SolverType: 0
|
||||
--- !u!1 &9015867826600335194
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 542854591214680858}
|
||||
- component: {fileID: 4174534150879381888}
|
||||
m_Layer: 0
|
||||
m_Name: Localizer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &542854591214680858
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 9015867826600335194}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 6323821621449692113}
|
||||
- {fileID: 1533780097516228215}
|
||||
m_Father: {fileID: 4682760393691964}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &4174534150879381888
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 9015867826600335194}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0113bf92df9fa4e24bd92cedc0f00ec6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_LocalizationMethodObjects:
|
||||
- {fileID: 3150119538342652997}
|
||||
- {fileID: 4803580791226008317}
|
||||
OnFirstSuccessfulLocalization:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnSuccessfulLocalizations:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnLocalizationResult:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
OnFailedLocalizations:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c6deb7afc7d34561941b1429c48ffaf
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Resources/Shaders.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Resources/Shaders.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18ff1b8c4a5924d558858261f7c27693
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
Shader "Immersal/Point Cloud"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Cull Off
|
||||
Tags{ "RenderType" = "Opaque" }
|
||||
LOD 100
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
float _PointSize;
|
||||
fixed _PerspectiveEnabled;
|
||||
fixed4 _PointColor;
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
float3 vertex : POSITION;
|
||||
};
|
||||
|
||||
struct VertexOut
|
||||
{
|
||||
float psize : PSIZE;
|
||||
float4 center : TEXCOORD0;
|
||||
half size : TEXCOORD1;
|
||||
UNITY_FOG_COORDS(0)
|
||||
};
|
||||
|
||||
VertexOut vert(Vertex vertex, out float4 outpos : SV_POSITION)
|
||||
{
|
||||
VertexOut o;
|
||||
outpos = UnityObjectToClipPos(vertex.vertex);
|
||||
|
||||
o.psize = lerp(_PointSize, _PointSize / outpos.w * _ScreenParams.y, step(0.5, _PerspectiveEnabled));
|
||||
o.size = o.psize;
|
||||
|
||||
o.center = ComputeScreenPos(outpos);
|
||||
UNITY_TRANSFER_FOG(o, o.position);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(VertexOut i, UNITY_VPOS_TYPE vpos : VPOS) : SV_Target
|
||||
{
|
||||
fixed4 c = _PointColor;
|
||||
float4 center = i.center;
|
||||
center.xy /= center.w;
|
||||
center.xy *= _ScreenParams.xy;
|
||||
float d = distance(vpos.xy, center.xy);
|
||||
|
||||
if (d > i.size * 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
UNITY_APPLY_FOG(input.fogCoord, c);
|
||||
return c;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb91ea361218943c5b6e55189c0af6f7
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Scripts.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 387bc195dff33405dbe9c8cc3b051912
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
570
Assets/99.imdk_unity/Runtime/Scripts/Core.cs
Normal file
570
Assets/99.imdk_unity/Runtime/Scripts/Core.cs
Normal file
@@ -0,0 +1,570 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Immersal.XR;
|
||||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
using System.Diagnostics;
|
||||
#endif
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CaptureInfo
|
||||
{
|
||||
public int captureSize;
|
||||
public int connected;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LocalizeInfo
|
||||
{
|
||||
public int mapId;
|
||||
public Vector3 position;
|
||||
public Quaternion rotation;
|
||||
public int confidence;
|
||||
};
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void LogCallback(IntPtr msg);
|
||||
|
||||
public static class Core
|
||||
{
|
||||
#region On-Device Mapping
|
||||
public static int MapAddImage(IntPtr pixels, int width, int height, int channels, ref Vector4 intrinsics, ref Vector3 pos, ref Quaternion rot) => Native.icvMapAddImage(pixels, width, height, channels, ref intrinsics, ref pos, ref rot);
|
||||
|
||||
public static int MapImageGetCount() => Native.icvMapImageGetCount();
|
||||
|
||||
public static int MapPrepare(string path) => Native.icvMapPrepare(path);
|
||||
|
||||
public static int MapGet(byte[] map) => Native.icvMapGet(map);
|
||||
|
||||
public static int MapPointsGetCount() => Native.icvMapPointsGetCount();
|
||||
|
||||
public static int MapPointsGet(Vector3[] points)
|
||||
{
|
||||
GCHandle pointsHandle = GCHandle.Alloc(points, GCHandleType.Pinned);
|
||||
int n = Native.icvMapPointsGet(pointsHandle.AddrOfPinnedObject(), points.Length);
|
||||
pointsHandle.Free();
|
||||
return n;
|
||||
}
|
||||
|
||||
public static int MapResourcesFree() => Native.icvMapResourcesFree();
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Get a Vector3 point cloud representation of the map data.
|
||||
/// </summary>
|
||||
/// <param name="mapId">An integer map id</param>
|
||||
/// <param name="points">A preallocated Vector3 array for the points</param>
|
||||
/// <returns>Returns the number of points if succeeded, 0 otherwise.</returns>
|
||||
public static int GetPointCloud(int mapId, Vector3[] points)
|
||||
{
|
||||
if (MapHandleMapping.TryGetHandle(mapId, out int handle))
|
||||
{
|
||||
GCHandle vector3ArrayHandle = GCHandle.Alloc(points, GCHandleType.Pinned);
|
||||
int n = Native.icvPointsGet(handle, vector3ArrayHandle.AddrOfPinnedObject(), points.Length);
|
||||
vector3ArrayHandle.Free();
|
||||
return n;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get point count of the map's point cloud.
|
||||
/// </summary>
|
||||
/// <param name="mapId">An integer map id</param>
|
||||
/// <returns>Returns the number of points.</returns>
|
||||
public static int GetPointCloudSize(int mapId)
|
||||
{
|
||||
if (MapHandleMapping.TryGetHandle(mapId, out int handle))
|
||||
{
|
||||
return Native.icvPointsGetCount(handle);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load map data from a .bytes file.
|
||||
/// </summary>
|
||||
/// <param name="buffer">Map data as a byte array</param>
|
||||
/// <param name="mapId">An integer map id</param>
|
||||
/// <returns>An integer map id</returns>
|
||||
public static int LoadMap(int mapId, byte[] buffer)
|
||||
{
|
||||
// if there is already a loaded map with the same id, return the handle pointing to that
|
||||
if (MapHandleMapping.TryGetHandle(mapId, out int handle))
|
||||
{
|
||||
ImmersalLogger.Log($"Trying to load map {mapId}({handle}) into plugin, but it's already mapped.");
|
||||
return handle;
|
||||
}
|
||||
|
||||
int mapHandle = Native.icvLoadMap(buffer);
|
||||
MapHandleMapping.AddMapping(mapId, mapHandle);
|
||||
ImmersalLogger.Log($"Loaded map {mapId}({mapHandle}) into plugin");
|
||||
return mapHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free the map data from memory.
|
||||
/// </summary>
|
||||
/// <param name="mapId">An integer map handle</param>
|
||||
/// <returns>Returns 1 if succeeded, 0 otherwise.</returns>
|
||||
public static int FreeMap(int mapId)
|
||||
{
|
||||
if (MapHandleMapping.TryGetHandle(mapId, out int mapHandle))
|
||||
{
|
||||
ImmersalLogger.Log($"Freeing map {mapId}({mapHandle}) from plugin");
|
||||
MapHandleMapping.RemoveMappingByMapId(mapId);
|
||||
return Native.icvFreeMap(mapHandle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Capture image into the current map.
|
||||
/// </summary>
|
||||
/// <param name="capture">A preallocated byte array for the captured PNG image</param>
|
||||
/// <param name="captureSizeMax">Int size of the array</param>
|
||||
/// <param name="pixels">Raw pixel buffer data from the camera</param>
|
||||
/// <param name="width">Image width</param>
|
||||
/// <param name="height">Image height</param>
|
||||
/// <param name="channels">1 or 3, monochromatic or RGB capture</param>
|
||||
/// <returns>Int size of the captured PNG bytes</returns>
|
||||
public static CaptureInfo CaptureImage(byte[] capture, int captureSizeMax, byte[] pixels, int width,
|
||||
int height, int channels, int useMatching = 0)
|
||||
{
|
||||
GCHandle captureHandle = GCHandle.Alloc(capture, GCHandleType.Pinned);
|
||||
GCHandle pixelsHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
|
||||
CaptureInfo info = Native.icvCaptureImage(captureHandle.AddrOfPinnedObject(), captureSizeMax,
|
||||
pixelsHandle.AddrOfPinnedObject(), width, height, channels, useMatching);
|
||||
captureHandle.Free();
|
||||
pixelsHandle.Free();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position and orientation of the image within the map.
|
||||
/// </summary>
|
||||
/// <param name="pos">Output Vector3 for the position</param>
|
||||
/// <param name="rot">Output Quaternion for the orientation</param>
|
||||
/// <param name="width">Image width</param>
|
||||
/// <param name="height">Image height</param>
|
||||
/// <param name="intrinsics">Camera intrinsics</param>
|
||||
/// <param name="pixels">Raw pixel buffer data from the camera</param>
|
||||
/// <returns>A LocalizeInfo struct with mapId. mapId will be -1 on failure.</returns>
|
||||
public static LocalizeInfo LocalizeImage(int n, int[] mapIds, int width,
|
||||
int height, ref Vector4 intrinsics, IntPtr pixels, int channels, int solverType, ref Quaternion cameraRotation)
|
||||
{
|
||||
if (MapHandleMapping.IdsToHandles(mapIds, out int[] handles))
|
||||
{
|
||||
GCHandle intHandle = GCHandle.Alloc(handles, GCHandleType.Pinned);
|
||||
LocalizeInfo result = Native.icvLocalize(n, intHandle.AddrOfPinnedObject(), width, height,
|
||||
ref intrinsics, pixels, channels, solverType, ref cameraRotation);
|
||||
intHandle.Free();
|
||||
|
||||
// result.mapId is a handle at this point -> convert
|
||||
if (MapHandleMapping.TryGetMapId(result.mapId, out int mapId))
|
||||
{
|
||||
result.mapId = mapId;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return new LocalizeInfo
|
||||
{
|
||||
mapId = -1
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position and orientation of the image within the map.
|
||||
/// </summary>
|
||||
/// <param name="pos">Output Vector3 for the position</param>
|
||||
/// <param name="rot">Output Quaternion for the orientation</param>
|
||||
/// <param name="width">Image width</param>
|
||||
/// <param name="height">Image height</param>
|
||||
/// <param name="intrinsics">Camera intrinsics</param>
|
||||
/// <param name="pixels">Raw pixel buffer data from the camera</param>
|
||||
/// <returns>A LocalizeInfo struct with mapId. mapId will be -1 on failure.</returns>
|
||||
public static LocalizeInfo LocalizeImage(int width, int height,
|
||||
ref Vector4 intrinsics, IntPtr pixels)
|
||||
{
|
||||
int n = 0;
|
||||
int[] mapIds = new int[1];
|
||||
int channels = 1;
|
||||
Quaternion cameraRotation = Quaternion.identity;
|
||||
return LocalizeImage(n, mapIds, width, height, ref intrinsics, pixels, channels, 0, ref cameraRotation);
|
||||
}
|
||||
|
||||
public static LocalizeInfo LocalizeImage(int width, int height,
|
||||
ref Vector4 intrinsics, IntPtr pixels, int channels, int solverType, ref Quaternion cameraRotation)
|
||||
{
|
||||
int n = 0;
|
||||
int[] mapIds = new int[1];
|
||||
return LocalizeImage(n, mapIds, width, height, ref intrinsics, pixels, channels, solverType, ref cameraRotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position and orientation of the image within the map.
|
||||
/// </summary>
|
||||
/// <param name="cameraData">ICameraData containing necessary data</param>
|
||||
/// <returns>A LocalizeInfo struct with mapId. mapId will be -1 on failure.</returns>
|
||||
public static LocalizeInfo LocalizeImage(ICameraData cameraData, IntPtr pixelBuffer, int solverType = 0)
|
||||
{
|
||||
int channels = cameraData.Channels == 0 ? 1 : cameraData.Channels; // default to 1
|
||||
Vector4 intrinsics = cameraData.Intrinsics;
|
||||
Quaternion r = cameraData.CameraRotationOnCapture * cameraData.Orientation;
|
||||
r.SwitchHandedness();
|
||||
return LocalizeImage(cameraData.Width, cameraData.Height, ref intrinsics, pixelBuffer, channels, solverType, ref r);
|
||||
}
|
||||
|
||||
public static LocalizeInfo icvLocalizeImageWithPrior(ICameraData cameraData, IntPtr pixelBuffer, ref Vector3 priorPos, int priorNNCount, float priorRadius)
|
||||
{
|
||||
int channels = cameraData.Channels == 0 ? 1 : cameraData.Channels; // default to 1
|
||||
Vector4 intrinsics = cameraData.Intrinsics;
|
||||
int n = 0;
|
||||
int[] mapIds = new int[1];
|
||||
if (MapHandleMapping.IdsToHandles(mapIds, out int[] handles))
|
||||
{
|
||||
GCHandle intHandle = GCHandle.Alloc(handles, GCHandleType.Pinned);
|
||||
LocalizeInfo result = Native.icvLocalizePrior(n, intHandle.AddrOfPinnedObject(), cameraData.Width, cameraData.Height,
|
||||
ref intrinsics, pixelBuffer, channels, ref priorPos, priorNNCount, priorRadius);
|
||||
intHandle.Free();
|
||||
|
||||
// result.mapId is a handle at this point -> convert
|
||||
if (MapHandleMapping.TryGetMapId(result.mapId, out int mapId))
|
||||
{
|
||||
result.mapId = mapId;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return new LocalizeInfo
|
||||
{
|
||||
mapId = -1
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="ecef"></param>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="mapToEcef"></param>
|
||||
/// <returns></returns>
|
||||
public static int PosMapToEcef(double[] ecef, Vector3 map, double[] mapToEcef)
|
||||
{
|
||||
GCHandle ecefHandle = GCHandle.Alloc(ecef, GCHandleType.Pinned);
|
||||
GCHandle mapToEcefHandle = GCHandle.Alloc(mapToEcef, GCHandleType.Pinned);
|
||||
int r = Native.icvPosMapToEcef(ecefHandle.AddrOfPinnedObject(), ref map,
|
||||
mapToEcefHandle.AddrOfPinnedObject());
|
||||
mapToEcefHandle.Free();
|
||||
ecefHandle.Free();
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="wgs84"></param>
|
||||
/// <param name="ecef"></param>
|
||||
/// <returns></returns>
|
||||
public static int PosEcefToWgs84(double[] wgs84, double[] ecef)
|
||||
{
|
||||
GCHandle wgs84Handle = GCHandle.Alloc(wgs84, GCHandleType.Pinned);
|
||||
GCHandle ecefHandle = GCHandle.Alloc(ecef, GCHandleType.Pinned);
|
||||
int r = Native.icvPosEcefToWgs84(wgs84Handle.AddrOfPinnedObject(), ecefHandle.AddrOfPinnedObject());
|
||||
ecefHandle.Free();
|
||||
wgs84Handle.Free();
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="ecef"></param>
|
||||
/// <param name="wgs84"></param>
|
||||
/// <returns></returns>
|
||||
public static int PosWgs84ToEcef(double[] ecef, double[] wgs84)
|
||||
{
|
||||
GCHandle ecefHandle = GCHandle.Alloc(ecef, GCHandleType.Pinned);
|
||||
GCHandle wgs84Handle = GCHandle.Alloc(wgs84, GCHandleType.Pinned);
|
||||
int r = Native.icvPosWgs84ToEcef(ecefHandle.AddrOfPinnedObject(), wgs84Handle.AddrOfPinnedObject());
|
||||
wgs84Handle.Free();
|
||||
ecefHandle.Free();
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="ecef"></param>
|
||||
/// <param name="mapToEcef"></param>
|
||||
/// <returns></returns>
|
||||
public static int PosEcefToMap(out Vector3 map, double[] ecef, double[] mapToEcef)
|
||||
{
|
||||
GCHandle ecefHandle = GCHandle.Alloc(ecef, GCHandleType.Pinned);
|
||||
GCHandle mapToEcefHandle = GCHandle.Alloc(mapToEcef, GCHandleType.Pinned);
|
||||
int r = Native.icvPosEcefToMap(out map, ecefHandle.AddrOfPinnedObject(),
|
||||
mapToEcefHandle.AddrOfPinnedObject());
|
||||
mapToEcefHandle.Free();
|
||||
ecefHandle.Free();
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="wgs84"></param>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="mapToEcef"></param>
|
||||
/// <returns></returns>
|
||||
public static int PosMapToWgs84(double[] wgs84, Vector3 map, double[] mapToEcef)
|
||||
{
|
||||
double[] ecef = new double[3];
|
||||
int err = PosMapToEcef(ecef, map, mapToEcef);
|
||||
if (err != 0)
|
||||
return err;
|
||||
return PosEcefToWgs84(wgs84, ecef);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="ecef"></param>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="mapToEcef"></param>
|
||||
/// <returns></returns>
|
||||
public static int RotMapToEcef(out Quaternion ecef, Quaternion map, double[] mapToEcef)
|
||||
{
|
||||
GCHandle mapToEcefHandle = GCHandle.Alloc(mapToEcef, GCHandleType.Pinned);
|
||||
int r = Native.icvRotMapToEcef(out ecef, ref map, mapToEcefHandle.AddrOfPinnedObject());
|
||||
mapToEcefHandle.Free();
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="ecef"></param>
|
||||
/// <param name="mapToEcef"></param>
|
||||
/// <returns></returns>
|
||||
public static int RotEcefToMap(out Quaternion map, Quaternion ecef, double[] mapToEcef)
|
||||
{
|
||||
GCHandle mapToEcefHandle = GCHandle.Alloc(mapToEcef, GCHandleType.Pinned);
|
||||
int r = Native.icvRotEcefToMap(out map, ref ecef, mapToEcefHandle.AddrOfPinnedObject());
|
||||
mapToEcefHandle.Free();
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get internal plugin parameters.
|
||||
/// </summary>
|
||||
/// <param name="parameter">Parameter name</param>
|
||||
/// <returns>Returns an integer value if set, -1 otherwise.</returns>
|
||||
public static int GetInteger(string parameter) => Native.icvGetInteger(parameter);
|
||||
|
||||
/// <summary>
|
||||
/// Set internal plugin parameters.
|
||||
///
|
||||
/// Available parameters:
|
||||
/// "LocalizationMaxPixels" - 0 is no limit (the default), 960*720 or higher.
|
||||
/// "NumThreads" - how many CPU cores to use; -1 (system default) or a positive integer.
|
||||
/// "ImageCompressionLevel" - 0 (no compression, fastest) to 9 (slowest). Defaults to 4.
|
||||
/// </summary>
|
||||
/// <param name="parameter">Parameter name</param>
|
||||
/// <param name="value">An integer parameter value</param>
|
||||
/// <returns>Returns 1 if succeeded, -1 otherwise.</returns>
|
||||
public static int SetInteger(string parameter, int value) => Native.icvSetInteger(parameter, value);
|
||||
|
||||
public static int ValidateUser(string token) => Native.icvValidateUser(token);
|
||||
}
|
||||
|
||||
public static class MapHandleMapping
|
||||
{
|
||||
private static Dictionary<int, int> mapIdToHandleMapping = new Dictionary<int, int>();
|
||||
private static Dictionary<int, int> handleToMapIdMapping = new Dictionary<int, int>();
|
||||
|
||||
public static void AddMapping(int mapId, int pluginHandle)
|
||||
{
|
||||
if (mapIdToHandleMapping.ContainsKey(mapId) || handleToMapIdMapping.ContainsKey(pluginHandle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mapIdToHandleMapping[mapId] = pluginHandle;
|
||||
handleToMapIdMapping[pluginHandle] = mapId;
|
||||
}
|
||||
|
||||
public static bool TryGetHandle(int mapId, out int pluginHandle)
|
||||
{
|
||||
return mapIdToHandleMapping.TryGetValue(mapId, out pluginHandle);
|
||||
}
|
||||
|
||||
public static bool TryGetMapId(int pluginHandle, out int mapId)
|
||||
{
|
||||
mapId = -1;
|
||||
return handleToMapIdMapping.TryGetValue(pluginHandle, out mapId);
|
||||
}
|
||||
|
||||
public static bool RemoveMappingByMapId(int mapId)
|
||||
{
|
||||
if (mapIdToHandleMapping.TryGetValue(mapId, out int pluginHandle))
|
||||
{
|
||||
mapIdToHandleMapping.Remove(mapId);
|
||||
handleToMapIdMapping.Remove(pluginHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool RemoveMappingByHandle(int pluginHandle)
|
||||
{
|
||||
if (handleToMapIdMapping.TryGetValue(pluginHandle, out int mapId))
|
||||
{
|
||||
handleToMapIdMapping.Remove(pluginHandle);
|
||||
mapIdToHandleMapping.Remove(mapId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Clear()
|
||||
{
|
||||
foreach (KeyValuePair<int,int> keyValuePair in mapIdToHandleMapping)
|
||||
{
|
||||
if (RemoveMappingByMapId(keyValuePair.Key) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IdsToHandles(int[] mapIds, out int[] handles)
|
||||
{
|
||||
handles = new int[mapIds.Length];
|
||||
|
||||
// single zero id case
|
||||
if (mapIds.Length == 1 && mapIds[0] == 0)
|
||||
{
|
||||
handles[0] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < handles.Length; i++)
|
||||
{
|
||||
// Dictionary lookups are O(1) complexity, no need for caching?
|
||||
if (!TryGetHandle(mapIds[i], out int handle))
|
||||
return false;
|
||||
|
||||
handles[i] = handle;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Native
|
||||
{
|
||||
private const string Assembly =
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
"__Internal";
|
||||
#else
|
||||
"PosePlugin";
|
||||
#endif
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void PP_RegisterLogCallback(IntPtr callbackDelegate);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvPointsGet(int mapHandle, IntPtr array, int maxCount);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvPointsGetCount(int mapHandle);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvLoadMap(byte[] buffer);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvFreeMap(int mapHandle);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CaptureInfo icvCaptureImage(IntPtr capture, int captureSizeMax, IntPtr pixels,
|
||||
int width, int height, int channels, int useMatching);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern LocalizeInfo icvLocalize(int n, IntPtr handles, int width,
|
||||
int height, ref Vector4 intrinsics, IntPtr pixels, int channels, int solverType, ref Quaternion cameraRotation);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern LocalizeInfo icvLocalizePrior(int n, IntPtr handles, int width,
|
||||
int height, ref Vector4 intrinsics, IntPtr pixels, int channels, ref Vector3 priorPos, int priorNNCount, float priorRadius);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvPosMapToEcef(IntPtr ecef, ref Vector3 map, IntPtr mapToEcef);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvPosEcefToWgs84(IntPtr wgs84, IntPtr ecef);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvPosWgs84ToEcef(IntPtr ecef, IntPtr wgs84);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvPosEcefToMap(out Vector3 map, IntPtr ecef, IntPtr mapToEcef);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvRotMapToEcef(out Quaternion ecef, ref Quaternion map, IntPtr mapToEcef);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvRotEcefToMap(out Quaternion map, ref Quaternion ecef, IntPtr mapToEcef);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvSetInteger([MarshalAs(UnmanagedType.LPStr)] string parameter, int value);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvGetInteger([MarshalAs(UnmanagedType.LPStr)] string parameter);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvValidateUser([MarshalAs(UnmanagedType.LPStr)] string token);
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
|
||||
public static extern int icvMapAddImage(IntPtr pixels, int width, int height, int channels, ref Vector4 intrinsics, ref Vector3 pos, ref Quaternion rot);
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvMapImageGetCount();
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvMapPrepare([MarshalAs(UnmanagedType.LPStr)] string path);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvMapGet(byte[] map);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvMapPointsGetCount();
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvMapPointsGet(IntPtr points, int countMax);
|
||||
|
||||
[DllImport(Assembly, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int icvMapResourcesFree();
|
||||
}
|
||||
}
|
||||
11
Assets/99.imdk_unity/Runtime/Scripts/Core.cs.meta
Normal file
11
Assets/99.imdk_unity/Runtime/Scripts/Core.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 665b1ef59d2854b70b4806c15ce9fa52
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
503
Assets/99.imdk_unity/Runtime/Scripts/ImmersalSDK.cs
Normal file
503
Assets/99.imdk_unity/Runtime/Scripts/ImmersalSDK.cs
Normal file
@@ -0,0 +1,503 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Immersal.XR;
|
||||
using Immersal.REST;
|
||||
using AOT;
|
||||
using UnityEngine.Serialization;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
public class ImmersalSDK : MonoBehaviour
|
||||
{
|
||||
// SDK properties
|
||||
|
||||
public static string sdkVersion = "2.1.1";
|
||||
private static readonly string[] ServerList = new[] {"https://api.immersal.com", "https://immersal.hexagon.com.cn"};
|
||||
public enum APIServer { DefaultServer = 0, ChinaServer = 1, CustomServer = 2 };
|
||||
|
||||
public APIServer ImmersalServer = APIServer.DefaultServer;
|
||||
|
||||
[Tooltip("SDK developer token")]
|
||||
public string developerToken;
|
||||
|
||||
#region Interfaced components
|
||||
|
||||
[Header("Components")]
|
||||
|
||||
/*
|
||||
* ImmersalSDK modular framework works with any implementation of the main components:
|
||||
* IImmersalSession, IPlatformSupport, ILocalizer, ISceneUpdater and ITrackingAnalyzer.
|
||||
*
|
||||
* Serialization and inspector support for these implementation references are
|
||||
* handled with an Object reference Property with a custom Attribute as well as
|
||||
* a custom PropertyDrawer. An additional public Property is used for casting
|
||||
* the Object to the relevant interface type.
|
||||
*/
|
||||
|
||||
[SerializeField][InterfaceAttribute(typeof(IImmersalSession))]
|
||||
private Object m_Session;
|
||||
public IImmersalSession Session => m_Session as IImmersalSession;
|
||||
|
||||
[SerializeField][InterfaceAttribute(typeof(IPlatformSupport))]
|
||||
private Object m_Platform;
|
||||
public IPlatformSupport PlatformSupport => m_Platform as IPlatformSupport;
|
||||
|
||||
[SerializeField][InterfaceAttribute(typeof(ILocalizer))]
|
||||
private Object m_Localizer;
|
||||
public ILocalizer Localizer => m_Localizer as ILocalizer;
|
||||
|
||||
[SerializeField][InterfaceAttribute(typeof(ISceneUpdater))]
|
||||
private Object m_SceneUpdater;
|
||||
public ISceneUpdater SceneUpdater => m_SceneUpdater as ISceneUpdater;
|
||||
|
||||
[SerializeField][InterfaceAttribute(typeof(ITrackingAnalyzer))]
|
||||
private Object m_TrackingAnalyzer;
|
||||
public ITrackingAnalyzer TrackingAnalyzer => m_TrackingAnalyzer as ITrackingAnalyzer;
|
||||
|
||||
#endregion
|
||||
|
||||
// Configuration properties
|
||||
|
||||
[Header("Configuration")]
|
||||
[SerializeField]
|
||||
[Tooltip("Initialize the SDK on Awake")]
|
||||
private bool m_InitializeAutomatically = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Application target frame rate")]
|
||||
private int m_TargetFrameRate = 60;
|
||||
|
||||
[Tooltip("Downsample image to HD resolution")]
|
||||
[SerializeField]
|
||||
private bool m_Downsample = true;
|
||||
|
||||
[SerializeField]
|
||||
private ImmersalLogger.LoggingLevel m_LoggingLevel = ImmersalLogger.LoggingLevel.ErrorsAndWarnings;
|
||||
|
||||
[Header("Editor")]
|
||||
[Tooltip("Map data download location in relation to Assets")]
|
||||
[SerializeField]
|
||||
private string m_DownloadDirectory = "Map Data";
|
||||
|
||||
// Public
|
||||
|
||||
public ITrackingStatus TrackingStatus => TrackingAnalyzer.TrackingStatus;
|
||||
public bool IsReady => m_IsReady;
|
||||
public int LicenseLevel => m_LicenseLevel;
|
||||
public bool HasValidated => m_HasValidated;
|
||||
public static HttpClient client;
|
||||
|
||||
public int targetFrameRate
|
||||
{
|
||||
get { return m_TargetFrameRate; }
|
||||
set
|
||||
{
|
||||
m_TargetFrameRate = value;
|
||||
SetFrameRate();
|
||||
}
|
||||
}
|
||||
|
||||
public string localizationServer
|
||||
{
|
||||
get => ImmersalServer == APIServer.CustomServer ? m_CustomServerUrl : ServerList[(int)ImmersalServer];
|
||||
set
|
||||
{
|
||||
ImmersalServer = APIServer.CustomServer;
|
||||
m_CustomServerUrl = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool downsample
|
||||
{
|
||||
get { return m_Downsample; }
|
||||
set
|
||||
{
|
||||
m_Downsample = value;
|
||||
SetDownsample();
|
||||
}
|
||||
}
|
||||
|
||||
public string DownloadDirectory
|
||||
{
|
||||
get { return m_DownloadDirectory; }
|
||||
}
|
||||
|
||||
private void SetDownsample()
|
||||
{
|
||||
if (downsample)
|
||||
{
|
||||
Core.SetInteger("LocalizationMaxPixels", 960*720);
|
||||
}
|
||||
else
|
||||
{
|
||||
Core.SetInteger("LocalizationMaxPixels", 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Events
|
||||
|
||||
[Header("Events")]
|
||||
public UnityEvent OnInitializationComplete;
|
||||
public UnityEvent OnUserValidationComplete;
|
||||
public UnityEvent OnReset;
|
||||
|
||||
[SerializeField]
|
||||
private string m_CustomServerUrl = "";
|
||||
private int m_LicenseLevel = -1;
|
||||
|
||||
private bool m_IsReady = false;
|
||||
private bool m_HasValidated = false;
|
||||
private bool m_PluginCallbackRegistered = false;
|
||||
private bool m_PlatformIsConfigured = false;
|
||||
private bool m_LocalizerIsConfigured = false;
|
||||
private bool m_MapsAreRegisteredAndLoaded = false;
|
||||
|
||||
|
||||
#region Singleton pattern
|
||||
|
||||
private static ImmersalSDK instance = null;
|
||||
|
||||
public static ImmersalSDK Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (instance == null && !Application.isPlaying)
|
||||
{
|
||||
instance = FindObjectOfType<ImmersalSDK>();
|
||||
}
|
||||
#endif
|
||||
if (instance == null)
|
||||
{
|
||||
ImmersalLogger.LogError("No ImmersalSDK instance found. Ensure one exists in the scene.");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
if (instance != this)
|
||||
{
|
||||
ImmersalLogger.LogError("There must be only one ImmersalSDK object in a scene.");
|
||||
UnityEngine.Object.DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_InitializeAutomatically)
|
||||
_ = Initialize();
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
{
|
||||
ImmersalLogger.Level = m_LoggingLevel;
|
||||
ImmersalLogger.Log("Initializing ImmersalSDK", ImmersalLogger.LoggingLevel.Verbose);
|
||||
|
||||
if (PlatformSupport == null || Localizer == null || SceneUpdater == null || TrackingAnalyzer == null)
|
||||
{
|
||||
throw new Exception("ImmersalSDK has null references, please assign all Properties.");
|
||||
}
|
||||
|
||||
// plugin log callback
|
||||
if (!m_PluginCallbackRegistered)
|
||||
{
|
||||
LogCallback callback_delegate = new LogCallback(Log);
|
||||
IntPtr intptr_delegate = Marshal.GetFunctionPointerForDelegate(callback_delegate);
|
||||
Native.PP_RegisterLogCallback(intptr_delegate);
|
||||
m_PluginCallbackRegistered = true;
|
||||
}
|
||||
|
||||
// http client
|
||||
HttpClientHandler handler = new HttpClientHandler();
|
||||
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
|
||||
client = new HttpClient(handler);
|
||||
client.DefaultRequestHeaders.ExpectContinue = false;
|
||||
client.Timeout = TimeSpan.FromDays(1);
|
||||
|
||||
// validate user
|
||||
if (developerToken != null && developerToken.Length > 0)
|
||||
{
|
||||
PlayerPrefs.SetString("token", developerToken);
|
||||
ValidateUser();
|
||||
}
|
||||
|
||||
SetFrameRate();
|
||||
#if !UNITY_EDITOR
|
||||
SetDownsample();
|
||||
#endif
|
||||
MapManager.RefreshLocalizationMethods();
|
||||
|
||||
await ConfigureComponents();
|
||||
|
||||
if (m_IsReady)
|
||||
{
|
||||
ImmersalLogger.Log("Immersal SDK ready!", ImmersalLogger.LoggingLevel.Verbose);
|
||||
OnInitializationComplete?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public async void ValidateUser()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
m_LicenseLevel = Core.ValidateUser(developerToken);
|
||||
string licenseLevel = m_LicenseLevel >= 1 ? "Enterprise" : "Free";
|
||||
ImmersalLogger.Log($"{licenseLevel} License");
|
||||
}
|
||||
else
|
||||
{
|
||||
JobStatusAsync j = new JobStatusAsync();
|
||||
SDKStatusResult result = await j.RunJobAsync();
|
||||
m_LicenseLevel = result.level;
|
||||
string licenseLevel = m_LicenseLevel >= 1 ? "Enterprise" : "Free";
|
||||
ImmersalLogger.Log($"{licenseLevel} License");
|
||||
}
|
||||
|
||||
m_HasValidated = true;
|
||||
OnUserValidationComplete?.Invoke();
|
||||
}
|
||||
|
||||
private async Task ConfigureComponents()
|
||||
{
|
||||
if (!m_MapsAreRegisteredAndLoaded)
|
||||
{
|
||||
m_MapsAreRegisteredAndLoaded = await RegisterAndLoadMaps();
|
||||
}
|
||||
|
||||
if (!m_PlatformIsConfigured)
|
||||
{
|
||||
m_PlatformIsConfigured = await ConfigurePlatform();
|
||||
if (m_PlatformIsConfigured)
|
||||
ImmersalLogger.Log("Platform configured.", ImmersalLogger.LoggingLevel.Verbose);
|
||||
}
|
||||
|
||||
if (!m_LocalizerIsConfigured)
|
||||
{
|
||||
m_LocalizerIsConfigured = await ConfigureLocalizer();
|
||||
if (m_LocalizerIsConfigured)
|
||||
ImmersalLogger.Log("Localizer configured.", ImmersalLogger.LoggingLevel.Verbose);
|
||||
}
|
||||
|
||||
m_IsReady = m_PlatformIsConfigured && m_LocalizerIsConfigured && m_MapsAreRegisteredAndLoaded;
|
||||
}
|
||||
|
||||
private async Task<bool> RegisterAndLoadMaps()
|
||||
{
|
||||
XRMap[] maps = FindObjectsOfType<XRMap>();
|
||||
ImmersalLogger.Log($"Found {maps.Length} maps in scene.");
|
||||
List<Task> mapRegisterTasks = new List<Task>();
|
||||
|
||||
foreach (XRMap map in maps)
|
||||
{
|
||||
ISceneUpdateable sceneUpdateable = map.gameObject.transform.GetComponentInParent<ISceneUpdateable>(true);
|
||||
if (sceneUpdateable != null)
|
||||
{
|
||||
ImmersalLogger.Log($"Starting RegisterAndLoad for map {map.mapId}");
|
||||
// map registering might initiate downloads so we should not await here
|
||||
Task t = MapManager.RegisterAndLoadMap(map, sceneUpdateable);
|
||||
mapRegisterTasks.Add(t);
|
||||
}
|
||||
}
|
||||
// wait for all register tasks to finish
|
||||
await Task.WhenAll(mapRegisterTasks.ToArray());
|
||||
List<XRMap> registeredMaps = MapManager.GetRegisteredMaps();
|
||||
ImmersalLogger.Log($"Registered maps: {(registeredMaps.Count > 0 ? string.Join(",", registeredMaps) : "none")}", ImmersalLogger.LoggingLevel.Verbose);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> ConfigurePlatform()
|
||||
{
|
||||
try
|
||||
{
|
||||
IPlatformConfigureResult result = await PlatformSupport.ConfigurePlatform();
|
||||
return result.Success;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AbortWithException(e, "PlatformSupport");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<bool> ConfigureLocalizer()
|
||||
{
|
||||
// Get all registered maps
|
||||
List<XRMap> maps = MapManager.GetRegisteredMaps();
|
||||
|
||||
// Create a mapping of maps and the associated localization methods
|
||||
Dictionary<ILocalizationMethod, XRMap[]> mapping = maps
|
||||
.GroupBy(map => map.LocalizationMethod)
|
||||
.ToDictionary(
|
||||
group => group.Key,
|
||||
group => group.ToArray());
|
||||
|
||||
DefaultLocalizerConfiguration config = new DefaultLocalizerConfiguration
|
||||
{
|
||||
ConfigurationsToAdd = mapping,
|
||||
StopRunningTasks = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
ILocalizerConfigurationResult result = await Localizer.ConfigureLocalizer(config);
|
||||
return result.Success;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AbortWithException(e, "Localizer");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetFrameRate()
|
||||
{
|
||||
Application.targetFrameRate = targetFrameRate;
|
||||
}
|
||||
|
||||
// Convenience method
|
||||
// Note: no data processing chain here
|
||||
public async Task LocalizeOnce()
|
||||
{
|
||||
if (m_IsReady)
|
||||
{
|
||||
ILocalizationResults localizerResults;
|
||||
|
||||
IPlatformUpdateResult platformResult = await PlatformSupport.UpdatePlatform();
|
||||
if (platformResult.Success)
|
||||
{
|
||||
localizerResults = await Localizer.Localize(platformResult.CameraData);
|
||||
|
||||
foreach (ILocalizationResult result in localizerResults.Results)
|
||||
{
|
||||
if (result.Success && MapManager.TryGetMapEntry(result.MapId, out MapEntry entry))
|
||||
{
|
||||
await SceneUpdater.UpdateScene(entry, platformResult.CameraData, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Localization never ran due to failed platform update
|
||||
// so we need invalidate results.
|
||||
localizerResults = new LocalizationResults
|
||||
{
|
||||
Results = Array.Empty<ILocalizationResult>()
|
||||
};
|
||||
}
|
||||
|
||||
// Update tracking status
|
||||
TrackingAnalyzer.Analyze(platformResult.Status, localizerResults);
|
||||
}
|
||||
}
|
||||
|
||||
private void AbortWithException(Exception e, string logPrefix = "")
|
||||
{
|
||||
m_IsReady = false;
|
||||
ImmersalLogger.LogError($"{logPrefix}: {e.Message}");
|
||||
Debug.LogException(e);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
m_IsReady = false;
|
||||
MapManager.RemoveAllMaps(false);
|
||||
}
|
||||
|
||||
public void TriggerSoftReset()
|
||||
{
|
||||
SoftReset();
|
||||
}
|
||||
|
||||
public async Task SoftReset()
|
||||
{
|
||||
await Session.ResetSession();
|
||||
await ResetScenes();
|
||||
TrackingAnalyzer.Reset();
|
||||
}
|
||||
|
||||
public void TriggerResetScenes()
|
||||
{
|
||||
ResetScenes();
|
||||
}
|
||||
|
||||
public async Task ResetScenes()
|
||||
{
|
||||
ImmersalLogger.Log("Resetting SceneUpdateables");
|
||||
List<ISceneUpdateable> sceneUpdateables = MapManager.GetSceneUpdateablesInUse();
|
||||
foreach (ISceneUpdateable sceneUpdateable in sceneUpdateables)
|
||||
{
|
||||
await sceneUpdateable.ResetScene();
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("RestartSdk")]
|
||||
public async void RestartSdk()
|
||||
{
|
||||
ImmersalLogger.Log("Restarting ImmersalSDK", ImmersalLogger.LoggingLevel.Verbose);
|
||||
m_IsReady = false;
|
||||
|
||||
// Stop and clean up components
|
||||
await Session.StopSession();
|
||||
|
||||
// Clear maps
|
||||
MapManager.RemoveAllMaps();
|
||||
m_MapsAreRegisteredAndLoaded = false;
|
||||
|
||||
m_LocalizerIsConfigured = false;
|
||||
await Localizer.StopAndCleanUp();
|
||||
|
||||
m_PlatformIsConfigured = false;
|
||||
await PlatformSupport.StopAndCleanUp();
|
||||
|
||||
// Reset scenes
|
||||
await ResetScenes();
|
||||
|
||||
// Invoke event
|
||||
OnReset?.Invoke();
|
||||
|
||||
// Restart
|
||||
await Initialize();
|
||||
}
|
||||
|
||||
// Logging callback for plugin
|
||||
[MonoPInvokeCallback(typeof(LogCallback))]
|
||||
public static void Log(IntPtr ansiString)
|
||||
{
|
||||
string msg = Marshal.PtrToStringAnsi(ansiString);
|
||||
ImmersalLogger.Log($"Plugin: {msg}", ImmersalLogger.LoggingLevel.Verbose);
|
||||
}
|
||||
}
|
||||
|
||||
public class ComponentTaskCriticalException : Exception
|
||||
{
|
||||
public ComponentTaskCriticalException(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
11
Assets/99.imdk_unity/Runtime/Scripts/ImmersalSDK.cs.meta
Normal file
11
Assets/99.imdk_unity/Runtime/Scripts/ImmersalSDK.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22271c1298ba444ffacf4138cd9ef2eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/99.imdk_unity/Runtime/Scripts/REST.meta
Normal file
3
Assets/99.imdk_unity/Runtime/Scripts/REST.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3df0ff440d74453be3bc85d3f9369ca
|
||||
timeCreated: 1707400520
|
||||
599
Assets/99.imdk_unity/Runtime/Scripts/REST/REST.cs
Normal file
599
Assets/99.imdk_unity/Runtime/Scripts/REST/REST.cs
Normal file
@@ -0,0 +1,599 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.REST
|
||||
{
|
||||
public struct SDKJobState
|
||||
{
|
||||
public const string Done = "done";
|
||||
public const string Sparse = "sparse";
|
||||
public const string Processing = "processing";
|
||||
public const string Failed = "failed";
|
||||
public const string Pending = "pending";
|
||||
}
|
||||
|
||||
public enum SDKJobType { Map, Stitch, Alignment, Edit };
|
||||
public enum SDKJobPrivacy { Private, Public };
|
||||
|
||||
public struct DeviceInfo
|
||||
{
|
||||
public static string DeviceModel => SystemInfo.deviceModel != SystemInfo.unsupportedIdentifier
|
||||
? SystemInfo.deviceModel
|
||||
: "unknown";
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKJob
|
||||
{
|
||||
public int id;
|
||||
public int type;
|
||||
public string version;
|
||||
public int creator;
|
||||
public int size;
|
||||
public string status;
|
||||
public int privacy;
|
||||
public string name;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double altitude;
|
||||
public string created;
|
||||
public string modified;
|
||||
public string sha256_al;
|
||||
public string sha256_sparse;
|
||||
public string sha256_dense;
|
||||
public string sha256_tex;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapId
|
||||
{
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKLoginRequest
|
||||
{
|
||||
public static string endpoint = "login";
|
||||
public string login;
|
||||
public string password;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKLoginResult
|
||||
{
|
||||
public string error;
|
||||
public int userId;
|
||||
public string token;
|
||||
public int level;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKClearRequest
|
||||
{
|
||||
public static string endpoint = "clear";
|
||||
public string token;
|
||||
public bool anchor;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKClearResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKConstructRequest
|
||||
{
|
||||
public static string endpoint = "construct";
|
||||
public string token;
|
||||
public string name;
|
||||
public int featureCount;
|
||||
public int featureType;
|
||||
public bool preservePoses;
|
||||
public int windowSize;
|
||||
public bool mapTrim;
|
||||
public int featureFilter;
|
||||
public int compressionLevel;
|
||||
public int dense;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKConstructResult
|
||||
{
|
||||
public string error;
|
||||
public int id;
|
||||
public int size;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKStatusRequest
|
||||
{
|
||||
public static string endpoint = "status";
|
||||
public string token;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKStatusResult
|
||||
{
|
||||
public string error;
|
||||
public int userId;
|
||||
public int imageCount;
|
||||
public int imageMax;
|
||||
public bool eulaAccepted;
|
||||
public int level;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKJobsRequest
|
||||
{
|
||||
public static string endpoint = "list";
|
||||
public string token;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKGeoJobsRequest
|
||||
{
|
||||
public static string endpoint = "geolist";
|
||||
public string token;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double radius;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKJobsResult
|
||||
{
|
||||
public string error;
|
||||
public int count;
|
||||
public SDKJob[] jobs;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKImageRequest
|
||||
{
|
||||
public static string endpoint = "capture";
|
||||
public string deviceModel;
|
||||
public string token;
|
||||
public int run;
|
||||
public int index;
|
||||
public bool anchor;
|
||||
public double px;
|
||||
public double py;
|
||||
public double pz;
|
||||
public double r00;
|
||||
public double r01;
|
||||
public double r02;
|
||||
public double r10;
|
||||
public double r11;
|
||||
public double r12;
|
||||
public double r20;
|
||||
public double r21;
|
||||
public double r22;
|
||||
public double fx;
|
||||
public double fy;
|
||||
public double ox;
|
||||
public double oy;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double altitude;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKImageResult
|
||||
{
|
||||
public string error;
|
||||
public string path;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKGeoLocalizeRequest
|
||||
{
|
||||
public static string endpoint = "geolocalize";
|
||||
public string token;
|
||||
public double fx;
|
||||
public double fy;
|
||||
public double ox;
|
||||
public double oy;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double radius;
|
||||
public double qx;
|
||||
public double qy;
|
||||
public double qz;
|
||||
public double qw;
|
||||
public int solverType;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKLocalizeRequest
|
||||
{
|
||||
public static string endpoint = "localize";
|
||||
public string deviceModel;
|
||||
public string token;
|
||||
public double fx;
|
||||
public double fy;
|
||||
public double ox;
|
||||
public double oy;
|
||||
public SDKMapId[] mapIds;
|
||||
public double qx;
|
||||
public double qy;
|
||||
public double qz;
|
||||
public double qw;
|
||||
public int solverType;
|
||||
public double priorX;
|
||||
public double priorY;
|
||||
public double priorZ;
|
||||
public double priorScaleX;
|
||||
public double priorScaleY;
|
||||
public double priorScaleZ;
|
||||
public int priorNeighborCountMin;
|
||||
public int priorNeighborCountMax;
|
||||
public double priorRadius;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKGeoPoseRequest
|
||||
{
|
||||
public static string endpoint = "geopose";
|
||||
public string token;
|
||||
public double fx;
|
||||
public double fy;
|
||||
public double ox;
|
||||
public double oy;
|
||||
public SDKMapId[] mapIds;
|
||||
public double qx;
|
||||
public double qy;
|
||||
public double qz;
|
||||
public double qw;
|
||||
public int solverType;
|
||||
public double priorX;
|
||||
public double priorY;
|
||||
public double priorZ;
|
||||
public double priorScaleX;
|
||||
public double priorScaleY;
|
||||
public double priorScaleZ;
|
||||
public int priorNeighborCountMin;
|
||||
public int priorNeighborCountMax;
|
||||
public double priorRadius;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKLocalizeResult
|
||||
{
|
||||
public string error;
|
||||
public bool success;
|
||||
public int map;
|
||||
public float px;
|
||||
public float py;
|
||||
public float pz;
|
||||
public float r00;
|
||||
public float r01;
|
||||
public float r02;
|
||||
public float r10;
|
||||
public float r11;
|
||||
public float r12;
|
||||
public float r20;
|
||||
public float r21;
|
||||
public float r22;
|
||||
public int confidence;
|
||||
public float time;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKGeoPoseResult
|
||||
{
|
||||
public string error;
|
||||
public bool success;
|
||||
public int map;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double ellipsoidHeight;
|
||||
public float[] quaternion;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKEcefRequest
|
||||
{
|
||||
public static string endpoint = "ecef";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKEcefResult
|
||||
{
|
||||
public string error;
|
||||
public double[] ecef;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKSetMapAccessTokenRequest
|
||||
{
|
||||
public static string endpoint = "setmaptoken";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKClearMapAccessTokenRequest
|
||||
{
|
||||
public static string endpoint = "clearmaptoken";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapAccessTokenResult
|
||||
{
|
||||
public string error;
|
||||
public int mapId;
|
||||
public string accessToken;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapBinaryRequest
|
||||
{
|
||||
public static string endpoint = "map";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapRequest
|
||||
{
|
||||
public static string endpoint = "mapb64";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapResult
|
||||
{
|
||||
public string error;
|
||||
public string sha256_al;
|
||||
public string b64;
|
||||
public byte[] mapData;
|
||||
public SDKMapMetadataGetResult metadata;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKDeleteMapRequest
|
||||
{
|
||||
public static string endpoint = "delete";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKDeleteMapResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKRestoreMapImagesRequest
|
||||
{
|
||||
public static string endpoint = "restore";
|
||||
public string token;
|
||||
public int id;
|
||||
public bool clear;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKRestoreMapImagesResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapPrivacyRequest
|
||||
{
|
||||
public static string endpoint = "privacy";
|
||||
public string token;
|
||||
public int id;
|
||||
public int privacy;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapPrivacyResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapDownloadRequest
|
||||
{
|
||||
public static string endpoint = "mapb64";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapDownloadResult
|
||||
{
|
||||
public string error;
|
||||
public string sha256_al;
|
||||
public string b64;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKSparseDownloadRequest
|
||||
{
|
||||
public static string endpoint = "sparse";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKSparseDownloadResult
|
||||
{
|
||||
public string error;
|
||||
public byte[] data;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapUploadRequest
|
||||
{
|
||||
public static string endpoint = "uploadmap";
|
||||
public string token;
|
||||
public string name;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double altitude;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapUploadResult
|
||||
{
|
||||
public string error;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapMetadataGetRequest
|
||||
{
|
||||
public static string endpoint = "metadataget";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapMetadataGetResult
|
||||
{
|
||||
public string error;
|
||||
public int id;
|
||||
public int type;
|
||||
public string created;
|
||||
public string version;
|
||||
public int user;
|
||||
public int creator;
|
||||
public string name;
|
||||
public int size;
|
||||
public string status;
|
||||
public int privacy;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double altitude;
|
||||
public double tx;
|
||||
public double ty;
|
||||
public double tz;
|
||||
public double qw;
|
||||
public double qx;
|
||||
public double qy;
|
||||
public double qz;
|
||||
public double scale;
|
||||
public string sha256_al;
|
||||
public string sha256_sparse;
|
||||
public string sha256_dense;
|
||||
public string sha256_tex;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapAlignmentSetRequest
|
||||
{
|
||||
public static string endpoint = "metadataset";
|
||||
public string token;
|
||||
public int id;
|
||||
public double tx;
|
||||
public double ty;
|
||||
public double tz;
|
||||
public double qw;
|
||||
public double qx;
|
||||
public double qy;
|
||||
public double qz;
|
||||
public double scale;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapAlignmentSetResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapAlignmentResetRequest
|
||||
{
|
||||
public static string endpoint = "reset";
|
||||
public string token;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKMapAlignmentResetResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKCopyMapRequest
|
||||
{
|
||||
public static string endpoint = "copy";
|
||||
public string token;
|
||||
public string login;
|
||||
public int id;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKCopyMapResult
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKVersionRequest
|
||||
{
|
||||
public static string endpoint = "version";
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKVersionResult
|
||||
{
|
||||
public string error;
|
||||
public string version;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKAlignMapsRequest
|
||||
{
|
||||
public static string endpoint = "align";
|
||||
public string token;
|
||||
public string name;
|
||||
public SDKMapId[] mapIds;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKAlignMapsResult
|
||||
{
|
||||
public string error;
|
||||
public int id;
|
||||
public int size;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKStitchMapsRequest
|
||||
{
|
||||
public static string endpoint = "fuse";
|
||||
public string token;
|
||||
public string name;
|
||||
public SDKMapId[] mapIds;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SDKStitchMapsResult
|
||||
{
|
||||
public string error;
|
||||
public int id;
|
||||
public int size;
|
||||
}
|
||||
}
|
||||
11
Assets/99.imdk_unity/Runtime/Scripts/REST/REST.cs.meta
Normal file
11
Assets/99.imdk_unity/Runtime/Scripts/REST/REST.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e94452b080313413fbb29e91798f73b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1126
Assets/99.imdk_unity/Runtime/Scripts/REST/RESTJobsAsync.cs
Normal file
1126
Assets/99.imdk_unity/Runtime/Scripts/REST/RESTJobsAsync.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64b9b9737277b49c4a82005474a8a637
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/99.imdk_unity/Runtime/Scripts/Util.meta
Normal file
8
Assets/99.imdk_unity/Runtime/Scripts/Util.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76b8047eae9f5472293eacba2a735fa0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using Immersal.XR;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal.XR
|
||||
{
|
||||
public static class ExtensionMethods
|
||||
{
|
||||
public static Matrix4x4 SwitchHandedness(this ref Matrix4x4 b)
|
||||
{
|
||||
Matrix4x4 D = Matrix4x4.identity;
|
||||
D.m00 = -1;
|
||||
b = D * b * D;
|
||||
return b;
|
||||
}
|
||||
|
||||
public static Quaternion SwitchHandedness(this ref Quaternion b)
|
||||
{
|
||||
Matrix4x4 m = Matrix4x4.Rotate(b);
|
||||
m.SwitchHandedness();
|
||||
b = m.rotation;
|
||||
return b;
|
||||
}
|
||||
|
||||
public static float[] ToFloats(this ref Quaternion q)
|
||||
{
|
||||
float[] result = new float[4] { q.x, q.y, q.z, q.w };
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector3 SwitchHandedness(this ref Vector3 b)
|
||||
{
|
||||
Matrix4x4 m = Matrix4x4.TRS(b, Quaternion.identity, Vector3.one);
|
||||
m.SwitchHandedness();
|
||||
b = m.GetColumn(3);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static double[] QuaternionsToDoubleMatrix3x3(this XRMap.MapAlignment ma)
|
||||
{
|
||||
double[] q = new double[] {ma.qw, ma.qx, ma.qy, ma.qz};
|
||||
double[] m = new double [] {1, 0, 0, 0, 1, 0, 0, 0, 1}; //identity matrix
|
||||
|
||||
// input quaternion should be in WXYZ order
|
||||
double w = q[0];
|
||||
double x = q[1];
|
||||
double y = q[2];
|
||||
double z = q[3];
|
||||
|
||||
double ww = w * w;
|
||||
double xx = x * x;
|
||||
double yy = y * y;
|
||||
double zz = z * z;
|
||||
|
||||
double xy = x * y;
|
||||
double zw = z * w;
|
||||
double xz = x * z;
|
||||
double yw = y * w;
|
||||
double yz = y * z;
|
||||
double xw = x * w;
|
||||
|
||||
double inv = 1.0 / (xx + yy + zz + ww);
|
||||
|
||||
m[0] = ( xx - yy - zz + ww) * inv;
|
||||
m[1] = 2.0 * (xy - zw) * inv;
|
||||
m[2] = 2.0 * (xz + yw) * inv;
|
||||
m[3] = 2.0 * (xy + zw) * inv;
|
||||
m[4] = (-xx + yy - zz + ww) * inv;
|
||||
m[5] = 2.0 * (yz - xw) * inv;
|
||||
m[6] = 2.0 * (xz - yw) * inv;
|
||||
m[7] = 2.0 * (yz + xw) * inv;
|
||||
m[8] = (-xx - yy + zz + ww) * inv;
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 868f0f079d08249bfbb371a0eaa8dbfe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
83
Assets/99.imdk_unity/Runtime/Scripts/Util/ImmersalLogger.cs
Normal file
83
Assets/99.imdk_unity/Runtime/Scripts/Util/ImmersalLogger.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
public class ImmersalLogger : MonoBehaviour
|
||||
{
|
||||
public enum LoggingLevel
|
||||
{
|
||||
All = 0,
|
||||
Verbose = 1,
|
||||
ErrorsAndWarnings = 2,
|
||||
ErrorsOnly = 3,
|
||||
None = 4
|
||||
}
|
||||
|
||||
public static LoggingLevel Level = LoggingLevel.All;
|
||||
|
||||
private const bool m_IncludeCallerName = true;
|
||||
private const string m_AdditionalPrefix = "";
|
||||
|
||||
// Include calling class name in logging messages
|
||||
private static string ProcessMessage(string message, string filePath = "")
|
||||
{
|
||||
if (m_IncludeCallerName)
|
||||
{
|
||||
string callerName;
|
||||
|
||||
// check if filePath is provided (by System.Runtime.CompilerServices)
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
callerName = System.IO.Path.GetFileNameWithoutExtension(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fall back to fetching calling class name from stack with reflection
|
||||
// note: will give unexpected results when call originates in an async Task
|
||||
|
||||
callerName = new StackFrame(2, false).GetMethod().DeclaringType?.Name
|
||||
?? "Unknown";
|
||||
}
|
||||
|
||||
message = $"[{callerName}] {message}";
|
||||
}
|
||||
|
||||
return $"{m_AdditionalPrefix}{message}";
|
||||
}
|
||||
|
||||
// note: filePath parameter is automagically included by System.Runtime.CompilerServices.CallerFilePath
|
||||
|
||||
public static void Log(string message, LoggingLevel messageLevel = LoggingLevel.All, [CallerFilePath] string filePath = "")
|
||||
{
|
||||
if (Level > messageLevel) return;
|
||||
UnityEngine.Debug.Log(ProcessMessage(message, filePath));
|
||||
}
|
||||
|
||||
public static void LogWarning(string message, [CallerFilePath] string filePath = "")
|
||||
{
|
||||
if (Level > LoggingLevel.ErrorsAndWarnings) return;
|
||||
UnityEngine.Debug.LogWarning(ProcessMessage(message, filePath));
|
||||
}
|
||||
|
||||
public static void LogError(string message, [CallerFilePath] string filePath = "")
|
||||
{
|
||||
if (Level > LoggingLevel.ErrorsOnly) return;
|
||||
UnityEngine.Debug.LogError(ProcessMessage(message, filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96faf0f52d99e4dd3ba0649f6b0f1e09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class InterfaceAttribute : PropertyAttribute
|
||||
{
|
||||
public Type TypeOfInterface;
|
||||
public InterfaceAttribute(Type type) { this.TypeOfInterface = type; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de499560337e94b6799eef1a2fcbd000
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
171
Assets/99.imdk_unity/Runtime/Scripts/Util/PlyImporter.cs
Normal file
171
Assets/99.imdk_unity/Runtime/Scripts/Util/PlyImporter.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
/*===============================================================================
|
||||
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
||||
|
||||
This file is part of the Immersal SDK.
|
||||
|
||||
The Immersal SDK cannot be copied, distributed, or made available to
|
||||
third-parties for commercial purposes without written permission of Immersal Ltd.
|
||||
|
||||
Contact sales@immersal.com for licensing requests.
|
||||
===============================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Immersal
|
||||
{
|
||||
public static class PlyImporter
|
||||
{
|
||||
public static Mesh PlyToMesh(byte[] bytes, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream(bytes))
|
||||
{
|
||||
Mesh mesh = StreamToMesh(stream);
|
||||
mesh.name = name;
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ImmersalLogger.LogError($"Failed importing {name}: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Mesh PlyToMesh(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
Mesh mesh = StreamToMesh(stream);
|
||||
mesh.name = Path.GetFileNameWithoutExtension(filePath);
|
||||
return mesh;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ImmersalLogger.LogError($"Failed importing {filePath}: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Mesh StreamToMesh(Stream stream)
|
||||
{
|
||||
if (!CheckHeader(new StreamReader(stream), out int vertexCount))
|
||||
throw new ArgumentException("Unexpected header data");
|
||||
|
||||
PlyDataBody body = ReadDataBody(new BinaryReader(stream), vertexCount);
|
||||
|
||||
var mesh = new Mesh
|
||||
{
|
||||
name = "Sparse",
|
||||
indexFormat = vertexCount > 65535 ? IndexFormat.UInt32 : IndexFormat.UInt16
|
||||
};
|
||||
|
||||
mesh.SetVertices(body.Vertices);
|
||||
mesh.SetColors(body.Colors);
|
||||
|
||||
mesh.SetIndices(
|
||||
Enumerable.Range(0, vertexCount).ToArray(),
|
||||
MeshTopology.Points, 0
|
||||
);
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
mesh.UploadMeshData(true);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private static bool CheckHeader(StreamReader reader, out int vertexCount, int maxHeaderLineReads = 15)
|
||||
{
|
||||
vertexCount = -1;
|
||||
int readCount = 0;
|
||||
int linesRead = 0;
|
||||
|
||||
// Magic number line ("ply")
|
||||
var line = reader.ReadLine();
|
||||
readCount += line.Length + 1;
|
||||
if (line != "ply")
|
||||
throw new ArgumentException("Magic number ('ply') mismatch.");
|
||||
|
||||
// check if it's binary/little endian.
|
||||
line = reader.ReadLine();
|
||||
readCount += line.Length + 1;
|
||||
if (line != "format binary_little_endian 1.0")
|
||||
throw new ArgumentException(
|
||||
"Invalid data format ('" + line + "'). " +
|
||||
"Should be binary/little endian.");
|
||||
|
||||
while (linesRead < maxHeaderLineReads)
|
||||
{
|
||||
line = reader.ReadLine();
|
||||
linesRead++;
|
||||
readCount += line.Length + 1;
|
||||
if (line == "end_header") break;
|
||||
var col = line.Split();
|
||||
|
||||
if (col[0] == "element")
|
||||
{
|
||||
if (col[1] == "vertex")
|
||||
{
|
||||
vertexCount = Convert.ToInt32(col[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rewind the stream back to the exact position of the reader.
|
||||
reader.BaseStream.Position = readCount;
|
||||
|
||||
return vertexCount > -1;
|
||||
}
|
||||
|
||||
private static PlyDataBody ReadDataBody(BinaryReader reader, int vertexCount)
|
||||
{
|
||||
PlyDataBody data = new PlyDataBody(vertexCount);
|
||||
|
||||
for (var i = 0; i < vertexCount; i++)
|
||||
{
|
||||
float x = reader.ReadSingle();
|
||||
float y = reader.ReadSingle();
|
||||
float z = reader.ReadSingle();
|
||||
Byte r = reader.ReadByte();
|
||||
Byte g = reader.ReadByte();
|
||||
Byte b = reader.ReadByte();
|
||||
|
||||
//a = reader.ReadByte();
|
||||
Byte a = Byte.MaxValue;
|
||||
|
||||
data.AddPoint(-x, y, z, r, g, b, a);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlyDataBody
|
||||
{
|
||||
public List<Vector3> Vertices;
|
||||
public List<Color32> Colors;
|
||||
|
||||
public PlyDataBody(int vertexCount)
|
||||
{
|
||||
Vertices = new List<Vector3>(vertexCount);
|
||||
Colors = new List<Color32>(vertexCount);
|
||||
}
|
||||
|
||||
public void AddPoint(
|
||||
float x, float y, float z,
|
||||
byte r, byte g, byte b, byte a
|
||||
)
|
||||
{
|
||||
Vertices.Add(new Vector3(x, y, z));
|
||||
Colors.Add(new Color32(r, g, b, a));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6e2d23c28b294a9197bb2445580a9f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user