I feel so close; why isn't this variable capturing?

This commit is contained in:
Zach Fox 2018-04-27 17:26:05 -07:00
parent e0352bbb29
commit 1b29946a48
8 changed files with 147 additions and 32 deletions

View file

@ -7278,6 +7278,12 @@ void Application::takeSecondaryCameraSnapshot(const QString& filename) {
});
}
void Application::takeSecondaryCamera360Snapshot(const QString& filename) {
postLambdaEvent([filename, this] {
Snapshot::save360Snapshot(filename);
});
}
void Application::shareSnapshot(const QString& path, const QUrl& href) {
postLambdaEvent([path, href] {
// not much to do here, everything is done in snapshot code...

View file

@ -273,6 +273,7 @@ public:
void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f, const QString& filename = QString());
void takeSecondaryCameraSnapshot(const QString& filename = QString());
void takeSecondaryCamera360Snapshot(const QString& filename = QString());
void shareSnapshot(const QString& filename, const QUrl& href = QUrl(""));

View file

@ -431,6 +431,10 @@ void WindowScriptingInterface::takeSecondaryCameraSnapshot(const QString& filena
qApp->takeSecondaryCameraSnapshot(filename);
}
void WindowScriptingInterface::takeSecondaryCamera360Snapshot(const QString& filename) {
qApp->takeSecondaryCamera360Snapshot(filename);
}
void WindowScriptingInterface::shareSnapshot(const QString& path, const QUrl& href) {
qApp->shareSnapshot(path, href);
}

View file

@ -366,6 +366,18 @@ public slots:
*/
void takeSecondaryCameraSnapshot(const QString& filename = QString());
/**jsdoc
* Takes a 360 snapshot of the current view from the secondary camera that can be set up through the {@link Render} API.
* NOTE: to provide a non-default value - all previous parameters must be provided.
* @function Window.takeSecondaryCameraSnapshot
* @param {string} [filename=""] - If this parameter is not given, the image will be saved as 'hifi-snap-by-<user name>-YYYY-MM-DD_HH-MM-SS'.
* If this parameter is <code>""</code> then the image will be saved as ".jpg".
* Otherwise, the image will be saved to this filename, with an appended ".jpg".
*
* var filename = QString();
*/
void takeSecondaryCamera360Snapshot(const QString& filename = QString());
/**jsdoc
* Emit a {@link Window.connectionAdded|connectionAdded} or a {@link Window.connectionError|connectionError} signal that
* indicates whether or not a user connection was successfully made using the Web API.

View file

@ -29,8 +29,12 @@
#include <NodeList.h>
#include <OffscreenUi.h>
#include <SharedUtil.h>
#include <SecondaryCamera.h>
#include <plugins/DisplayPlugin.h>
#include "Application.h"
#include "scripting/WindowScriptingInterface.h"
#include "MainWindow.h"
#include "Snapshot.h"
#include "SnapshotUploader.h"
@ -87,6 +91,84 @@ QString Snapshot::saveSnapshot(QImage image, const QString& filename) {
return snapshotPath;
}
void Snapshot::save360Snapshot(const QString& filename) {
SecondaryCameraJobConfig* secondaryCameraRenderConfig = static_cast<SecondaryCameraJobConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera"));
// Save initial values of secondary camera render config
auto oldAttachedEntityId = secondaryCameraRenderConfig->property("attachedEntityId");
auto oldOrientation = secondaryCameraRenderConfig->property("orientation");
auto oldvFoV = secondaryCameraRenderConfig->property("vFoV");
auto oldNearClipPlaneDistance = secondaryCameraRenderConfig->property("nearClipPlaneDistance");
auto oldFarClipPlaneDistance = secondaryCameraRenderConfig->property("farClipPlaneDistance");
// Initialize some secondary camera render config options for 360 snapshot capture
secondaryCameraRenderConfig->resetSizeSpectatorCamera(2048, 2048);
secondaryCameraRenderConfig->setProperty("attachedEntityId", "");
secondaryCameraRenderConfig->setProperty("vFoV", 90.0f);
secondaryCameraRenderConfig->setProperty("nearClipPlaneDistance", 0.5f);
secondaryCameraRenderConfig->setProperty("farClipPlaneDistance", 1000.0f);
secondaryCameraRenderConfig->setOrientation(glm::quat(glm::radians(glm::vec3(-90.0f, 0.0f, 0.0f))));
qint16 snapshotIndex = 0;
QTimer* snapshotTimer = new QTimer();
snapshotTimer->setSingleShot(false);
snapshotTimer->setInterval(200);
connect(snapshotTimer, &QTimer::timeout, [&] {
SecondaryCameraJobConfig* config = static_cast<SecondaryCameraJobConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera"));
qDebug() << "ZRF HERE" << snapshotIndex;
if (snapshotIndex == 0) {
QImage downImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
Snapshot::saveSnapshot(downImage, "down");
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 0.0f, 0.0f))));
} else if (snapshotIndex == 1) {
QImage frontImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
Snapshot::saveSnapshot(frontImage, "front");
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 90.0f, 0.0f))));
} else if (snapshotIndex == 2) {
QImage leftImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
Snapshot::saveSnapshot(leftImage, "left");
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f))));
} else if (snapshotIndex == 3) {
QImage backImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
Snapshot::saveSnapshot(backImage, "back");
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 270.0f, 0.0f))));
} else if (snapshotIndex == 4) {
QImage rightImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
Snapshot::saveSnapshot(rightImage, "right");
config->setOrientation(glm::quat(glm::radians(glm::vec3(90.0f, 0.0f, 0.0f))));
} else if (snapshotIndex == 5) {
QImage upImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
Snapshot::saveSnapshot(upImage, "up");
} else if (snapshotIndex == 6) {
// Reset secondary camera render config
config->resetSizeSpectatorCamera(qApp->getWindow()->geometry().width(), qApp->getWindow()->geometry().height());
config->setProperty("attachedEntityId", oldAttachedEntityId);
config->setProperty("vFoV", oldvFoV);
config->setProperty("nearClipPlaneDistance", oldNearClipPlaneDistance);
config->setProperty("farClipPlaneDistance", oldFarClipPlaneDistance);
QFile* snapshotFile = savedFileForSnapshot(qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), false, filename);
// we don't need the snapshot file, so close it, grab its filename and delete it
snapshotFile->close();
QString snapshotPath = QFileInfo(*snapshotFile).absoluteFilePath();
delete snapshotFile;
snapshotTimer->stop();
snapshotTimer->deleteLater();
emit DependencyManager::get<WindowScriptingInterface>()->stillSnapshotTaken(snapshotPath, true);
}
snapshotIndex++;
});
snapshotTimer->start();
}
QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) {
// return whatever we get back from saved file for snapshot
return static_cast<QTemporaryFile*>(savedFileForSnapshot(image, true));

View file

@ -38,6 +38,7 @@ class Snapshot : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
static QString saveSnapshot(QImage image, const QString& filename);
static void save360Snapshot(const QString& filename);
static QTemporaryFile* saveTempSnapshot(QImage image);
static SnapshotMetaData* parseSnapshotData(QString snapshotPath);

View file

@ -185,33 +185,11 @@ Rectangle {
// SPECTATOR APP DESCRIPTION END
//
Item {
visible: !HMD.active;
height: root.height - spectatorDescriptionContainer.height - titleBarContainer.height;
anchors.top: spectatorDescriptionContainer.bottom;
anchors.topMargin: 20;
anchors.left: parent.left;
anchors.leftMargin: 25;
anchors.right: parent.right;
anchors.rightMargin: anchors.leftMargin;
HifiStylesUit.FiraSansRegular {
text: "Spectator Camera only works in VR mode.\nPlease put on your headset.";
size: 18;
color: hifi.colors.lightGrayText;
anchors.fill: parent;
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
wrapMode: Text.Wrap;
}
}
//
// SPECTATOR CONTROLS START
//
Item {
id: spectatorControlsContainer;
visible: HMD.active;
// Size
height: root.height - spectatorDescriptionContainer.height - titleBarContainer.height;
// Anchors
@ -332,7 +310,7 @@ Rectangle {
colorScheme: hifi.colorSchemes.dark;
anchors.left: parent.left;
anchors.top: monitorShowsSwitch.bottom;
anchors.topMargin: 25;
anchors.topMargin: 14;
text: "";
boxSize: 24;
onClicked: {
@ -343,6 +321,7 @@ Rectangle {
// "Take Snapshot" Checkbox
HifiControlsUit.CheckBox {
id: takeSnapshotFromControllerCheckBox;
visible: HMD.active;
colorScheme: hifi.colorSchemes.dark;
anchors.left: parent.left;
anchors.top: switchViewFromControllerCheckBox.bottom;
@ -353,6 +332,21 @@ Rectangle {
sendToScript({method: 'changeTakeSnapshotFromControllerPreference', params: checked});
}
}
HifiControlsUit.Button {
id: take360SnapshotButton;
text: "Take 360 Snapshot"
colorScheme: hifi.colorSchemes.dark;
color: hifi.buttons.blue;
anchors.top: takeSnapshotFromControllerCheckBox.visible ? takeSnapshotFromControllerCheckBox.bottom : switchViewFromControllerCheckBox.bottom;
anchors.topMargin: 8;
anchors.left: parent.left;
anchors.right: parent.right;
height: 40;
onClicked: {
sendToScript({method: 'takeSecondaryCamera360Snapshot'});
}
}
}
//
// SPECTATOR CONTROLS END

View file

@ -46,7 +46,6 @@
// -Far clip plane distance
// -viewFinderOverlay: The in-world overlay that displays the spectator camera's view.
// -camera: The in-world entity that corresponds to the spectator camera.
// -cameraIsDynamic: "false" for now - maybe it shouldn't be? False means that the camera won't drift when you let go...
// -cameraRotation: The rotation of the spectator camera.
// -cameraPosition: The position of the spectator camera.
// -glassPaneWidth: The width of the glass pane above the spectator camera that holds the viewFinderOverlay.
@ -56,7 +55,6 @@
var spectatorCameraConfig = Render.getConfig("SecondaryCamera");
var viewFinderOverlay = false;
var camera = false;
var cameraIsDynamic = false;
var cameraRotation;
var cameraPosition;
var glassPaneWidth = 0.16;
@ -70,11 +68,11 @@
spectatorCameraConfig.resetSizeSpectatorCamera(Window.innerWidth, Window.innerHeight);
cameraRotation = Quat.multiply(MyAvatar.orientation, Quat.fromPitchYawRollDegrees(15, -155, 0)), cameraPosition = inFrontOf(0.85, Vec3.sum(MyAvatar.position, { x: 0, y: 0.28, z: 0 }));
camera = Entities.addEntity({
"angularDamping": 1,
"damping": 1,
"angularDamping": 0.8,
"damping": 0.8,
"collidesWith": "static,dynamic,kinematic,",
"collisionMask": 7,
"dynamic": cameraIsDynamic,
"dynamic": true,
"modelURL": Script.resolvePath("spectator-camera.fbx"),
"registrationPoint": {
"x": 0.56,
@ -89,8 +87,12 @@
}, true);
spectatorCameraConfig.attachedEntityId = camera;
updateOverlay();
setDisplay(monitorShowsCameraView);
// Change button to active when window is first openend OR if the camera is on, false otherwise.
if (!HMD.active) {
setMonitorShowsCameraView(false);
} else {
setDisplay(monitorShowsCameraView);
}
// Change button to active when window is first opened OR if the camera is on, false otherwise.
if (button) {
button.editProperties({ isActive: onSpectatorCameraScreen || camera });
}
@ -238,7 +240,7 @@
function setDisplay(showCameraView) {
var url = (camera) ? (showCameraView ? "resource://spectatorCameraFrame" : "resource://hmdPreviewFrame") : "";
sendToQml({ method: 'showPreviewTextureNotInstructions', setting: !!url, url: url});
sendToQml({ method: 'showPreviewTextureNotInstructions', setting: !!url, url: url });
// FIXME: temporary hack to avoid setting the display texture to hmdPreviewFrame
// until it is the correct mono.
@ -336,7 +338,7 @@
setSwitchViewControllerMappingStatus(switchViewFromController);
Settings.setValue('spectatorCamera/switchViewFromController', setting);
}
const TAKE_SNAPSHOT_FROM_CONTROLLER_DEFAULT = false;
var takeSnapshotFromController = !!Settings.getValue('spectatorCamera/takeSnapshotFromController', TAKE_SNAPSHOT_FROM_CONTROLLER_DEFAULT);
function setTakeSnapshotControllerMappingStatus(status) {
@ -401,6 +403,16 @@
Window.takeSecondaryCameraSnapshot();
}
}
function maybeTake360Snapshot() {
if (camera) {
Audio.playSound(SNAPSHOT_SOUND, {
position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z },
localOnly: true,
volume: 1.0
});
Window.takeSecondaryCamera360Snapshot();
}
}
function registerTakeSnapshotControllerMapping() {
takeSnapshotControllerMapping = Controller.newMapping(takeSnapshotControllerMappingName);
if (controllerType === "OculusTouch") {
@ -541,6 +553,9 @@
case 'changeTakeSnapshotFromControllerPreference':
setTakeSnapshotFromController(message.params);
break;
case 'takeSecondaryCamera360Snapshot':
maybeTake360Snapshot();
break;
default:
print('Unrecognized message from SpectatorCamera.qml:', JSON.stringify(message));
}