//-------------------------------------------------------------------------------------------------------- // Haptic Feedback /// <summary> Send a new Force-Feedback command for this frame. </summary> /// <param name="ffb"></param> public virtual void SendCmd(SGCore.Haptics.SG_FFBCmd ffb) { if (this.isActiveAndEnabled) { this.ffbQueue.Add(ffb.Copy()); if (this.ffbQueue.Count > maxQueue) { ffbQueue.RemoveAt(0); } } }
/// <summary> Go through any active haptic effects this frame, update any timers and flush everything as a single set of commands. </summary> protected virtual void UpdateHaptics() { if (this.ffbQueue.Count > 0 || this.buzzQueue.Count > 0 || thumperQueue.Count > 0) { int startBuzz = this.buzzQueue.Count; SGCore.Haptics.SG_FFBCmd finalBrakeCmd = SGCore.Haptics.SG_FFBCmd.Off; SGCore.Haptics.SG_BuzzCmd finalBuzzCmd = SGCore.Haptics.SG_BuzzCmd.Off; if (ffbQueue.Count > 0) { for (int i = 0; i < ffbQueue.Count; i++) { finalBrakeCmd = finalBrakeCmd.Merge(ffbQueue[i]); } } else { finalBrakeCmd = lastFFB; } ffbQueue.Clear(); //clear buffer for next frame. float dTSec = Time.deltaTime; //Buzz motor for (int i = 0; i < buzzQueue.Count;) { buzzQueue[i].UpdateTiming(dTSec); if (buzzQueue[i].TimeElapsed()) //no more relevant cmds { buzzQueue.RemoveAt(i); //do nothing } else { finalBuzzCmd = buzzQueue[i].Merge(finalBuzzCmd); //add to final cmd i++; } } //evaluate thumper int finalThump = 0; for (int i = 0; i < thumperQueue.Count;) { thumperQueue[i].Update(dTSec); if (thumperQueue[i].Elapsed) { thumperQueue.RemoveAt(i); } else { finalThump = Mathf.Max(finalThump, thumperQueue[i].magnitude); i++; } } //evaluate based on FFBEnabled BuzzEnabled int[] fForceLevels = finalBrakeCmd.Levels; int[] fBuzzLevels = finalBuzzCmd.Levels; for (int f = 0; f < 5; f++) { if (!ffbEnabled[f]) { fForceLevels[f] = 0; } if (!vibroEnabled[f]) { fBuzzLevels[f] = 0; } } finalBrakeCmd.Levels = fForceLevels; finalBuzzCmd.Levels = fBuzzLevels; //ToDo: Only send if there is a change? lastBuzz = finalBuzzCmd; lastFFB = finalBrakeCmd; lastThumpCmd = new ThumperCmd(finalThump); if (this.lastGlove != null) { //Debug.Log("Sending Hatpics: " + finalBrakeCmd.ToString() + ", " + finalBuzzCmd.ToString() + ", [" + finalThump + "]"); this.lastGlove.SendHaptics(finalBrakeCmd, finalBuzzCmd, new ThumperCmd(finalThump)); } } }
// Update is called once per frame void Update() { if (!sComRuns) { bool nowRunning = SGCore.DeviceList.SenseCommRunning(); if (!sComRuns && nowRunning) { titleText.color = Color.white; titleText.text = "Awaiting connection to glove..."; } sComRuns = nowRunning; } else if (glove.IsConnected) { if (!setup) { setup = true; this.SetupAfterConnect(); } if (hapticGlove != null) { if (hapticGlove.IsConnected()) { titleText.text = "Connected to " + hapticGlove.GetDeviceID() + " running firmware v" + hapticGlove.GetFirmwareVersion() + "." + hapticGlove.GetSubFirmwareVersion() + "\r\n" + "Receiving " + hapticGlove.PacketsPerSecondReceived() + " packets/s"; //collect ffb and send. int[] ffb = new int[this.fingerFFB.Length]; for (int f = 0; f < this.fingerFFB.Length; f++) { ffb[f] = (int)fingerFFB[f].SlideValue; } ffbCmd = new SG_FFBCmd(ffb); int[] buzz = new int[this.fingerVibration.Length]; for (int f = 0; f < this.fingerVibration.Length; f++) { buzz[f] = (int)fingerVibration[f].SlideValue; } buzzCmd = new SG_BuzzCmd(buzz); thumprCmd = new ThumperCmd((int)thumperVibration.SlideValue); hapticGlove.SendHaptics(ffbCmd, buzzCmd, thumprCmd); } else { titleText.text = hapticGlove.GetDeviceID() + " is no longer connected..."; } } //KeyBinds if (Input.GetKeyDown(this.resetWristKey)) { this.CalibrateIMU(); } if (Input.GetKeyDown(this.testBuzzKey)) { this.VibroEnabled = !this.VibroEnabled; } if (Input.GetKeyDown(this.testFFbKey)) { this.FFBEnabled = !this.FFBEnabled; } if (Input.GetKeyDown(this.testThumperKey)) { this.TestThumperSG(); } if (Input.GetKeyDown(this.resetCalibrKey)) { this.ResetCalibration(); } } }