add additional functionality to tap detection (#375)

This commit is contained in:
Collin Kees
2022-12-16 05:37:36 -08:00
committed by GitHub
parent f273d3a9bb
commit 88f649ae5c
11 changed files with 481 additions and 91 deletions

View File

@@ -49,8 +49,15 @@ interface SettingsForm {
skatingCorrection: boolean;
};
tapDetection: {
tapMountingResetEnabled: boolean;
tapQuickResetEnabled: boolean;
tapResetEnabled: boolean;
tapQuickResetDelay: number;
tapResetDelay: number;
tapMountingResetDelay: number;
tapQuickResetTaps: number;
tapResetTaps: number;
tapMountingResetTaps: number;
};
legTweaks: {
correctionStrength: number;
@@ -79,7 +86,17 @@ const defaultValues = {
skatingCorrection: false,
},
filtering: { amount: 0.1, type: FilteringType.NONE },
tapDetection: { tapResetEnabled: false, tapResetDelay: 0.2 },
tapDetection: {
tapMountingResetEnabled: false,
tapQuickResetEnabled: false,
tapResetEnabled: false,
tapQuickResetDelay: 0.2,
tapResetDelay: 1.0,
tapMountingResetDelay: 1.0,
tapQuickResetTaps: 2,
tapResetTaps: 3,
tapMountingResetTaps: 3,
},
legTweaks: { correctionStrength: 0.3 },
interface: { devmode: false, watchNewDevices: true },
};
@@ -125,8 +142,15 @@ export function GeneralSettings() {
settings.modelSettings = modelSettings;
const tapDetection = new TapDetectionSettingsT();
tapDetection.tapResetEnabled = values.tapDetection.tapResetEnabled;
tapDetection.tapResetDelay = values.tapDetection.tapResetDelay;
tapDetection.tapResetEnabled = values.tapDetection.tapResetEnabled;
tapDetection.tapResetTaps = values.tapDetection.tapResetTaps;
tapDetection.tapQuickResetDelay = values.tapDetection.tapQuickResetDelay;
tapDetection.tapQuickResetEnabled = values.tapDetection.tapQuickResetEnabled;
tapDetection.tapQuickResetTaps = values.tapDetection.tapQuickResetTaps;
tapDetection.tapMountingResetEnabled = values.tapDetection.tapMountingResetEnabled;
tapDetection.tapMountingResetDelay = values.tapDetection.tapMountingResetDelay;
tapDetection.tapMountingResetTaps = values.tapDetection.tapMountingResetTaps;
settings.tapDetectionSettings = tapDetection;
const filtering = new FilteringSettingsT();
@@ -182,12 +206,33 @@ export function GeneralSettings() {
if (settings.tapDetectionSettings) {
formData.tapDetection = {
tapResetDelay:
settings.tapDetectionSettings.tapResetDelay ||
defaultValues.tapDetection.tapResetDelay,
tapQuickResetEnabled:
settings.tapDetectionSettings.tapQuickResetEnabled ||
defaultValues.tapDetection.tapQuickResetEnabled,
tapResetEnabled:
settings.tapDetectionSettings.tapResetEnabled ||
defaultValues.tapDetection.tapResetEnabled,
tapMountingResetEnabled:
settings.tapDetectionSettings.tapMountingResetEnabled ||
defaultValues.tapDetection.tapMountingResetEnabled,
tapQuickResetDelay:
settings.tapDetectionSettings.tapQuickResetDelay ||
defaultValues.tapDetection.tapQuickResetDelay,
tapResetDelay:
settings.tapDetectionSettings.tapResetDelay ||
defaultValues.tapDetection.tapResetDelay,
tapMountingResetDelay:
settings.tapDetectionSettings.tapMountingResetDelay ||
defaultValues.tapDetection.tapMountingResetDelay,
tapQuickResetTaps:
settings.tapDetectionSettings.tapQuickResetTaps ||
defaultValues.tapDetection.tapQuickResetTaps,
tapResetTaps:
settings.tapDetectionSettings.tapResetTaps ||
defaultValues.tapDetection.tapResetTaps,
tapMountingResetTaps:
settings.tapDetectionSettings.tapMountingResetTaps ||
defaultValues.tapDetection.tapMountingResetTaps,
};
}
@@ -464,23 +509,98 @@ export function GeneralSettings() {
{t('settings.general.gesture-control.description')}
</Typography>
</div>
<div className="grid sm:grid-cols-1 gap-3 pb-5">
<div className="grid sm:grid-cols-3 gap-5 pb-2">
<CheckBox
variant="toggle"
outlined
control={control}
name="tapDetection.tapQuickResetEnabled"
label={t('settings.general.gesture-control.quickResetEnabled')}
/>
<CheckBox
variant="toggle"
outlined
control={control}
name="tapDetection.tapResetEnabled"
label={t('settings.general.gesture-control.enable')}
label={t('settings.general.gesture-control.resetEnabled')}
/>
<CheckBox
variant="toggle"
outlined
control={control}
name="tapDetection.tapMountingResetEnabled"
label={t('settings.general.gesture-control.mountingResetEnabled')}
/>
</div>
<div className="grid sm:grid-cols-3 gap-5 pb-2">
<NumberSelector
control={control}
name="tapDetection.tapResetDelay"
label={t('settings.general.gesture-control.delay')}
name="tapDetection.tapQuickResetDelay"
label={t('settings.general.gesture-control.quickResetDelay')}
valueLabelFormat={(value) => `${Math.round(value * 10) / 10} s`}
min={0.2}
max={3.0}
step={0.2}
/>
<NumberSelector
control={control}
name="tapDetection.tapResetDelay"
label={t('settings.general.gesture-control.resetDelay')}
valueLabelFormat={(value) => `${Math.round(value * 10) / 10} s`}
min={0.2}
max={3.0}
step={0.2}
/>
<NumberSelector
control={control}
name="tapDetection.tapMountingResetDelay"
label={t('settings.general.gesture-control.mountingResetDelay')}
valueLabelFormat={(value) => `${Math.round(value * 10) / 10} s`}
min={0.2}
max={3.0}
step={0.2}
/>
</div>
<div className="grid sm:grid-cols-3 gap-5 pb-2">
<NumberSelector
control={control}
name="tapDetection.tapQuickResetTaps"
label={t('settings.general.gesture-control.quickResetTaps')}
valueLabelFormat={(value) =>
`${Math.round(value)} ${t(
'settings.general.gesture-control.taps'
)}`
}
min={2}
max={3}
step={1}
/>
<NumberSelector
control={control}
name="tapDetection.tapResetTaps"
label={t('settings.general.gesture-control.resetTaps')}
valueLabelFormat={(value) =>
`${Math.round(value)} ${t(
'settings.general.gesture-control.taps'
)}`
}
min={2}
max={3}
step={1}
/>
<NumberSelector
control={control}
name="tapDetection.tapMountingResetTaps"
label={t('settings.general.gesture-control.mountingResetTaps')}
valueLabelFormat={(value) =>
`${Math.round(value)} ${t(
'settings.general.gesture-control.taps'
)}`
}
min={2}
max={3}
step={1}
/>
</div>
</>
</SettingsPageLayout>

View File

@@ -230,10 +230,18 @@
},
"gesture-control": {
"title": "Gesture control",
"subtitle": "Double Tap quick reset",
"description": "Enable or disable double tap quick reset. When enabled double tapping anywhere on the highest torso tracker will activate a quick reset. Delay is the time between registering a tap and resetting.",
"enable": "Double tap quick reset",
"delay": "Delay"
"subtitle": "Tap based resets",
"description": "Allows for resets to be triggered by tapping a tracker. The tracker highest up on your torso is used for Quick Reset, the tracker highest up on your left leg is used for Reset, and the tracker highest up on your right leg is used for Mounting Reset. It should be mentioned that taps must happen within 0.6 seconds to be registered",
"taps": "taps",
"quickResetEnabled": "Enable tap to quick reset",
"quickResetDelay": "Quick reset delay",
"quickResetTaps": "Taps for quick reset",
"resetEnabled": "Enable tap to reset",
"resetDelay": "Reset delay",
"resetTaps": "Taps for reset",
"mountingResetEnabled": "Enable tap to reset mounting",
"mountingResetDelay": "Mounting reset delay",
"mountingResetTaps": "Taps for mounting reset"
},
"interface": {
"title": "Interface",

View File

@@ -227,10 +227,18 @@
},
"gesture-control": {
"title": "gestauw cantwol",
"subtitle": "dubble bap qwick weset",
"description": "enawbwe owr disawbwe dubble bap qwick weset. when enawbwed dubble bapping enywhewe on teh hyighest towso twackaw wil activate a qwick weset. deway is teh time between wowgistewing a bap and wowstting.",
"enable": "dubble bap qwick weset",
"delay": "deway"
"subtitle": "bap bwased wesets",
"description": "allaws owr wesets wo be twiggered by wapping a twackaw. The twackaw hyighest wup on youwur twursuu is uwued for qwick weset, wa twackaw hyighest up on youwur weft weg is uwused for weset, and teh twackaw hyighest up on youwur wight weg is used for mmountwing weset. It showold we wentioned what waps muwst happen within 0.6 seconds wo be wegistered",
"taps": "baps",
"quickResetEnabled": "enable wap to quwuick weset",
"quickResetDelay": "quwuick weset deway",
"quickResetTaps": "baps for quwuick weset",
"resetEnabled": "enable wap to weset",
"resetDelay": "weset deway",
"resetTaps": "baps for weset",
"mountingResetEnabled": "enable wap to weset mountwing",
"mountingResetDelay": "mountwing weset deway",
"mountingResetTaps": "baps for mountwing weset"
},
"interface": {
"title": "intewface",

View File

@@ -1,23 +1,99 @@
package dev.slimevr.config;
import com.jme3.math.FastMath;
// handles the tap detection config
// this involves the number of taps, the delay, and whether or not the feature is enabled
// for each reset type
public class TapDetectionConfig {
private float delay = 0.2f;
private boolean enabled = true;
private float quickResetDelay = 0.2f;
private float resetDelay = 1.0f;
private float mountingResetDelay = 1.0f;
private boolean quickResetEnabled = true;
private boolean resetEnabled = true;
private boolean mountingResetEnabled = true;
private int quickResetTaps = 2;
private int resetTaps = 3;
private int mountingResetTaps = 3;
public float getDelay() {
return delay;
public float getQuickResetDelay() {
return quickResetDelay;
}
public void setDelay(float delay) {
this.delay = delay;
public void setQuickResetDelay(float quickResetDelay) {
this.quickResetDelay = quickResetDelay;
}
public boolean getEnabled() {
return enabled;
public float getResetDelay() {
return resetDelay;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
public void setResetDelay(float resetDelay) {
this.resetDelay = resetDelay;
}
public float getMountingResetDelay() {
return mountingResetDelay;
}
public void setMountingResetDelay(float mountingResetDelay) {
this.mountingResetDelay = mountingResetDelay;
}
public boolean getQuickResetEnabled() {
return quickResetEnabled;
}
public void setQuickResetEnabled(boolean quickResetEnabled) {
this.quickResetEnabled = quickResetEnabled;
}
public boolean getResetEnabled() {
return resetEnabled;
}
public void setResetEnabled(boolean resetEnabled) {
this.resetEnabled = resetEnabled;
}
public boolean getMountingResetEnabled() {
return mountingResetEnabled;
}
public void setMountingResetEnabled(boolean mountingResetEnabled) {
this.mountingResetEnabled = mountingResetEnabled;
}
public int getQuickResetTaps() {
return quickResetTaps;
}
// clamp to 2-3 to prevent errors
public void setQuickResetTaps(int quickResetTaps) {
if (quickResetTaps > 3 || quickResetTaps < 2)
FastMath.clamp(quickResetTaps, 2, 3);
this.quickResetTaps = quickResetTaps;
}
public int getResetTaps() {
return resetTaps;
}
public void setResetTaps(int resetTaps) {
if (resetTaps > 3 || resetTaps < 2)
FastMath.clamp(resetTaps, 2, 3);
this.resetTaps = resetTaps;
}
public int getMountingResetTaps() {
return mountingResetTaps;
}
public void setMountingResetTaps(int mountingResetTaps) {
if (mountingResetTaps > 3 || mountingResetTaps < 2)
FastMath.clamp(mountingResetTaps, 2, 3);
this.mountingResetTaps = mountingResetTaps;
}
}

View File

@@ -96,8 +96,15 @@ public class RPCSettingsBuilder {
return TapDetectionSettings
.createTapDetectionSettings(
fbb,
tapDetectionConfig.getDelay(),
tapDetectionConfig.getEnabled()
tapDetectionConfig.getResetDelay(),
tapDetectionConfig.getResetEnabled(),
tapDetectionConfig.getResetTaps(),
tapDetectionConfig.getQuickResetDelay(),
tapDetectionConfig.getQuickResetEnabled(),
tapDetectionConfig.getQuickResetTaps(),
tapDetectionConfig.getMountingResetDelay(),
tapDetectionConfig.getMountingResetEnabled(),
tapDetectionConfig.getMountingResetTaps()
);
}

View File

@@ -174,10 +174,40 @@ public record RPCSettingsHandler(RPCHandler rpcHandler, ProtocolAPI api) {
var tapDetectionSettings = req.tapDetectionSettings();
if (tapDetectionSettings != null) {
tapDetectionConfig.setEnabled(tapDetectionSettings.tapResetEnabled());
// enable/disable tap detection
tapDetectionConfig
.setQuickResetEnabled(tapDetectionSettings.tapQuickResetEnabled());
tapDetectionConfig
.setResetEnabled(tapDetectionSettings.tapResetEnabled());
tapDetectionConfig
.setMountingResetEnabled(tapDetectionSettings.tapMountingResetEnabled());
// set tap detection delays
if (tapDetectionSettings.hasTapQuickResetDelay()) {
tapDetectionConfig
.setQuickResetDelay(tapDetectionSettings.tapQuickResetDelay());
}
if (tapDetectionSettings.hasTapResetDelay()) {
tapDetectionConfig.setDelay(tapDetectionSettings.tapResetDelay());
tapDetectionConfig
.setResetDelay(tapDetectionSettings.tapResetDelay());
}
if (tapDetectionSettings.hasTapMountingResetDelay()) {
tapDetectionConfig
.setMountingResetDelay(tapDetectionSettings.tapMountingResetDelay());
}
// set the number of taps required for each action
if (tapDetectionSettings.hasTapQuickResetTaps()) {
tapDetectionConfig
.setQuickResetTaps(tapDetectionSettings.tapQuickResetTaps());
}
if (tapDetectionSettings.hasTapResetTaps()) {
tapDetectionConfig
.setResetTaps(tapDetectionSettings.tapResetTaps());
}
if (tapDetectionSettings.hasTapMountingResetTaps()) {
tapDetectionConfig
.setMountingResetTaps(tapDetectionSettings.tapMountingResetTaps());
}
this.api.server.humanPoseProcessor.getSkeleton().updateTapDetectionConfig();

View File

@@ -139,7 +139,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
// #endregion
// #region tap detection
protected TapDetection tapDetection = new TapDetection(this);
protected TapDetectionManager tapDetectionManager = new TapDetectionManager(this);
// #endregion
// #region Constructors
@@ -165,7 +165,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
setTrackersFromServer(server);
skeletonConfig.loadFromConfig(server.getConfigManager());
tapDetection = new TapDetection(
tapDetectionManager = new TapDetectionManager(
this,
server.getVrcOSCHandler(),
server.getConfigManager().getVrConfig().getTapDetection()
@@ -790,7 +790,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
@VRServerThread
@Override
public void updatePose() {
tapDetection.update();
tapDetectionManager.update();
updateLocalTransforms();
updateRootTrackers();
updateComputedTrackers();
@@ -1846,7 +1846,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
}
public void updateTapDetectionConfig() {
tapDetection.updateConfig();
tapDetectionManager.updateConfig();
}
public void updateLegTweaksConfig() {

View File

@@ -27,7 +27,7 @@ public class LegTweakBuffer {
public static final int FOOT_ACCEL = 3;
public static final int ANKLE_ACCEL = 4;
public static final float NS_CONVERT = 1000000000.0f;
public static final float NS_CONVERT = 1.0e9f;
private static final Vector3f GRAVITY = new Vector3f(0, -9.81f, 0);
private static final float GRAVITY_MAGNITUDE = GRAVITY.length();
private static final int BUFFER_LEN = 10;

View File

@@ -3,37 +3,35 @@ package dev.slimevr.vr.processor.skeleton;
import java.util.LinkedList;
import com.jme3.math.Vector3f;
import dev.slimevr.config.TapDetectionConfig;
import dev.slimevr.osc.VRCOSCHandler;
import dev.slimevr.vr.trackers.Tracker;
// class that monitors the acceleration of the waist, hip, or chest trackers to detect taps
// and use this to trigger a quick reset (if your wondering why no single tap class exists, it's because
// and use this to trigger a varaity of resets (if your wondering why no single tap class exists, it's because
// to many false positives)
public class TapDetection {
// server and related classes
private HumanSkeleton skeleton;
private VRCOSCHandler oscHandler;
private TapDetectionConfig config;
// tap detection
private boolean enabled = false;
private LinkedList<float[]> accelList = new LinkedList<>();
private LinkedList<Float> tapTimes = new LinkedList<>();
private float resetDelayNs = 0.20f * 1000000000.0f;
private Tracker trackerToWatch = null;
// hyperparameters
private static final float NS_CONVERTER = 1.0e9f;
private static final float NEEDED_ACCEL_DELTA = 6.0f;
private static final float ALLOWED_BODY_ACCEL = 1.5f;
private static final float ALLOWED_BODY_ACCEL_SQUARED = ALLOWED_BODY_ACCEL * ALLOWED_BODY_ACCEL;
private static final float CLUMP_TIME_NS = 0.03f * 1000000000.0f;
private static final float TIME_WINDOW_NS = 0.5f * 1000000000.0f;
private static final float CLUMP_TIME_NS = 0.03f * NS_CONVERTER;
private static final float TIME_WINDOW_NS = 0.6f * NS_CONVERTER;
// state
private float resetRequestTime = -1.0f;
private float detectionTime = -1.0f;
private boolean doubleTaped = false;
private boolean tripleTaped = false;
public TapDetection(HumanSkeleton skeleton) {
this.skeleton = skeleton;
@@ -41,18 +39,10 @@ public class TapDetection {
public TapDetection(
HumanSkeleton skeleton,
VRCOSCHandler oscHandler,
TapDetectionConfig config
Tracker trackerToWatch
) {
this.skeleton = skeleton;
this.oscHandler = oscHandler;
this.config = config;
updateConfig();
}
public void updateConfig() {
this.enabled = config.getEnabled();
this.resetDelayNs = config.getDelay() * 1000000000.0f;
this.trackerToWatch = trackerToWatch;
}
public void setEnabled(boolean enabled) {
@@ -63,29 +53,42 @@ public class TapDetection {
return enabled;
}
// set the tracker to watch and detect taps on
public void setTrackerToWatch(Tracker tracker) {
trackerToWatch = tracker;
}
public boolean getDoubleTapped() {
return doubleTaped;
}
public boolean getTripleTapped() {
return tripleTaped;
}
public float getDetectionTime() {
return detectionTime;
}
// reset the lists for detecting taps
public void resetDetector() {
tapTimes.clear();
accelList.clear();
doubleTaped = false;
tripleTaped = false;
}
// main function for tap detection
public void update() {
if (skeleton == null || !enabled)
return;
Tracker tracker = getTrackerToWatch();
if (tracker == null)
if (trackerToWatch == null)
return;
// check if we should reset
if (resetRequestTime != -1.0f) {
if (System.nanoTime() - resetRequestTime > resetDelayNs) {
if (oscHandler != null)
oscHandler.yawAlign();
skeleton.resetTrackersYaw();
resetRequestTime = -1.0f;
}
return;
}
// get the acceleration of the tracker and add it to the list
Vector3f accel = new Vector3f();
tracker.getAcceleration(accel);
trackerToWatch.getAcceleration(accel);
float time = System.nanoTime();
float[] listval = { accel.length(), time };
accelList.add(listval);
@@ -110,7 +113,7 @@ public class TapDetection {
}
// if the user is moving their body too much, reset the tap list
if (!isUserStatic(tracker)) {
if (!isUserStatic(trackerToWatch)) {
tapTimes.clear();
accelList.clear();
}
@@ -119,29 +122,17 @@ public class TapDetection {
int tapEvents = getTapEvents();
// if there are two tap events and the user is moving relatively slowly,
// reset the skeleton
// quick reset
if (tapEvents == 2) {
resetRequestTime = System.nanoTime();
// reset the list
tapTimes.clear();
accelList.clear();
doubleTaped = true;
detectionTime = time;
} else if (tapEvents >= 3) {
detectionTime = time;
tripleTaped = true;
doubleTaped = false;
}
}
// returns either the chest tracker, hip tracker, or waist tracker depending
// on which one is available
// if none are available, returns null
public Tracker getTrackerToWatch() {
if (skeleton.chestTracker != null)
return skeleton.chestTracker;
else if (skeleton.hipTracker != null)
return skeleton.hipTracker;
else if (skeleton.waistTracker != null)
return skeleton.waistTracker;
else
return null;
}
private float getAccelDelta() {
float max = -999.9f;
float min = 999.9f;

View File

@@ -0,0 +1,150 @@
package dev.slimevr.vr.processor.skeleton;
import dev.slimevr.config.TapDetectionConfig;
import dev.slimevr.osc.VRCOSCHandler;
import dev.slimevr.vr.trackers.Tracker;
// handles tap detection for the skeleton
public class TapDetectionManager {
// server and related classes
private HumanSkeleton skeleton;
private VRCOSCHandler oscHandler;
private TapDetectionConfig config;
// tap detectors
private TapDetection quickResetDetector;
private TapDetection resetDetector;
private TapDetection mountingResetDetector;
// number of taps to detect
private int quickResetTaps = 2;
private int resetTaps = 3;
private int mountingResetTaps = 3;
// delay
private static final float NS_CONVERTER = 1.0e9f;
private float resetDelayNs = 0.20f * NS_CONVERTER;
private float quickResetDelayNs = 1.00f * NS_CONVERTER;
private float mountingResetDelayNs = 1.00f * NS_CONVERTER;
public TapDetectionManager(HumanSkeleton skeleton) {
this.skeleton = skeleton;
}
public TapDetectionManager(
HumanSkeleton skeleton,
VRCOSCHandler oscHandler,
TapDetectionConfig config
) {
this.skeleton = skeleton;
this.oscHandler = oscHandler;
this.config = config;
quickResetDetector = new TapDetection(skeleton, getTrackerToWatchQuickReset());
resetDetector = new TapDetection(skeleton, getTrackerToWatchReset());
mountingResetDetector = new TapDetection(skeleton, getTrackerToWatchMountingReset());
updateConfig();
}
public void updateConfig() {
this.quickResetDelayNs = config.getQuickResetDelay() * NS_CONVERTER;
this.resetDelayNs = config.getResetDelay() * NS_CONVERTER;
this.mountingResetDelayNs = config.getMountingResetDelay() * NS_CONVERTER;
quickResetDetector.setEnabled(config.getQuickResetEnabled());
resetDetector.setEnabled(config.getResetEnabled());
mountingResetDetector.setEnabled(config.getMountingResetEnabled());
quickResetTaps = config.getQuickResetTaps();
resetTaps = config.getResetTaps();
mountingResetTaps = config.getMountingResetTaps();
}
public void update() {
if (quickResetDetector == null || resetDetector == null || mountingResetDetector == null)
return;
// update the tap detectors
quickResetDetector.update();
resetDetector.update();
mountingResetDetector.update();
// check if any tap detectors have detected taps
checkQuickReset();
checkReset();
checkMountingReset();
}
private void checkQuickReset() {
boolean tapped = (quickResetTaps == 2)
? quickResetDetector.getDoubleTapped()
: quickResetDetector.getTripleTapped();
if (
tapped && System.nanoTime() - quickResetDetector.getDetectionTime() > quickResetDelayNs
) {
if (oscHandler != null)
oscHandler.yawAlign();
skeleton.resetTrackersYaw();
quickResetDetector.resetDetector();
}
}
private void checkReset() {
boolean tapped = (resetTaps == 2)
? resetDetector.getDoubleTapped()
: resetDetector.getTripleTapped();
if (
tapped && System.nanoTime() - resetDetector.getDetectionTime() > resetDelayNs
) {
if (oscHandler != null)
oscHandler.yawAlign();
skeleton.resetTrackersFull();
resetDetector.resetDetector();
}
}
private void checkMountingReset() {
boolean tapped = (mountingResetTaps == 2)
? mountingResetDetector.getDoubleTapped()
: mountingResetDetector.getTripleTapped();
if (
tapped
&& System.nanoTime() - mountingResetDetector.getDetectionTime()
> mountingResetDelayNs
) {
skeleton.resetTrackersMounting();
mountingResetDetector.resetDetector();
}
}
// returns either the chest tracker, hip tracker, or waist tracker depending
// on which one is available
// if none are available, returns null
private Tracker getTrackerToWatchQuickReset() {
if (skeleton.chestTracker != null)
return skeleton.chestTracker;
else if (skeleton.hipTracker != null)
return skeleton.hipTracker;
else if (skeleton.waistTracker != null)
return skeleton.waistTracker;
else
return null;
}
private Tracker getTrackerToWatchReset() {
if (skeleton.leftUpperLegTracker != null)
return skeleton.leftUpperLegTracker;
else if (skeleton.leftLowerLegTracker != null)
return skeleton.leftLowerLegTracker;
return null;
}
private Tracker getTrackerToWatchMountingReset() {
if (skeleton.rightUpperLegTracker != null)
return skeleton.rightUpperLegTracker;
else if (skeleton.rightLowerLegTracker != null)
return skeleton.rightLowerLegTracker;
return null;
}
}