WIP
This commit is contained in:
parent
ebc3910c9d
commit
80f54f5297
|
|
@ -529,7 +529,7 @@ export default class BreezyDesktopExtension extends Extension {
|
||||||
this._distance_connection = null;
|
this._distance_connection = null;
|
||||||
}
|
}
|
||||||
if (this._data_stream_connection) {
|
if (this._data_stream_connection) {
|
||||||
this._device_data_stream.unbind(this._data_stream_connection);
|
this._data_stream_connection.unbind();
|
||||||
this._data_stream_connection = null;
|
this._data_stream_connection = null;
|
||||||
}
|
}
|
||||||
if (this._follow_threshold_connection) {
|
if (this._follow_threshold_connection) {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ function findClosestVector(quaternion, vectors, previousClosestIndex) {
|
||||||
|
|
||||||
const lookVector = [1.0, 0.0, 0.0]; // NWU vector pointing to the center of the screen
|
const lookVector = [1.0, 0.0, 0.0]; // NWU vector pointing to the center of the screen
|
||||||
const rotatedLookVector = applyQuaternionToVector(lookVector, [quaternion.x, quaternion.y, quaternion.z, quaternion.w]);
|
const rotatedLookVector = applyQuaternionToVector(lookVector, [quaternion.x, quaternion.y, quaternion.z, quaternion.w]);
|
||||||
Globals.logger.log(`\t\t\tQuaternion: ${JSON.stringify(quaternion)}`);
|
|
||||||
Globals.logger.log(`\t\t\tRotated look vector: ${rotatedLookVector}`);
|
Globals.logger.log(`\t\t\tRotated look vector: ${rotatedLookVector}`);
|
||||||
|
|
||||||
let closestIndex = -1;
|
let closestIndex = -1;
|
||||||
|
|
@ -81,23 +80,28 @@ function monitorWrap(radiusPixels, previousMonitorEndRadians, monitorPixels) {
|
||||||
const monitorHalfRadians = Math.asin(monitorHalfPixels / radiusPixels);
|
const monitorHalfRadians = Math.asin(monitorHalfPixels / radiusPixels);
|
||||||
const centerRadians = previousMonitorEndRadians + monitorHalfRadians;
|
const centerRadians = previousMonitorEndRadians + monitorHalfRadians;
|
||||||
return {
|
return {
|
||||||
|
begin: previousMonitorEndRadians,
|
||||||
center: centerRadians,
|
center: centerRadians,
|
||||||
end: centerRadians + monitorHalfRadians
|
end: centerRadians + monitorHalfRadians
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the given monitor details into NWU vectors pointing to the center of each monitor.
|
* Convert the given monitor details into NWU vectors describing the center of the fully placed monitor,
|
||||||
|
* and the top-left of the partially placed monitor (minus only a single-axis rotation)
|
||||||
*
|
*
|
||||||
* @param {Object} fovDetails - contains reference fovDegrees (diagonal), widthPixels, heightPixels
|
* @param {Object} fovDetails - contains reference fovDegrees (diagonal), widthPixels, heightPixels
|
||||||
* @param {Object[]} monitorDetailsList - contains x, y, width, height (coordinates from top-left)
|
* @param {Object[]} monitorDetailsList - contains x, y, width, height (coordinates from top-left)
|
||||||
* @param {string} monitorWrappingScheme - horizontal, vertical, none
|
* @param {string} monitorWrappingScheme - horizontal, vertical, none
|
||||||
* @returns {number[]} - Vector [x, y, z]
|
* @returns {Object[]} - contains NWU vectors pointing to `topLeftNoRotate` and `center` of each monitor
|
||||||
*/
|
*/
|
||||||
function monitorsToVectors(fovDetails, monitorDetailsList, monitorWrappingScheme) {
|
function monitorsToVectors(fovDetails, monitorDetailsList, monitorWrappingScheme) {
|
||||||
const aspect = fovDetails.widthPixels / fovDetails.heightPixels;
|
const aspect = fovDetails.widthPixels / fovDetails.heightPixels;
|
||||||
const fovVerticalRadians = degreesToRadians(fovDetails.fovDegrees / Math.sqrt(1 + aspect * aspect));
|
const fovVerticalRadians = degreesToRadians(fovDetails.fovDegrees / Math.sqrt(1 + aspect * aspect));
|
||||||
|
|
||||||
|
// distance needed for the FOV-sized monitor to fill up the screen
|
||||||
|
const centerRadius = fovDetails.heightPixels / 2 / Math.sin(fovVerticalRadians / 2);
|
||||||
|
|
||||||
// NWU vectors pointing to the center of the screen for each monitor
|
// NWU vectors pointing to the center of the screen for each monitor
|
||||||
const monitorVectors = [];
|
const monitorVectors = [];
|
||||||
|
|
||||||
|
|
@ -105,55 +109,76 @@ function monitorsToVectors(fovDetails, monitorDetailsList, monitorWrappingScheme
|
||||||
// monitors wrap around us horizontally
|
// monitors wrap around us horizontally
|
||||||
const fovHorizontalRadians = fovVerticalRadians * aspect;
|
const fovHorizontalRadians = fovVerticalRadians * aspect;
|
||||||
|
|
||||||
// radius is the hypothenuse of the triangle where the opposite side is half the width of the reference fov screen
|
// distance to a horizontal edge is the hypothenuse of the triangle where the opposite side is half the width of the reference fov screen
|
||||||
const radius = fovDetails.widthPixels / 2 / Math.sin(fovHorizontalRadians / 2);
|
const edgeRadius = fovDetails.widthPixels / 2 / Math.sin(fovHorizontalRadians / 2);
|
||||||
|
|
||||||
let previousMonitorEndRadians = -fovHorizontalRadians / 2;
|
let previousMonitorEndRadians = -fovHorizontalRadians / 2;
|
||||||
monitorDetailsList.forEach(monitorDetails => {
|
monitorDetailsList.forEach(monitorDetails => {
|
||||||
const monitorWrapDetails = monitorWrap(radius, previousMonitorEndRadians, monitorDetails.width);
|
const monitorWrapDetails = monitorWrap(edgeRadius, previousMonitorEndRadians, monitorDetails.width);
|
||||||
previousMonitorEndRadians = monitorWrapDetails.end;
|
previousMonitorEndRadians = monitorWrapDetails.end;
|
||||||
|
|
||||||
monitorVectors.push([
|
monitorVectors.push({
|
||||||
// north is adjacent where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
topLeftNoRotate: [
|
||||||
radius * Math.cos(monitorWrapDetails.center),
|
centerRadius,
|
||||||
|
fovDetails.widthPixels / 2,
|
||||||
|
-(monitorDetails.y - fovDetails.heightPixels / 2)
|
||||||
|
],
|
||||||
|
center: [
|
||||||
|
// north is adjacent where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
||||||
|
centerRadius * Math.cos(monitorWrapDetails.center),
|
||||||
|
|
||||||
// west is opposite where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
// west is opposite where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
||||||
-radius * Math.sin(monitorWrapDetails.center),
|
-centerRadius * Math.sin(monitorWrapDetails.center),
|
||||||
|
|
||||||
// up is flat when wrapping horizontally
|
// up is flat when wrapping horizontally
|
||||||
-(monitorDetails.y + monitorDetails.height / 2 - fovDetails.heightPixels / 2)
|
-(monitorDetails.y + monitorDetails.height / 2 - fovDetails.heightPixels / 2)
|
||||||
]);
|
]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else if (monitorWrappingScheme === 'vertical') {
|
} else if (monitorWrappingScheme === 'vertical') {
|
||||||
// monitors wrap around us vertically
|
// monitors wrap around us vertically
|
||||||
|
|
||||||
// radius is the hypothenuse of the triangle where the opposite side is half the height of the reference fov screen
|
// distance to a vertical edge is the hypothenuse of the triangle where the opposite side is half the height of the reference fov screen
|
||||||
const radius = fovDetails.heightPixels / 2 / Math.sin(fovVerticalRadians / 2);
|
const edgeRadius = fovDetails.heightPixels / 2 / Math.sin(fovVerticalRadians / 2);
|
||||||
|
|
||||||
let previousMonitorEndRadians = -fovVerticalRadians / 2;
|
let previousMonitorEndRadians = -fovVerticalRadians / 2;
|
||||||
monitorDetailsList.forEach(monitorDetails => {
|
monitorDetailsList.forEach(monitorDetails => {
|
||||||
const monitorWrapDetails = monitorWrap(radius, previousMonitorEndRadians, monitorDetails.height);
|
const monitorWrapDetails = monitorWrap(edgeRadius, previousMonitorEndRadians, monitorDetails.height);
|
||||||
previousMonitorEndRadians = monitorWrapDetails.end;
|
previousMonitorEndRadians = monitorWrapDetails.end;
|
||||||
|
|
||||||
monitorVectors.push([
|
monitorVectors.push({
|
||||||
// north is adjacent where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
topLeftNoRotate: [
|
||||||
radius * Math.cos(monitorWrapDetails.center),
|
centerRadius,
|
||||||
|
-(monitorDetails.x - fovDetails.widthPixels / 2),
|
||||||
|
fovDetails.heightPixels / 2
|
||||||
|
],
|
||||||
|
center: [
|
||||||
|
// north is adjacent where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
||||||
|
centerRadius * Math.cos(monitorWrapDetails.center),
|
||||||
|
|
||||||
// west is flat when wrapping vertically
|
// west is flat when wrapping vertically
|
||||||
-(monitorDetails.x + monitorDetails.width / 2 - fovDetails.widthPixels / 2),
|
-(monitorDetails.x + monitorDetails.width / 2 - fovDetails.widthPixels / 2),
|
||||||
|
|
||||||
// up is opposite where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
// up is opposite where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
||||||
-radius * Math.sin(monitorWrapDetails.center)
|
-centerRadius * Math.sin(monitorWrapDetails.center)
|
||||||
]);
|
]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// monitors make a flat wall in front of us, no wrapping
|
// monitors make a flat wall in front of us, no wrapping
|
||||||
monitorDetailsList.forEach(monitorDetails => {
|
monitorDetailsList.forEach(monitorDetails => {
|
||||||
monitorVectors.push([
|
monitorVectors.push({
|
||||||
fovDetails.heightPixels / 2 / Math.sin(fovVerticalRadians / 2),
|
topLeftNoRotate: [
|
||||||
-(monitorDetails.x + monitorDetails.width / 2 - fovDetails.widthPixels / 2),
|
centerRadius,
|
||||||
-(monitorDetails.y + monitorDetails.height / 2 - fovDetails.heightPixels / 2)
|
-(monitorDetails.x - fovDetails.widthPixels / 2),
|
||||||
]);
|
-(monitorDetails.y - fovDetails.heightPixels / 2)
|
||||||
|
],
|
||||||
|
center: [
|
||||||
|
centerRadius,
|
||||||
|
-(monitorDetails.x + monitorDetails.width / 2 - fovDetails.widthPixels / 2),
|
||||||
|
-(monitorDetails.y + monitorDetails.height / 2 - fovDetails.heightPixels / 2)
|
||||||
|
]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,13 +189,13 @@ function monitorVectorToRotationAngle(vector, monitorWrappingScheme) {
|
||||||
if (monitorWrappingScheme === 'horizontal') {
|
if (monitorWrappingScheme === 'horizontal') {
|
||||||
// monitors wrap around us horizontally
|
// monitors wrap around us horizontally
|
||||||
return {
|
return {
|
||||||
angle: radiansToDegrees(Math.atan2(vector[1], vector[0])),
|
angle: Math.atan2(vector[1], vector[0]),
|
||||||
axis: Clutter.RotateAxis.Y_AXIS
|
axis: Clutter.RotateAxis.Y_AXIS
|
||||||
};
|
};
|
||||||
} else if (monitorWrappingScheme === 'vertical') {
|
} else if (monitorWrappingScheme === 'vertical') {
|
||||||
// monitors wrap around us vertically
|
// monitors wrap around us vertically
|
||||||
return {
|
return {
|
||||||
angle: radiansToDegrees(Math.atan2(vector[2], vector[0])),
|
angle: Math.atan2(vector[2], vector[0]),
|
||||||
axis: Clutter.RotateAxis.X_AXIS
|
axis: Clutter.RotateAxis.X_AXIS
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -222,6 +247,13 @@ export const TestActorEffect = GObject.registerClass({
|
||||||
GObject.ParamFlags.READWRITE,
|
GObject.ParamFlags.READWRITE,
|
||||||
'horizontal', ['horizontal', 'vertical', 'none']
|
'horizontal', ['horizontal', 'vertical', 'none']
|
||||||
),
|
),
|
||||||
|
'monitor-wrapping-rotation-radians': GObject.ParamSpec.double(
|
||||||
|
'monitor-wrapping-rotation-radians',
|
||||||
|
'Monitor Wrapping Rotation Radians',
|
||||||
|
'Rotation of the monitor wrapping around the viewport',
|
||||||
|
GObject.ParamFlags.READWRITE,
|
||||||
|
-360.0, 360.0, 0.0
|
||||||
|
),
|
||||||
'focused-monitor-index': GObject.ParamSpec.int(
|
'focused-monitor-index': GObject.ParamSpec.int(
|
||||||
'focused-monitor-index',
|
'focused-monitor-index',
|
||||||
'Focused Monitor Index',
|
'Focused Monitor Index',
|
||||||
|
|
@ -234,9 +266,9 @@ export const TestActorEffect = GObject.registerClass({
|
||||||
'Display Distance',
|
'Display Distance',
|
||||||
'Distance of the display from the camera',
|
'Distance of the display from the camera',
|
||||||
GObject.ParamFlags.READWRITE,
|
GObject.ParamFlags.READWRITE,
|
||||||
0.2,
|
0.0,
|
||||||
2.5,
|
10000.0,
|
||||||
1.0
|
2900.0
|
||||||
),
|
),
|
||||||
'toggle-display-distance-start': GObject.ParamSpec.double(
|
'toggle-display-distance-start': GObject.ParamSpec.double(
|
||||||
'toggle-display-distance-start',
|
'toggle-display-distance-start',
|
||||||
|
|
@ -256,6 +288,12 @@ export const TestActorEffect = GObject.registerClass({
|
||||||
2.5,
|
2.5,
|
||||||
1.05
|
1.05
|
||||||
),
|
),
|
||||||
|
'actor-to-display-ratios': GObject.ParamSpec.jsobject(
|
||||||
|
'actor-to-display-ratios',
|
||||||
|
'Actor to Display Ratios',
|
||||||
|
'Ratios to convert actor coordinates to display coordinates',
|
||||||
|
GObject.ParamFlags.READWRITE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}, class TestActorEffect extends Shell.GLSLEffect {
|
}, class TestActorEffect extends Shell.GLSLEffect {
|
||||||
perspective(fovDiagonalRadians, aspect, near, far) {
|
perspective(fovDiagonalRadians, aspect, near, far) {
|
||||||
|
|
@ -281,58 +319,66 @@ export const TestActorEffect = GObject.registerClass({
|
||||||
uniform vec4 u_quaternion;
|
uniform vec4 u_quaternion;
|
||||||
uniform mat4 u_projection_matrix;
|
uniform mat4 u_projection_matrix;
|
||||||
uniform float u_display_north_offset;
|
uniform float u_display_north_offset;
|
||||||
|
uniform float u_rotation_x_radians;
|
||||||
|
uniform float u_rotation_y_radians;
|
||||||
|
uniform float u_aspect_ratio;
|
||||||
|
|
||||||
|
// for some reason the vector positions are relative to the width and height of the uiGroup actor
|
||||||
|
uniform vec2 u_actor_to_display_ratios;
|
||||||
|
|
||||||
|
// constants that help me adjust CoGL vector positions so their components are at the ratios intended, for proper rotation
|
||||||
|
float cogl_position_width = 51.7; // no idea...
|
||||||
|
float cogl_z_factor = 2.5; // no idea...
|
||||||
|
|
||||||
vec4 applyQuaternionToVector(vec4 v, vec4 q) {
|
vec4 applyQuaternionToVector(vec4 v, vec4 q) {
|
||||||
vec3 t = 2.0 * cross(q.xyz, v.xyz);
|
vec3 t = 2.0 * cross(q.xyz, v.xyz);
|
||||||
vec3 rotated = v.xyz + q.w * t + cross(q.xyz, t);
|
vec3 rotated = v.xyz + q.w * t + cross(q.xyz, t);
|
||||||
return vec4(rotated, v.w);
|
return vec4(rotated, v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 applyXRotationToVector(vec4 v, float angle) {
|
||||||
|
float c = cos(angle);
|
||||||
|
float s = sin(angle);
|
||||||
|
return vec4(v.x, v.y * c - v.z * s, v.y * s + v.z * c, v.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 applyYRotationToVector(vec4 v, float angle) {
|
||||||
|
float c = cos(angle);
|
||||||
|
float s = sin(angle);
|
||||||
|
return vec4(v.x * c + v.z * s, v.y, v.z * c - v.x * s, v.w);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const main = `
|
const main = `
|
||||||
vec4 world_pos = cogl_position_in;
|
vec4 world_pos = cogl_position_in;
|
||||||
|
|
||||||
// // move pixel space to texcoord space
|
float cogl_position_height = cogl_position_width / u_aspect_ratio;
|
||||||
// world_pos.x = (world_pos.x / 192.0);
|
float position_width_adjustment_count = u_actor_to_display_ratios.x - 1.0;
|
||||||
// world_pos.y = (world_pos.y / 108.0);
|
float position_height_adjustment_count = u_actor_to_display_ratios.y - 1.0;
|
||||||
|
|
||||||
// float displayAspectRatio = 1920.0 / 1080.0;
|
world_pos.z /= cogl_z_factor;
|
||||||
// float diagToVertRatio = sqrt(pow(displayAspectRatio, 2) + 1);
|
|
||||||
// float halfFovZRads = radians(46.0 / diagToVertRatio) / 2.0;
|
|
||||||
// float halfFovYRads = halfFovZRads * displayAspectRatio;
|
|
||||||
// vec2 fovHalfWidths = vec2(tan(halfFovYRads), tan(halfFovZRads));
|
|
||||||
// vec2 fovWidths = fovHalfWidths * 2.0;
|
|
||||||
|
|
||||||
// float vec_y = -world_pos.x * fovWidths.x + fovHalfWidths.x;
|
// if the perspective includes more than just our actor, move vertices towards the center of the perspective so they'll be properly rotated
|
||||||
// float vec_z = -world_pos.y * fovWidths.y + fovHalfWidths.y;
|
world_pos.x += position_width_adjustment_count * cogl_position_width;
|
||||||
// vec4 look_vector = vec4(1.0, vec_y, vec_z, 1.0);
|
world_pos.y += position_height_adjustment_count * cogl_position_height;
|
||||||
// // vec3 rotated_vector = applyQuaternionToVector(look_vector, u_quaternion).xyz;
|
|
||||||
// vec3 rotated_vector = look_vector.xyz;
|
|
||||||
|
|
||||||
// // scale back to the screen distance
|
world_pos.z *= u_aspect_ratio;
|
||||||
// rotated_vector /= rotated_vector.x;
|
world_pos = applyXRotationToVector(world_pos, u_rotation_x_radians);
|
||||||
// cogl_position_out = vec4(
|
world_pos = applyYRotationToVector(world_pos, u_rotation_y_radians);
|
||||||
// ((fovHalfWidths.x - rotated_vector.y) / fovWidths.x) * 2.0 - 1.0,
|
|
||||||
// ((fovHalfWidths.y - rotated_vector.z) / fovWidths.y) * 2.0 - 1.0,
|
|
||||||
// 0.0,
|
|
||||||
// 1.0
|
|
||||||
// );
|
|
||||||
|
|
||||||
// float z_orig = world_pos.z;
|
|
||||||
// world_pos.z -= z_orig / 1920.0;
|
|
||||||
// world_pos.x /= 2.0;
|
|
||||||
// world_pos *= u_display_north_offset;
|
|
||||||
world_pos = applyQuaternionToVector(world_pos, u_quaternion);
|
world_pos = applyQuaternionToVector(world_pos, u_quaternion);
|
||||||
// world_pos /= u_display_north_offset;
|
world_pos.z /= u_aspect_ratio;
|
||||||
// world_pos.x *= 2.0;
|
|
||||||
// world_pos.z += z_orig / 1920.0;
|
|
||||||
world_pos = cogl_modelview_matrix * world_pos;
|
|
||||||
cogl_position_out = cogl_projection_matrix * world_pos;
|
|
||||||
|
|
||||||
// cogl_position_out.x = world_pos.x / 103.4;
|
world_pos.x /= u_actor_to_display_ratios.x;
|
||||||
// cogl_position_out.y = world_pos.y / 29.075;
|
world_pos.y /= u_actor_to_display_ratios.y;
|
||||||
// cogl_position_out.z = -1.0;
|
|
||||||
// cogl_position_out.w = 1.0;
|
world_pos = u_projection_matrix * world_pos;
|
||||||
|
|
||||||
|
// if the perspective includes more than just our actor, move the vertices back to just the area we can see.
|
||||||
|
// this needs to be done after the projection matrix multiplication so it will be projected as if centered in our vision
|
||||||
|
world_pos.x -= 0.5 * position_width_adjustment_count * world_pos.w;
|
||||||
|
world_pos.y -= 0.5 * position_height_adjustment_count * world_pos.w;
|
||||||
|
|
||||||
|
cogl_position_out = world_pos;
|
||||||
|
|
||||||
cogl_tex_coord_out[0] = cogl_tex_coord_in;
|
cogl_tex_coord_out[0] = cogl_tex_coord_in;
|
||||||
`
|
`
|
||||||
|
|
@ -351,12 +397,16 @@ export const TestActorEffect = GObject.registerClass({
|
||||||
);
|
);
|
||||||
Globals.logger.log(`aspect: ${aspect}, fov: ${this.fov_degrees}, width: ${this.get_actor().width}, height: ${this.get_actor().height}, projection matrix: ${JSON.stringify(projection_matrix)}`);
|
Globals.logger.log(`aspect: ${aspect}, fov: ${this.fov_degrees}, width: ${this.get_actor().width}, height: ${this.get_actor().height}, projection matrix: ${JSON.stringify(projection_matrix)}`);
|
||||||
this.set_uniform_matrix(this.get_uniform_location("u_projection_matrix"), false, 4, projection_matrix);
|
this.set_uniform_matrix(this.get_uniform_location("u_projection_matrix"), false, 4, projection_matrix);
|
||||||
|
this.set_uniform_float(this.get_uniform_location("u_rotation_x_radians"), 1, [this.monitor_wrapping_scheme === 'vertical' ? this.monitor_wrapping_rotation_radians : 0.0]);
|
||||||
|
this.set_uniform_float(this.get_uniform_location("u_rotation_y_radians"), 1, [this.monitor_wrapping_scheme === 'horizontal' ? this.monitor_wrapping_rotation_radians : 0.0]);
|
||||||
|
this.set_uniform_float(this.get_uniform_location("u_aspect_ratio"), 1, [aspect]);
|
||||||
|
this.set_uniform_float(this.get_uniform_location("u_actor_to_display_ratios"), 2, this.actor_to_display_ratios);
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set_uniform_float(this.get_uniform_location("u_display_north_offset"), 1, [this.focused_monitor_index === this.monitor_index ? this.display_distance : this.toggle_display_distance_start]);
|
this.set_uniform_float(this.get_uniform_location("u_display_north_offset"), 1, [this.display_distance]);
|
||||||
|
|
||||||
// NUW to east-up-south conversion, inverted
|
// NWU to east-up-south conversion, inverted
|
||||||
this.set_uniform_float(this.get_uniform_location("u_quaternion"), 4, [this.quaternion.y, -this.quaternion.z, this.quaternion.x, this.quaternion.w]);
|
this.set_uniform_float(this.get_uniform_location("u_quaternion"), 4, [this.quaternion.y, -this.quaternion.z, this.quaternion.x, this.quaternion.w]);
|
||||||
|
|
||||||
this.get_pipeline().set_layer_filters(
|
this.get_pipeline().set_layer_filters(
|
||||||
|
|
@ -450,58 +500,65 @@ export const TestActor = GObject.registerClass({
|
||||||
})),
|
})),
|
||||||
'horizontal'
|
'horizontal'
|
||||||
);
|
);
|
||||||
this.monitorAsNormalizedVectors = this.monitorsAsVectors.map(vector => {
|
|
||||||
|
// normalize the center vectors
|
||||||
|
this.monitorAsNormalizedVectors = this.monitorsAsVectors.map(monitorVectors => {
|
||||||
|
const vector = monitorVectors.center;
|
||||||
const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
|
const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
|
||||||
return [vector[0] / length, vector[1] / length, vector[2] / length];
|
return [vector[0] / length, vector[1] / length, vector[2] / length];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const actorToDisplayRatios = [
|
||||||
|
Main.layoutManager.uiGroup.width / this.width,
|
||||||
|
Main.layoutManager.uiGroup.height / this.height
|
||||||
|
];
|
||||||
|
|
||||||
Main.layoutManager.monitors.forEach(((monitor, index) => {
|
Main.layoutManager.monitors.forEach(((monitor, index) => {
|
||||||
// if (index === 0) return;
|
// if (index === 0) return;
|
||||||
Globals.logger.log(`\t\t\tMonitor ${index}: ${monitor.x}, ${monitor.y}, ${monitor.width}, ${monitor.height}`);
|
Globals.logger.log(`\t\t\tMonitor ${index}: ${monitor.x}, ${monitor.y}, ${monitor.width}, ${monitor.height}`);
|
||||||
|
|
||||||
// this is in NWU coordinates
|
// this is in NWU coordinates
|
||||||
const monitorVector = this.monitorsAsVectors[index];
|
const noRotationVector = this.monitorsAsVectors[index].topLeftNoRotate;
|
||||||
const monitorRotation = monitorVectorToRotationAngle(monitorVector, 'horizontal');
|
Globals.logger.log_debug(`\t\t\tMonitor ${index} vectors: ${JSON.stringify(this.monitorsAsVectors[index])}`);
|
||||||
Globals.logger.log_debug(`\t\t\tMonitor ${index} vector: ${monitorVector} rotation: ${JSON.stringify(monitorRotation)}`);
|
|
||||||
|
|
||||||
// actor coordinates are east-up-south
|
// actor coordinates are east-up-south
|
||||||
const containerActor = new Clutter.Actor({
|
const containerActor = new Clutter.Actor({
|
||||||
x: -monitorVector[1],
|
x: -noRotationVector[1],
|
||||||
y: -monitorVector[2],
|
y: -noRotationVector[2],
|
||||||
'z-position': -monitorVector[0],
|
'z-position': -noRotationVector[0],
|
||||||
width: monitor.width,
|
width: monitor.width,
|
||||||
height: monitor.height,
|
height: monitor.height,
|
||||||
reactive: false
|
reactive: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a clone of the stage content for this monitor
|
// Create a clone of the stage content for this monitor
|
||||||
const monitorClone = new Clutter.Clone({
|
const monitorClone = new Clutter.Clone({
|
||||||
source: Main.layoutManager.uiGroup,
|
source: Main.layoutManager.uiGroup,
|
||||||
reactive: false
|
reactive: false,
|
||||||
|
x: -containerActor.x - monitor.x,
|
||||||
|
y: -containerActor.y - monitor.y
|
||||||
});
|
});
|
||||||
|
monitorClone.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
|
||||||
monitorClone.x = -containerActor.x;
|
|
||||||
// monitorActor.y = 0;
|
|
||||||
monitorClone.set_clip(monitor.x, 0, monitor.width, monitor.height);
|
|
||||||
|
|
||||||
// Add the monitor actor to the scene
|
// Add the monitor actor to the scene
|
||||||
containerActor.add_child(monitorClone);
|
containerActor.add_child(monitorClone);
|
||||||
containerActor.set_pivot_point(0.5, 0.5);
|
|
||||||
containerActor.set_rotation_angle(monitorRotation.axis, monitorRotation.angle);
|
|
||||||
const effect = new TestActorEffect({
|
const effect = new TestActorEffect({
|
||||||
quaternion: this.quaternion,
|
quaternion: this.quaternion,
|
||||||
fov_degrees: this.fov_degrees,
|
fov_degrees: this.fov_degrees,
|
||||||
monitor_index: index,
|
monitor_index: index,
|
||||||
display_distance: this.toggle_display_distance_start
|
display_distance: noRotationVector[0],
|
||||||
|
monitor_wrapping_scheme: 'horizontal',
|
||||||
|
monitor_wrapping_rotation_radians: monitorVectorToRotationAngle(this.monitorsAsVectors[index].center, 'horizontal').angle,
|
||||||
|
actor_to_display_ratios: actorToDisplayRatios
|
||||||
});
|
});
|
||||||
containerActor.add_effect_with_name('viewport-effect', effect);
|
containerActor.add_effect_with_name('viewport-effect', effect);
|
||||||
this.add_child(containerActor);
|
this.add_child(containerActor);
|
||||||
this.bind_property('quaternion', effect, 'quaternion', GObject.BindingFlags.DEFAULT);
|
this.bind_property('quaternion', effect, 'quaternion', GObject.BindingFlags.DEFAULT);
|
||||||
this.bind_property('focused-monitor-index', effect, 'focused-monitor-index', GObject.BindingFlags.DEFAULT);
|
this.bind_property('focused-monitor-index', effect, 'focused-monitor-index', GObject.BindingFlags.DEFAULT);
|
||||||
this.bind_property('display-distance', effect, 'display-distance', GObject.BindingFlags.DEFAULT);
|
// this.bind_property('display-distance', effect, 'display-distance', GObject.BindingFlags.DEFAULT);
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
|
|
||||||
GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, (() => {
|
GLib.timeout_add(GLib.PRIORITY_DEFAULT, 500, (() => {
|
||||||
if (this.quaternion) {
|
if (this.quaternion) {
|
||||||
const closestMonitorIndex = findClosestVector(this.quaternion, this.monitorAsNormalizedVectors, this.closestMonitorIndex);
|
const closestMonitorIndex = findClosestVector(this.quaternion, this.monitorAsNormalizedVectors, this.closestMonitorIndex);
|
||||||
|
|
||||||
|
|
@ -516,9 +573,9 @@ export const TestActor = GObject.registerClass({
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
|
|
||||||
this._distance_ease_timeline = null;
|
this._distance_ease_timeline = null;
|
||||||
this.connect('notify::toggle-display-distance-start', this._handle_display_distance_properties_change.bind(this));
|
// this.connect('notify::toggle-display-distance-start', this._handle_display_distance_properties_change.bind(this));
|
||||||
this.connect('notify::toggle-display-distance-end', this._handle_display_distance_properties_change.bind(this));
|
// this.connect('notify::toggle-display-distance-end', this._handle_display_distance_properties_change.bind(this));
|
||||||
this.connect('notify::display-distance', this._handle_display_distance_properties_change.bind(this));
|
// this.connect('notify::display-distance', this._handle_display_distance_properties_change.bind(this));
|
||||||
this._handle_display_distance_properties_change();
|
this._handle_display_distance_properties_change();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue