matzman666 / OpenVR-InputEmulator

An OpenVR driver that allows to create virtual controllers, emulate controller input, manipulate poses of existing controllers and remap buttons. A client-side library that communicates with the driver via shared-memory is also included.
GNU General Public License v3.0
716 stars 138 forks source link

Feature Request: emulate vive trackpad directly with analog stick input (ie oculus) #39

Open lordbinky opened 6 years ago

lordbinky commented 6 years ago

A ridiculous scenario caused intentionally by Bethesda. I tried a few variations of settings and couldn't the analog sticks to not track the return to center movement. I apologize if this is already possible and I missed the configuration. I don't think this would be too tricky if a function just translates axis change directionally. Mentally I picture something like increase from center position to it's limit on any given axis corresponds to trackpad's center to it's limit on that axis, but do not decrement on analog stick's decrease back to center, where center analog equals center trackpad or maybe the proximity sensor triggering a finger lift response.

lordbinky commented 6 years ago

I may make a fork and do a pull request but my next few weeks are...fully scheduled.

If someone would like to beat me to it, after my peek at the code my plan of attack is..

Data: 1) Add a bool and two floats to the struct AnalogBinding struct, ex: bool emulateTrackpad; const vr::VRControllerAxis_t& axisState; in lib_vrinputemulator/include/vrinputemulator_types.h

2) Add functions to update these variables in AnalogInputRemappingController client_overlay/src/tabcontrollers/AnalogInputRemappingController.cpp & .h ex: setOldAxisState(const vr::VRControllerAxis_t& axisState axisState)

Logic: 3) In void OpenvrDeviceManipulationInfo::sendAnalogBindingput the logic to decide to keep the present axisState compaired to the oldAxisState (or reset if it's 0) before the deadzone logic so I don't break it's magic. located in /driver_vrinputemulator/src/driver_deviceinfo.cpp

GUI: 4) Figure out how to add a a checkbox for the emulateTrackPad bool in the client_overlay/bin/win64/res/qml/DeviceAnalogInputRemappingPage.qml Which appears to be another straightforward task.

I may have missed something glaring, my job is all electrical engineering based now, so take pity on me if I derped. I still think this may get the basic emulation in and check box in place even if it is not fully fleshed out with a full function set in the AnalogInputRemappingController class.

matzman666 commented 6 years ago

I don't quite understand what exactly you want to achieve with your planned additions. The AnalogBinding struct is supposed to only contain configuration information, but the two floats you plan to add seem to be state information, or what config are they representing?

In my opinion the best course of action would be to suppress all axis events as long as there is no finger "touching" the stick. This way you can let the stick go whenever you are finished interacting with it, and OpenVR and subsequently the application you are running does not notice the stick returning to it's neutral position at all. Or did I understand the problem wrong?

lordbinky commented 6 years ago

Ew, Ok I didn't proof read after getting distracted. In fallout 4 vr, it seems they use swipe motions of the touchpad so the return to center of the analog stick undoes the movement through things like menus. You can get away with flicking the stick and sometimes it misses the sticks movement on its center.

So i thought if I prevented axisState changes from being passed on by the sendAnalogBinding function during the stick's return to center. Although I need to keeping track of the initial direction I moved out of center from as a proxy for the users intended direction change. At least until the stick returns or passes through the center (I have that as axisState.x or y of.5 in my head right now for some reason) where I can assume the whatever the next axisState change is one desired by the user. For that I needed somewhere persistent between events to hold a couple floats or use a copy the last axisState ( for its x and y floats) to compare off of which ended up getting stuck it in analogBinding hoping it would take the abuse well and be reachable inside send analog binding. With a little hope that I didn't foul responsiveness up I thought the worst that would happen is clicking back one menu item when the stick hit center again.

My personal tendency is to keep my thumb on the stick the whole time, so I didn't consider using the sticks sensor state to determine the user intent. I see that would be much cleaner without adding any bloat elsewhere ( sorry analogBinding...)and avoid odd behavior that might crop up, that way just requires a little retraining on the user end.

lordbinky commented 6 years ago

Didn't realize that was a wall of text, so in short I think you understood despite my description and your idea is much more elegant.

matzman666 commented 6 years ago

I uploaded a test version where it test the idea of ignoring axis events when the finger does not touch the joystick. Please try it out and report results.

lordbinky commented 6 years ago

From my experience so far testing it works but it's not consistent. Which is pretty awesome, but not well enough to stop binding the unused buttons (A & X) to up and down (which is still doesn't work for scrolling in every in-game menu). I believe there's a race condition when pressing upward and letting go ( probably the race is in the event update between the stick re-centering and the touch sensor updating that I lifted my thumb away, it is possible just the way I lift it doesn't get it out of the thumbstick's sensing zone since that extends above the thumbstick's top a bit). To me this thought process is reinforced when I did an extra bit of testing using two hands. While holding the stick in position with the off hand ( being careful not to trigger the touch sensor) and removing the thumb before letting the stick return, it does scroll correctly.

So in the other direction I get much better consistency when scrolling down. This is simply because I can move my thumb back in a swipe that moves the thumb out of the sensors field while the very tip of the thumb keeping the the thumb stick in place just long enough. This isn't 100% consistent though, if I do it too quickly, the thumb sensor doesn't update fast enough.

I'd also note that there's a good amount of unpredictability with the joysticks and moving fast in the first place (the basis of the flick the stick method working to scroll through menus), I'm not sure if it's just a polling speed issue or what exactly, but it seems to make relying on the user to do snap actions more difficult.

Also, if it's a trivial effort to get any regular gamepad recognized in OpenVR, using it's analog inputs may replicate the Oculus Touch joystick well enough to watch what happens in debug for yourself. Just a thought in case it's helpful, I know I like to watch things for myself.

I really do appreciate your help on this, and I know there's lots of people excited for it. I still have to configure visual studio before I can be of more help than a tester, my PC was setup for gaming and free of anything productive.