MS15916: Fix multiple issues with Spectator Camera

This commit is contained in:
Zach Fox 2018-06-14 12:20:57 -07:00
parent 883c758722
commit e806348eeb
5 changed files with 147 additions and 35 deletions

View file

@ -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));
} }

View file

@ -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"
} }

View file

@ -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);