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

Provide a JSON schema for the hmdq json output #4

Open
Bluscream opened this issue Dec 22, 2023 · 5 comments
Open

Provide a JSON schema for the hmdq json output #4

Bluscream opened this issue Dec 22, 2023 · 5 comments

Comments

@Bluscream
Copy link

Currently we're using a C# class autogenerated by quicktype.io from some example outputs i got from myself and friends, but it's missing a lot of values like the oculus stuff and also quicktype is bad at recognizing ulongs and floats which requires me to do a bunch of trial and error. Would be nice if this repository contained a json schema for the output that can be easily converted to classes/parsers in a bunch of different languages

@risa2000
Copy link
Owner

risa2000 commented Jan 2, 2024

I believe you can, for the sake of having JSON schema, generate one from the actual data file.
I never had ambitions to "codify" the data in the JSON file, even though it is versioned and hmdv can even read the older versions and "upgrade" them to the latest one.

At the beginning the JSON format changed several times, but I believe the last time it happened was when I added support for Oculus runtime. The next big change probably will come with OpenXR.

On the other hand, for example the list of properties recorded in OpenVR section is generated from OpenVR definition file (which may add or drop a property as needed), so should be considered non-reliable (apart from model and manufacturer name, which are used for rendering of visualizations in HMDGDB).

If you need a "canonical" format I would suggest writing a simple translator to your JSON format, which hopefully could skip all the irrelevant info and also simplify the implementation of the additional processing as you probably would not need the data which differ between different runtimes (OpenVR and Oculus).

On the other hand, the data related to the view geometry should be stable enough, so you could use them as a template (at least until OpenXR which may introduce multiview) for you schema.

@Bluscream
Copy link
Author

A schema file would still be prefered, and also do you know a better way to get fallback than this?

@risa2000
Copy link
Owner

risa2000 commented Jan 2, 2024

A schema file would still be prefered, and also do you know a better way to get fallback than this?

I understand the advantage of a schema, but I am still not sure, if it makes sense in my case - I will need to think it through - and even if there will be one, it will be just a partial schema for parts which are fixed. Anyway, I am not promising anything.

For what concerns the code snippet you referenced, let me put few comments in. First the general comment about the preference of OpenVR over Oculus:

  • Oculus headsets can run as OpenVR headsets (when run in SteamVR), but not vice versa. Oculus headsets, when run in Oculus runtime (OVR) can report values which may not be exposed over OpenVR API and thus not be present in OpenVR data, or may be slightly different (due to internal conversion SteamVR driver does to them), so the general logic should be reversed - first check for direct Oculus data and if they exist prefer those. I also believe some Oculus headsets my report HAM in OVR but not in SteamVR. Which has an impact on "total" FOV values as HAM is taken into account when doing the calculation.

Now for the particular properties:

  • I am not sure what OpenVrHmd property is supposed to represent. The property PropRenderModelNameString is set to generic_hmd for any OpenVR HMD supported by OpenVR runtime. Now, Oculus headsets can also run in OpenVR runtime using Oculus OpenVR driver, and if they are run this way, they will have this property set as well. If they are run in Oculus runtime, this property is not defined and will never be set (in oculus branch in hmdq JSON data). You can even run hmdq on Oculus headsets while having both runtimes active (OpenVr, OVR) which will result in having both branches (openvr and oculus) in hmdq JSON data filled.

So your OpenVrHmd property effectively only indicates that OpenVR runtime (SteamVR) was active when hmdq was run on particular headset and that the headset is supported, but since all Oculus headsets are supported, it actually just indicates that SteamVR was running at the same moment you executed hmdq. Is it what you meant?

BTW: It is true even for Windows MR headsets (e.g. HP Reverb) when using SteamVR runtime, except there is no explicit support (and data branch) for Windows MR runtime in hmdq (data).

  • Fallback for Manufacturer and Model looks alright. Just keep in mind that there is no formal requirement in OpenVR what the corresponding properties should read and there are some creative implementations. For HMDGDB purposes I basically use the reported values if they match the actual HMD name and manufacturer. For the other cases I use a hard coded translation table so that the names in the database read as one would expect. For HMDGDB it is what I wanted, but in your case, when using directly the values reported by the runtime, you may end up with somewhat convoluted names as HP Reverb Virtual Reality Headset G20 for HP Reverb 2 or HP Reverb VR Headset VR1000-2xxx for HP Reverb. Which is probably fine for your case, just do not get upset when it does not match the names in HMDGDB.

  • Width and Height if meant to be the render target resolution is fine too. Just keep in mind that it is probably what user has set up in SteamVR UI (or OVR) by changing the resolution slider and would correspond to "global" settings. If any "local" value is set for any particular SteamVR app it will not get captured by hmdq because hmdq runs as a separate app, independent from any other app (and its setting). The other consequence is that this is really an arbitrary value (set by a user) and not something tied to the particular headset. I have it displayed in HMDGDB, but technically it really does not say anything about the headset, it just says that at the particular moment when hmdq run, the global setting was set to these particular values. Depending on how you use it in your app, it may or may not be what you wanted.

  • VerticalFov might be tricky one. fov_tot::fov_ver is the calculated visible vertical FOV while incorporating HAM (if it is defined). Which may be less if the HAM masks some area at the bottom or the top of the viewing frustum. (The same is true for horizontal FOV.) I would expect that if you are interested in a view geometry for the rendering, instead of using of "total FOV" you might want to use "raw_eye" data (basically the viewing frustum definition) to avoid getting the values impacted by the HAM. So again, depending on what you are actually interested in, you may or may not get what you want.

  • Considering default_fov vs max_fov geometry data in oculus branch (runtime) the default_fov branch is the only one you ever want to use. The other one, while exposed through OVR API (and recorded by hmdq), seems to never be used and sometimes even broken.

Finally, let me conclude with this thought (without knowing the details of your app):

It looks like you might be interested in knowing "just" the view geometry (viewing frustums) used in a stereo rendering for particular headset. If this is the case, it may be probably far easier simply interfacing the corresponding VR runtime directly from your app and obtain those values this way as in this case you would not need to know the HAM and its (eventual) impact on views (and consequently visible FOV).

@Bluscream
Copy link
Author

I understand the advantage of a schema, but I am still not sure, if it makes sense in my case - I will need to think it through - and even if there will be one, it will be just a partial schema for parts which are fixed. Anyway, I am not promising anything.

First of all, thanks for your detailed response and the insights. I've let a online converter generate this schema for me but obviously that's hella wrong since it doesn't know whats required and what's optional and can't properly parse data types like floats.

  • Oculus headsets can run as OpenVR headsets (when run in SteamVR), but not vice versa. Oculus headsets, when run in Oculus runtime (OVR) can report values which may not be exposed over OpenVR API and thus not be present in OpenVR data, or may be slightly different (due to internal conversion SteamVR driver does to them), so the general logic should be reversed - first check for direct Oculus data and if they exist prefer those. I also believe some Oculus headsets my report HAM in OVR but not in SteamVR. Which has an impact on "total" FOV values as HAM is taken into account when doing the calculation.

Thanks for your take on this, i will reverse the detection in the next commit. So when OpenXR support is added it will be Data.Oculus.Properties.Hmd.<Prop*> ?? OpenVrHmd.<Prop*> ?? Data.OpenXR.Properties.Hmd.<Prop*>, right?

  • I am not sure what OpenVrHmd property is supposed to represent.

OpenVrHmd is just containing the actual Hmd instance given by OpenVR since i'm not interested in other devices like base stations, controllers, etc...

BTW: It is true even for Windows MR headsets (e.g. HP Reverb) when using SteamVR runtime, except there is no explicit support (and data branch) for Windows MR runtime in hmdq (data).

No idea how i would handle WinMR since i don't know anyone with such a HMD.

  • Fallback for Manufacturer and Model looks alright. Just keep in mind that there is no formal requirement in OpenVR what the corresponding properties should read and there are some creative implementations. For HMDGDB purposes I basically use the reported values if they match the actual HMD name and manufacturer. For the other cases I use a hard coded translation table so that the names in the database read as one would expect. For HMDGDB it is what I wanted, but in your case, when using directly the values reported by the runtime, you may end up with somewhat convoluted names as HP Reverb Virtual Reality Headset G20 for HP Reverb 2 or HP Reverb VR Headset VR1000-2xxx for HP Reverb. Which is probably fine for your case, just do not get upset when it does not match the names in HMDGDB.

That is indeed interesting. I hoped it would be more consistent. Would you mind sharing your translation table so i can show a name that makes sense to the user?

  • Width and Height if meant to be the render target resolution is fine too.
  • VerticalFov might be tricky one.

Thanks for these insights. I'm not good with math so i'll leave the headscratching stuff to @ibigsnet 🙃

It looks like you might be interested in knowing "just" the view geometry (viewing frustums) used in a stereo rendering for particular headset. If this is the case, it may be probably far easier simply interfacing the corresponding VR runtime directly from your app and obtain those values this way as in this case you would not need to know the HAM and its (eventual) impact on views (and consequently visible FOV).

That might be a possibility but i'll be honest with you i don't know if there's libraries for all the different runtimes and i really don't want to basically have to rewrite most of hmdq to get to where we are now. I just would've hoped you had split up hmdq into a library and the actual parser/ui so i could've just used DLLImport instead of the weird output capture that is probably very susceptible to errors.

@risa2000
Copy link
Owner

risa2000 commented Jan 3, 2024

First of all, thanks for your detailed response and the insights. I've let a online converter generate this schema for me but obviously that's hella wrong since it doesn't know whats required and what's optional and can't properly parse data types like floats.

It looks like you may need only a very small subset of all values, for those, it should not be that difficult to "guess" the schema from the values.

Thanks for your take on this, i will reverse the detection in the next commit. So when OpenXR support is added it will be Data.Oculus.Properties.Hmd.<Prop*> ?? OpenVrHmd.<Prop*> ?? Data.OpenXR.Properties.Hmd.<Prop*>, right?

Right.

OpenVrHmd is just containing the actual Hmd instance given by OpenVR since i'm not interested in other devices like base stations, controllers, etc...

Ah, ok, I misread the code. In this case, what do you want to look for is "Prop_DeviceClass_Int32": 1 in the list of properties. Device class 1 identifies HMD.

BTW: It is true even for Windows MR headsets (e.g. HP Reverb) when using SteamVR runtime, except there is no explicit support (and data branch) for Windows MR runtime in hmdq (data).

No idea how i would handle WinMR since i don't know anyone with such a HMD.

You won't. Unless they are run in SteamVR context (as SteamVR headsets), they are not visible for hmdq.

It looks like you might be interested in knowing "just" the view geometry (viewing frustums) used in a stereo rendering for particular headset. If this is the case, it may be probably far easier simply interfacing the corresponding VR runtime directly from your app and obtain those values this way as in this case you would not need to know the HAM and its (eventual) impact on views (and consequently visible FOV).

That might be a possibility but i'll be honest with you i don't know if there's libraries for all the different runtimes and i really don't want to basically have to rewrite most of hmdq to get to where we are now. I just would've hoped you had split up hmdq into a library and the actual parser/ui so i could've just used DLLImport instead of the weird output capture that is probably very susceptible to errors.

I understand what you want, but it would be a pain to do pretty. The data collected from any VR runtime are basically set of properties of different types (some of them are even vectors or matrices) and exposing them in a programmatic way from a library with "C" API would lead to the complexity of the original API.

hmdq uses internally a json instance for this purpose (think an analogy to Python's dict) which is elegant enough for internal usage but pain to expose while using "plain old types".

What I think might be relatively easy to add though is a command line option to write the output JSON file to stdout instead of the file, if it could be of any help to you.

For what concerns the translation from "raw" headset names to user friendly names, I will see if I could expose that in a consistent way.

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

No branches or pull requests

2 participants