|
|
- using UnityEngine;
- using Oculus.Avatar;
- using System;
- using System.Collections.Generic;
-
- public delegate void specificationCallback(IntPtr specification);
- public delegate void assetLoadedCallback(OvrAvatarAsset asset);
- public delegate void combinedMeshLoadedCallback(IntPtr asset);
-
- public class OvrAvatarSDKManager : MonoBehaviour
- {
- private static OvrAvatarSDKManager _instance;
- private bool initialized = false;
- private Dictionary<ulong, HashSet<specificationCallback>> specificationCallbacks;
- private Dictionary<ulong, HashSet<assetLoadedCallback>> assetLoadedCallbacks;
- private Dictionary<IntPtr, combinedMeshLoadedCallback> combinedMeshLoadedCallbacks;
- private Dictionary<UInt64, OvrAvatarAsset> assetCache;
- private OvrAvatarTextureCopyManager textureCopyManager;
-
- public ovrAvatarLogLevel LoggingLevel = ovrAvatarLogLevel.Info;
- private Queue<AvatarSpecRequestParams> avatarSpecificationQueue;
- private List<int> loadingAvatars;
- private bool avatarSpecRequestAvailable = true;
- private float lastDispatchedAvatarSpecRequestTime = 0f;
- private const float AVATAR_SPEC_REQUEST_TIMEOUT = 5f;
-
- #if AVATAR_DEBUG
- private ovrAvatarDebugContext debugContext = ovrAvatarDebugContext.None;
- #endif
-
- public struct AvatarSpecRequestParams
- {
- public UInt64 _userId;
- public specificationCallback _callback;
- public bool _useCombinedMesh;
- public ovrAvatarAssetLevelOfDetail _lod;
- public bool _forceMobileTextureFormat;
- public ovrAvatarLookAndFeelVersion _lookVersion;
- public ovrAvatarLookAndFeelVersion _fallbackVersion;
- public bool _enableExpressive;
-
- public AvatarSpecRequestParams(
- UInt64 userId,
- specificationCallback callback,
- bool useCombinedMesh,
- ovrAvatarAssetLevelOfDetail lod,
- bool forceMobileTextureFormat,
- ovrAvatarLookAndFeelVersion lookVersion,
- ovrAvatarLookAndFeelVersion fallbackVersion,
- bool enableExpressive)
- {
- _userId = userId;
- _callback = callback;
- _useCombinedMesh = useCombinedMesh;
- _lod = lod;
- _forceMobileTextureFormat = forceMobileTextureFormat;
- _lookVersion = lookVersion;
- _fallbackVersion = fallbackVersion;
- _enableExpressive = enableExpressive;
- }
- }
-
- public static OvrAvatarSDKManager Instance
- {
- get
- {
- if (_instance == null)
- {
- _instance = GameObject.FindObjectOfType<OvrAvatarSDKManager>();
- if (_instance == null)
- {
- GameObject manager = new GameObject("OvrAvatarSDKManager");
- _instance = manager.AddComponent<OvrAvatarSDKManager>();
- _instance.textureCopyManager = manager.AddComponent<OvrAvatarTextureCopyManager>();
- _instance.initialized = _instance.Initialize();
- }
- }
- return _instance.initialized ? _instance : null;
- }
- }
-
- private bool Initialize()
- {
- CAPI.Initialize();
-
- string appId = GetAppId();
-
- if (appId == "")
- {
- AvatarLogger.LogError("No Oculus App ID has been provided for target platform. " +
- "Go to Oculus Avatar > Edit Configuration to supply one", OvrAvatarSettings.Instance);
- appId = "0";
- }
-
- #if UNITY_ANDROID && !UNITY_EDITOR
- #if AVATAR_XPLAT
- CAPI.ovrAvatar_Initialize(appId);
- #else
- CAPI.ovrAvatar_InitializeAndroidUnity(appId);
- #endif
- #else
- CAPI.ovrAvatar_Initialize(appId);
- CAPI.SendEvent("initialize", appId);
- #endif
- specificationCallbacks = new Dictionary<UInt64, HashSet<specificationCallback>>();
- assetLoadedCallbacks = new Dictionary<UInt64, HashSet<assetLoadedCallback>>();
- combinedMeshLoadedCallbacks = new Dictionary<IntPtr, combinedMeshLoadedCallback>();
- assetCache = new Dictionary<ulong, OvrAvatarAsset>();
- avatarSpecificationQueue = new Queue<AvatarSpecRequestParams>();
- loadingAvatars = new List<int>();
-
- CAPI.ovrAvatar_SetLoggingLevel(LoggingLevel);
- CAPI.ovrAvatar_RegisterLoggingCallback(CAPI.LoggingCallback);
- #if AVATAR_DEBUG
- CAPI.ovrAvatar_SetDebugDrawContext((uint)debugContext);
- #endif
-
- return true;
- }
-
- void OnDestroy()
- {
- CAPI.Shutdown();
- CAPI.ovrAvatar_RegisterLoggingCallback(null);
- CAPI.ovrAvatar_Shutdown();
- }
-
- void Update()
- {
- if (Instance == null)
- {
- return;
- }
- #if AVATAR_DEBUG
- // Call before ovrAvatarMessage_Pop which flushes the state
- CAPI.ovrAvatar_DrawDebugLines();
- #endif
-
- // Dispatch waiting avatar spec request
- if (avatarSpecificationQueue.Count > 0 &&
- (avatarSpecRequestAvailable ||
- Time.time - lastDispatchedAvatarSpecRequestTime >= AVATAR_SPEC_REQUEST_TIMEOUT))
- {
- avatarSpecRequestAvailable = false;
- AvatarSpecRequestParams avatarSpec = avatarSpecificationQueue.Dequeue();
- DispatchAvatarSpecificationRequest(avatarSpec);
- lastDispatchedAvatarSpecRequestTime = Time.time;
- AvatarLogger.Log("Avatar spec request dispatched: " + avatarSpec._userId);
- }
-
- IntPtr message = CAPI.ovrAvatarMessage_Pop();
- if (message == IntPtr.Zero)
- {
- return;
- }
-
- ovrAvatarMessageType messageType = CAPI.ovrAvatarMessage_GetType(message);
- switch (messageType)
- {
- case ovrAvatarMessageType.AssetLoaded:
- {
- ovrAvatarMessage_AssetLoaded assetMessage = CAPI.ovrAvatarMessage_GetAssetLoaded(message);
- IntPtr asset = assetMessage.asset;
- UInt64 assetID = assetMessage.assetID;
- ovrAvatarAssetType assetType = CAPI.ovrAvatarAsset_GetType(asset);
- OvrAvatarAsset assetData = null;
- IntPtr avatarOwner = IntPtr.Zero;
-
- switch (assetType)
- {
- case ovrAvatarAssetType.Mesh:
- assetData = new OvrAvatarAssetMesh(assetID, asset, ovrAvatarAssetType.Mesh);
- break;
- case ovrAvatarAssetType.Texture:
- assetData = new OvrAvatarAssetTexture(assetID, asset);
- break;
- case ovrAvatarAssetType.Material:
- assetData = new OvrAvatarAssetMaterial(assetID, asset);
- break;
- case ovrAvatarAssetType.CombinedMesh:
- avatarOwner = CAPI.ovrAvatarAsset_GetAvatar(asset);
- assetData = new OvrAvatarAssetMesh(assetID, asset, ovrAvatarAssetType.CombinedMesh);
- break;
- case ovrAvatarAssetType.FailedLoad:
- AvatarLogger.LogWarning("Asset failed to load from SDK " + assetID);
- break;
- default:
- throw new NotImplementedException(string.Format("Unsupported asset type format {0}", assetType.ToString()));
- }
-
- HashSet<assetLoadedCallback> callbackSet;
- if (assetType == ovrAvatarAssetType.CombinedMesh)
- {
- if (!assetCache.ContainsKey(assetID))
- {
- assetCache.Add(assetID, assetData);
- }
-
- combinedMeshLoadedCallback callback;
- if (combinedMeshLoadedCallbacks.TryGetValue(avatarOwner, out callback))
- {
- callback(asset);
- combinedMeshLoadedCallbacks.Remove(avatarOwner);
- }
- else
- {
- AvatarLogger.LogWarning("Loaded a combined mesh with no owner: " + assetMessage.assetID);
- }
- }
- else
- {
- if (assetData != null && assetLoadedCallbacks.TryGetValue(assetMessage.assetID, out callbackSet))
- {
- assetCache.Add(assetID, assetData);
-
- foreach (var callback in callbackSet)
- {
- callback(assetData);
- }
-
- assetLoadedCallbacks.Remove(assetMessage.assetID);
- }
- }
- break;
- }
- case ovrAvatarMessageType.AvatarSpecification:
- {
- avatarSpecRequestAvailable = true;
- ovrAvatarMessage_AvatarSpecification spec = CAPI.ovrAvatarMessage_GetAvatarSpecification(message);
- HashSet<specificationCallback> callbackSet;
- if (specificationCallbacks.TryGetValue(spec.oculusUserID, out callbackSet))
- {
- foreach (var callback in callbackSet)
- {
- callback(spec.avatarSpec);
- }
-
- specificationCallbacks.Remove(spec.oculusUserID);
- }
- else
- {
- AvatarLogger.LogWarning("Error, got an avatar specification callback from a user id we don't have a record for: " + spec.oculusUserID);
- }
- break;
- }
- default:
- throw new NotImplementedException("Unhandled ovrAvatarMessageType: " + messageType);
- }
- CAPI.ovrAvatarMessage_Free(message);
- }
-
- public bool IsAvatarSpecWaiting()
- {
- return avatarSpecificationQueue.Count > 0;
- }
-
- public bool IsAvatarLoading()
- {
- return loadingAvatars.Count > 0;
- }
-
- // Add avatar gameobject ID to loading list to keep track of loading avatars
- public void AddLoadingAvatar(int gameobjectID)
- {
- loadingAvatars.Add(gameobjectID);
- }
-
- // Remove avatar gameobject ID from loading list
- public void RemoveLoadingAvatar(int gameobjectID)
- {
- loadingAvatars.Remove(gameobjectID);
- }
-
- // Request an avatar specification to be loaded by adding to the queue.
- // Requests are dispatched in Update().
- public void RequestAvatarSpecification(AvatarSpecRequestParams avatarSpecRequest)
- {
- avatarSpecificationQueue.Enqueue(avatarSpecRequest);
- AvatarLogger.Log("Avatar spec request queued: " + avatarSpecRequest._userId.ToString());
- }
-
- private void DispatchAvatarSpecificationRequest(AvatarSpecRequestParams avatarSpecRequest)
- {
- textureCopyManager.CheckFallbackTextureSet(avatarSpecRequest._lod);
- CAPI.ovrAvatar_SetForceASTCTextures(avatarSpecRequest._forceMobileTextureFormat);
-
- HashSet<specificationCallback> callbackSet;
- if (!specificationCallbacks.TryGetValue(avatarSpecRequest._userId, out callbackSet))
- {
- callbackSet = new HashSet<specificationCallback>();
- specificationCallbacks.Add(avatarSpecRequest._userId, callbackSet);
-
- IntPtr specRequest = CAPI.ovrAvatarSpecificationRequest_Create(avatarSpecRequest._userId);
- CAPI.ovrAvatarSpecificationRequest_SetLookAndFeelVersion(specRequest, avatarSpecRequest._lookVersion);
- CAPI.ovrAvatarSpecificationRequest_SetFallbackLookAndFeelVersion(specRequest, avatarSpecRequest._fallbackVersion);
- CAPI.ovrAvatarSpecificationRequest_SetLevelOfDetail(specRequest, avatarSpecRequest._lod);
- CAPI.ovrAvatarSpecificationRequest_SetCombineMeshes(specRequest, avatarSpecRequest._useCombinedMesh);
- CAPI.ovrAvatarSpecificationRequest_SetExpressiveFlag(specRequest, avatarSpecRequest._enableExpressive);
- CAPI.ovrAvatar_RequestAvatarSpecificationFromSpecRequest(specRequest);
- CAPI.ovrAvatarSpecificationRequest_Destroy(specRequest);
- }
-
- callbackSet.Add(avatarSpecRequest._callback);
- }
-
- public void BeginLoadingAsset(
- UInt64 assetId,
- ovrAvatarAssetLevelOfDetail lod,
- assetLoadedCallback callback)
- {
- HashSet<assetLoadedCallback> callbackSet;
- if (!assetLoadedCallbacks.TryGetValue(assetId, out callbackSet))
- {
- callbackSet = new HashSet<assetLoadedCallback>();
- assetLoadedCallbacks.Add(assetId, callbackSet);
- }
- AvatarLogger.Log("Loading Asset ID: " + assetId);
- CAPI.ovrAvatarAsset_BeginLoadingLOD(assetId, lod);
- callbackSet.Add(callback);
- }
-
- public void RegisterCombinedMeshCallback(
- IntPtr sdkAvatar,
- combinedMeshLoadedCallback callback)
- {
- combinedMeshLoadedCallback currentCallback;
- if (!combinedMeshLoadedCallbacks.TryGetValue(sdkAvatar, out currentCallback))
- {
- combinedMeshLoadedCallbacks.Add(sdkAvatar, callback);
- }
- else
- {
- throw new Exception("Adding second combind mesh callback for same avatar");
- }
- }
-
- public OvrAvatarAsset GetAsset(UInt64 assetId)
- {
- OvrAvatarAsset asset;
- if (assetCache.TryGetValue(assetId, out asset))
- {
- return asset;
- }
- else
- {
- return null;
- }
- }
-
- public void DeleteAssetFromCache(UInt64 assetId)
- {
- if (assetCache.ContainsKey(assetId))
- {
- assetCache.Remove(assetId);
- }
- }
-
- public string GetAppId()
- {
- return UnityEngine.Application.platform == RuntimePlatform.Android ?
- OvrAvatarSettings.MobileAppID : OvrAvatarSettings.AppID;
- }
-
- public OvrAvatarTextureCopyManager GetTextureCopyManager()
- {
- if (textureCopyManager != null)
- {
- return textureCopyManager;
- }
- else
- {
- return null;
- }
- }
- }
|