mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 18:06:57 +02:00
MS15916: Fix multiple issues with Spectator Camera
This commit is contained in:
parent
883c758722
commit
e806348eeb
5 changed files with 147 additions and 35 deletions
|
@ -25,6 +25,8 @@ Rectangle {
|
||||||
HifiStylesUit.HifiConstants { id: hifi; }
|
HifiStylesUit.HifiConstants { id: hifi; }
|
||||||
|
|
||||||
id: root;
|
id: root;
|
||||||
|
property bool uiReady: false;
|
||||||
|
property bool processingStillSnapshot: false;
|
||||||
property bool processing360Snapshot: false;
|
property bool processing360Snapshot: false;
|
||||||
// Style
|
// Style
|
||||||
color: "#404040";
|
color: "#404040";
|
||||||
|
@ -58,7 +60,7 @@ Rectangle {
|
||||||
// "Spectator" text
|
// "Spectator" text
|
||||||
HifiStylesUit.RalewaySemiBold {
|
HifiStylesUit.RalewaySemiBold {
|
||||||
id: titleBarText;
|
id: titleBarText;
|
||||||
text: "Spectator Camera";
|
text: "Spectator Camera 2.2";
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 30;
|
anchors.leftMargin: 30;
|
||||||
|
@ -91,13 +93,16 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
if (!checked) {
|
||||||
|
flashCheckBox.checked = false;
|
||||||
|
}
|
||||||
sendToScript({method: (checked ? 'spectatorCameraOn' : 'spectatorCameraOff')});
|
sendToScript({method: (checked ? 'spectatorCameraOn' : 'spectatorCameraOff')});
|
||||||
sendToScript({method: 'updateCameravFoV', vFoV: fieldOfViewSlider.value});
|
sendToScript({method: 'updateCameravFoV', vFoV: fieldOfViewSlider.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: parent.checked ? "#1FC6A6" : hifi.colors.white;
|
color: parent.checked ? "#1FC6A6" : hifi.colors.white;
|
||||||
implicitWidth: masterSwitch.switchWidth;
|
implicitWidth: masterSwitch.width;
|
||||||
implicitHeight: masterSwitch.height;
|
implicitHeight: masterSwitch.height;
|
||||||
radius: height/2;
|
radius: height/2;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +132,7 @@ Rectangle {
|
||||||
z: 999;
|
z: 999;
|
||||||
id: processingSnapshot;
|
id: processingSnapshot;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
visible: root.processing360Snapshot;
|
visible: root.processing360Snapshot || !root.uiReady;
|
||||||
color: Qt.rgba(0.0, 0.0, 0.0, 0.85);
|
color: Qt.rgba(0.0, 0.0, 0.0, 0.85);
|
||||||
|
|
||||||
// This object is always used in a popup.
|
// This object is always used in a popup.
|
||||||
|
@ -149,7 +154,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiStylesUit.RalewaySemiBold {
|
HifiStylesUit.RalewaySemiBold {
|
||||||
text: "Processing...";
|
text: root.uiReady ? "Processing..." : "";
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: processingImage.bottom;
|
anchors.top: processingImage.bottom;
|
||||||
anchors.topMargin: 4;
|
anchors.topMargin: 4;
|
||||||
|
@ -202,10 +207,20 @@ Rectangle {
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.FiraSansRegular {
|
||||||
|
text: ":)";
|
||||||
|
size: 28;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
visible: root.processing360Snapshot || root.processingStillSnapshot;
|
||||||
|
anchors.fill: parent;
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
// Spectator Camera Preview
|
// Spectator Camera Preview
|
||||||
Hifi.ResourceImageItem {
|
Hifi.ResourceImageItem {
|
||||||
id: spectatorCameraPreview;
|
id: spectatorCameraPreview;
|
||||||
visible: masterSwitch.checked && !root.processing360Snapshot;
|
visible: masterSwitch.checked && !root.processing360Snapshot && !root.processingStillSnapshot;
|
||||||
url: showCameraView.checked || !HMD.active ? "resource://spectatorCameraFrame" : "resource://hmdPreviewFrame";
|
url: showCameraView.checked || !HMD.active ? "resource://spectatorCameraFrame" : "resource://hmdPreviewFrame";
|
||||||
ready: masterSwitch.checked;
|
ready: masterSwitch.checked;
|
||||||
mirrorVertically: true;
|
mirrorVertically: true;
|
||||||
|
@ -311,7 +326,30 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.HiFiGlyphs {
|
||||||
|
id: flashGlyph;
|
||||||
|
visible: flashCheckBox.visible;
|
||||||
|
text: hifi.glyphs.lightning;
|
||||||
|
size: 26;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
anchors.verticalCenter: flashCheckBox.verticalCenter;
|
||||||
|
anchors.right: flashCheckBox.left;
|
||||||
|
anchors.rightMargin: -2;
|
||||||
|
}
|
||||||
|
HifiControlsUit.CheckBox {
|
||||||
|
id: flashCheckBox;
|
||||||
|
visible: masterSwitch.checked;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
colorScheme: hifi.colorSchemes.dark;
|
||||||
|
anchors.right: takeSnapshotButton.left;
|
||||||
|
anchors.rightMargin: -8;
|
||||||
|
anchors.verticalCenter: takeSnapshotButton.verticalCenter;
|
||||||
|
boxSize: 22;
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: 'setFlashStatus', enabled: checked});
|
||||||
|
}
|
||||||
|
}
|
||||||
HifiControlsUit.Button {
|
HifiControlsUit.Button {
|
||||||
id: takeSnapshotButton;
|
id: takeSnapshotButton;
|
||||||
enabled: masterSwitch.checked;
|
enabled: masterSwitch.checked;
|
||||||
|
@ -325,6 +363,7 @@ Rectangle {
|
||||||
width: 135;
|
width: 135;
|
||||||
height: 35;
|
height: 35;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
root.processingStillSnapshot = true;
|
||||||
sendToScript({method: 'takeSecondaryCameraSnapshot'});
|
sendToScript({method: 'takeSecondaryCameraSnapshot'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,8 +621,12 @@ Rectangle {
|
||||||
//
|
//
|
||||||
function fromScript(message) {
|
function fromScript(message) {
|
||||||
switch (message.method) {
|
switch (message.method) {
|
||||||
case 'updateSpectatorCameraCheckbox':
|
case 'initializeUI':
|
||||||
masterSwitch.checked = message.params;
|
masterSwitch.checked = message.masterSwitchOn;
|
||||||
|
flashCheckBox.checked = message.flashCheckboxChecked;
|
||||||
|
showCameraView.checked = message.monitorShowsCamView;
|
||||||
|
showHmdPreview.checked = !message.monitorShowsCamView;
|
||||||
|
root.uiReady = true;
|
||||||
break;
|
break;
|
||||||
case 'updateMonitorShowsSwitch':
|
case 'updateMonitorShowsSwitch':
|
||||||
showCameraView.checked = message.params;
|
showCameraView.checked = message.params;
|
||||||
|
@ -611,6 +654,12 @@ Rectangle {
|
||||||
case 'finishedProcessing360Snapshot':
|
case 'finishedProcessing360Snapshot':
|
||||||
root.processing360Snapshot = false;
|
root.processing360Snapshot = false;
|
||||||
break;
|
break;
|
||||||
|
case 'startedProcessingStillSnapshot':
|
||||||
|
root.processingStillSnapshot = true;
|
||||||
|
break;
|
||||||
|
case 'finishedProcessingStillSnapshot':
|
||||||
|
root.processingStillSnapshot = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.log('Unrecognized message from spectatorCamera.js:', JSON.stringify(message));
|
console.log('Unrecognized message from spectatorCamera.js:', JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
|
BIN
unpublishedScripts/marketplace/spectator-camera/flashOff.wav
Normal file
BIN
unpublishedScripts/marketplace/spectator-camera/flashOff.wav
Normal file
Binary file not shown.
BIN
unpublishedScripts/marketplace/spectator-camera/flashOn.wav
Normal file
BIN
unpublishedScripts/marketplace/spectator-camera/flashOn.wav
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"scriptURL": "http://mpassets-staging.highfidelity.com/26156ea5-cdff-43c2-9581-d6b0fa5e00ef-v1/spectatorCamera.js",
|
"scriptURL": "http://mpassets.highfidelity.com/80d02930-f409-4f1a-824f-ae0109da32d6-v1/spectatorCamera.js",
|
||||||
"homeURL": "http://mpassets-staging.highfidelity.com/26156ea5-cdff-43c2-9581-d6b0fa5e00ef-v1/SpectatorCamera.qml"
|
"homeURL": "http://mpassets.highfidelity.com/80d02930-f409-4f1a-824f-ae0109da32d6-v1/SpectatorCamera.qml"
|
||||||
}
|
}
|
|
@ -97,7 +97,7 @@
|
||||||
if (button) {
|
if (button) {
|
||||||
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
|
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
|
||||||
}
|
}
|
||||||
Audio.playSound(CAMERA_ON_SOUND, {
|
Audio.playSound(SOUND_CAMERA_ON, {
|
||||||
volume: 0.15,
|
volume: 0.15,
|
||||||
position: cameraPosition,
|
position: cameraPosition,
|
||||||
localOnly: true
|
localOnly: true
|
||||||
|
@ -113,8 +113,14 @@
|
||||||
var WAIT_AFTER_DOMAIN_SWITCH_BEFORE_CAMERA_DELETE_MS = 1 * 1000;
|
var WAIT_AFTER_DOMAIN_SWITCH_BEFORE_CAMERA_DELETE_MS = 1 * 1000;
|
||||||
function spectatorCameraOff(isChangingDomains) {
|
function spectatorCameraOff(isChangingDomains) {
|
||||||
function deleteCamera() {
|
function deleteCamera() {
|
||||||
Entities.deleteEntity(camera);
|
if (flash) {
|
||||||
camera = false;
|
Entities.deleteEntity(flash);
|
||||||
|
flash = false;
|
||||||
|
}
|
||||||
|
if (camera) {
|
||||||
|
Entities.deleteEntity(camera);
|
||||||
|
camera = false;
|
||||||
|
}
|
||||||
if (button) {
|
if (button) {
|
||||||
// Change button to active when window is first openend OR if the camera is on, false otherwise.
|
// Change button to active when window is first openend OR if the camera is on, false otherwise.
|
||||||
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
|
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
|
||||||
|
@ -391,21 +397,81 @@
|
||||||
}
|
}
|
||||||
var takeSnapshotControllerMapping;
|
var takeSnapshotControllerMapping;
|
||||||
var takeSnapshotControllerMappingName = 'Hifi-SpectatorCamera-Mapping-TakeSnapshot';
|
var takeSnapshotControllerMappingName = 'Hifi-SpectatorCamera-Mapping-TakeSnapshot';
|
||||||
|
|
||||||
|
var flash = false;
|
||||||
|
function setFlashStatus(enabled) {
|
||||||
|
var cameraPosition = Entities.getEntityProperties(camera, ["positon"]).position;
|
||||||
|
if (enabled) {
|
||||||
|
if (camera) {
|
||||||
|
Audio.playSound(SOUND_FLASH_ON, {
|
||||||
|
position: cameraPosition,
|
||||||
|
localOnly: true,
|
||||||
|
volume: 0.8
|
||||||
|
});
|
||||||
|
flash = Entities.addEntity({
|
||||||
|
"collidesWith": "",
|
||||||
|
"collisionMask": 0,
|
||||||
|
"color": {
|
||||||
|
"blue": 173,
|
||||||
|
"green": 252,
|
||||||
|
"red": 255
|
||||||
|
},
|
||||||
|
"cutoff": 90,
|
||||||
|
"dimensions": {
|
||||||
|
"x": 4,
|
||||||
|
"y": 4,
|
||||||
|
"z": 4
|
||||||
|
},
|
||||||
|
"dynamic": false,
|
||||||
|
"falloffRadius": 0.20000000298023224,
|
||||||
|
"intensity": 37,
|
||||||
|
"isSpotlight": true,
|
||||||
|
"localRotation": { w: 1, x: 0, y: 0, z: 0 },
|
||||||
|
"localPosition": { x: 0, y: -0.005, z: -0.08 },
|
||||||
|
"name": "Camera Flash",
|
||||||
|
"type": "Light",
|
||||||
|
"parentID": camera,
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (flash) {
|
||||||
|
Audio.playSound(SOUND_FLASH_OFF, {
|
||||||
|
position: cameraPosition,
|
||||||
|
localOnly: true,
|
||||||
|
volume: 0.8
|
||||||
|
});
|
||||||
|
Entities.deleteEntity(flash);
|
||||||
|
flash = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onStillSnapshotTaken() {
|
function onStillSnapshotTaken() {
|
||||||
Render.getConfig("SecondaryCameraJob.ToneMapping").curve = 1;
|
Render.getConfig("SecondaryCameraJob.ToneMapping").curve = 1;
|
||||||
|
sendToQml({
|
||||||
|
method: 'finishedProcessingStillSnapshot'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function maybeTakeSnapshot() {
|
function maybeTakeSnapshot() {
|
||||||
if (camera) {
|
if (camera) {
|
||||||
|
sendToQml({
|
||||||
|
method: 'startedProcessingStillSnapshot'
|
||||||
|
});
|
||||||
|
|
||||||
Render.getConfig("SecondaryCameraJob.ToneMapping").curve = 0;
|
Render.getConfig("SecondaryCameraJob.ToneMapping").curve = 0;
|
||||||
// Wait a moment before taking the snapshot for the tonemapping curve to update
|
// Wait a moment before taking the snapshot for the tonemapping curve to update
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
Audio.playSound(SNAPSHOT_SOUND, {
|
Audio.playSound(SOUND_SNAPSHOT, {
|
||||||
position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z },
|
position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z },
|
||||||
localOnly: true,
|
localOnly: true,
|
||||||
volume: 1.0
|
volume: 1.0
|
||||||
});
|
});
|
||||||
Window.takeSecondaryCameraSnapshot();
|
Window.takeSecondaryCameraSnapshot();
|
||||||
}, 250);
|
}, 250);
|
||||||
|
} else {
|
||||||
|
sendToQml({
|
||||||
|
method: 'finishedProcessingStillSnapshot'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function on360SnapshotTaken() {
|
function on360SnapshotTaken() {
|
||||||
|
@ -418,7 +484,7 @@
|
||||||
}
|
}
|
||||||
function maybeTake360Snapshot() {
|
function maybeTake360Snapshot() {
|
||||||
if (camera) {
|
if (camera) {
|
||||||
Audio.playSound(SNAPSHOT_SOUND, {
|
Audio.playSound(SOUND_SNAPSHOT, {
|
||||||
position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z },
|
position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z },
|
||||||
localOnly: true,
|
localOnly: true,
|
||||||
volume: 1.0
|
volume: 1.0
|
||||||
|
@ -508,18 +574,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSpectatorCameraQML() {
|
function updateSpectatorCameraQML() {
|
||||||
sendToQml({ method: 'updateSpectatorCameraCheckbox', params: !!camera });
|
sendToQml({ method: 'initializeUI', masterSwitchOn: !!camera, flashCheckboxChecked: !!flash, monitorShowsCamView: monitorShowsCameraView });
|
||||||
sendToQml({ method: 'updateMonitorShowsSwitch', params: monitorShowsCameraView });
|
registerButtonMappings();
|
||||||
if (!switchViewControllerMapping || !takeSnapshotControllerMapping) {
|
|
||||||
registerButtonMappings();
|
|
||||||
} else {
|
|
||||||
sendToQml({
|
|
||||||
method: 'updateControllerMappingCheckbox',
|
|
||||||
switchViewSetting: switchViewFromController,
|
|
||||||
takeSnapshotSetting: takeSnapshotFromController,
|
|
||||||
controller: controllerType
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Menu.setIsOptionChecked("Disable Preview", false);
|
Menu.setIsOptionChecked("Disable Preview", false);
|
||||||
Menu.setIsOptionChecked("Mono Preview", true);
|
Menu.setIsOptionChecked("Mono Preview", true);
|
||||||
}
|
}
|
||||||
|
@ -537,9 +593,13 @@
|
||||||
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
|
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onSpectatorCameraScreen) {
|
// In the case of a remote QML app, it takes a bit of time
|
||||||
updateSpectatorCameraQML();
|
// for the event bridge to actually connect, so we have to wait...
|
||||||
}
|
Script.setTimeout(function () {
|
||||||
|
if (onSpectatorCameraScreen) {
|
||||||
|
updateSpectatorCameraQML();
|
||||||
|
}
|
||||||
|
}, 700);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function Name: sendToQml()
|
// Function Name: sendToQml()
|
||||||
|
@ -576,6 +636,9 @@
|
||||||
case 'updateCameravFoV':
|
case 'updateCameravFoV':
|
||||||
spectatorCameraConfig.vFoV = message.vFoV;
|
spectatorCameraConfig.vFoV = message.vFoV;
|
||||||
break;
|
break;
|
||||||
|
case 'setFlashStatus':
|
||||||
|
setFlashStatus(message.enabled);
|
||||||
|
break;
|
||||||
case 'takeSecondaryCameraSnapshot':
|
case 'takeSecondaryCameraSnapshot':
|
||||||
maybeTakeSnapshot();
|
maybeTakeSnapshot();
|
||||||
break;
|
break;
|
||||||
|
@ -600,9 +663,7 @@
|
||||||
// Description:
|
// Description:
|
||||||
// -Called from C++ when HMD mode is changed. The argument "isHMDMode" is true if HMD is on; false otherwise.
|
// -Called from C++ when HMD mode is changed. The argument "isHMDMode" is true if HMD is on; false otherwise.
|
||||||
function onHMDChanged(isHMDMode) {
|
function onHMDChanged(isHMDMode) {
|
||||||
if (!switchViewControllerMapping || !takeSnapshotControllerMapping) {
|
registerButtonMappings();
|
||||||
registerButtonMappings();
|
|
||||||
}
|
|
||||||
if (!isHMDMode) {
|
if (!isHMDMode) {
|
||||||
setMonitorShowsCameraView(false);
|
setMonitorShowsCameraView(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -646,8 +707,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// These functions will be called when the script is loaded.
|
// These functions will be called when the script is loaded.
|
||||||
var CAMERA_ON_SOUND = SoundCache.getSound(Script.resolvePath("cameraOn.wav"));
|
var SOUND_CAMERA_ON = SoundCache.getSound(Script.resolvePath("cameraOn.wav"));
|
||||||
var SNAPSHOT_SOUND = SoundCache.getSound(Script.resourcesPath() + "sounds/snapshot/snap.wav");
|
var SOUND_SNAPSHOT = SoundCache.getSound(Script.resolvePath("snap.wav"));
|
||||||
|
var SOUND_FLASH_ON = SoundCache.getSound(Script.resolvePath("flashOn.wav"));
|
||||||
|
var SOUND_FLASH_OFF = SoundCache.getSound(Script.resolvePath("flashOff.wav"));
|
||||||
startup();
|
startup();
|
||||||
Script.scriptEnding.connect(shutdown);
|
Script.scriptEnding.connect(shutdown);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue