mirror of
https://github.com/astromaddie/HaloCE-VR.git
synced 2026-10-17 18:00:12 +02:00
Fix strafing on foot, the invisible laser, script text and glassy windshields (headset-unverified)
From the 2026-10-05 wear (round 2): - The drive throttle zeroed the stick's sideways on foot too (whenever vr.vehicle_steering was "drive"): now only for a driver. - The pointer's beam pose wasn't a unit quaternion (look_rotation from an unnormalised direction), so SteamVR refused every frame that drew it (XR_ERROR_POSE_INVALID, 564 frames in the wear): look_rotation now normalises, and the host normalises every layer pose. The beam ends 2 cm short of the panel (a quad through another hides in it). - Level scripts' print (green over cutscenes as a map loads) goes to debug.txt only in the headset, unless game.console_log is "all". - Glass reflects vr.glass_reflection (0.3) of the game's own in the headset: the Warthog's windshield was too bright to see through.
This commit is contained in:
1 parent
6853839b85
commit
5a88349558
8 files changed
+118
-3
No files matched your search
@@ -478,3 +478,22 @@ the Frame's display at 72 Hz, which Halo held before.
|
||||
| 10 | The image isn't sharp | Eye images at the render size, anisotropic filtering, and `vr.resolution_scale` 1.25 by default (2160 square, about the panels; settings version 3 moves an untouched 1.5 to it), which should also give open levels the frame time for 90 Hz. **Not yet worn** |
|
||||
| Wish | An immersive main menu around the ring | Not started. The menu scene has no player window, so it needs its own stereo path; the world-locked menu panel above is the piece it was missing |
|
||||
|
||||
## Wear feedback, 2026-10-05 (round 2, on 69b76356)
|
||||
|
||||
"Definitely better than before." The play log
|
||||
(`lepton-steamlaunch-3667167125.log`) shows `xrEndFrame failed: XR_ERROR_POSE_INVALID` on
|
||||
564 frames.
|
||||
|
||||
| # | Report | Status |
|
||||
| --- | --- | --- |
|
||||
| 1 | Can't strafe on foot (VR controls and room-scale off didn't help) | A regression from the driving work: the drive throttle zeroed the stick's sideways whenever `vr.vehicle_steering` was "drive", on foot too. Now only for a driver. **Not yet worn** |
|
||||
| 2 | The Warthog's windshield too reflective to see through | Glass reflects `vr.glass_reflection` (0.3) of the game's own in the headset (`rasterizer_xbox_transparent_geometry.c`, all glass shaders). **Not yet worn** |
|
||||
| 3 | No laser on the main or pause menu | The beam's pose wasn't a unit quaternion (`look_rotation` from an unnormalised direction), so SteamVR refused every frame that drew it. `look_rotation` normalises, and the host normalises every layer pose. The beam ends 2 cm short of the panel and the dot lies 1 cm off it (a quad through another hides in it). **Not yet worn** |
|
||||
| 4 | Green debug text over cutscenes as a map loads | The level scripts' `print` (the beta's debugging, `hs_print`): in the headset it goes to debug.txt only, unless `game.console_log` is "all". **Not yet worn** |
|
||||
| 5 | Silent Cartographer's opening cutscenes drop frames | Not yet measured |
|
||||
| 6 | Wish: anti-aliasing | Not started (MSAA on the eye targets would cost frame time that 90 Hz doesn't have yet) |
|
||||
|
||||
**120 Hz standard** (cross-port, 2026-10-05: 120 Hz at about 2160² an eye, falling back to 90
|
||||
then 72). Halo hasn't been measured against it. Silent Cartographer ran at about 46 fps on
|
||||
90 Hz at 1.5× before the 1.25× default.
|
||||
|
||||
@@ -214,6 +214,25 @@ static void local_pose(const struct halo_xr_pose *pose, XrPosef *out)
|
||||
|
||||
rotate_y(xr.recentre_yaw, pose->position, position);
|
||||
quaternion_multiply(yaw, pose->orientation, orientation);
|
||||
/* a unit quaternion whatever the guest sent: one that is not makes
|
||||
xrEndFrame refuse the whole frame (XR_ERROR_POSE_INVALID) */
|
||||
{
|
||||
float length = sqrtf(orientation[0] * orientation[0] + orientation[1] * orientation[1] +
|
||||
orientation[2] * orientation[2] + orientation[3] * orientation[3]);
|
||||
|
||||
if (length > 1e-6f)
|
||||
{
|
||||
orientation[0] /= length;
|
||||
orientation[1] /= length;
|
||||
orientation[2] /= length;
|
||||
orientation[3] /= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
orientation[0] = orientation[1] = orientation[2] = 0.0f;
|
||||
orientation[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
out->position.x = position[0] + xr.recentre_position[0];
|
||||
out->position.y = position[1] + xr.recentre_position[1];
|
||||
out->position.z = position[2] + xr.recentre_position[2];
|
||||
|
||||
@@ -153,7 +153,8 @@ enum
|
||||
_vr_vehicle_turret,
|
||||
};
|
||||
|
||||
/* how a driver is steered this frame (vr.vehicle_steering and the vehicle):
|
||||
/* how a driver is steered this frame (vr.vehicle_steering and the vehicle;
|
||||
the setting itself for anyone but a driver, so callers check the seat):
|
||||
drive and wheel apply to the Warthog and the Ghost; a flier (the Banshee)
|
||||
flies where the hand points; the Scorpion keeps the game's own driving, its
|
||||
cannon aimed by the head */
|
||||
@@ -219,8 +220,12 @@ void vr_render_drive_throttle(
|
||||
float steer, pedals;
|
||||
int wheel;
|
||||
|
||||
if (local_player_index != local_player_get_next(NONE) || !vr_active() || cinematic_in_progress())
|
||||
/* (only a driver: on foot the stick's sideways is the player's strafe) */
|
||||
if (local_player_index != local_player_get_next(NONE) || !vr_active() || cinematic_in_progress() ||
|
||||
!vr_render.seat.seated || !vr_render.seat.driver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
steering = vr_driver_steering();
|
||||
if (steering != _vr_steering_drive && steering != _vr_steering_wheel)
|
||||
return;
|
||||
@@ -868,6 +873,22 @@ void vr_render_room_scale(
|
||||
*position = clipped;
|
||||
}
|
||||
|
||||
real vr_render_glass_reflection_scale(
|
||||
void)
|
||||
{
|
||||
static real scale = -1.0f;
|
||||
static int generation = -1;
|
||||
|
||||
if (!vr_active())
|
||||
return 1.0f;
|
||||
if (scale < 0.0f || generation != vr_settings_generation())
|
||||
{
|
||||
scale = (real)config_real("vr.glass_reflection");
|
||||
generation = vr_settings_generation();
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
int vr_render_motion_sensor_yaw(
|
||||
short local_player_index,
|
||||
real *yaw)
|
||||
|
||||
@@ -120,6 +120,9 @@ void vr_render_room_scale(long biped_index, union real_point3d *position, real h
|
||||
"drive" or "wheel" (no strafing; with the hands on the wheel, the triggers) */
|
||||
union real_vector2d;
|
||||
void vr_render_drive_throttle(short local_player_index, union real_vector2d *throttle);
|
||||
/* glass's reflection in the headset, a scale (vr.glass_reflection; 1 off
|
||||
the headset) */
|
||||
real vr_render_glass_reflection_scale(void);
|
||||
/* motion_sensor_update: the yaw (radians) the first local player's motion
|
||||
sensor turns with, the head's, not the hand's aim; 0 to leave the
|
||||
facing's */
|
||||
|
||||
@@ -272,6 +272,9 @@ static const struct config_setting config_settings[] =
|
||||
"older file up to date (1: vr.hud_distance and vr.hud_width default to 0,\n"
|
||||
"the HUD mode's own; 2: vr.turn_mode and vr.snap_angle replace\n"
|
||||
"vr.snap_turn). Leave it be." },
|
||||
{ "vr.glass_reflection", _config_real, "0.3", "HALO_VR_GLASS_REFLECTION", _environment_value, _platform_vr,
|
||||
"How much glass reflects in the headset, 0 to 1 of the game's own: the\n"
|
||||
"Warthog's windshield at the game's own is too bright to see through." },
|
||||
{ "vr.texture_anisotropy", _config_integer, "8", "HALO_VR_TEXTURE_ANISOTROPY", _environment_value, _platform_vr,
|
||||
"Anisotropic filtering for the game's textures in the headset, 1 (off)\n"
|
||||
"to 16: keeps floors and walls sharp seen at a slant." },
|
||||
@@ -915,6 +918,7 @@ static const struct config_range
|
||||
{
|
||||
{ "vr.resolution_scale", 0.75, 1.5, 0 }, /* sfvr */
|
||||
{ "vr.texture_anisotropy", 1.0, 16.0, 0 },
|
||||
{ "vr.glass_reflection", 0.0, 1.0, 0 },
|
||||
{ "vr.screen_distance", 0.8, 5.0, 0 },
|
||||
{ "vr.screen_width", 0.5, 6.0, 0 },
|
||||
{ "vr.world_scale", 0.1, 1.0, 0 },
|
||||
|
||||
@@ -1591,6 +1591,18 @@ static void look_rotation(const float forward[3], const float up[3], float out[4
|
||||
{
|
||||
float z[3] = { -forward[0], -forward[1], -forward[2] }, x[3], y[3], length, trace;
|
||||
|
||||
/* (any length of `forward`: a basis from an unnormalised one makes a
|
||||
quaternion that is not a unit, and the runtime refuses the whole frame
|
||||
for one such layer pose with XR_ERROR_POSE_INVALID) */
|
||||
length = sqrtf(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
|
||||
if (length < 1e-6f)
|
||||
{
|
||||
out[0] = out[1] = out[2] = 0.0f;
|
||||
out[3] = 1.0f;
|
||||
return;
|
||||
}
|
||||
z[0] /= length; z[1] /= length; z[2] /= length;
|
||||
|
||||
x[0] = up[1] * z[2] - up[2] * z[1];
|
||||
x[1] = up[2] * z[0] - up[0] * z[2];
|
||||
x[2] = up[0] * z[1] - up[1] * z[0];
|
||||
@@ -2542,8 +2554,10 @@ static void place_pointer(struct halo_xr_layers *layers)
|
||||
layers->flags |= HALO_XR_LAYER_POINTER;
|
||||
if (!(vr.frame.hand_valid[vr.weapon_hand] & 2))
|
||||
return;
|
||||
/* (the beam ends 2 cm short of the panel, the dot 1 cm off it: a quad
|
||||
through another is depth-composited by SteamVR, and hides in it) */
|
||||
for (axis = 0; axis < 3; axis++)
|
||||
along[axis] = layers->pointer_pose.position[axis] - aim->position[axis];
|
||||
along[axis] = vr.pointer_hit[axis] + out[axis] * 0.02f - aim->position[axis];
|
||||
length = sqrtf(along[0] * along[0] + along[1] * along[1] + along[2] * along[2]);
|
||||
if (length < 0.05f)
|
||||
return;
|
||||
|
||||
@@ -170,6 +170,16 @@ void hs_print(
|
||||
* text, from a scenario script or typed at this build's console, reads arguments
|
||||
* that were never passed. A corrected build should print it through "%s".
|
||||
* Source-policy approval pending (2026-09-27 audit). */
|
||||
#ifdef HALO_VR
|
||||
/* port: in the headset a level script's prints (the beta's debugging,
|
||||
green over cutscenes as a level loads) go to debug.txt only, unless
|
||||
game.console_log is "all" */
|
||||
if (!terminal_shows(_terminal_message_chatter))
|
||||
{
|
||||
error(_error_log, "%s", message);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
terminal_printf(global_real_argb_green, message);
|
||||
|
||||
return;
|
||||
|
||||
@@ -166,6 +166,9 @@ symbols in this file:
|
||||
#include "rasterizer/xbox/rasterizer_xbox_plasma_energy.h"
|
||||
#include "rasterizer/xbox/rasterizer_xbox_water.h"
|
||||
#include "rasterizer/xbox/shader_transparent_chicago_preprocessor.h"
|
||||
#ifdef HALO_VR
|
||||
#include "halo_vr.h"
|
||||
#endif
|
||||
|
||||
/* ---------- constants */
|
||||
|
||||
@@ -3020,10 +3023,32 @@ void rasterizer_transparent_geometry_group_draw(
|
||||
}
|
||||
pixel_shader.rgb_inputs[2] = 0x0C0C0D0D;
|
||||
pixel_shader.rgb_outputs[2] = 0xD;
|
||||
#ifdef HALO_VR
|
||||
/* port: in the headset glass reflects less
|
||||
(vr.glass_reflection): the Warthog's windshield
|
||||
was too bright to see through */
|
||||
{
|
||||
real scale = vr_render_glass_reflection_scale();
|
||||
real_argb_color perpendicular = glass->reflection_view_perpendicular_color;
|
||||
real_argb_color parallel = glass->reflection_view_parallel_color;
|
||||
|
||||
perpendicular.alpha *= scale;
|
||||
perpendicular.red *= scale;
|
||||
perpendicular.green *= scale;
|
||||
perpendicular.blue *= scale;
|
||||
parallel.alpha *= scale;
|
||||
parallel.red *= scale;
|
||||
parallel.green *= scale;
|
||||
parallel.blue *= scale;
|
||||
pixel_shader.constant_0[3] = real_argb_color_to_pixel32(&perpendicular);
|
||||
pixel_shader.constant_1[3] = real_argb_color_to_pixel32(¶llel);
|
||||
}
|
||||
#else
|
||||
pixel_shader.constant_0[3] = real_argb_color_to_pixel32(
|
||||
&glass->reflection_view_perpendicular_color);
|
||||
pixel_shader.constant_1[3] = real_argb_color_to_pixel32(
|
||||
&glass->reflection_view_parallel_color);
|
||||
#endif
|
||||
pixel_shader.alpha_outputs[3] = 0xC00;
|
||||
pixel_shader.rgb_outputs[3] = 0xC00;
|
||||
pixel_shader.rgb_outputs[4] = 0xC00;
|
||||
|
||||
Reference in new issue
Block a user