public void StartRecording() { source_type = Source.FILE; //NEED to run this world-sycnrhonously World currentWorld = metagen_comp.World; int currentTotalUpdates = currentWorld.TotalUpdates; Slot logix_slot = metagen_comp.World.RootSlot.AddSlot("temporary logix slot"); bool added_logix = false; currentWorld.RunSynchronously(() => { foreach (var userItem in metagen_comp.userMetaData) { User user = userItem.Key; UserMetadata metadata = userItem.Value; if (!metadata.isRecording || (metagen_comp.LocalUser == user && !metagen_comp.record_local_user)) { continue; } RefID user_id = user.ReferenceID; current_tracked_users.Add(user_id); ReferenceRegister <User> userRegister = logix_slot.AttachComponent <ReferenceRegister <User> >(); userRegister.Target.Target = user; StandardController standardControllerLeft = logix_slot.AttachComponent <FrooxEngine.LogiX.Input.StandardController>(); EnumInput <Chirality> nodeEnum = logix_slot.AttachComponent <EnumInput <Chirality> >(); nodeEnum.Value.Value = Chirality.Left; standardControllerLeft.User.Target = userRegister; standardControllerLeft.Node.Target = nodeEnum; SyncRef <ValueStream <bool> > _primaryStreamLeft = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_primaryStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerLeft); SyncRef <ValueStream <bool> > _secondaryStreamLeft = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_secondaryStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerLeft); SyncRef <ValueStream <bool> > _grabStreamLeft = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_grabStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerLeft); SyncRef <ValueStream <bool> > _menuStreamLeft = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_menuStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerLeft); SyncRef <ValueStream <float> > _strengthStreamLeft = (SyncRef <ValueStream <float> >) typeof(StandardController).GetField("_strengthStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerLeft); SyncRef <ValueStream <float2> > _axisStreamLeft = (SyncRef <ValueStream <float2> >) typeof(StandardController).GetField("_axisStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerLeft); StandardController standardControllerRight = logix_slot.AttachComponent <FrooxEngine.LogiX.Input.StandardController>(); EnumInput <Chirality> nodeEnum2 = logix_slot.AttachComponent <EnumInput <Chirality> >(); nodeEnum2.Value.Value = Chirality.Right; standardControllerRight.User.Target = userRegister; standardControllerRight.Node.Target = nodeEnum2; SyncRef <ValueStream <bool> > _primaryStreamRight = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_primaryStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerRight); SyncRef <ValueStream <bool> > _secondaryStreamRight = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_secondaryStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerRight); SyncRef <ValueStream <bool> > _grabStreamRight = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_grabStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerRight); SyncRef <ValueStream <bool> > _menuStreamRight = (SyncRef <ValueStream <bool> >) typeof(StandardController).GetField("_menuStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerRight); SyncRef <ValueStream <float> > _strengthStreamRight = (SyncRef <ValueStream <float> >) typeof(StandardController).GetField("_strengthStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerRight); SyncRef <ValueStream <float2> > _axisStreamRight = (SyncRef <ValueStream <float2> >) typeof(StandardController).GetField("_axisStream", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(standardControllerRight); primaryStreamsRefs[user_id] = new Tuple <SyncRef <ValueStream <bool> >, SyncRef <ValueStream <bool> > >(_primaryStreamLeft, _primaryStreamRight); secondaryStreamsRefs[user_id] = new Tuple <SyncRef <ValueStream <bool> >, SyncRef <ValueStream <bool> > >(_secondaryStreamLeft, _secondaryStreamRight); grabStreamsRefs[user_id] = new Tuple <SyncRef <ValueStream <bool> >, SyncRef <ValueStream <bool> > >(_grabStreamLeft, _grabStreamRight); menuStreamsRefs[user_id] = new Tuple <SyncRef <ValueStream <bool> >, SyncRef <ValueStream <bool> > >(_menuStreamLeft, _menuStreamRight); strengthStreamsRefs[user_id] = new Tuple <SyncRef <ValueStream <float> >, SyncRef <ValueStream <float> > >(_strengthStreamLeft, _strengthStreamRight); axisStreamsRefs[user_id] = new Tuple <SyncRef <ValueStream <float2> >, SyncRef <ValueStream <float2> > >(_axisStreamLeft, _axisStreamRight); } added_logix = true; UniLog.Log("Added logix"); }); metagen_comp.StartTask(async() => { Task task = Task.Run(() => { bool all_streams_not_null = false; List <RefID> good_tracking_users = new List <RefID>(); //UniLog.Log("HO"); while (!all_streams_not_null & currentWorld.TotalUpdates <= currentTotalUpdates + 60) { if (!added_logix) { continue; } //UniLog.Log("HI"); bool all_user_streams_not_null = true; all_streams_not_null = true; foreach (RefID user_id in current_tracked_users) { //HMM: why does using .Target here rather than .RawTarget give a NullReferenceException?? bool primary_streams_not_null = (primaryStreamsRefs[user_id].Item1.RawTarget != null) & (primaryStreamsRefs[user_id].Item2.RawTarget != null); bool secondary_streams_not_null = (secondaryStreamsRefs[user_id].Item1.RawTarget != null) & (secondaryStreamsRefs[user_id].Item2.RawTarget != null); bool grab_streams_not_null = (grabStreamsRefs[user_id].Item1.RawTarget != null) & (grabStreamsRefs[user_id].Item2.RawTarget != null); bool menu_streams_not_null = (menuStreamsRefs[user_id].Item1.RawTarget != null) & (menuStreamsRefs[user_id].Item2.RawTarget != null); bool strength_streams_not_null = (strengthStreamsRefs[user_id].Item1.RawTarget != null) & (strengthStreamsRefs[user_id].Item2.RawTarget != null); bool axis_streams_not_null = (axisStreamsRefs[user_id].Item1.RawTarget != null) & (axisStreamsRefs[user_id].Item2.RawTarget != null); all_user_streams_not_null = primary_streams_not_null & secondary_streams_not_null & grab_streams_not_null & menu_streams_not_null & strength_streams_not_null & axis_streams_not_null; if (all_user_streams_not_null) { if (!good_tracking_users.Contains(user_id)) { good_tracking_users.Add(user_id); UniLog.Log("Added user " + user_id.ToString()); } } all_streams_not_null &= all_user_streams_not_null; } } current_tracked_users = good_tracking_users; //Get CommonToolStreamDriver List <RefID> good_tracking_users2 = new List <RefID>(); foreach (RefID user_id in current_tracked_users) { User user = currentWorld.GetUser(user_id); List <CommonToolStreamDriver> commonToolStreamDrivers = user.Root.Slot.GetComponents <CommonToolStreamDriver>(); ValueStream <bool> primaryBlockedStreamLeft = null; ValueStream <bool> secondaryBlockedStreamLeft = null; ValueStream <bool> laserActiveStreamLeft = null; ValueStream <bool> showLaserToOthersStreamLeft = null; ValueStream <float3> laserTargetStreamLeft = null; ValueStream <float> grabDistanceStreamLeft = null; ValueStream <bool> primaryBlockedStreamRight = null; ValueStream <bool> secondaryBlockedStreamRight = null; ValueStream <bool> laserActiveStreamRight = null; ValueStream <bool> showLaserToOthersStreamRight = null; ValueStream <float3> laserTargetStreamRight = null; ValueStream <float> grabDistanceStreamRight = null; foreach (CommonToolStreamDriver driver in commonToolStreamDrivers) { if (driver.Side.Value == Chirality.Left) { primaryBlockedStreamLeft = driver.PrimaryBlockedStream.Target; secondaryBlockedStreamLeft = driver.SecondaryBlockedStream.Target; laserActiveStreamLeft = driver.LaserActiveStream.Target; showLaserToOthersStreamLeft = driver.ShowLaserToOthersStream.Target; laserTargetStreamLeft = driver.LaserTargetStream.Target; grabDistanceStreamLeft = driver.GrabDistanceStream.Target; } else if (driver.Side.Value == Chirality.Right) { primaryBlockedStreamRight = driver.PrimaryBlockedStream.Target; secondaryBlockedStreamRight = driver.SecondaryBlockedStream.Target; laserActiveStreamRight = driver.LaserActiveStream.Target; showLaserToOthersStreamRight = driver.ShowLaserToOthersStream.Target; laserTargetStreamRight = driver.LaserTargetStream.Target; grabDistanceStreamRight = driver.GrabDistanceStream.Target; } } bool all_common_tool_streams_not_null = primaryBlockedStreamLeft != null & primaryBlockedStreamRight != null & secondaryBlockedStreamLeft != null & secondaryBlockedStreamRight != null & laserActiveStreamLeft != null & laserActiveStreamRight != null & showLaserToOthersStreamLeft != null & showLaserToOthersStreamRight != null & laserTargetStreamLeft != null & laserActiveStreamRight != null & grabDistanceStreamLeft != null & grabDistanceStreamRight != null; if (all_common_tool_streams_not_null) { good_tracking_users2.Add(user_id); primaryBlockedStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(primaryBlockedStreamLeft, primaryBlockedStreamRight); secondaryBlockedStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(secondaryBlockedStreamLeft, secondaryBlockedStreamRight); laserActiveStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(laserActiveStreamLeft, laserActiveStreamRight); showLaserToOthersStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(showLaserToOthersStreamLeft, showLaserToOthersStreamRight); laserTargetStreams[user_id] = new Tuple <ValueStream <float3>, ValueStream <float3> >(laserTargetStreamLeft, laserTargetStreamRight); grabDistanceStreams[user_id] = new Tuple <ValueStream <float>, ValueStream <float> >(grabDistanceStreamLeft, grabDistanceStreamRight); } } current_tracked_users = good_tracking_users2; foreach (RefID user_id in current_tracked_users) { primaryStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(primaryStreamsRefs[user_id].Item1.RawTarget, primaryStreamsRefs[user_id].Item2.RawTarget); secondaryStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(secondaryStreamsRefs[user_id].Item1.RawTarget, secondaryStreamsRefs[user_id].Item2.RawTarget); grabStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(grabStreamsRefs[user_id].Item1.RawTarget, grabStreamsRefs[user_id].Item2.RawTarget); menuStreams[user_id] = new Tuple <ValueStream <bool>, ValueStream <bool> >(menuStreamsRefs[user_id].Item1.RawTarget, menuStreamsRefs[user_id].Item2.RawTarget); strengthStreams[user_id] = new Tuple <ValueStream <float>, ValueStream <float> >(strengthStreamsRefs[user_id].Item1.RawTarget, strengthStreamsRefs[user_id].Item2.RawTarget); axisStreams[user_id] = new Tuple <ValueStream <float2>, ValueStream <float2> >(axisStreamsRefs[user_id].Item1.RawTarget, axisStreamsRefs[user_id].Item2.RawTarget); RegisterUserStream(user_id, "controller_streams"); } //Destroy LogiX nodes currentWorld.RunSynchronously(() => { logix_slot.Destroy(); }); isRecording = true; }); //await CancelAfterAsync(ct=>task, TimeSpan.FromSeconds(30), CancellationToken.None); await task; }); }
private void OpenConnectedPanel() { UIBuilder uiBuilder1 = panel.SwapPanel(NeosSwapCanvasPanel.Slide.None, 0.5f); //uiBuilder1.VerticalLayout(4f, 0.0f, new Alignment?()); uiBuilder1.VerticalLayout(4f, 0, new Alignment?()); uiBuilder1.FitContent(SizeFit.Disabled, SizeFit.PreferredSize); uiBuilder1.Style.PreferredHeight = 65f; uiBuilder1.Style.MinHeight = 32f; uiBuilder1.Style.TextAutoSizeMin = 45f; uiBuilder1.Style.TextAutoSizeMax = 65f; //status text //SyncRef<Text> status = this._status; //LocaleString localeString1 = (LocaleString)""; //ref LocaleString local1 = ref localeString1; //Alignment? alignment1 = new Alignment?(); //Text text1 = uiBuilder1.Text(in local1, true, alignment1, true, (string)null); //status.Target = text1; //Title uiBuilder1.Style.PreferredHeight = 200f; Text text4 = uiBuilder1.Text("MetaGenNeos"); text4.AutoSizeMax.Value = 150f; text4.Size.Value = 150f; //Description uiBuilder1.Style.MinHeight = 350f; Text text1 = uiBuilder1.Text("<b>This recording system is currenlty in Beta. Expect bugs</b>. MetaGen is a project to explore the intersection between AI and VR technologies, for Science, Art, and Wonder. See more details at http://metagen.ai"); uiBuilder1.Style.MinHeight = 32f; ////Recording checkbox //uiBuilder1.Style.PreferredHeight = 100f; //uiBuilder1.Style.MinHeight = 100f; //Checkbox checkbox_record_user = uiBuilder1.Checkbox("Record me (local)",false); //this._recordUserCheckbox.Target = checkbox_record_user; //if (!mg.admin_mode) //{ // recordUserOverride = uiBuilder1.Current.AttachComponent<ValueUserOverride<bool>>(); // recordUserOverride.CreateOverrideOnWrite.Value = true; // recordUserOverride.Target.Target = checkbox_record_user.State; //} ////Data submission checkbox //uiBuilder1.Style.MinHeight = 350f; //Text text2 = uiBuilder1.Text("<b>By checking this box you agree to license the recorded data as CC0 (Public domain), as part of the MetaGen Public Dataset (intended for research in AI and other sciences).</b>"); //text2.HorizontalAlign.Value = CodeX.TextHorizontalAlignment.Left; //uiBuilder1.Style.PreferredHeight = 100f; //uiBuilder1.Style.MinHeight = 100f; //Checkbox checkbox_public_domain = uiBuilder1.Checkbox("Public domain",false); //this._publicDomainCheckbox.Target = checkbox_public_domain; //if (!mg.admin_mode) //{ // publicDomainOverride = uiBuilder1.Current.AttachComponent<ValueUserOverride<bool>>(); // publicDomainOverride.Target.Target = checkbox_public_domain.State; //} //recording time uiBuilder1.Style.PreferredHeight = 75f; uiBuilder1.Style.MinHeight = 75f; SyncRef <Text> recording_time = this._recordingTime; LocaleString localeString2 = (LocaleString)""; Text text3 = uiBuilder1.Text(localeString2); recording_time.Target = text3; uiBuilder1.Style.PreferredHeight = 100f; uiBuilder1.Style.MinHeight = 100f; //animation checkbox Checkbox animCheckbox = uiBuilder1.Checkbox("Generate animation", true); this._animationsCheckbox.Target = animCheckbox; //Generate bvh checkbox Checkbox checkbox5 = uiBuilder1.Checkbox("Generate bvh", false); this._generateBvhCheckbox.Target = checkbox5; //Recording voices checkbox Checkbox recording_voices_checkbox = uiBuilder1.Checkbox("Record voices", true); this._recordVoicesCheckbox.Target = recording_voices_checkbox; #if NOHL //Recording hearing checkbox Checkbox recording_hearing_checkbox = uiBuilder1.Checkbox("Record hearing", true); this._recordHearingCheckbox.Target = recording_hearing_checkbox; #endif //video checkbox //Checkbox videoCheckbox = uiBuilder1.Checkbox("Record vision",true); #if NOHL Checkbox videoCheckbox = uiBuilder1.Checkbox("Record vision", false); this._videoCheckbox.Target = videoCheckbox; #endif //record button uiBuilder1.Style.PreferredHeight = 120f; uiBuilder1.Style.MinHeight = 120f; SyncRef <Button> recordButton = this._recordButton; Button button1 = uiBuilder1.Button(""); recordButton.Target = button1; ButtonValueSet <bool> comp1 = button1.Slot.AttachComponent <ButtonValueSet <bool> >(); comp1.SetValue.Value = true; comp1.TargetValue.Target = record_button_pressed.Target; ////Hiding for now as its WIP ////interact button uiBuilder1.Style.PreferredHeight = 120f; uiBuilder1.Style.MinHeight = 120f; SyncRef <Button> interactButton = this._interactButton; Button button1b = uiBuilder1.Button("Toggle Interaction"); interactButton.Target = button1b; ButtonValueSet <bool> comp1b = button1b.Slot.AttachComponent <ButtonValueSet <bool> >(); comp1b.SetValue.Value = true; comp1b.TargetValue.Target = interact_button_pressed.Target; //Text for debug play section uiBuilder1.Style.PreferredHeight = 200f; uiBuilder1.Style.MinHeight = 100f; Text text5 = uiBuilder1.Text("Debug play"); text4.AutoSizeMax.Value = 130f; text4.Size.Value = 130f; uiBuilder1.Style.MinHeight = 100f; uiBuilder1.Style.PreferredHeight = 100f; //Recording index uiBuilder1.Style.PreferredHeight = 75f; uiBuilder1.Style.MinHeight = 75f; Text text6 = uiBuilder1.Text("Recording index:"); TextField field1 = uiBuilder1.TextField("0"); this._recordIndexField.Target = field1; uiBuilder1.Style.MinHeight = 100f; uiBuilder1.Style.PreferredHeight = 100f; //Voices checkbox Checkbox checkbox1 = uiBuilder1.Checkbox("Voices", true); this._voicesCheckbox.Target = checkbox1; //Hearing checkbox Checkbox checkbox2 = uiBuilder1.Checkbox("Hearing", false); this._hearingCheckbox.Target = checkbox2; //External source checkpoint Checkbox checkbox3 = uiBuilder1.Checkbox("External source", false); this._externalSourceCheckbox.Target = checkbox3; //animation checkbox2 Checkbox animCheckbox2 = uiBuilder1.Checkbox("Generate animation", false); this._animationsCheckbox2.Target = animCheckbox2; //Generate bvh checkbox Checkbox bvhCheckbox2 = uiBuilder1.Checkbox("Generate bvh", false); this._generateBvhCheckbox2.Target = bvhCheckbox2; //Avatar ref uiBuilder1.Style.PreferredHeight = 75f; uiBuilder1.Style.MinHeight = 75f; Text text7 = uiBuilder1.Text("Avatar slot:"); uiBuilder1.Next("Root"); ReferenceField <Slot> refField = uiBuilder1.Current.AttachComponent <ReferenceField <Slot> >(); this._avatarRefField.Target = refField; RefEditor avatarRefEditor = uiBuilder1.Current.AttachComponent <RefEditor>(); avatarRefEditor.Setup(refField.Reference); uiBuilder1.Style.MinHeight = 100f; uiBuilder1.Style.PreferredHeight = 100f; //play button SyncRef <Button> streamButton = this._playButton; Button button2 = uiBuilder1.Button(""); streamButton.Target = button2; ButtonValueSet <bool> comp2 = button2.Slot.AttachComponent <ButtonValueSet <bool> >(); comp2.SetValue.Value = true; comp2.TargetValue.Target = play_button_pressed.Target; ////UI slot ref //uiBuilder1.Style.PreferredHeight = 75f; //uiBuilder1.Style.MinHeight = 75f; //Text text8 = uiBuilder1.Text("UI slot:"); //uiBuilder1.Next("Root"); //ReferenceField<Slot> refField2 = uiBuilder1.Current.AttachComponent<ReferenceField<Slot>>(); //this._uiTemplateRefField.Target = refField2; //RefEditor uiTemplateRefEditor = uiBuilder1.Current.AttachComponent<RefEditor>(); //uiTemplateRefEditor.Setup(refField2.Reference); //uiBuilder1.Style.MinHeight = 100f; //uiBuilder1.Style.PreferredHeight = 100f; ////swapUI button //Button button3 = uiBuilder1.Button(""); //this._swapUIButton.Target = button3; //ButtonValueSet<bool> comp3 = button3.Slot.AttachComponent<ButtonValueSet<bool>>(); //comp3.SetValue.Value = true; //comp3.TargetValue.Target = swapUI_button_pressed.Target; }
private async void StartPlayingInternal() { try { if (generateAnimation) { metagen_comp.World.RunSynchronously(() => { animationRecorder = metagen_comp.Slot.AttachComponent <RecordingTool>(); animationRecorder.metagen_comp = metagen_comp; }); } //Dictionary<RefID, User>.ValueCollection users = metagen_comp.World.AllUsers; avatarManager = new metagen.AvatarManager(); List <UserMetadata> userMetadatas = new List <UserMetadata>(); userMetadatas.Add(new UserMetadata { userId = "U-test", bodyNodes = "", devices = "", headDevice = "", isPublic = true, isRecording = true, platform = "", userRefId = "ID2B00" }); Dictionary <RefID, AudioOutput> audio_outputs = new Dictionary <RefID, AudioOutput>(); foreach (UserMetadata user in userMetadatas) { if (!user.isRecording || !user.isPublic) { continue; //at the moment we only allow playing back of public recording, for privacy reasons. In the future, we'll allow private access to the data } RefID user_id = RefID.Parse(user.userRefId); UniLog.Log(user_id.ToString()); user_ids.Add(user_id); channel = new Channel("127.0.0.1:" + (40052).ToString(), ChannelCredentials.Insecure); client = new DataComm.DataCommClient(channel); output_readers[user_id] = client.GetPose(new Empty()).ResponseStream; fake_proxies[user_id] = new List <Tuple <BodyNode, AvatarObjectSlot> >(); avatar_pose_nodes[user_id] = new List <Tuple <BodyNode, IAvatarObject> >(); avatar_stream_channels[user_id] = new Dictionary <BodyNode, Tuple <bool, bool, bool> >(); proxy_slots[user_id] = new Dictionary <BodyNode, Slot>(); if (avatarManager.avatar_template == null && avatar_template != null) { avatarManager.avatar_template = avatar_template; } Slot avatar = await avatarManager.GetAvatar(); UniLog.Log("AVATAR"); UniLog.Log(avatar.ToString()); avatars[user_id] = avatar; List <IAvatarObject> components = avatar.GetComponentsInChildren <IAvatarObject>(); List <AvatarObjectSlot> root_comps = avatar.GetComponentsInChildren <AvatarObjectSlot>(); boness[user_id] = avatar.GetComponentInChildren <Rig>()?.Bones.ToList(); VRIKAvatar avatarIK = avatar.GetComponentInChildren <VRIKAvatar>(); //READ absolute time //output_readers[user_id].ReadSingle(); //READ number of body nodes int numBodyNodes = 28; //TODO CHECK for (int i = 0; i < numBodyNodes; i++) { //READ body node type //int nodeInt = //READ if scale stream exists bool scale_exists = true; //READ if position stream exists bool pos_exists = true; //READ if rotation stream exists bool rot_exists = true; BodyNode bodyNodeType = VNetcBodyNodeConverter[i]; bool node_found = false; foreach (IAvatarObject comp in components) { foreach (AvatarObjectSlot comp2 in root_comps) { if (comp.Node == bodyNodeType && comp2.Node == bodyNodeType) { UniLog.Log((comp.Node, scale_exists, pos_exists, rot_exists)); if (bodyNodeType == BodyNode.Root) { proxy_slots[user_id][bodyNodeType] = avatar; } else { proxy_slots[user_id][bodyNodeType] = comp.Slot; } comp.Equip(comp2); if (bodyNodeType != BodyNode.Root) { SyncRef <Slot> sourceField = (SyncRef <Slot>)comp.GetType().GetField("_source", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(comp); sourceField.Target = null; FieldDrive <float3> posField = (FieldDrive <float3>)comp.GetType().GetField("_position", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(comp); posField.Target = null; FieldDrive <floatQ> rotField = (FieldDrive <floatQ>)comp.GetType().GetField("_rotation", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(comp); rotField.Target = null; } fake_proxies[user_id].Add(new Tuple <BodyNode, AvatarObjectSlot>(bodyNodeType, comp2)); avatar_pose_nodes[user_id].Add(new Tuple <BodyNode, IAvatarObject>(comp.Node, comp)); comp2.IsTracking.Value = true; if (bodyNodeType == BodyNode.LeftFoot || bodyNodeType == BodyNode.RightFoot) { avatarIK.ForceUseFeetProxies.Value = true; } if (bodyNodeType == BodyNode.LeftLowerLeg || bodyNodeType == BodyNode.RightLowerLeg) { avatarIK.ForceUseKneeProxies.Value = true; } if (bodyNodeType == BodyNode.LeftLowerArm || bodyNodeType == BodyNode.RightLowerArm) { avatarIK.ForceUseElbowProxies.Value = true; } if (bodyNodeType == BodyNode.Chest) { avatarIK.ForceUseChestProxy.Value = true; } if (bodyNodeType == BodyNode.Hips) { avatarIK.ForceUsePelvisProxy.Value = true; } node_found = true; break; } if (node_found) { break; } } } //if (!node_found) throw new Exception("Node " + bodyNodeType.ToString() + " not found in avatar!"); if (!node_found) { fake_proxies[user_id].Add(new Tuple <BodyNode, AvatarObjectSlot>(bodyNodeType, null)); avatar_pose_nodes[user_id].Add(new Tuple <BodyNode, IAvatarObject>(bodyNodeType, null)); } avatar_stream_channels[user_id][bodyNodeType] = new Tuple <bool, bool, bool>(scale_exists, pos_exists, rot_exists); } Slot avatarRootSlot = avatar.GetComponentInChildren <AvatarRoot>()?.Slot; if (avatarRootSlot != null) { avatarRootSlot.LocalPosition = new float3(0, 0, 0); avatarRootSlot.LocalRotation = new floatQ(0, 0, 0, 1); } //READ whether hands are being tracked hands_are_tracked[user_id] = false; //READ whether metacarpals are being tracked //output_readers[user_id].ReadBoolean(); List <HandPoser> these_hand_posers = avatar.GetComponentsInChildren <HandPoser>(null, excludeDisabled: false, includeLocal: false); UniLog.Log("getting finger rotation vars"); finger_slots[user_id] = new Dictionary <BodyNode, Slot>(); hand_posers[user_id] = new Dictionary <Chirality, HandPoser>(); finger_compensations[user_id] = new Dictionary <BodyNode, floatQ>(); foreach (HandPoser hand_poser in these_hand_posers) { UniLog.Log("HI"); hand_posers[user_id][hand_poser.Side] = hand_poser; BodyNode side1 = BodyNode.LeftThumb_Metacarpal.GetSide((Chirality)hand_poser.Side); BodyNode side2 = BodyNode.LeftPinky_Tip.GetSide((Chirality)hand_poser.Side); for (BodyNode nodee = side1; nodee <= side2; ++nodee) { int index = nodee - side1; FingerType fingerType = nodee.GetFingerType(); FingerSegmentType fingerSegmentType = nodee.GetFingerSegmentType(); HandPoser.FingerSegment fingerSegment = hand_poser[fingerType][fingerSegmentType]; if (fingerSegment != null && fingerSegment.Root.Target != null)//&& fingerSegment.RotationDrive.IsLinkValid) { UniLog.Log(nodee.ToString()); finger_slots[user_id][nodee] = fingerSegment.Root.Target; proxy_slots[user_id][nodee] = fingerSegment.Root.Target; finger_compensations[user_id][nodee] = fingerSegment.CoordinateCompensation.Value; fingerSegment.RotationDrive.Target = (IField <floatQ>)null; } } } UniLog.Log("got finger rotation vars"); //AUDIO PLAY audio_outputs[user_id] = null; //UniLog.Log("Setting up audio!"); //avatar.GetComponentInChildren<AudioOutput>().Source.Target = null; //for (int i = 0; i < 2; i++) //{ // string audio_file; // if (i==0) // { // if (!play_hearing) continue; // string[] files = Directory.GetFiles(reading_directory, user_id.ToString() + "*_hearing.ogg"); // audio_file = files.Length > 0 ? files[0] : null; // } else // { // if (!play_voice) continue; // string[] files = Directory.GetFiles(reading_directory, user_id.ToString() + "*_voice.ogg"); // audio_file = files.Length > 0 ? files[0] : null; // } // if (File.Exists(audio_file)) // { // AudioOutput audio_output = avatar.GetComponentInChildren<AudioOutput>(); // if (audio_output.Source.Target != null) audio_output = audio_output.Slot.AttachComponent<AudioOutput>(); // VisemeAnalyzer visemeAnalyzer = avatar.GetComponentInChildren<VisemeAnalyzer>(); // audio_output.Volume.Value = 1f; // audio_output.Enabled = true; // //audio_outputs[user_id] = audio_output; // //AudioX audioData = new AudioX(reading_directory + "/" + user_id.ToString() + "_audio.wav"); // //AssetRef<AudioClip> audioClip = new AssetRef<AudioClip>(); // Uri uri = this.World.Engine.LocalDB.ImportLocalAsset(audio_file, LocalDB.ImportLocation.Original, (string)null); // //ToWorld thing = new ToWorld(); // //var awaiter = thing.GetAwaiter(); // //awaiter.GetResult(); // StaticAudioClip audioClip = audio_output.Slot.AttachAudioClip(uri); // AudioClipPlayer player = audio_output.Slot.AttachComponent<AudioClipPlayer>(); // if (visemeAnalyzer != null) // { // visemeAnalyzer.Source.Target = player; // } // UniLog.Log("attaching clip to player"); // player.Clip.Target = (IAssetProvider<AudioClip>) audioClip; // UniLog.Log("attaching player to audio output"); // audio_output.Source.Target = (IAudioSource) player; // audio_output.Slot.AttachComponent<AudioMetadata>(true, (Action<AudioMetadata>)null).SetFromCurrentWorld(); // player.Play(); // } //} } avatars_finished_loading = true; isPlaying = true; if (generateAnimation) { animationRecorder.StartRecordingAvatars(avatars, audio_outputs); } if (generateBvh) { bvhRecorder.StartRecordingAvatars(avatars); } } catch (Exception e) { UniLog.Log("TwT: " + e.Message); UniLog.Log(e.StackTrace); } }