Add support for display-size in the effect
This commit is contained in:
parent
e826292d3e
commit
9e15a500b8
|
|
@ -35,6 +35,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this._data_stream_bindings = [];
|
||||
this._show_banner_connection = null;
|
||||
this._distance_connection = null;
|
||||
this._display_size_connection = null;
|
||||
this._focused_monitor_distance_connection = null;
|
||||
this._follow_threshold_connection = null;
|
||||
this._breezy_desktop_running_connection = null;
|
||||
|
|
@ -241,6 +242,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
viewport_offset_x: this.settings.get_double('viewport-offset-x'),
|
||||
viewport_offset_y: this.settings.get_double('viewport-offset-y'),
|
||||
display_distance: this.settings.get_double('display-distance'),
|
||||
display_size: this.settings.get_double('display-size'),
|
||||
toggle_display_distance_start: this.settings.get_double('toggle-display-distance-start'),
|
||||
toggle_display_distance_end: this.settings.get_double('toggle-display-distance-end'),
|
||||
framerate_cap: this.settings.get_double('framerate-cap'),
|
||||
|
|
@ -299,6 +301,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
);
|
||||
|
||||
this._distance_connection = this.settings.connect('changed::display-distance', this._update_display_distance.bind(this));
|
||||
this._display_size_connection = this.settings.connect('changed::display-size', this._update_display_distance.bind(this));
|
||||
this._focused_monitor_distance_connection =
|
||||
this._virtual_displays_actor.connect('notify::focused-monitor-details', this._update_display_distance.bind(this));
|
||||
this._follow_threshold_connection = this.settings.connect('changed::follow-threshold', this._update_follow_threshold.bind(this));
|
||||
|
|
@ -398,17 +401,18 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
}
|
||||
|
||||
_update_display_distance(object, event) {
|
||||
const value = this.settings.get_double('display-distance');
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _update_display_distance ${value}`);
|
||||
if (value !== undefined) {
|
||||
const distance = this.settings.get_double('display-distance');
|
||||
const size = this.settings.get_double('display-size');
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _update_display_distance ${distance} ${size}`);
|
||||
if (distance !== undefined && size !== undefined) {
|
||||
let focusedMonitorSizeAdjustment = 1.0;
|
||||
if (this._virtual_displays_actor?.focused_monitor_details && this._target_monitor) {
|
||||
const fovMonitor = this._target_monitor.monitor;
|
||||
const focusedMonitor = this._virtual_displays_actor.focused_monitor_details;
|
||||
focusedMonitorSizeAdjustment =
|
||||
Math.max(focusedMonitor.width / fovMonitor.width, focusedMonitor.height / fovMonitor.height);
|
||||
Math.max(size * focusedMonitor.width / fovMonitor.width, size * focusedMonitor.height / fovMonitor.height);
|
||||
}
|
||||
this._write_control('breezy_desktop_display_distance', value / focusedMonitorSizeAdjustment);
|
||||
this._write_control('breezy_desktop_display_distance', distance / focusedMonitorSizeAdjustment);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -586,6 +590,10 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this.settings.disconnect(this._distance_connection);
|
||||
this._distance_connection = null;
|
||||
}
|
||||
if (this._display_size_connection) {
|
||||
this.settings.disconnect(this._display_size_connection);
|
||||
this._display_size_connection = null;
|
||||
}
|
||||
if (this._focused_monitor_distance_connection) {
|
||||
this._virtual_displays_actor.disconnect(this._focused_monitor_distance_connection);
|
||||
this._focused_monitor_distance_connection = null;
|
||||
|
|
|
|||
|
|
@ -176,12 +176,21 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
|||
GObject.ParamFlags.READWRITE,
|
||||
true
|
||||
),
|
||||
'display-size': GObject.ParamSpec.double(
|
||||
'display-size',
|
||||
'Display size',
|
||||
'Size of the display',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.1,
|
||||
2.5,
|
||||
1.0
|
||||
),
|
||||
'display-distance': GObject.ParamSpec.double(
|
||||
'display-distance',
|
||||
'Display Distance',
|
||||
'Distance of the display from the camera',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.0,
|
||||
0.1,
|
||||
2.5,
|
||||
1.0
|
||||
),
|
||||
|
|
@ -190,7 +199,7 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
|||
'Display distance default',
|
||||
'Distance to use when not explicitly set, or when reset',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.2,
|
||||
0.1,
|
||||
2.5,
|
||||
1.0
|
||||
),
|
||||
|
|
@ -253,6 +262,7 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
|||
this._use_smooth_follow_origin = false;
|
||||
|
||||
this.connect('notify::display-distance', this._update_display_distance.bind(this));
|
||||
this.connect('notify::display-size', this._update_display_position.bind(this));
|
||||
this.connect('notify::focused-monitor-index', this._update_display_distance.bind(this));
|
||||
this.connect('notify::monitor-placements', this._update_display_position.bind(this));
|
||||
this.connect('notify::show-banner', this._handle_banner_update.bind(this));
|
||||
|
|
@ -389,7 +399,11 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
|||
finalPositionVector = noRotationVector.map(coord => coord * inverse_follow_ease);
|
||||
finalPositionVector[0] = noRotationVector[0];
|
||||
}
|
||||
this._vertices = createVertexMesh(this.fov_details, this.monitor_details, finalPositionVector);
|
||||
const resizedMonitorDetails = {
|
||||
width: this.monitor_details.width * this.display_size,
|
||||
height: this.monitor_details.height * this.display_size
|
||||
};
|
||||
this._vertices = createVertexMesh(this.fov_details, resizedMonitorDetails, finalPositionVector);
|
||||
|
||||
const rotation_radians = this.monitor_placements[this.monitor_index].rotationAngleRadians;
|
||||
if (this._initialized) {
|
||||
|
|
@ -574,6 +588,7 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
|||
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);
|
||||
console.log(`Breezy - Setting pose position: ${posePositionPixels}`);
|
||||
} else {
|
||||
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]);
|
||||
|
|
|
|||
|
|
@ -19,11 +19,8 @@ const FOCUS_THRESHOLD = 0.95 / 2.0;
|
|||
// if we leave the monitor with some margin, unfocus even if no other monitor is in focus
|
||||
const UNFOCUS_THRESHOLD = 1.1 / 2.0;
|
||||
|
||||
// returns how far the look vector is from the center of the monitor, as a percentage of the monitor's width
|
||||
// returns how far the look vector is from the center of the monitor, as a percentage of the monitor's dimensions
|
||||
function getMonitorDistance(fovDetails, lookUpPixels, lookWestPixels, monitorVector, monitorDetails, upAngleToLength, westAngleToLength) {
|
||||
const monitorAspectRatio = monitorDetails.width / monitorDetails.height;
|
||||
|
||||
// weight the up distance by the aspect ratio
|
||||
const vectorUpPixels = upAngleToLength(
|
||||
fovDetails.defaultDistanceVerticalRadians,
|
||||
fovDetails.heightPixels,
|
||||
|
|
@ -31,7 +28,7 @@ function getMonitorDistance(fovDetails, lookUpPixels, lookWestPixels, monitorVec
|
|||
monitorVector[2],
|
||||
monitorVector[0]
|
||||
);
|
||||
const upDeltaPixels = (lookUpPixels - vectorUpPixels) * monitorAspectRatio;
|
||||
const upPercentage = Math.abs(lookUpPixels - vectorUpPixels) / monitorDetails.height;
|
||||
|
||||
const vectorWestPixels = westAngleToLength(
|
||||
fovDetails.defaultDistanceHorizontalRadians,
|
||||
|
|
@ -40,11 +37,10 @@ function getMonitorDistance(fovDetails, lookUpPixels, lookWestPixels, monitorVec
|
|||
monitorVector[1],
|
||||
monitorVector[0]
|
||||
);
|
||||
const westDeltaPixels = lookWestPixels - vectorWestPixels;
|
||||
const totalDeltaPixels = Math.sqrt(upDeltaPixels * upDeltaPixels + westDeltaPixels * westDeltaPixels);
|
||||
const westPercentage = Math.abs(lookWestPixels - vectorWestPixels) / monitorDetails.width;
|
||||
|
||||
// threshold is a percentage of width, and height was already properly weighted
|
||||
return totalDeltaPixels / monitorDetails.width;
|
||||
// how close we are to any edge is the largest of the two percentages
|
||||
return Math.max(upPercentage, westPercentage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -60,6 +56,8 @@ function getMonitorDistance(fovDetails, lookUpPixels, lookWestPixels, monitorVec
|
|||
* @returns {number} Index of the closest vector, if it surpasses the previous closest index by a certain margin, otherwise the previous index
|
||||
*/
|
||||
function findFocusedMonitor(quaternion, monitorVectors, currentFocusedIndex, focusedMonitorDistance, smoothFollowEnabled, fovDetails, monitorsDetails) {
|
||||
if (currentFocusedIndex !== -1 && smoothFollowEnabled) return currentFocusedIndex;
|
||||
|
||||
const lookVector = [1.0, 0.0, 0.0]; // NWU vector pointing to the center of the screen
|
||||
const rotatedLookVector = applyQuaternionToVector(lookVector, quaternion);
|
||||
|
||||
|
|
@ -82,9 +80,6 @@ function findFocusedMonitor(quaternion, monitorVectors, currentFocusedIndex, foc
|
|||
rotatedLookVector[0]
|
||||
);
|
||||
|
||||
let closestIndex = -1;
|
||||
let closestDistance = Infinity;
|
||||
|
||||
// the currently focused monitor is the most likely to be the closest, check it first and exit early if it is
|
||||
if (currentFocusedIndex !== -1) {
|
||||
const focusedDistance = getMonitorDistance(
|
||||
|
|
@ -97,9 +92,12 @@ function findFocusedMonitor(quaternion, monitorVectors, currentFocusedIndex, foc
|
|||
westConversionFns.angleToLength
|
||||
) * focusedMonitorDistance;
|
||||
|
||||
if (smoothFollowEnabled || focusedDistance < UNFOCUS_THRESHOLD) return currentFocusedIndex;
|
||||
if (focusedDistance < UNFOCUS_THRESHOLD) return currentFocusedIndex;
|
||||
}
|
||||
|
||||
let closestIndex = -1;
|
||||
let closestDistance = Infinity;
|
||||
|
||||
// find the vector closest to the rotated look vector
|
||||
monitorVectors.forEach((monitorVector, index) => {
|
||||
if (index === currentFocusedIndex) return;
|
||||
|
|
@ -499,7 +497,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
'Display size',
|
||||
'Size of the display',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.2,
|
||||
0.1,
|
||||
2.5,
|
||||
1.0
|
||||
),
|
||||
|
|
@ -515,7 +513,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
'Display Distance',
|
||||
'Distance of the display from the camera',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.2,
|
||||
0.1,
|
||||
2.5,
|
||||
1.05
|
||||
),
|
||||
|
|
@ -537,7 +535,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
'Display distance start',
|
||||
'Start distance when using the "change distance" shortcut.',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.2,
|
||||
0.1,
|
||||
2.5,
|
||||
1.05
|
||||
),
|
||||
|
|
@ -546,7 +544,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
'Display distance end',
|
||||
'End distance when using the "change distance" shortcut.',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.2,
|
||||
0.1,
|
||||
2.5,
|
||||
1.05
|
||||
),
|
||||
|
|
@ -578,7 +576,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
constructor(params = {}) {
|
||||
super(params);
|
||||
|
||||
this._all_monitors = [
|
||||
this._all_monitors_unmodified = [
|
||||
this.target_monitor,
|
||||
...this.virtual_monitors
|
||||
];
|
||||
|
|
@ -653,6 +651,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
notifyToFunction('toggle-display-distance-start', this._handle_display_distance_properties_change);
|
||||
notifyToFunction('toggle-display-distance-end', this._handle_display_distance_properties_change);
|
||||
notifyToFunction('display-distance', this._handle_display_distance_properties_change);
|
||||
notifyToFunction('display-size', this._handle_display_size_change);
|
||||
notifyToFunction('monitor-wrapping-scheme', this._update_monitor_placements);
|
||||
notifyToFunction('monitor-spacing', this._update_monitor_placements);
|
||||
notifyToFunction('headset-display-as-viewport-center', this._update_monitor_placements);
|
||||
|
|
@ -663,6 +662,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
notifyToFunction('custom-banner-enabled', this._handle_banner_update);
|
||||
notifyToFunction('framerate-cap', this._handle_frame_rate_cap_change);
|
||||
notifyToFunction('smooth-follow-enabled', this._handle_smooth_follow_enabled_change);
|
||||
this._handle_display_size_change(false);
|
||||
this._handle_display_distance_properties_change();
|
||||
this._handle_frame_rate_cap_change();
|
||||
|
||||
|
|
@ -680,8 +680,8 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
];
|
||||
|
||||
Globals.logger.log_debug(`\t\t\tActor to display ratios: ${actorToDisplayRatios}, offsets: ${actorToDisplayOffsets}`);
|
||||
|
||||
this._all_monitors.forEach(((monitor, index) => {
|
||||
|
||||
this._all_monitors_unmodified.forEach(((monitor, index) => {
|
||||
Globals.logger.log_debug(`\t\t\tMonitor ${index}: ${monitor.x}, ${monitor.y}, ${monitor.width}, ${monitor.height}`);
|
||||
|
||||
const containerActor = new Clutter.Actor({
|
||||
|
|
@ -711,6 +711,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
monitor_placements: this.monitor_placements,
|
||||
fov_details: this.fov_details,
|
||||
target_monitor: this.target_monitor,
|
||||
display_size: this.display_size,
|
||||
display_distance: this.display_distance,
|
||||
display_distance_default: this._display_distance_default(),
|
||||
actor_to_display_ratios: actorToDisplayRatios,
|
||||
|
|
@ -735,6 +736,7 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
|
||||
[
|
||||
'monitor-placements',
|
||||
'display-size',
|
||||
'fov-details',
|
||||
'imu-snapshots',
|
||||
'smooth-follow-enabled',
|
||||
|
|
@ -827,6 +829,10 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
this._redraw_timeline.start();
|
||||
}
|
||||
|
||||
_size_adjusted_target_monitor() {
|
||||
return this._all_monitors[0];
|
||||
}
|
||||
|
||||
_display_distance_default() {
|
||||
return Math.max(this.display_distance, this.toggle_display_distance_start, this.toggle_display_distance_end);
|
||||
}
|
||||
|
|
@ -869,7 +875,8 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
const minY = Math.min(...this._all_monitors.map(monitor => monitor.y));
|
||||
const maxY = Math.max(...this._all_monitors.map(monitor => monitor.y + monitor.height));
|
||||
|
||||
if ((maxX - minX) / this.target_monitor.width >= (maxY - minY) / this.target_monitor.height) {
|
||||
const targetMonitor = this._size_adjusted_target_monitor();
|
||||
if ((maxX - minX) / targetMonitor.width >= (maxY - minY) / targetMonitor.height) {
|
||||
return 'horizontal';
|
||||
} else {
|
||||
return 'vertical';
|
||||
|
|
@ -878,17 +885,19 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
|
||||
_update_monitor_placements() {
|
||||
try {
|
||||
const targetMonitor = this._size_adjusted_target_monitor();
|
||||
|
||||
const minX = Math.min(...this._all_monitors.map(monitor => monitor.x));
|
||||
const maxX = Math.max(...this._all_monitors.map(monitor => monitor.x + monitor.width));
|
||||
const minY = Math.min(...this._all_monitors.map(monitor => monitor.y));
|
||||
const maxY = Math.max(...this._all_monitors.map(monitor => monitor.y + monitor.height));
|
||||
|
||||
// the beginning edges of the viewport if it's centered on all displays
|
||||
const allDisplaysCenterXBegin = (minX + maxX) / 2 - this.target_monitor.width / 2;
|
||||
const allDisplaysCenterYBegin = (minY + maxY) / 2 - this.target_monitor.height / 2;
|
||||
const allDisplaysCenterXBegin = (minX + maxX) / 2 - targetMonitor.width / 2;
|
||||
const allDisplaysCenterYBegin = (minY + maxY) / 2 - targetMonitor.height / 2;
|
||||
|
||||
const viewportXBegin = this.headset_display_as_viewport_center ? this.target_monitor.x : allDisplaysCenterXBegin;
|
||||
const viewportYBegin = this.headset_display_as_viewport_center ? this.target_monitor.y : allDisplaysCenterYBegin;
|
||||
const viewportXBegin = this.headset_display_as_viewport_center ? targetMonitor.x : allDisplaysCenterXBegin;
|
||||
const viewportYBegin = this.headset_display_as_viewport_center ? targetMonitor.y : allDisplaysCenterYBegin;
|
||||
|
||||
this.fov_details = this._fov_details();
|
||||
this.lens_vector = [0.0, 0.0, -this.fov_details.lensDistancePixels];
|
||||
|
|
@ -897,8 +906,8 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
|
||||
// shift all monitors so they center around the viewport center, then adjusted by the offsets
|
||||
this._all_monitors.map(monitor => ({
|
||||
x: monitor.x - viewportXBegin - this.viewport_offset_x * this.target_monitor.width,
|
||||
y: monitor.y - viewportYBegin + this.viewport_offset_y * this.target_monitor.height,
|
||||
x: monitor.x - viewportXBegin - this.viewport_offset_x * targetMonitor.width,
|
||||
y: monitor.y - viewportYBegin + this.viewport_offset_y * targetMonitor.height,
|
||||
width: monitor.width,
|
||||
height: monitor.height
|
||||
})),
|
||||
|
|
@ -916,6 +925,16 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
|||
this._update_monitor_placements();
|
||||
}
|
||||
|
||||
_handle_display_size_change(update_placements = true) {
|
||||
this._all_monitors = this._all_monitors_unmodified.map(monitor => ({
|
||||
x: monitor.x * this.display_size,
|
||||
y: monitor.y * this.display_size,
|
||||
width: monitor.width * this.display_size,
|
||||
height: monitor.height * this.display_size
|
||||
}));
|
||||
if (update_placements) this._update_monitor_placements();
|
||||
}
|
||||
|
||||
_handle_banner_update() {
|
||||
if (this.bannerActor) {
|
||||
if (this.show_banner) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue