private Task AddContactDeviceAsync() { var deviceId = ContactDeviceId; var trace = new ContactDescriptor(deviceId, DateTime.UtcNow); ContactDeviceId = string.Empty; DeviceProcessorProvider.GetInstance().Process(trace); return(Task.CompletedTask); }
/// <summary> /// Consolidates the given contact with its surrounding contacts. /// </summary> /// <param name="contacts"></param> /// <param name="start"></param> /// <returns></returns> private void ConsolidateContacts(List <ContactDescriptor> contacts, ContactDescriptor start) { contacts.Remove(start); List <ContactDescriptor> removedContacts = new List <ContactDescriptor>(); BulletSharp.Math.Vector3 lastPoint = start.Position; int startIndex = contactPoints.IndexOf(contacts); int lowerBound = startIndex; for (; lowerBound >= 0; lowerBound--) { List <ContactDescriptor> lc = GetValidContacts(lowerBound, lastPoint, ref start); int numContacts = lc.Count; if (numContacts == 0) { if (lowerBound == startIndex) { continue; } break; } lastPoint = BulletSharp.Math.Vector3.Zero; foreach (ContactDescriptor c in lc) { lastPoint += c.Position; removedContacts.Add(c); } lastPoint /= numContacts; } for (int i = startIndex; i >= lowerBound; i--) { List <ContactDescriptor> currentContacts = contactPoints[i]; if (currentContacts == null) { continue; } currentContacts.RemoveAll((x) => removedContacts.Contains(x)); } contacts.Add(start); }
public void Process(ContactDescriptor contact) { _logger.LogDebug( $"DeviceProcessor - processing deviceId: {contact.DeviceToken}."); var trace = new Trace() { ContactTimestamp = contact.ContactTimestamp, ContactToken = contact.DeviceToken }; _tracesStorage.AddAsync(trace); InvokeCleanupIfNeeded(); }
public void HandleDeviceCommunicationDiscoveredCharacteristicRead(DeviceDescriptor descriptor, byte[] payload, Action <DeviceDescriptor> onNext = null) { try { if (_discoveredDevices.TryGetValue(descriptor.Identifier, out var deviceDescriptor)) { try { if (PayloadFormatter.TryGetValue(payload, out var packageData)) { _logger.LogDebug( $"DeviceManager - Characteristic read - processing. id: {descriptor.Identifier}."); deviceDescriptor.Context = descriptor.Context; var contact = new ContactDescriptor(packageData.DeviceId, DateTime.UtcNow); DeviceProcessorProvider.GetInstance().Process(contact); Monitor.Enter(deviceDescriptor.ProcessingLock); try { deviceDescriptor.Processed = true; } finally { Monitor.Exit(deviceDescriptor.ProcessingLock); } } } catch (Exception ex) { _logger.LogError(ex, $"DeviceManager - Characteristic read - Processing failed. id: {deviceDescriptor.Identifier}."); } // Disconnect peripheral onNext?.Invoke(deviceDescriptor); } } catch (Exception ex) { _logger.LogError(ex, $"DeviceManager - Characteristic read - Processing failed. id: {descriptor.Identifier}. Reason: {ex.Message}."); } }
/// <summary> /// Loads the replay from the given replay file name. /// </summary> /// <param name="name"></param> void LoadReplay(string name) { List <FixedQueue <StateDescriptor> > fieldStates; List <KeyValuePair <string, List <FixedQueue <StateDescriptor> > > > robotStates; Dictionary <string, List <FixedQueue <StateDescriptor> > > gamePieceStates; List <List <KeyValuePair <ContactDescriptor, int> > > contacts; string fieldDirectory; ReplayImporter.Read(name, out fieldDirectory, out fieldStates, out robotStates, out gamePieceStates, out contacts); if (!LoadField(fieldDirectory)) { AppModel.ErrorToMenu("Could not load field: " + fieldDirectory + "\nHas it been moved or deleted?"); return; } foreach (KeyValuePair <string, List <FixedQueue <StateDescriptor> > > rs in robotStates) { if (!LoadRobot(rs.Key, false)) { AppModel.ErrorToMenu("Could not load robot: " + rs.Key + "\nHas it been moved or deleted?"); return; } int j = 0; foreach (Tracker t in SpawnedRobots.Last().GetComponentsInChildren <Tracker>()) { t.States = rs.Value[j]; j++; } } Tracker[] fieldTrackers = fieldObject.GetComponentsInChildren <Tracker>(); int i = 0; foreach (Tracker t in fieldTrackers) { t.States = fieldStates[i]; i++; } foreach (KeyValuePair <string, List <FixedQueue <StateDescriptor> > > k in gamePieceStates) { GameObject referenceObject = GameObject.Find(k.Key); if (referenceObject == null) { continue; } foreach (FixedQueue <StateDescriptor> f in k.Value) { GameObject currentPiece = UnityEngine.Object.Instantiate(referenceObject); currentPiece.name = k.Key + "(Clone)"; currentPiece.GetComponent <Tracker>().States = f; } } foreach (var c in contacts) { if (c != null) { List <ContactDescriptor> currentContacts = new List <ContactDescriptor>(); foreach (var d in c) { ContactDescriptor currentContact = d.Key; currentContact.RobotBody = ActiveRobot.transform.GetChild(d.Value).GetComponent <BRigidBody>(); currentContacts.Add(currentContact); } CollisionTracker.ContactPoints.Add(currentContacts); } else { CollisionTracker.ContactPoints.Add(null); } } }
void LoadReplay(string name) { List <FixedQueue <StateDescriptor> > fieldStates; List <FixedQueue <StateDescriptor> > robotStates; Dictionary <string, List <FixedQueue <StateDescriptor> > > gamePieceStates; List <List <KeyValuePair <ContactDescriptor, int> > > contacts; string simSelectedField; string simSelectedRobot; ReplayImporter.Read(name, out simSelectedField, out simSelectedRobot, out fieldStates, out robotStates, out gamePieceStates, out contacts); LoadField(simSelectedField); LoadRobot(simSelectedRobot); List <Tracker> robotTrackers = Trackers.Where(x => x.transform.parent.name.Equals("Robot")).ToList(); List <Tracker> fieldTrackers = Trackers.Except(robotTrackers).ToList(); int i = 0; foreach (Tracker t in fieldTrackers) { t.States = fieldStates[i]; i++; } i = 0; foreach (Tracker t in robotTrackers) { t.States = robotStates[i]; i++; } foreach (KeyValuePair <string, List <FixedQueue <StateDescriptor> > > k in gamePieceStates) { GameObject referenceObject = GameObject.Find(k.Key); if (referenceObject == null) { continue; } foreach (FixedQueue <StateDescriptor> f in k.Value) { GameObject currentPiece = UnityEngine.Object.Instantiate(referenceObject); currentPiece.name = "clone_" + k.Key; currentPiece.GetComponent <Tracker>().States = f; } } foreach (var c in contacts) { if (c != null) { List <ContactDescriptor> currentContacts = new List <ContactDescriptor>(); foreach (var d in c) { ContactDescriptor currentContact = d.Key; currentContact.RobotBody = robotTrackers[d.Value].GetComponent <BRigidBody>(); currentContacts.Add(currentContact); } contactPoints.Add(currentContacts); } else { contactPoints.Add(null); } } }
/// <summary> /// Finds all nearby contacts within the consolidation epsilon. /// </summary> /// <param name="index"></param> /// <param name="point"></param> /// <param name="contact"></param> /// <returns></returns> private List <ContactDescriptor> GetValidContacts(int index, BulletSharp.Math.Vector3 point, ref ContactDescriptor contact) { List <ContactDescriptor> currentContacts = contactPoints[index]; List <ContactDescriptor> validContacts = new List <ContactDescriptor>(); if (currentContacts == null) { return(validContacts); } foreach (ContactDescriptor c in currentContacts) { if (c.RobotBody != contact.RobotBody || c.Equals(contact) || (c.Position - point).Length > ConsolidationEpsilon) { continue; } contact.AppliedImpulse += c.AppliedImpulse; validContacts.Add(c); } return(validContacts); }
/// <summary> /// Renders the GUI. /// </summary> public override void OnGUI() { Rect controlRect = new Rect(helpMenu.activeSelf ? ControlButtonMargin + 200 : ControlButtonMargin, Screen.height - (SliderBottomMargin + SliderThickness + SliderThickness / 2), ButtonSize, ButtonSize); if (UnityEngine.GUI.Button(controlRect, string.Empty, rewindStyle)) { if (rewindTime == Tracker.Lifetime) { rewindTime = 0f; } playbackMode = PlaybackMode.Rewind; } controlRect.x += ButtonSize + ControlButtonMargin; if (UnityEngine.GUI.Button(controlRect, string.Empty, stopStyle)) { playbackMode = PlaybackMode.Paused; } controlRect.x += ButtonSize + ControlButtonMargin; if (UnityEngine.GUI.Button(controlRect, string.Empty, playStyle)) { if (rewindTime == 0f) { rewindTime = Tracker.Lifetime; } playbackMode = PlaybackMode.Play; } controlRect.x = Screen.width - SliderRightMargin + EditButtonMargin; if (UnityEngine.GUI.Button(controlRect, string.Empty, collisionStyle)) { editMode = editMode == EditMode.Threshold ? EditMode.None : EditMode.Threshold; } Rect collisionSliderRect = new Rect(controlRect.x + (ButtonSize - SliderThickness) / 2, controlRect.y - CollisionSliderMargin - CollisionSliderHeight, SliderThickness, CollisionSliderHeight); if (editMode == EditMode.Threshold) { contactThreshold = UnityEngine.GUI.VerticalSlider(collisionSliderRect, contactThreshold, Mathf.Sqrt(CollisionSliderTopValue), 0f, windowStyle, thumbStyle); Rect collisionLabelRect = new Rect(controlRect.x + controlRect.width, controlRect.y - controlRect.height - CollisionSliderMargin, Screen.width - (controlRect.x + controlRect.width), controlRect.height); UnityEngine.GUI.Label(collisionLabelRect, "Impulse Threshold:\n" + AdjustedContactThreshold.ToString("F2") + " Newtons", windowStyle); } controlRect.x += ButtonSize + EditButtonMargin; bool consolidatePressed = editMode == EditMode.Consolidate ? UnityEngine.GUI.Button(controlRect, consolidateStyle.hover.background, GUIStyle.none) : UnityEngine.GUI.Button(controlRect, string.Empty, consolidateStyle); if (consolidatePressed) { editMode = editMode == EditMode.Consolidate ? EditMode.None : EditMode.Consolidate; } if (editMode == EditMode.Consolidate) { UnityEngine.GUI.Label(new Rect(Screen.width - SliderLeftMargin, controlRect.y - InfoBoxHeight - CollisionSliderMargin, Screen.width - SliderLeftMargin, InfoBoxHeight), "Select a collision to consolidate.", windowStyle); } Rect sliderRect = new Rect(helpMenu.activeSelf ? SliderLeftMargin + 200 : SliderLeftMargin, Screen.height - (SliderBottomMargin + SliderThickness), helpMenu.activeSelf ? Screen.width - (SliderRightMargin + SliderLeftMargin + 200) : Screen.width - (SliderRightMargin + SliderLeftMargin), SliderThickness); rewindTime = UnityEngine.GUI.HorizontalSlider(sliderRect, rewindTime, Tracker.Lifetime, 0.0f, windowStyle, thumbStyle); Rect guiRect = new Rect(0, Screen.height - (SliderBottomMargin + SliderThickness + KeyframeHeight), Screen.width, SliderBottomMargin + SliderThickness + KeyframeHeight); if (!active && (guiRect.Contains(Event.current.mousePosition) || (editMode == EditMode.Threshold && collisionSliderRect.Contains(Event.current.mousePosition))) && UnityEngine.Input.GetMouseButton(0)) { DynamicCamera.ControlEnabled = false; active = true; playbackMode = PlaybackMode.Paused; } else if (active && !UnityEngine.Input.GetMouseButton(0)) { DynamicCamera.ControlEnabled = true; active = false; } bool circleHovered = false; int i = Tracker.Length - 1; foreach (List <ContactDescriptor> l in contactPoints) { if (l != null) { ContactDescriptor lastContact = default(ContactDescriptor); for (int j = 0; j < l.Count; j++) { ContactDescriptor currentContact = l[j]; if (currentContact.AppliedImpulse >= AdjustedContactThreshold) { float keyframeTime = Tracker.Lifetime - (float)i / (Tracker.Length - 1) * Tracker.Lifetime; if (!lastContact.Equals(currentContact)) { lastContact = currentContact; float pixelsPerValue = (sliderRect.width - KeyframeWidth - ThumbWidth / 2) / Tracker.Lifetime; Rect keyframeRect = new Rect( (Tracker.Lifetime - keyframeTime) * pixelsPerValue + sliderRect.x + (ThumbWidth - KeyframeWidth) / 2, sliderRect.y - KeyframeHeight, KeyframeWidth, sliderRect.height); if (UnityEngine.GUI.Button(keyframeRect, keyframeTexture, GUIStyle.none)) { rewindTime = keyframeTime; playbackMode = PlaybackMode.Paused; } } Vector3 collisionPoint = camera != null?camera.WorldToScreenPoint(currentContact.Position.ToUnity()) : Vector3.zero; if (collisionPoint.z > 0.0f) { Rect circleRect = new Rect(collisionPoint.x - CircleRadius, Screen.height - (collisionPoint.y + CircleRadius), CircleRadius * 2, CircleRadius * 2); bool shouldActivate = false; if (circleRect.Contains(MousePosition) && !circleHovered) { UnityEngine.GUI.color = Color.white; SelectedBody = currentContact.RobotBody; shouldActivate = true; } else { UnityEngine.GUI.color = new Color(1f, 1f, 1f, Math.Max((CircleRenderDistance - Math.Abs(Tracker.Length - 1 - i - RewindFrame)) / CircleRenderDistance, 0.1f)); } if (UnityEngine.GUI.Button(circleRect, circleTexture, GUIStyle.none) && Event.current.button == 0 && shouldActivate) { if (editMode == EditMode.Consolidate) { ConsolidateContacts(l, currentContact); editMode = EditMode.None; break; } else { rewindTime = keyframeTime; playbackMode = PlaybackMode.Paused; } } if (circleRect.Contains(MousePosition) && shouldActivate) { UnityEngine.GUI.Label(new Rect(MousePosition.x, MousePosition.y - InfoBoxHeight, InfoBoxWidth, InfoBoxHeight), "Impulse: " + currentContact.AppliedImpulse.ToString("F2") + " N", windowStyle); } UnityEngine.GUI.color = Color.white; circleHovered = circleHovered || shouldActivate; } } } } i--; } if (!circleHovered) { SelectedBody = null; } }