/// <summary> /// Applies the scene manipulation on the scene /// </summary> /// <param name="sceneUpdates">The scene manipulations to be considered</param> /// <param name="deepCopy">Specifies whether the scene manipulations are directly applied or a deep copy is performed</param> public virtual MBoolResponse Apply(MSceneUpdate sceneUpdate, bool deepCopy = false) { MBoolResponse result = new MBoolResponse(true); //Increment the frame id this.FrameID++; //Stores the history SceneHistory.Enqueue(new Tuple <int, MSceneUpdate>(FrameID, sceneUpdate)); //Only allow the max buffer size while (SceneHistory.Count > this.HistoryBufferSize) { this.SceneHistory.Dequeue(); } //Set the scene changes to the input of the present frame this.SceneUpdate = sceneUpdate; //Check if there are avatars to be added if (sceneUpdate.AddedAvatars?.Count > 0) { this.AddAvatars(sceneUpdate.AddedAvatars, deepCopy); } //Check if there are new scene objects which should be added if (sceneUpdate.AddedSceneObjects?.Count > 0) { this.AddSceneObjects(sceneUpdate.AddedSceneObjects, deepCopy); } //Check if there are changed avatars that need to be retransmitted if (sceneUpdate.ChangedAvatars?.Count > 0) { this.UpdateAvatars(sceneUpdate.ChangedAvatars, deepCopy); } //Check if there are changed sceneObjects that need to be retransmitted if (sceneUpdate.ChangedSceneObjects?.Count > 0) { this.UpdateSceneObjects(sceneUpdate.ChangedSceneObjects, deepCopy); } //Check if there are avatars that need to be removed if (sceneUpdate.RemovedAvatars?.Count > 0) { this.RemoveAvatars(sceneUpdate.RemovedAvatars, deepCopy); } //Check if there are scene objects that need to be removed if (sceneUpdate.RemovedSceneObjects?.Count > 0) { this.RemoveSceneObjects(sceneUpdate.RemovedSceneObjects, deepCopy); } return(result); }
/// <summary> /// Returns the contents of the respective sessionID (if available). /// Otherwise false is returned, whereas the specific message is provided in the LogData. /// </summary> /// <param name="sessionID"></param> /// <param name="sessionContent"></param> /// <param name="avatarContent"></param> /// <returns></returns> public MBoolResponse GetContents(string sessionID, out SessionContent sessionContent, out AvatarContent avatarContent) { sessionContent = null; avatarContent = null; MBoolResponse sessionResult = GetSessionContent(sessionID, out sessionContent); if (!sessionResult.Successful) { return(sessionResult); } SessionID idContainer = new SessionID(sessionID); if (!sessionContent.AvatarContent.TryGetValue(idContainer.AvatarID, out avatarContent)) { //Session content not available return(new MBoolResponse(false) { LogData = new List <string>() { "Avatar content not available " + sessionID + ", avatarId: " + idContainer.AvatarID } }); } return(new MBoolResponse(true)); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState avatarState) { //Initialize the ik service this.ServiceAccess.IKService.Setup(this.AvatarDescription, new Dictionary <string, string>()); //Create a new constraint manager this.constraintManager = new ConstraintManager(this.SceneAccess); //Assign the instruction this.instruction = instruction; //Set state to ik this.state = ReleaseMotionState.IK; this.trajectoryIndex = 0; //Parse the parameters MBoolResponse response = this.ParseParameters(instruction); if (!response.Successful) { return(response); } return(new MBoolResponse(true)); }
/// <summary> /// Initialization method -> just call the base class /// </summary> /// <param name="avatarDescription"></param> /// <param name="properties"></param> /// <returns></returns> public override MBoolResponse Initialize(MAvatarDescription avatarDescription, Dictionary <string, string> properties) { MBoolResponse res = base.Initialize(avatarDescription, properties); this.SkeletonAccess = new IntermediateSkeleton(); this.SkeletonAccess.InitializeAnthropometry(avatarDescription); return(res); }
public MBoolResponse ApplyUpdates(MSceneUpdate sceneUpdates) { MBoolResponse response = new MBoolResponse(false); //Execute on main thread MainThreadDispatcher.Instance.ExecuteBlocking(() => { response = this.sceneAccess.ApplyUpdates(sceneUpdates); }); return(response); }
/// <summary> /// Initialization method -> just call the base class /// </summary> /// <param name="avatarDescription"></param> /// <param name="properties"></param> /// <returns></returns> public override MBoolResponse Initialize(MAvatarDescription avatarDescription, Dictionary <string, string> properties) { MBoolResponse res = base.Initialize(avatarDescription, properties); // Added new intermediate skeleton representation. this.SkeletonAccess = new IntermediateSkeleton(); this.SkeletonAccess.InitializeAnthropometry(avatarDescription); this.constraintManager = new ConstraintManager(this.SceneAccess); return(res); }
/// <summary> /// Initialization method -> just call the base class /// </summary> /// <param name="avatarDescription"></param> /// <param name="properties"></param> /// <returns></returns> public override MBoolResponse Initialize(MAvatarDescription avatarDescription, Dictionary <string, string> properties) { MBoolResponse response = base.Initialize(avatarDescription, properties); //Setuo the skeleton access this.SkeletonAccess = new IntermediateSkeleton(); this.SkeletonAccess.InitializeAnthropometry(avatarDescription); //Create a new constraint manager this.constraintManager = new ConstraintManager(this.SceneAccess); return(response); }
public virtual List <MConstraint> GetBoundaryConstraints(MInstruction instruction, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(new List <MConstraint>()); } sessionContent.UpdateLastAccessTime(); return(avatarContent.MMUs[mmuID].GetBoundaryConstraints(instruction)); }
public virtual List <MMUDescription> GetMMus(string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(new List <MMUDescription>()); } sessionContent.UpdateLastAccessTime(); return(SessionData.MMUDescriptions.Where(s => avatarContent.MMUs.Keys.Contains(s.ID)).ToList()); }
public virtual MBoolResponse Dispose(string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(sessionResult); } sessionContent.UpdateLastAccessTime(); //Call the dispose method of the respective MMU return(avatarContent.MMUs[mmuID].Dispose(new Dictionary <string, string>())); }
public virtual MBoolResponse Abort(string instructionId, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(sessionResult); } sessionContent.UpdateLastAccessTime(); //Abort the respective MMU return(avatarContent.MMUs[mmuID].Abort(instructionId)); }
/// <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 } }); } }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //Setup the ik this.ServiceAccess.IKService.Setup(this.AvatarDescription, new Dictionary <string, string>()); //Reset all flags/states this.constraintManager = new ConstraintManager(this.SceneAccess); this.singleShotIK = false; this.singleShotIKTargetPosture = null; //Assign the instruction this.instruction = instruction; //Parse the parameters MBoolResponse result = this.ParseParameters(instruction); if (!result.Successful) { return(result); } //Compute the target posture if (this.singleShotIK) { List <MConstraint> tempConstraints = new List <MConstraint>(); constraintManager.SetConstraints(ref tempConstraints); //Set the ik constraints constraintManager.SetEndeffectorConstraint(this.handJoint, targetTransform.Position, targetTransform.Rotation); //Compute the posture MIKServiceResult ikResult = this.ServiceAccess.IKService.CalculateIKPosture(simulationState.Current, constraintManager.GetJointConstraints(), new Dictionary <string, string>()); this.singleShotIKTargetPosture = ikResult.Posture.Copy(); //Clear the constraints in the constraint manager tempConstraints.Clear(); } //Return true/success return(new MBoolResponse(true)); }
/// <summary> /// Adds scene obnjects to the internal scene representation /// </summary> /// <param name="sceneObjects"></param> /// <param name="deepCopy"></param> /// <returns></returns> private MBoolResponse AddSceneObjects(List <MSceneObject> sceneObjects, bool deepCopy) { MBoolResponse result = new MBoolResponse(true); //Iterate over each scene object foreach (MSceneObject sceneObject in sceneObjects) { if (this.sceneObjectsByID.ContainsKey(sceneObject.ID)) { if (result.LogData == null) { result.LogData = new List <string>(); } result.LogData.Add($"Cannot add scene object {sceneObject.Name}, object is already registered"); continue; } //Add the scene object to id dictionary if (!sceneObjectsByID.ContainsKey(sceneObject.ID)) { //Add either a clone or the original one this.sceneObjectsByID.Add(sceneObject.ID, deepCopy ? sceneObject.Clone() : sceneObject); } //Add name <-> id mapping if (!this.nameIdMappingSceneObjects.ContainsKey(sceneObject.Name)) { this.nameIdMappingSceneObjects.Add(sceneObject.Name, new List <string>() { sceneObject.ID }); } else { //To do check if list already contains the id this.nameIdMappingSceneObjects[sceneObject.Name].Add(sceneObject.ID); } } return(result); }
public virtual MBoolResponse CheckPrerequisites(MInstruction instruction, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(sessionResult); } sessionContent.UpdateLastAccessTime(); //Execute the method of the MMU return(avatarContent.MMUs[mmuID].CheckPrerequisites(instruction)); }
/// <summary> /// Basic do step routine which triggers the simulation update of the repsective MMU /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <param name="mmuID"></param> /// <param name="sessionID"></param> /// <returns></returns> public virtual MSimulationResult DoStep(double time, MSimulationState simulationState, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); //Skip if invalid session result if (!sessionResult.Successful) { return(null); } sessionContent.UpdateLastAccessTime(); //Execute the do step of the respective MMU return(avatarContent.MMUs[mmuID].DoStep(time, simulationState)); }
/// <summary> /// Validates whether the instruction is correct regarding the available MMUs /// </summary> /// <param name="instruction"></param> /// <param name="availableMMUs"></param> /// <returns></returns> public virtual MBoolResponse Validate(MInstruction instruction, List <MMUDescription> availableMMUs) { //Check if the motion type is present List <MMUDescription> matchingDescriptions = availableMMUs.Where(s => s.MotionType == instruction.MotionType).ToList(); if (matchingDescriptions.Count == 0) { return(new MBoolResponse(false) { LogData = new List <string>() { "No matching MMU available (motionType)" } }); } //Create a new container to provide the result MBoolResponse result = new MBoolResponse(true) { LogData = new List <string>() }; //Next check the parameters foreach (MMUDescription description in matchingDescriptions) { foreach (var validationFunction in this.ValidationFunctions) { MBoolResponse currentResult = validationFunction(instruction, description); //Invalid instruction if (!currentResult.Successful) { //Set successful to false result.Successful = false; //Add the log data result.LogData.AddRange(currentResult.LogData); } } } return(result); }
public Dictionary <string, string> ExecuteFunction(string name, Dictionary <string, string> parameters, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(null); } sessionContent.UpdateLastAccessTime(); Logger.Log(Log_level.L_DEBUG, $"Ecexute function {name} of {mmuID}"); return(avatarContent.MMUs[mmuID].ExecuteFunction(name, parameters)); }
public virtual MBoolResponse RestoreCheckpoint(string mmuID, string sessionID, byte[] checkpointData) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(sessionResult); } sessionContent.UpdateLastAccessTime(); Logger.Log(Log_level.L_INFO, $"Restore checkpoint of {mmuID}"); return(avatarContent.MMUs[mmuID].RestoreCheckpoint(checkpointData)); }
/// <summary> /// Adds avatars to the internal scene representation /// </summary> /// <param name="avatars"></param> /// <param name="deepCopy"></param> private MBoolResponse AddAvatars(List <MAvatar> avatars, bool deepCopy) { MBoolResponse result = new MBoolResponse(true); //Iterate over each avatar foreach (MAvatar avatar in avatars) { if (this.avatarsByID.ContainsKey(avatar.ID)) { if (result.LogData == null) { result.LogData = new List <string>(); } result.LogData.Add($"Cannot add avatar {avatar.Name}, object is already registered"); continue; } //Add the scene object to id dictionary if (!this.avatarsByID.ContainsKey(avatar.ID)) { //Add either a clone or the original one this.avatarsByID.Add(avatar.ID, deepCopy ? avatar.Clone() : avatar); } //Add name <-> id mapping if (!this.nameIdMappingAvatars.ContainsKey(avatar.Name)) { this.nameIdMappingAvatars.Add(avatar.Name, new List <string>() { avatar.ID }); } else { //To do check if list already contains the id this.nameIdMappingAvatars[avatar.ID].Add(avatar.ID); } } return(result); }
/// <summary> /// Should work /// </summary> /// <param name="sceneManipulations"></param> /// <param name="sessionID"></param> public virtual MBoolResponse PushScene(MSceneUpdate sceneUpdates, string sessionID) { SessionContent sessionContent = null; //Get the session content for the id MBoolResponse sessionResult = SessionData.GetSessionContent(sessionID, out sessionContent); //Skip if invalid session result if (!sessionResult.Successful) { Debug.Fail(sessionResult.LogData.ToString()); return(sessionResult); } //Set the last access time sessionContent.UpdateLastAccessTime(); //Synchronize the respective scene return(sessionContent.SceneBuffer.Apply(sceneUpdates)); }
/// <summary> /// Returns the deltas of the last frame /// </summary> /// <param name="sessionID"></param> /// <returns></returns> public virtual MSceneUpdate GetSceneChanges(string sessionID) { SessionContent sessionContent = null; MBoolResponse sessionResult = SessionData.GetSessionContent(sessionID, out sessionContent); if (sessionResult.Successful) { //Set the last access time sessionContent.UpdateLastAccessTime(); return(sessionContent.SceneBuffer.GetSceneChanges()); } else { Logger.Log(Log_level.L_ERROR, sessionResult.LogData.ToString()); } return(new MSceneUpdate()); }
/// <summary> /// Creates a checkpoint for all specified MMUs. /// The checkpoint contains the internal state of each MMU whoch can be later used to restore the state. /// </summary> /// <param name="mmuIDs"></param> /// <param name="sessionID"></param> /// <param name="checkpointID"></param> public virtual byte[] CreateCheckpoint(string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); if (!sessionResult.Successful) { return(null); } sessionContent.UpdateLastAccessTime(); //Add method to interface byte[] checkpointData = avatarContent.MMUs[mmuID].CreateCheckpoint(); Logger.Log(Log_level.L_INFO, $"Checkpoint of {mmuID} sucessfully created ({checkpointData.Length} bytes)"); return(checkpointData); }
/// <summary> /// Execute command of a MMU /// </summary> /// <param name="instruction"></param> /// <param name="simulationState"></param> /// <param name="hierarchy"></param> /// <param name="mmuID"></param> /// <param name="sessionID"></param> public virtual MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); //Directly return if not successfull if (!sessionResult.Successful) { return(sessionResult); } sessionContent.UpdateLastAccessTime(); Logger.Log(Log_level.L_DEBUG, $"Execute instruction {instruction.Name}, {mmuID}"); //Directly assign the instruction return(avatarContent.MMUs[mmuID].AssignInstruction(instruction, simulationState)); }
/// <summary> /// Returns the scene contained within the adapter /// </summary> /// <param name="sessionID"></param> /// <returns></returns> public virtual List <MSceneObject> GetScene(string sessionID) { SessionContent sessionContent = null; MBoolResponse sessionResult = SessionData.GetSessionContent(sessionID, out sessionContent); if (sessionResult.Successful) { //Set the last access time sessionContent.UpdateLastAccessTime(); Logger.Log(Log_level.L_INFO, "Transfer all scene objects"); return(sessionContent.SceneBuffer.GetSceneObjects()); } else { Debug.Fail(sessionResult.LogData.ToString()); } return(new List <MSceneObject>()); }
private MBoolResponse RemoveSceneObjects(List <string> sceneObjectIDs, bool deepCopy) { MBoolResponse result = new MBoolResponse(true); //Iterate over each scene object foreach (string id in sceneObjectIDs) { //Find the object if (sceneObjectsByID.ContainsKey(id)) { string sceneObjectName = sceneObjectsByID[id].Name; //Remove the mapping if (nameIdMappingSceneObjects.ContainsKey(sceneObjectName)) { nameIdMappingSceneObjects[sceneObjectName].Remove(id); } //Remove the scene object from the dictionary sceneObjectsByID.Remove(id); } } return(result); }
/// <summary> /// Adds avatars to the internal scene representation /// </summary> /// <param name="avatars"></param> /// <param name="deepCopy"></param> private MBoolResponse UpdateAvatars(List <MAvatarUpdate> avatars, bool deepCopy) { MBoolResponse result = new MBoolResponse(true); //Iterate over each avatar foreach (MAvatarUpdate avatarUpdate in avatars) { //Add the scene object to id dictionary if (!this.avatarsByID.ContainsKey(avatarUpdate.ID)) { result.LogData.Add($"Cannot update avatar {avatarUpdate.ID}, object is not available"); } if (this.avatarsByID.ContainsKey(avatarUpdate.ID)) { if (avatarUpdate.Description != null) { this.avatarsByID[avatarUpdate.ID].Description = avatarUpdate.Description; } if (avatarUpdate.PostureValues != null) { this.avatarsByID[avatarUpdate.ID].PostureValues = avatarUpdate.PostureValues; } if (avatarUpdate.SceneObjects != null) { this.avatarsByID[avatarUpdate.ID].SceneObjects = avatarUpdate.SceneObjects; } //To do update the name <-> id mapping } } return(result); }
private MBoolResponse RemoveAvatars(List <string> avatarIDs, bool deepCopy) { MBoolResponse result = new MBoolResponse(true); //Iterate over each scene object foreach (string id in avatarIDs) { //Find the object if (avatarsByID.ContainsKey(id)) { string avatarName = avatarsByID[id].Name; //Remove the mapping if (nameIdMappingAvatars.ContainsKey(avatarName)) { nameIdMappingAvatars[avatarName].Remove(id); } //Remove the scene object from the dictionary avatarsByID.Remove(id); } } return(result); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //Assign the instruction this.instruction = instruction; MBoolResponse response = new MBoolResponse(true); if (instruction.Constraints.Count > 0 && instruction.Constraints[0].GeometryConstraint != null) { MSceneObject parent = this.SceneAccess.GetSceneObjectByID(instruction.Constraints[0].GeometryConstraint.ParentObjectID); if (instruction.Constraints[0].GeometryConstraint.ParentToConstraint != null) { MTransform ptc = instruction.Constraints[0].GeometryConstraint.ParentToConstraint; String gtp = ptc.Parent; if (gtp != null && this.SceneAccess.GetSceneObjectByID(gtp) != null) { // transform parent takes precedent. this.targetTransform = ptc.LocalToGlobal(this.SceneAccess); } else if (parent != null) { // parent to constraint has not valid parent, thus the geometry constraint parent is this.targetTransform = ptc.Multiply(parent.Transform.LocalToGlobal(this.SceneAccess)); } else { this.targetTransform = ptc; } } else { MVector3 pos = new MVector3(0, 0, 0); if (instruction.Constraints[0].GeometryConstraint.TranslationConstraint != null) { MTranslationConstraint trlCstr = instruction.Constraints[0].GeometryConstraint.TranslationConstraint; if (parent != null) { pos = parent.Transform.Position.Add(trlCstr.GetVector3()); } else { pos = trlCstr.GetVector3(); } } MQuaternion rot = new MQuaternion(0, 0, 0, 1); if (instruction.Constraints[0].GeometryConstraint.RotationConstraint != null) { MRotationConstraint rtCstr = instruction.Constraints[0].GeometryConstraint.RotationConstraint; if (parent != null) { rot = rtCstr.GetQuaternion().Multiply(parent.Transform.Rotation); } else { rot = rtCstr.GetQuaternion(); } } this.targetTransform = new MTransform("", pos, rot); } } else { response = new MBoolResponse(false) { LogData = new List <string>() { "Required target constraint (MGeometryConstraint) not defined" } }; } //Extract the velocity if defined if (instruction.Properties.ContainsKey("Velocity")) { Console.WriteLine("vel: " + instruction.Properties["Velocity"]); float.TryParse(instruction.Properties["Velocity"], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out velocity); } else { velocity = -1.0f; } /* * //Get the target id * if (instruction.Properties.ContainsKey("TargetID")) * this.targetTransform = this.SceneAccess.GetTransformByID(instruction.Properties["TargetID"]); * //Error id not available * else * { * return new MBoolResponse(false) * { * }; * }*/ //Return true/success return(response); }
/// <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); }