using GLTFast;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
public class SceneManagementGLTF : MonoBehaviour
{
///
/// Path to GLTF File (relative to streaming assets in editor, else persistentdatapath)
///
public string _PathToGLTF;
///
/// Validity in milliseconds for a subscription to the WA
///
public int _ValiditySubscription = 100000;
///
/// List of trackables and anchors in the AR Scene
///
private Dictionary m_trackablesAndAnchorsInARScene;
///
/// Unity Start Method
///
protected async void Start()
{
m_trackablesAndAnchorsInARScene = new Dictionary();
await LoadGltfBinaryFromMemory();
Transform loaded = this.transform.GetChild(0);
FindWorldStorageTransform(loaded);
foreach(KeyValuePair toSubscribe in m_trackablesAndAnchorsInARScene)
{
int validity = _ValiditySubscription;
Guid subscriptionUUID;
// TODO : if only one : subscribeToPose, if multiple subscribetoPoses
WorldAnalysisInterface.Instance.SubscribeToPose(null, toSubscribe.Key, ETSI.ARF.OpenAPI.WorldAnalysis.Mode_WorldAnalysis.DEVICE_TO_TRACKABLES, PoseCallback, ref validity, out subscriptionUUID); //TODO : find a value for the token parameter.
}
}
///
/// The callback function used in the susbscription method. It instantiate a prefab or update its pose based on the current situation.
///
///
/// The pose to update in the SM
public void PoseCallback(WorldAnalysisInterface.PoseEstimationResult result, ETSI.ARF.OpenAPI.WorldAnalysis.Pose pose)
{
if (pose.EstimationState != ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.OK)
{
Debug.Log("State Not Ok for " + pose.Uuid + " "+ pose.EstimationState.ToString() + " " + pose.InstructionInfo);
return;
}
if (pose.Value.Type == ETSI.ARF.OpenAPI.WorldAnalysis.PoseValueType.VECTOR_QUATERNION)
{
ETSI.ARF.OpenAPI.WorldAnalysis.VectorQuaternionPoseValue value = (ETSI.ARF.OpenAPI.WorldAnalysis.VectorQuaternionPoseValue)pose.Value;
if (m_trackablesAndAnchorsInARScene.ContainsKey(pose.Uuid))
{
m_trackablesAndAnchorsInARScene[pose.Uuid].transform.position = WorldAnalysisUnityHelper.ConvertETSIVector3ToUnity(value.Position);
m_trackablesAndAnchorsInARScene[pose.Uuid].transform.rotation = WorldAnalysisUnityHelper.ConvertETSIARFQuaternionToUnity(value.Rotation);
}
else
{
Debug.LogWarning("Callback for unwanted uuid");
}
}
else
{
Debug.LogWarning("Pose value type not supported yet :" +pose.Value.Type); // Todo : manage other types
}
}
///
/// Load a GLTF from local memory according to _PathToGLTF
///
/// ascync method
protected async Task LoadGltfBinaryFromMemory()
{
#if UNITY_EDITOR
string prefix = Application.streamingAssetsPath;
#else
string prefix = Application.persistentDataPath;
#endif
var filePath = prefix + "/" + _PathToGLTF;
Debug.Log("PATH : " + filePath);
byte[] data = File.ReadAllBytes(filePath);
Debug.Log("File Size " + data.Length);
var gltf = new GltfImport();
bool success = await gltf.LoadGltfBinary(
data,
// The URI of the original data is important for resolving relative URIs within the glTF
new Uri(filePath)
);
GameObjectInstantiator instantiator = new GameObjectInstantiator(gltf, this.transform);
if (success)
{
success = await gltf.InstantiateMainSceneAsync(instantiator);
}
}
///
/// In the loaded GLTF File : find all World Storage Trackables and Anchors
///
/// Loaded GLTF Transforms
protected void FindWorldStorageTransform(Transform trGLTF)
{
if (trGLTF.name.StartsWith("ws:"))
{
string id = trGLTF.name.Substring(3);
Debug.Log("Add " + id + " " + trGLTF.name);
m_trackablesAndAnchorsInARScene.Add(new Guid(id), trGLTF);
}
foreach(Transform child in trGLTF)
{
FindWorldStorageTransform(child);
}
}
}