Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Controller Haptics #76

Open
wants to merge 34 commits into
base: master
Choose a base branch
from

Conversation

TheKrisSodroski
Copy link

@TheKrisSodroski TheKrisSodroski commented Dec 6, 2024

This commit contains the base code to have haptics working (Resolves #5).

I've checked in knuckles_right.json and updated actions.json to include the required entries for haptics. I'm unsure how actions.json (or the knuckles_right/left) is delivered to the end user, so I committed the files in here for now as an example.

Haptics are controlled through haptics.json file, which defines the haptics for both single handed, and dual handed haptics for each weapon. If this file isn't found, haptics are disabled by using a default WEaponHaptic object with everything zeroed out.

I have not tweaked the values in this json file: any help or suggestions would be appreciated.

Code recognizes whether user is left handed or right handed, and can assign different values for dominant vs non-dominant vibrations.

Notes:

  1. WeaponScopeType can probably be collapsed into new WeaponType enum.
  2. Unsure how to figure out if the gun is a charged plasma pistol. If someone could point me in the right direction, that'd be great.

@97saundersj
Copy link
Contributor

Wow great work, I know this is a highly requested feature and I can't wait to give this a test!
I had a quick look through the changes and its looking good, I like some of the refactoring changes, but I'll try and have a more in depth look at some point.
I'm just wondering why you mentioned only index knuckles controllers specifically, I'm guessing because that's the only controller you have access to for testing?
Also for the charged plasma pistol maybe you could check for how long the user has held the trigger button whilst holding the weapon? That would probably be too 'hacky' though.
Also it would be great to have the compiled zip files available for easy testing.

@TheKrisSodroski
Copy link
Author

Wow great work, I know this is a highly requested feature and I can't wait to give this a test!

Thanks, but I can't stress enough that it's built on top of the shoulders of giants. Your work is so good, that someone like myself without any vr or game experience was able to come in and quickly figure out how to add features. This is unheard of in the real world! 👏👏👏

I'm just wondering why you mentioned only index knuckles controllers specifically, I'm guessing because that's the only controller you have access to for testing?

Yes, I only have knuckles to test with.

No, because I don't actually understand how the json files are being delivered to clients.

The actions.json file checked into the repo is different than the ones that's delivered to clients.

image

Not sure where these are coming from. Do you manually make the release by copying these files (from somewhere other than the repo) and then zip it up to deliver to clients? If so, maybe I can take a stab at building a release script to automatically do this.

On top of that, in order to get haptics to work, I added the action to knuckles_right.json. i assume by doing this, haptics won't actually work with other controllers until these entries are there. I'm not a vr developer, so I'm not exactly sure how to add haptics to all controllers, or if there's a generic place to put these haptic actions.

Also for the charged plasma pistol maybe you could check for how long the user has held the trigger button whilst holding the weapon? That would probably be too 'hacky' though.

That was my additional thoughts. The haptics.json file could probably define tick bound haptics so for things like the plasma pistol I can ramp up vibration as charge happens. I'll start working towards refining that, but off the top of my head, I'm not sure how to recognize when the plasma pistol is actually fired (mouse release) so that I can trigger a large vibration. Same with the "overheat" mechanism. Maybe I can pick this off the weapon model somehow?

Also it would be great to have the compiled zip files available for easy testing.

If there's no distribution script, I can start to add that in so that haptics and other json files are automatically zipped up ready for client release. We can probably built it into github actions to autorelease moving forward.

Couple other notes:

  1. I've gotten my fiancé to agree to help me flesh out the haptics values. I'll check in a more refined haptics.json file next week when she has some time to modify the config while I test (as I added automatic haptics reloading on change).
  2. I'm wondering if you have some time in the coming weeks to maybe chat with me so I can ask some questions about how everything is working. My next big goal would be to get multiplayer to work, but I'd like to mine your knowledge about how you decompiled and reverse engineered this.

@LivingFray
Copy link
Owner

Nice work, I haven't had a chance to look over this properly yet but from what I've seen its looking great.
A few notes/comments:

  • You should be able to detect the plasma pistol charging by detecting the player's shooting property remaining greater than zero while that gun is equipped (static_cast<UnitDynamicObject*>(Helpers::GetLocalPlayer())->Shooting)
  • actions.json is delivered to the player by being copied into the /VR/OpenVR folder of HaloCEVR.zip by makerelease.bat and the mod instructs OpenVR to look there on startup
  • I have a jank python script (manifest.py) for auto generating the binding files (including actions.json) which I manually run whenever I make changes to the default bindings, it should be fairly straightforward to add the haptics section to that to avoid having to manually update every json file. (That script also needs refactoring, it is quite the mess)
  • You should probably go ahead and remove the scoped weapon enum and replace it with the more fleshed out one you've created

@teddybear082
Copy link
Contributor

teddybear082 commented Dec 8, 2024

So in theory other controller users could copy the haptics part of the knuckles(right) json file to the bindings files for the other controllers it seems, if I understand this correctly? Also, is there a reload haptic event? I think some people were asking for that at one point (I'm not demanding it just if it's something "easy" relatively speaking to the other massive work done here it might be considered at the same time).

@TheKrisSodroski
Copy link
Author

TheKrisSodroski commented Dec 8, 2024 via email

Update manifest.py to include new haptic actions.

Update makerelease to include new haptics.json
@TheKrisSodroski TheKrisSodroski changed the title Index Knuckles Controller Haptics Controller Haptics Dec 9, 2024
@TheKrisSodroski
Copy link
Author

I've updated makerelease.bat to include haptics automatically.

I've also added the vibration actions to the manifest.py file and refactored ScopedWeaponType to use WeaponType instead.

@TheKrisSodroski
Copy link
Author

  • You should be able to detect the plasma pistol charging by detecting the player's shooting property remaining greater than zero while that gun is equipped (static_cast<UnitDynamicObject*>(Helpers::GetLocalPlayer())->Shooting)

I gave this a shot, but it seems this location doesn't seem to correspond to the way we would need to deal with haptics for the plasma pistol.

One issue, is that WeaponHandler.Prefire doesn't actually get called during charging, only when the weapon is actually fired. For the plasma pistol, this is the "release" of the charge.

To work around this, I had to hook into the main input hook and start the logic there. Needs a lot of work, and is going to be hacky and error prone, but with some finesse it should provide a decent enough experience I think.

Branch for Plasma pistol:

https://github.com/TheKrisSodroski/HaloCEVR/tree/plasmaPistol

@97saundersj
Copy link
Contributor

@TheKrisSodroski I want to give these changes a test but when I try and build the files I get these errors, do I need to do anything different from normal?
image
Is it worth trying to test your changes now or should we wait for your plasma pistol changes to be finished off first? I'm just excited to give them a try :)

@TheKrisSodroski
Copy link
Author

TheKrisSodroski commented Dec 13, 2024

@97saundersj

Oops. Forgot to checkin the vs proj file with the new compiled files. I've updated that so it should build correctly now. You will need to update the haptics/controller json files into your halo directory. You can do this by running the makereleasse.bat file or just copying the files in the Bindings folder to the correct locations (haptics should be located next to the inject logs file).

The work on haptics is basically done I think from my side. I've implemented the plasma pistol as best as I could.

Having tested it for a couple hours, even though it's not perfect, it felt good enough that I forgot I was even testing it!

Some issues:

  1. There's no way for us to know if the player is reloading (as far as I can tell).
  2. The different values for haptics don't seem to make much of a difference. I've set the values to default 1 for frequency and amplitude for now. It uses OpenVR TriggerHapticAction. Not sure if TriggerHapticPulse would be better, but this seems to be on it's way to deprecation.
  3. Unsure how to get this to work with vehicles.

Other notes:

  1. Now that holsters are available, we probably should add haptics in the event that the user enters the holster area.

@97saundersj
Copy link
Contributor

Thanks for fixing that @TheKrisSodroski, I can build the files now but when actually launching Halo I get an error. I get a DirectX 9.0b needs to be installed error when launching halo, and the inject.log reads only

WeaponHapticsConfig] Initializing
[WeaponHapticsConfig] Loading Config

So i'm not sure if it's crashing somewhere whilst trying to load the hapticsConfig? The haptics.json is placed in the "Halo/VR" folder.

With weapon holsters I'm happy to add haptics to them after this PR goes in,

I've had a look over your code and it looks good but just left a few minor comments.

Copy link
Contributor

@97saundersj 97saundersj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor comments, but getting issues with launching the game so I can't actually test the haptics.

@@ -85,12 +86,15 @@ class Game

bool bNeedsRecentre = true;
bool bUseTwoHandAim = false;
bool bIsMouse1Down = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we call this 'bIsFiring'? I feel like that would be more descriptive for how it is used.

};
virtual void TriggerHapticVibration(ControllerRole role, float fStartSecondsFromNow, float fDurationSeconds, float fFrequency, float fAmplitude) = 0;

//virtual IVRInput* GetVrInput() { return NULL; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this comment?

"startSeconds: "
<< fStartSecondsFromNow
<< "\n"
"duration: "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like theres too much indentation for these lines.


void WeaponHapticsConfigManager::LoadConfig()
{
std::string hapticsConfig = "VR/haptics.json";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make the path "VR/OpenVR/haptics.json"? Just so it's in the folder with the other json files.

return plasmaPistolSettings.isCharging;
}

void WeaponHapticsConfigManager::WeaponFired(WeaponType Weapon)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Weapon' doesn't seem to be used, should we be using it or can it be removed?

Logger::log << "[WeaponHapticsConfig]: Weapon fired" << std::endl;
#endif

if (plasmaPistolSettings.isCharging == true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a check to see your current weapon is a plasma pistol before this?

@TheKrisSodroski
Copy link
Author

@97saundersj

That issue should be resolved now. Was missing a comma in the Bindings/haptics.json file.

I'll start working on your feedback this weekend.

Happy testing!

@97saundersj
Copy link
Contributor

97saundersj commented Dec 14, 2024

Thanks @TheKrisSodroski I managed to test these changes and wow they feel great! The Assault Rifle in particular now feels like a proper gun and not a pea shooter!
I came across a few bugs while testing:

  • When out of ammo the Plasma Pistol seemed to keep its overcharged vibrations
  • If I fired with a weapon and then swapped to the Plasma Pistol it was vibrating like it was overcharging
  • The needler didn't seem to have any vibrations
  • When a weapon was out of ammo and held in two hands the foregrip was still vibrating after firing
  • When fireing a weapon two handed it felt like the vibrations in the foregrip were stronger than the vibrations of the hand pulling the trigger (Not sure if this is actually the case but thats what it felt like to me, so might just be a personal thing)

Keep up the good work I'm very excited for these improved haptics :)

@LivingFray
Copy link
Owner

Some issues:

1. There's no way for us to know if the player is reloading (as far as I can tell).

Try this, it should be some help
3063953

Also, on an unrelated note, having separate json configs for each weapon got me thinking: I wonder if at some point in the future it would be worth expanding these files beyond haptics to make things more data-driven so that custom weapons can be better supported.
For example having a json file that says any weapon with string "\XXXX\" in its filename should use these haptics, this scope offset, can't be two handed, etc.
Not something you should necessarily add in this PR, but something to think about perhaps.

@teddybear082
Copy link
Contributor

Wow amazing work! Whenever this is ready for testing if someone can share the compiled version I am happy to

@TheKrisSodroski
Copy link
Author

@teddybear082

I'll be implementing the review items this week. Should have another version out later this week and I'll compile it up for you.

@slipperfish
Copy link
Contributor

Wow amazing work! Whenever this is ready for testing if someone can share the compiled version I am happy to

I just happened to compile this and it works for me, let me know if it doesn't work or wait for Kris's update.

HaloCEVR.zip

@teddybear082
Copy link
Contributor

Just reporting back - I tried the DLL shared by slipperfish above and I can feel the haptics but they are very low power (almost like the type of haptic you would get from picking up an item rather than firing a gun). On Quest 3 + VirtualDesktop. Would playing around with the "amplitude" value in the haptics.json work potentially to increase the haptics? Figured I would share either way. Great work!

@TheKrisSodroski
Copy link
Author

TheKrisSodroski commented Dec 18, 2024

but they are very low power (almost like the type of haptic you would get from picking up an item rather than firing a gun)

Yes, I feel that as well.

What's odd is that the amplitude is at it's maximum value according to the api documentation (between 0f and 1f, and we have 1f as the value).

TriggerHapticVibration

There's also an undocumented parameter that's necessary. Not sure what they're supposed to do, but I found a random sample on the internet that seemed to allow me to call the api.

Missing Documentation

EVRInputError TriggerHapticVibrationAction( VRActionHandle_t action, float fStartSecondsFromNow, float fDurationSeconds, float fFrequency, float fAmplitude )

Triggers a haptic vibration action.

action - The action to trigger
fStartSecondsFromNow - When to start the haptic event
fDurationSeconds - How long to trigger the haptic event for
fFrequency - The frequency in cycles per second of the haptic event
fAmplitude - The magnitude of the haptic event. This value must be between 0.0 and 1.0.

I might try and use "TriggerHapticPulse" instead, but I believe it's being deprecated.

@LivingFray
Copy link
Owner

Have you tried adjusting the frequency? I believe the docs say it has a range of 0-360 and from a quick scan through the files you have it at 1 by default

@TheKrisSodroski
Copy link
Author

Have you tried adjusting the frequency? I believe the docs say it has a range of 0-360 and from a quick scan through the files you have it at 1 by default

I'm going to get a chance to do some additional testing today. I've added proxies for TriggerHapticPulse as well to see if that's what developers are generally using for weapon haptics.

@LivingFray
Copy link
Owner

Hey, I've not really been keeping up with this PR. Beyond fixing the merge conflict from a recent change of mine, is this ready to merge into master? Or are there still some issues that need resolving first?

@TheKrisSodroski
Copy link
Author

With the holidays, it's been tough doing some last testing. I'll be getting to it this weekend to make some final changes, but I think it should be good to go early next week.

@LivingFray
Copy link
Owner

Alright, no worries. Just wanted to make sure I wasn't neglecting a completed feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feature request: haptics on shooting weapon/finishing a reload
5 participants