/// <summary> /// Basic initialization of a MMMU /// </summary> /// <param name="mmuID"></param> /// <param name="sessionID"></param> public virtual MBoolResponse Initialize(MAvatarDescription avatarDescription, Dictionary <string, string> properties, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); this.skeletonAccess = new IntermediateSkeleton(); this.skeletonAccess.InitializeAnthropometry(avatarDescription); //Skip if invalid session result if (!sessionResult.Successful) { return(sessionResult); } try { //Update the access time sessionContent.UpdateLastAccessTime(); //Get the corresponding MMU IMotionModelUnitDev mmu = avatarContent.MMUs[mmuID]; Logger.Log(Log_level.L_INFO, "MMU initialized: " + mmu.Name + " " + sessionID); //Call the respective MMU return(avatarContent.MMUs[mmuID].Initialize(avatarDescription, properties)); } catch (Exception e) { Logger.Log(Log_level.L_ERROR, $"Problem at initializing MMU: {mmuID}, message: {e.Message}"); return(new MBoolResponse(false) { LogData = new List <string>() { e.Message, e.StackTrace, e.InnerException.ToString(), e.StackTrace } }); } }
/// <summary> /// Instantiates a MMU from file /// </summary> /// <param name="folderPath"></param> /// <param name="mmuDescription"></param> /// <param name="sessionId"></param> /// <returns></returns> public IMotionModelUnitDev InstantiateMMU(MMULoadingProperty mmuLoadingProperty) { //Check if the MMU supports the specified language if (mmuLoadingProperty.Description.Language != "C#" && mmuLoadingProperty.Description.Language != "C++CLR") { return(null); } //Load the mmu from filesystem and instantiate if (mmuLoadingProperty.Path != null) { Assembly assembly = Assembly.LoadFrom(mmuLoadingProperty.Path); //Get the specific type of the class which implementd the IMotionModelUnitDev interface Type classType = GetMMUClassType(assembly); if (classType != null) { try { //Create a new mmu instance within the same app domain IMotionModelUnitDev mmuInstance = Activator.CreateInstance(classType) as IMotionModelUnitDev; //To do -> in future instantiate directly from ram -> Loading properties already provide within the data dictionary all dlls and resources //To do -> incorporate app domain -> currently not working //IMotionModelUnitDev mmuInstance = InstantiateInAppDomain(mmuDescription, sessionContent.SessionId, filePath); return(mmuInstance); } catch (Exception e) { Logger.Log(Log_level.L_ERROR, $"Could not load MMU: {mmuLoadingProperty.Description.Name} {mmuLoadingProperty.Description.AssemblyName}, exception: {e.Message}"); } } } return(null); }
/// <summary> /// /// </summary> /// <param name="mmus"></param> /// <param name="sessionID"></param> /// <returns>A mapping from MMUID to a specific instance id</returns> public virtual Dictionary <string, string> LoadMMUs(List <string> mmus, string sessionID) { SessionContent sessionContent = null; SessionID idContainer = new SessionID(sessionID); //Get the session content for the id MBoolResponse sessionResult = SessionData.GetSessionContent(sessionID, out sessionContent); //Skip if invalid session result if (!sessionResult.Successful) { Logger.Log(Log_level.L_ERROR, "Cannot generate session content"); return(new Dictionary <string, string>()); } //Set the last access time sessionContent.UpdateLastAccessTime(); Dictionary <string, string> mmuInstanceMapping = new Dictionary <string, string>(); //Iterate over each desired MMU foreach (string mmuID in mmus) { MMULoadingProperty mmuLoadingProperty = null; //Skip MMU is not contained in adapter if (!SessionData.MMULoadingProperties.TryGetValue(mmuID, out mmuLoadingProperty)) { continue; } IMotionModelUnitDev mmu = null; //Instantiate MMU try { mmu = this.mmuInstantiator.InstantiateMMU(mmuLoadingProperty); } catch (Exception e) { Logger.Log(Log_level.L_ERROR, $"Problem at loading MMU {mmuLoadingProperty.Description.Name}, Exception: {e.Message}, {e.StackTrace}"); return(new Dictionary <string, string>()); } //Assign the service access mmu.ServiceAccess = sessionContent.ServiceAccess; //Assign the scene mmu.SceneAccess = sessionContent.SceneBuffer; //Assign a new instance of the skeleton access mmu.SkeletonAccess = this.skeletonAccess;//new SkeletonAccess(); //Set the instance as the adapter mmu.AdapterEndpoint = new AdapterEndpoint() { Instance = SessionData.AdapterInstance, Description = SessionData.AdapterDescription, MMIRegisterAddress = SessionData.MMIRegisterAddress }; Logger.Log(Log_level.L_INFO, $"Loaded MMU: {mmuLoadingProperty.Description.Name} for session: {sessionID}"); //Add to the specific avatar content AvatarContent avatarContent = null; if (!sessionContent.AvatarContent.TryGetValue(idContainer.AvatarID, out avatarContent)) { avatarContent = new AvatarContent(idContainer.AvatarID); sessionContent.AvatarContent.TryAdd(idContainer.AvatarID, avatarContent); } //Add the mmu avatarContent.MMUs.Add(mmuLoadingProperty.Description.ID, mmu); //To do -> create a unique instance ID mmuInstanceMapping.Add(mmuLoadingProperty.Description.ID, "tbd"); } return(mmuInstanceMapping); }
/// <summary> /// Instantiates a MMU from file /// </summary> /// <param name="folderPath"></param> /// <param name="mmuDescription"></param> /// <param name="sessionId"></param> /// <returns></returns> public IMotionModelUnitDev InstantiateMMU(MMULoadingProperty mmuLoadingProperty) { Debug.Log("Calling Unity MMU instantiator " + mmuLoadingProperty.Path); MMUDescription mmuDescription = mmuLoadingProperty.Description; string filePath = mmuLoadingProperty.Path; //Check if the MMU supports the specified language if (mmuDescription.Language != "UnityC#" && mmuDescription.Language != "Unity") { throw new NotSupportedException("MMU is not supported"); } //Skip if file path invalid if (filePath == null) { throw new NullReferenceException("File path of MMU is null " + mmuDescription.Name); } //Skip if the MMU has no dependencies if (mmuDescription.Dependencies.Count == 0) { throw new Exception("No dependencies of MMU specified " + mmuDescription.Name); } //Create a variable which hols the mmu IMotionModelUnitDev mmu = null; //Get the paths string folderPath = System.IO.Directory.GetParent(filePath).ToString(); string assetBundlePath = folderPath + "\\" + mmuDescription.Dependencies[0].Name; //Perform on unity main thread MainThreadDispatcher.Instance.ExecuteBlocking(delegate { //To do in futre -> Create a new scene for each MMU //Scene scene = SceneManager.CreateScene("Scene" + mmuDescription.Name); //SceneManager.SetActiveScene(scene); //First load the resources AssetBundle mmuAssetBundle = null; try { if (!mmuLoadingProperty.Data.ContainsKey(assetBundlePath)) { mmuAssetBundle = AssetBundle.LoadFromFile(assetBundlePath); if (mmuAssetBundle == null) { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, "Failed to load AssetBundle! AssetBundle is null!" + mmuDescription.Name); return; } mmuLoadingProperty.Data.Add(assetBundlePath, mmuAssetBundle); } else { mmuAssetBundle = mmuLoadingProperty.Data[assetBundlePath] as AssetBundle; } } catch (Exception e) { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, "Cannot load asset bundle: " + mmuDescription.Name + " " + e.Message); return; } GameObject prefab = null; try { prefab = mmuAssetBundle.LoadAsset <GameObject>(mmuDescription.Name); } catch (Exception e) { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, "Cannot load prefab: " + mmuDescription.Name + " " + e.Message); } GameObject mmuObj = null; try { mmuObj = GameObject.Instantiate(prefab); } catch (Exception e) { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, "Cannot instantiate prefab: " + mmuDescription.Name + " " + e.Message); } try { Assembly assembly = Assembly.LoadFile(filePath); //Find the class type which implements the IMotionModelInterface Type classType = assembly.GetTypes().ToList().Find(s => s.GetInterfaces().Contains(typeof(IMotionModelUnitDev))); if (classType != null) { //Add the script to the game object mmu = mmuObj.AddComponent(classType) as IMotionModelUnitDev; ///Loading and assigning the configuration file if (mmuObj.GetComponent <UnityMMUBase>() != null) { MMICSharp.Adapter.Logger.Log(Log_level.L_DEBUG, $"MMU {mmuDescription.Name} implements the UnityMMUBase"); //Get the UnityMMUBse interface UnityMMUBase mmuBase = mmuObj.GetComponent <UnityMMUBase>(); //By default set the configuration file path and define it globally string avatarConfigFilePath = AppDomain.CurrentDomain.BaseDirectory + "/" + "avatar.mos"; //Check if the MMU has a custom configuration file if (this.GetLocalAvatarConfigurationFile(folderPath, out string localConfigFilePath)) { //Setting the local avatar as reference for retargeting MMICSharp.Adapter.Logger.Log(Log_level.L_DEBUG, $"Local avatar configuration was found: {mmuDescription.Name} ({avatarConfigFilePath})."); //Set to the utilized path avatarConfigFilePath = localConfigFilePath; } //Further perform a check whether the file is available at all if (System.IO.File.Exists(avatarConfigFilePath)) { mmuBase.ConfigurationFilePath = avatarConfigFilePath; MMICSharp.Adapter.Logger.Log(Log_level.L_DEBUG, $"Setting the configuration file path for loading the avatar of {mmuDescription.Name} to {avatarConfigFilePath}"); } //Problem in here -> File is obviously not available else { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, $"Problem setting the configuration file path for loading the avatar of {mmuDescription.Name} to {avatarConfigFilePath}. File not available."); } } } else { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, "Cannot instantiate MMU: " + mmuDescription.Name); } } catch (Exception e) { MMICSharp.Adapter.Logger.Log(Log_level.L_ERROR, "Problem at instantiating class of MMU: " + mmuDescription.Name + " " + e.Message + " " + e.StackTrace); } //Disable all renderers in the scene foreach (Renderer renderer in GameObject.FindObjectsOfType <Renderer>()) { renderer.enabled = false; } });