Update Breezy GNOME to support 6DoF position
This commit is contained in:
parent
c68ab16ef1
commit
e31778f6cc
|
|
@ -21,7 +21,7 @@ const IPC_FILE_PATH = "/dev/shm/breezy_desktop_imu";
|
||||||
const KEEPALIVE_REFRESH_INTERVAL_SEC = 1;
|
const KEEPALIVE_REFRESH_INTERVAL_SEC = 1;
|
||||||
|
|
||||||
// the driver should be using the same data layout version
|
// the driver should be using the same data layout version
|
||||||
const DATA_LAYOUT_VERSION = 4;
|
const DATA_LAYOUT_VERSION = 5;
|
||||||
|
|
||||||
// DataView info: [offset, size, count]
|
// DataView info: [offset, size, count]
|
||||||
const VERSION = [0, UINT8_SIZE, 1];
|
const VERSION = [0, UINT8_SIZE, 1];
|
||||||
|
|
@ -34,16 +34,17 @@ const SBS_ENABLED = [dataViewEnd(LENS_DISTANCE_RATIO), BOOL_SIZE, 1];
|
||||||
const CUSTOM_BANNER_ENABLED = [dataViewEnd(SBS_ENABLED), BOOL_SIZE, 1];
|
const CUSTOM_BANNER_ENABLED = [dataViewEnd(SBS_ENABLED), BOOL_SIZE, 1];
|
||||||
const SMOOTH_FOLLOW_ENABLED = [dataViewEnd(CUSTOM_BANNER_ENABLED), BOOL_SIZE, 1];
|
const SMOOTH_FOLLOW_ENABLED = [dataViewEnd(CUSTOM_BANNER_ENABLED), BOOL_SIZE, 1];
|
||||||
const SMOOTH_FOLLOW_ORIGIN_DATA = [dataViewEnd(SMOOTH_FOLLOW_ENABLED), FLOAT_SIZE, 16];
|
const SMOOTH_FOLLOW_ORIGIN_DATA = [dataViewEnd(SMOOTH_FOLLOW_ENABLED), FLOAT_SIZE, 16];
|
||||||
const EPOCH_MS = [dataViewEnd(SMOOTH_FOLLOW_ORIGIN_DATA), UINT_SIZE, 2];
|
const POSE_POSITION = [dataViewEnd(SMOOTH_FOLLOW_ORIGIN_DATA), FLOAT_SIZE, 3];
|
||||||
const IMU_QUAT_DATA = [dataViewEnd(EPOCH_MS), FLOAT_SIZE, 16];
|
const EPOCH_MS = [dataViewEnd(POSE_POSITION), UINT_SIZE, 2];
|
||||||
const IMU_PARITY_BYTE = [dataViewEnd(IMU_QUAT_DATA), UINT8_SIZE, 1];
|
const POSE_ORIENTATION = [dataViewEnd(EPOCH_MS), FLOAT_SIZE, 16];
|
||||||
|
const IMU_PARITY_BYTE = [dataViewEnd(POSE_ORIENTATION), UINT8_SIZE, 1];
|
||||||
const DATA_VIEW_LENGTH = dataViewEnd(IMU_PARITY_BYTE);
|
const DATA_VIEW_LENGTH = dataViewEnd(IMU_PARITY_BYTE);
|
||||||
|
|
||||||
function checkParityByte(dataView) {
|
function checkParityByte(dataView) {
|
||||||
const parityByte = dataViewUint8(dataView, IMU_PARITY_BYTE);
|
const parityByte = dataViewUint8(dataView, IMU_PARITY_BYTE);
|
||||||
let parity = 0;
|
let parity = 0;
|
||||||
const epochUint8 = dataViewUint8Array(dataView, EPOCH_MS);
|
const epochUint8 = dataViewUint8Array(dataView, EPOCH_MS);
|
||||||
const imuDataUint8 = dataViewUint8Array(dataView, IMU_QUAT_DATA);
|
const imuDataUint8 = dataViewUint8Array(dataView, POSE_ORIENTATION);
|
||||||
for (let i = 0; i < epochUint8.length; i++) {
|
for (let i = 0; i < epochUint8.length; i++) {
|
||||||
parity ^= epochUint8[i];
|
parity ^= epochUint8[i];
|
||||||
}
|
}
|
||||||
|
|
@ -210,10 +211,11 @@ export const DeviceDataStream = GObject.registerClass({
|
||||||
const validData = validKeepAlive && displayFov !== 0.0;
|
const validData = validKeepAlive && displayFov !== 0.0;
|
||||||
const version = dataViewUint8(dataView, VERSION);
|
const version = dataViewUint8(dataView, VERSION);
|
||||||
const enabled = dataViewUint8(dataView, ENABLED) !== 0 && version === DATA_LAYOUT_VERSION && validData;
|
const enabled = dataViewUint8(dataView, ENABLED) !== 0 && version === DATA_LAYOUT_VERSION && validData;
|
||||||
let imuData = dataViewFloatArray(dataView, IMU_QUAT_DATA);
|
let poseOrientation = dataViewFloatArray(dataView, POSE_ORIENTATION);
|
||||||
|
let posePosition = dataViewFloatArray(dataView, POSE_POSITION);
|
||||||
let smoothFollowEnabled = !this.legacy_follow_mode && dataViewUint8(dataView, SMOOTH_FOLLOW_ENABLED) !== 0;
|
let smoothFollowEnabled = !this.legacy_follow_mode && dataViewUint8(dataView, SMOOTH_FOLLOW_ENABLED) !== 0;
|
||||||
let smoothFollowOrigin = dataViewFloatArray(dataView, SMOOTH_FOLLOW_ORIGIN_DATA);
|
let smoothFollowOrigin = dataViewFloatArray(dataView, SMOOTH_FOLLOW_ORIGIN_DATA);
|
||||||
const imuResetState = enabled && validData && imuData[0] === 0.0 && imuData[1] === 0.0 && imuData[2] === 0.0 && imuData[3] === 1.0;
|
const imuResetState = enabled && validData && poseOrientation[0] === 0.0 && poseOrientation[1] === 0.0 && poseOrientation[2] === 0.0 && poseOrientation[3] === 1.0;
|
||||||
const customBannerEnabled = dataViewUint8(dataView, CUSTOM_BANNER_ENABLED) !== 0;
|
const customBannerEnabled = dataViewUint8(dataView, CUSTOM_BANNER_ENABLED) !== 0;
|
||||||
const sbsEnabled = dataViewUint8(dataView, SBS_ENABLED) !== 0;
|
const sbsEnabled = dataViewUint8(dataView, SBS_ENABLED) !== 0;
|
||||||
|
|
||||||
|
|
@ -261,7 +263,8 @@ export const DeviceDataStream = GObject.registerClass({
|
||||||
if (checkParityByte(dataView)) {
|
if (checkParityByte(dataView)) {
|
||||||
|
|
||||||
this.imu_snapshots = {
|
this.imu_snapshots = {
|
||||||
imu_data: imuData,
|
pose_orientation: poseOrientation,
|
||||||
|
pose_position: posePosition,
|
||||||
timestamp_ms: imuDateMs,
|
timestamp_ms: imuDateMs,
|
||||||
smooth_follow_origin: smoothFollowOrigin
|
smooth_follow_origin: smoothFollowOrigin
|
||||||
};
|
};
|
||||||
|
|
@ -277,7 +280,8 @@ export const DeviceDataStream = GObject.registerClass({
|
||||||
buffer = new Uint8Array(data[1]).buffer;
|
buffer = new Uint8Array(data[1]).buffer;
|
||||||
dataView = new DataView(buffer);
|
dataView = new DataView(buffer);
|
||||||
imuDateMs = dataViewBigUint(dataView, EPOCH_MS);
|
imuDateMs = dataViewBigUint(dataView, EPOCH_MS);
|
||||||
imuData = dataViewFloatArray(dataView, IMU_QUAT_DATA);
|
poseOrientation = dataViewFloatArray(dataView, POSE_ORIENTATION);
|
||||||
|
posePosition = dataViewFloatArray(dataView, POSE_POSITION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -311,15 +315,17 @@ export const DeviceDataStream = GObject.registerClass({
|
||||||
if (!keepalive_only) {
|
if (!keepalive_only) {
|
||||||
this._counter = ((this._counter ?? -1)+1)%COUNTER_MAX;
|
this._counter = ((this._counter ?? -1)+1)%COUNTER_MAX;
|
||||||
|
|
||||||
const imuDataFirst = nextDebugIMUQuaternion(this._counter);
|
const poseOrientationFirst = nextDebugIMUQuaternion(this._counter);
|
||||||
const imuData = [
|
const poseOrientation = [
|
||||||
...imuDataFirst,
|
...poseOrientationFirst,
|
||||||
...imuDataFirst,
|
...poseOrientationFirst,
|
||||||
...imuDataFirst,
|
...poseOrientationFirst,
|
||||||
2.0, 1.0, 0.0, 0.0
|
2.0, 1.0, 0.0, 0.0
|
||||||
]
|
]
|
||||||
|
const posePosition = [0.0, 0.0, 0.0];
|
||||||
this.imu_snapshots = {
|
this.imu_snapshots = {
|
||||||
imu_data: imuData,
|
pose_orientation: poseOrientation,
|
||||||
|
pose_position: posePosition,
|
||||||
timestamp_ms: Date.now(),
|
timestamp_ms: Date.now(),
|
||||||
smooth_follow_origin: [0.0, 0.0, 0.0, 1.0]
|
smooth_follow_origin: [0.0, 0.0, 0.0, 1.0]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -417,7 +417,8 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
||||||
vfunc_build_pipeline() {
|
vfunc_build_pipeline() {
|
||||||
const declarations = `
|
const declarations = `
|
||||||
uniform bool u_show_banner;
|
uniform bool u_show_banner;
|
||||||
uniform mat4 u_imu_data;
|
uniform mat4 u_pose_orientation;
|
||||||
|
uniform vec3 u_pose_position;
|
||||||
uniform float u_look_ahead_ms;
|
uniform float u_look_ahead_ms;
|
||||||
uniform vec4 u_look_ahead_cfg;
|
uniform vec4 u_look_ahead_cfg;
|
||||||
uniform mat4 u_projection_matrix;
|
uniform mat4 u_projection_matrix;
|
||||||
|
|
@ -461,6 +462,10 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
||||||
return vec4(-v.y, v.z, -v.x, v.w);
|
return vec4(-v.y, v.z, -v.x, v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 nwuToESU(vec3 v) {
|
||||||
|
return vec3(-v.y, v.z, -v.x);
|
||||||
|
}
|
||||||
|
|
||||||
// returns the rate of change between the two vectors, in same time units as delta_time
|
// returns the rate of change between the two vectors, in same time units as delta_time
|
||||||
// e.g. if delta_time is in ms, then the rate of change is "per ms"
|
// e.g. if delta_time is in ms, then the rate of change is "per ms"
|
||||||
vec3 rateOfChange(vec3 v1, vec3 v2, float delta_time) {
|
vec3 rateOfChange(vec3 v1, vec3 v2, float delta_time) {
|
||||||
|
|
@ -487,14 +492,23 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
||||||
if (!u_show_banner) {
|
if (!u_show_banner) {
|
||||||
float aspect_ratio = u_display_resolution.x / u_display_resolution.y;
|
float aspect_ratio = u_display_resolution.x / u_display_resolution.y;
|
||||||
|
|
||||||
|
vec4 quat_t0 = nwuToESU(quatConjugate(u_pose_orientation[0]));
|
||||||
|
vec3 position_vector = applyQuaternionToVector(nwuToESU(u_pose_position), quat_t0);
|
||||||
|
vec3 final_lens_position = u_lens_vector + position_vector;
|
||||||
|
|
||||||
vec3 complete_vector = applyXRotationToVector(world_pos.xyz, u_rotation_x_radians);
|
vec3 complete_vector = applyXRotationToVector(world_pos.xyz, u_rotation_x_radians);
|
||||||
complete_vector = applyYRotationToVector(complete_vector, u_rotation_y_radians);
|
complete_vector = applyYRotationToVector(complete_vector, u_rotation_y_radians);
|
||||||
|
|
||||||
vec4 quat_t0 = nwuToESU(quatConjugate(u_imu_data[0]));
|
|
||||||
vec3 rotated_vector_t0 = applyQuaternionToVector(complete_vector, quat_t0);
|
vec3 rotated_vector_t0 = applyQuaternionToVector(complete_vector, quat_t0);
|
||||||
vec3 rotated_vector_t1 = applyQuaternionToVector(complete_vector, nwuToESU(quatConjugate(u_imu_data[1])));
|
vec3 rotated_vector_t1 = applyQuaternionToVector(complete_vector, nwuToESU(quatConjugate(u_pose_orientation[1])));
|
||||||
float delta_time_t0 = u_imu_data[3][0] - u_imu_data[3][1];
|
float delta_time_t0 = u_pose_orientation[3][0] - u_pose_orientation[3][1];
|
||||||
vec3 velocity_t0 = rateOfChange(rotated_vector_t0, rotated_vector_t1, delta_time_t0);
|
|
||||||
|
// how quickly the vertex is moving relative to the camera
|
||||||
|
vec3 velocity_t0 = rateOfChange(
|
||||||
|
rotated_vector_t0 - final_lens_position,
|
||||||
|
rotated_vector_t1 - final_lens_position,
|
||||||
|
delta_time_t0
|
||||||
|
);
|
||||||
|
|
||||||
// compute the capped look ahead with scanline adjustments
|
// compute the capped look ahead with scanline adjustments
|
||||||
float look_ahead_scanline_ms = u_look_ahead_ms == 0.0 ? 0.0 : vectorToScanline(u_fov_vertical_radians, rotated_vector_t0) * u_look_ahead_cfg[2];
|
float look_ahead_scanline_ms = u_look_ahead_ms == 0.0 ? 0.0 : vectorToScanline(u_fov_vertical_radians, rotated_vector_t0) * u_look_ahead_cfg[2];
|
||||||
|
|
@ -502,7 +516,7 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
||||||
|
|
||||||
vec3 look_ahead_vector = applyLookAhead(rotated_vector_t0, velocity_t0, effective_look_ahead_ms);
|
vec3 look_ahead_vector = applyLookAhead(rotated_vector_t0, velocity_t0, effective_look_ahead_ms);
|
||||||
|
|
||||||
world_pos = vec4(look_ahead_vector - u_lens_vector, world_pos.w);
|
world_pos = vec4(look_ahead_vector - final_lens_position, world_pos.w);
|
||||||
|
|
||||||
world_pos.z /= aspect_ratio / u_actor_to_display_ratios.y;
|
world_pos.z /= aspect_ratio / u_actor_to_display_ratios.y;
|
||||||
|
|
||||||
|
|
@ -557,9 +571,12 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
||||||
this.set_uniform_float(this.get_uniform_location('u_look_ahead_ms'), 1, [0.0]);
|
this.set_uniform_float(this.get_uniform_location('u_look_ahead_ms'), 1, [0.0]);
|
||||||
lookAheadSet = true;
|
lookAheadSet = true;
|
||||||
}
|
}
|
||||||
this.set_uniform_matrix(this.get_uniform_location("u_imu_data"), false, 4, this.imu_snapshots.imu_data);
|
const posePositionPixels = this.imu_snapshots.pose_position.map(coord => coord * this.fov_details.completeScreenDistancePixels);
|
||||||
|
this.set_uniform_matrix(this.get_uniform_location("u_pose_orientation"), false, 4, this.imu_snapshots.pose_orientation);
|
||||||
|
this.set_uniform_float(this.get_uniform_location("u_pose_position"), 3, posePositionPixels);
|
||||||
} else {
|
} else {
|
||||||
this.set_uniform_matrix(this.get_uniform_location("u_imu_data"), false, 4, this.imu_snapshots.smooth_follow_origin);
|
this.set_uniform_matrix(this.get_uniform_location("u_pose_orientation"), false, 4, this.imu_snapshots.smooth_follow_origin);
|
||||||
|
this.set_uniform_float(this.get_uniform_location("u_pose_position"), 3, [0.0, 0.0, 0.0]);
|
||||||
}
|
}
|
||||||
if (!lookAheadSet) {
|
if (!lookAheadSet) {
|
||||||
this.set_uniform_float(this.get_uniform_location('u_look_ahead_ms'), 1, [lookAheadMS(this.imu_snapshots.timestamp_ms, Globals.data_stream.device_data.lookAheadCfg, this.look_ahead_override)]);
|
this.set_uniform_float(this.get_uniform_location('u_look_ahead_ms'), 1, [lookAheadMS(this.imu_snapshots.timestamp_ms, Globals.data_stream.device_data.lookAheadCfg, this.look_ahead_override)]);
|
||||||
|
|
|
||||||
|
|
@ -785,12 +785,12 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
||||||
(!this._smooth_follow_slerping || this.focused_monitor_index === -1)) {
|
(!this._smooth_follow_slerping || this.focused_monitor_index === -1)) {
|
||||||
// if smooth follow is enabled, use the origin IMU data to inform the initial focused monitor
|
// if smooth follow is enabled, use the origin IMU data to inform the initial focused monitor
|
||||||
// since it reflects where the user is looking in relation to the original monitor positions
|
// since it reflects where the user is looking in relation to the original monitor positions
|
||||||
const currentPoseQuat = this.smooth_follow_enabled ?
|
const currentOrientationQuat = this.smooth_follow_enabled ?
|
||||||
this.imu_snapshots.smooth_follow_origin.splice(0, 4) :
|
this.imu_snapshots.smooth_follow_origin.splice(0, 4) :
|
||||||
this.imu_snapshots.imu_data.splice(0, 4);
|
this.imu_snapshots.pose_orientation.splice(0, 4);
|
||||||
|
|
||||||
const focusedMonitorIndex = findFocusedMonitor(
|
const focusedMonitorIndex = findFocusedMonitor(
|
||||||
currentPoseQuat,
|
currentOrientationQuat,
|
||||||
this.monitor_placements.map(monitorVectors => monitorVectors.centerLook),
|
this.monitor_placements.map(monitorVectors => monitorVectors.centerLook),
|
||||||
this.focused_monitor_index,
|
this.focused_monitor_index,
|
||||||
this.display_distance / this._display_distance_default(),
|
this.display_distance / this._display_distance_default(),
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit f32a2951d6ce8d97b528281b6bab78c654020e01
|
Subproject commit d3b903eb33b09cc13a93ee51463c3b3fcb2840b6
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0eb04ff4429ce7a025f126843cd0d3b24bc0d73e
|
Subproject commit da173bd9e0392aaeb2cb68a332e5d4a20dd4dae1
|
||||||
Loading…
Reference in New Issue