Prof-Butts / xwa_ddraw_d3d11

Direct3D 11 implementation of DDraw.dll for XWA with VR support and New Shaders
MIT License
6 stars 4 forks source link

Fully remove use of MouseLook for headtracking #59

Open morallo opened 2 years ago

morallo commented 2 years ago

With the new hooking method, it is not necessary to use MousePositionX,Y variables in CockpitLookHook to inject the headtracking in the camera, and we can apply the full transform including roll.

However, if we stop updating mouselook variables, there are a number of things that rely on it that will be incorrectly positioned as XWA or ddraw uses mouselook variables to position them in the right place relative to the camera position.

The main benefit is that the fix is just to apply the full headtracking pose transform as offset, instead of having to decompose it and apply only one part in CockpitLook (pitch,yaw) and the rest in ddraw, which makes things complex.

Things to review/fix:

@Prof-Butts did I miss anything?

morallo commented 2 years ago

Lock on target mode (camera follows your target) works in non-VR mode, but not in VR mode. It just breaks the reticle positioning and the speedeffect (and probably other things)

However, I think this should never be used in VR. It will cause sickness and you can always follow the target with your own head instead, which is the whole point of headtracking.

We should capture the L key and just ignore it. Any ideas how to do that @Prof-Butts ?

morallo commented 2 years ago

The HUD is fixed by setting the g_VSMatrixCB.fullViewMat to the inverse of the headtracking pose in DrawHUDVertices() The aiming reticle can be correctly positioned just by setting g_ShadertoyBuffer.reticleMat = g_VSMatrixCB.fullViewMat in RenderExternalHUD().

morallo commented 2 years ago

The SpeedEffect can be fixed with ViewMatrix = g_VSMatrixCB.fullViewMat * ViewMatrix; in RenderSpeedEffect.

morallo commented 2 years ago

It turns out you can fix the hyperspace and the reticle in one single place: GetCraftViewMatrix() This function is used by RenderExternalHUD() and RenderHyperspaceEffect() to get the g_ShadertoyBuffer.viewMat.

I have removed the reticleMatas it is not necessary anymore. The headtracking offset is applied to the viewMatdirectly.

morallo commented 2 years ago

I added some hooking points in CockpitLook to fix the External camera. However, the transformation is not ideal. Instead of rotating with your head as a pivot point, the camera "orbits" around the ship so that you always have it in your view. This is bearable but not playable. I will need to patch part of the code that calculates the camera orientation to prevent that behavior. Also, the reticle is shifted upwards (like in cockpit view), while the lasers actually aim to the center of the view.

I also fixed the "no cockpit" mode. Now it's possible to play in VR without a cockpit displayed (when you press ".").

The map still needs to be fixed, same as the shadows.

morallo commented 2 years ago

Hangar external camera works by hooking the call to UpdateCameraTransform (0x459AC2) in DrawHangarView (0x4598E0).

However, there seems to be some distortion when rotating the head. Maybe the HMD FOV is not correctly applied? Also, there is no positional tracking as the CockpitPositionTransformHook() is not called.

morallo commented 2 years ago

I "kind of" fixed the map. It now displays something in the HMD in SteamVR (before, WaitGetPoses() was never called). However, the tracking and the rendering of the objects on screen are not correct.

I modified TrackIR mode to use the new hook without MousePositionX,Y. FreePIE should work too but I didn't test it. However, it has the same problem as SteamVR with the positioning of elements that used to depend on MousePosition (reticle, hyperspace, speedeffect...).

We need to apply the headtracking transformation to those elements in ddraw. Unfortunately, we don't currently have this matrix in ddraw, and it's not as easy to get as in SteamVR (GetLastPoses()). I think it should be included in the SharedData for any type of tracking, and then used in an agnostic way in ddraw, regardless of the tracking input.

Also, probably the matrix should include the inertia so that the aiming reticle is accurate when the ship is turning. However, considering the laser "trailing", this may be hardly noticeable.