how to manage XBOX and other joysticks with JXinput inputs, especially stick for rotating mobiles - StrikerX3/JXInput GitHub Wiki
Hi,
For participating to the JXInput effort development, here is what I wrote for my PC game. Stick inputs are smoothly filtered as follows. It is a low-pass filter.
// Get some joystick inputs (XB360, ...) as sticks:
// Threshold for moving and rotating objects
static final double MIN_THRESHOLD_STICK_MOVING = 0.2;
static final double THRESHOLD_STICK_ROTATION = 0.2;
static final double THRESHOLD_TRIGGER_ARMT_LANCT = 0.5;
// Low-pass filter for X and Y
final static int NB_SAMPLES_ACQ_ROTATION = 3;
final static int FILTERING_WEIGHT_ROTATION = NB_SAMPLES_ACQ_ROTATION * (NB_SAMPLES_ACQ_ROTATION+1) / 2;
final static int WEIGHTS_SUM = NB_SAMPLES_ACQ_ROTATION * (NB_SAMPLES_ACQ_ROTATION+1) / 2;
// The rotation with the previous values saved on X and Y axes
static LinkedList<Double> sampleAcqRotationX = new LinkedList<Double>();
static LinkedList<Double> sampleAcqRotationY = new LinkedList<Double>();
static double averageRotationOnX = 0;
static double averageRotationOnY = 0;
// _______________________________________
// Initialization:
static XInputDevice device0 = XInputDevice.getDeviceFor(0); // 1st device of the Joystick
if (device0.isConnected()) {
bJoystickOKandConnectedToThisPlatform = true;
choixDuModeUtilisationDuJeu = IHMpossibles.JOYSTICK;
components = device0.getComponents();
boutons = components.getButtons();
componentsDelta = device0.getDelta();
boutonsDelta = componentsDelta.getButtons();
axesDelta = componentsDelta.getAxes();
axes = components.getAxes();
for (int i=0; i< NB_SAMPLES_ACQ_ROTATION; i++){
sampleAcqRotationX.add(0.0);
sampleAcqRotationY.add(0.0);
}
}
// _______________________________________
// PERIODIC processing:
// On each X ms (with X inside the values 100ms and 150 ms):
if (device0.poll()) {
// Right stick events: raw values
double posRX = axes.get(XInputAxis.RIGHT_THUMBSTICK_X);
double posRY = axes.get(XInputAxis.RIGHT_THUMBSTICK_Y);
boolean bStickRightActif = false;
if ((Math.abs(posRX) > THRESHOLD_STICK_ROTATION) || (Math.abs(posRY) > THRESHOLD_STICK_ROTATION)) {
bStickRightActif = true;
}
// Left stick events: raw values
double posLX = axes.get(XInputAxis.LEFT_THUMBSTICK_X);
double posLY = axes.get(XInputAxis.LEFT_THUMBSTICK_Y);
boolean bStickLeftActif = false;
if ((Math.abs(posLX) > MIN_THRESHOLD_STICK_MOVING) || (Math.abs(posLY) > MIN_THRESHOLD_STICK_MOVING)) {
bStickLeftActif = true;
}
// here your code of other events of your Joystick:
.....
// _______________________________________
if (bStickLeftActif) { // moving case
double[] deplactXY = {0.0,0.0};
deplactXY[0] = DISTANCE_MAX* posLX;
deplactXY[1] = - DISTANCE_MAX * posLY;
// and now, your code for moving your object is here
.....
}
else { // rotation case
// remove the oldest value and add the new one (for X and Y)
sampleAcqRotationX.removeFirst();
sampleAcqRotationY.removeFirst();
sampleAcqRotationX.add(posRX);
sampleAcqRotationY.add(posRY);
double sumX = 0;
double sumY = 0;
double sampleWeight=0;
// The filtering by calculating the weighted values (the highest weight for the more recent value, the lowest weight for the oldest value)
// and, then, computing the average values
int sizeSampleList = sampleAcqRotationX.size();
for (int i=0; i < sizeSampleList; i++) {
sampleWeight++; // from 1 to NB_SAMPLES_ACQ_ROTATION, necessarily
sumX += sampleWeight * sampleAcqRotationX.get(i);
sumY += sampleWeight * sampleAcqRotationY.get(i);
}
averageRotationOnX = sumX / WEIGHTS_SUM;
averageRotationOnY = sumY / WEIGHTS_SUM;
// and now, your code for rotating your object is here
.....
}
} // end poll