Note: Something you might run into is the jme api for dealing with controllers leaves a lot to be desired, and is a little outdated.
Here is the code I use for getting controllers, it is oriented around using device names to get HTC devices, but you can easily add the oculus names in here too:
//Get models of trackers
ArrayList<Integer> deviceIndexList = new ArrayList<>();
for (int i = 0; i < VR.k_unMaxTrackedDeviceCount; i++) {
int classCallback = VRSystem.VRSystem_GetTrackedDeviceClass(i);
if (classCallback == VR.ETrackedDeviceClass_TrackedDeviceClass_Controller || classCallback == VR.ETrackedDeviceClass_TrackedDeviceClass_GenericTracker) {
IntBuffer error = BufferUtils.createIntBuffer(1);
String controllerModelNumber = VRSystem.VRSystem_GetStringTrackedDeviceProperty(i, VR.ETrackedDeviceProperty_Prop_ModelNumber_String, error);
if (error.get(0) != 0) {
LOGGER.warning("Error getting controller information: " + i);
}
deviceIndexList.add(i);
LOGGER.fine(" Tracked controller " + (i + 1) + "/" + VR.k_unMaxTrackedDeviceCount + " " + controllerModelNumber + " attached.");
}
}
//Setup trackers
int controllers = vrAppState.getVRinput().getTrackedControllerCount();
for (int i = 0; i < controllers; i++) { //Assuming 0 & 1 are controllers
IntBuffer error = BufferUtils.createIntBuffer(1);
String model = VRSystem.VRSystem_GetStringTrackedDeviceProperty(deviceIndexList.get(i), VR.ETrackedDeviceProperty_Prop_ModelNumber_String, error);
if (error.get(0) != 0) {
LOGGER.warning("Error getting controller information: " + deviceIndexList.get(i));
}
model = model.toLowerCase();
if (model.contains("vive") && model.contains("tracker")) {
Node trackerNode = new Node("vive tracker " + (i - 2));
Spatial tracker = app.getAssetManager().loadModel("Models/VR/vive_tracker.j3o");
tracker.setUserData("input_index", i);
tracker.setUserData("device_index", deviceIndexList.get(i));
((SimpleApplication) app).getRootNode().attachChild(tracker);
trackers.add(trackerNode);
LOGGER.info("Found Vive Tracker");
}
}
And then later in your program:
@Override
public void update(float tpf) {
//This assumes that controller index 0 = left, and 1 = right... IDK if this is correct or not when only one controller and a tracker is present...
moveVrInput(0, leftHand);
moveVrInput(1, rightHand);
//Update trackers
for (Spatial tracker : trackers) {
moveVrInput(tracker.getUserData("input_index"), tracker);
}
}
private void moveVrInput(int index, Spatial geo) {
Quaternion q = vrAppState.getVRinput().getFinalObserverRotation(index);
Vector3f v = vrAppState.getVRinput().getFinalObserverPosition(index);
if (q != null && v != null) {
geo.setCullHint(Spatial.CullHint.Dynamic); // make sure we see it
geo.setLocalTranslation(v);
geo.setLocalRotation(q);
} else {
geo.setCullHint(Spatial.CullHint.Always); // hide it
}
}