Tons of stability and clarity improvements

This commit is contained in:
Zach Fox 2018-05-01 13:00:04 -07:00
parent c115f2bd36
commit 249e2a2bac
5 changed files with 97 additions and 67 deletions

View file

@ -367,9 +367,9 @@ public slots:
void takeSecondaryCameraSnapshot(const QString& filename = QString()); void takeSecondaryCameraSnapshot(const QString& filename = QString());
/**jsdoc /**jsdoc
* Takes a 360 snapshot of the current view from the secondary camera that can be set up through the {@link Render} API. * Takes a 360 snapshot given a position of the secondary camera (which does not need to have been previously set up).
* NOTE: to provide a non-default value - all previous parameters must be provided.
* @function Window.takeSecondaryCameraSnapshot * @function Window.takeSecondaryCameraSnapshot
* @param {vec3} [cameraPosition] - The (x, y, z) position of the camera for the 360 snapshot
* @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'. * @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". * 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". * Otherwise, the image will be saved to this filename, with an appended ".jpg".
@ -587,10 +587,10 @@ signals:
void stillSnapshotTaken(const QString& pathStillSnapshot, bool notify); void stillSnapshotTaken(const QString& pathStillSnapshot, bool notify);
/**jsdoc /**jsdoc
* Triggered when a still equirectangular snapshot has been taken by calling {@link Window.take360Snapshot|take360Snapshot} * Triggered when a still equirectangular snapshot has been taken by calling {@link Window.takeSecondaryCamera360Snapshot|takeSecondaryCamera360Snapshot}
* @function Window.equirectangularSnapshotTaken * @function Window.equirectangularSnapshotTaken
* @param {string} pathStillSnapshot - The path and name of the snapshot image file. * @param {string} pathStillSnapshot - The path and name of the snapshot image file.
* @param {boolean} notify - The value of the <code>notify</code> parameter that {@link Window.take360Snapshot|take360Snapshot} * @param {boolean} notify - The value of the <code>notify</code> parameter that {@link Window.takeSecondaryCamera360Snapshot|takeSecondaryCamera360Snapshot}
* was called with. * was called with.
* @returns {Signal} * @returns {Signal}
*/ */

View file

@ -51,6 +51,14 @@ const QString URL = "highfidelity_url";
Setting::Handle<QString> Snapshot::snapshotsLocation("snapshotsLocation"); Setting::Handle<QString> Snapshot::snapshotsLocation("snapshotsLocation");
QTimer Snapshot::snapshotTimer;
Snapshot::Snapshot() {
Snapshot::snapshotTimer.setSingleShot(false);
Snapshot::snapshotTimer.setTimerType(Qt::PreciseTimer);
Snapshot::snapshotTimer.setInterval(250);
connect(&Snapshot::snapshotTimer, &QTimer::timeout, &Snapshot::takeNextSnapshot);
}
SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) {
if (!QFile(snapshotPath).exists()) { if (!QFile(snapshotPath).exists()) {
@ -93,15 +101,6 @@ QString Snapshot::saveSnapshot(QImage image, const QString& filename) {
return snapshotPath; return snapshotPath;
} }
QTimer Snapshot::snapshotTimer;
qint16 Snapshot::snapshotIndex = 0;
QVariant Snapshot::oldAttachedEntityId = 0;
QVariant Snapshot::oldOrientation = 0;
QVariant Snapshot::oldvFoV = 0;
QVariant Snapshot::oldNearClipPlaneDistance = 0;
QVariant Snapshot::oldFarClipPlaneDistance = 0;
QImage Snapshot::downImage; QImage Snapshot::downImage;
QImage Snapshot::frontImage; QImage Snapshot::frontImage;
QImage Snapshot::leftImage; QImage Snapshot::leftImage;
@ -109,15 +108,70 @@ QImage Snapshot::backImage;
QImage Snapshot::rightImage; QImage Snapshot::rightImage;
QImage Snapshot::upImage; QImage Snapshot::upImage;
void Snapshot::takeNextSnapshot() {
SecondaryCameraJobConfig* config = static_cast<SecondaryCameraJobConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera"));
if (snapshotIndex == 0) {
Snapshot::downImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 0.0f, 0.0f))));
} else if (snapshotIndex == 1) {
Snapshot::frontImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 90.0f, 0.0f))));
} else if (snapshotIndex == 2) {
Snapshot::leftImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f))));
} else if (snapshotIndex == 3) {
Snapshot::backImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 270.0f, 0.0f))));
} else if (snapshotIndex == 4) {
Snapshot::rightImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(90.0f, 0.0f, 0.0f))));
} else if (snapshotIndex == 5) {
Snapshot::upImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
} else {
Snapshot::snapshotTimer.stop();
// Reset secondary camera render config
static_cast<ToneMappingConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCameraJob.ToneMapping"))->setCurve(1);
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);
if (!Snapshot::oldEnabled) {
config->enableSecondaryCameraRenderConfigs(false);
}
// Process six QImages
QtConcurrent::run(Snapshot::convertToEquirectangular);
}
Snapshot::snapshotIndex++;
}
QString Snapshot::snapshotFilename;
qint16 Snapshot::snapshotIndex = 0;
bool Snapshot::oldEnabled = false;
QVariant Snapshot::oldAttachedEntityId = 0;
QVariant Snapshot::oldOrientation = 0;
QVariant Snapshot::oldvFoV = 0;
QVariant Snapshot::oldNearClipPlaneDistance = 0;
QVariant Snapshot::oldFarClipPlaneDistance = 0;
void Snapshot::save360Snapshot(const glm::vec3& cameraPosition, const QString& filename) { void Snapshot::save360Snapshot(const glm::vec3& cameraPosition, const QString& filename) {
Snapshot::snapshotFilename = filename;
SecondaryCameraJobConfig* secondaryCameraRenderConfig = static_cast<SecondaryCameraJobConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera")); SecondaryCameraJobConfig* secondaryCameraRenderConfig = static_cast<SecondaryCameraJobConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera"));
// Save initial values of secondary camera render config // Save initial values of secondary camera render config
oldAttachedEntityId = secondaryCameraRenderConfig->property("attachedEntityId"); Snapshot::oldEnabled = secondaryCameraRenderConfig->isEnabled();
oldOrientation = secondaryCameraRenderConfig->property("orientation"); Snapshot::oldAttachedEntityId = secondaryCameraRenderConfig->property("attachedEntityId");
oldvFoV = secondaryCameraRenderConfig->property("vFoV"); Snapshot::oldOrientation = secondaryCameraRenderConfig->property("orientation");
oldNearClipPlaneDistance = secondaryCameraRenderConfig->property("nearClipPlaneDistance"); Snapshot::oldvFoV = secondaryCameraRenderConfig->property("vFoV");
oldFarClipPlaneDistance = secondaryCameraRenderConfig->property("farClipPlaneDistance"); Snapshot::oldNearClipPlaneDistance = secondaryCameraRenderConfig->property("nearClipPlaneDistance");
Snapshot::oldFarClipPlaneDistance = secondaryCameraRenderConfig->property("farClipPlaneDistance");
if (!Snapshot::oldEnabled) {
secondaryCameraRenderConfig->enableSecondaryCameraRenderConfigs(true);
}
// Initialize some secondary camera render config options for 360 snapshot capture // Initialize some secondary camera render config options for 360 snapshot capture
static_cast<ToneMappingConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCameraJob.ToneMapping"))->setCurve(0); static_cast<ToneMappingConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCameraJob.ToneMapping"))->setCurve(0);
@ -131,48 +185,11 @@ void Snapshot::save360Snapshot(const glm::vec3& cameraPosition, const QString& f
secondaryCameraRenderConfig->setOrientation(glm::quat(glm::radians(glm::vec3(-90.0f, 0.0f, 0.0f)))); secondaryCameraRenderConfig->setOrientation(glm::quat(glm::radians(glm::vec3(-90.0f, 0.0f, 0.0f))));
snapshotIndex = 0; Snapshot::snapshotIndex = 0;
snapshotTimer.setSingleShot(false); Snapshot::snapshotTimer.start(250);
snapshotTimer.setInterval(250);
connect(&snapshotTimer, &QTimer::timeout, [] {
SecondaryCameraJobConfig* config = static_cast<SecondaryCameraJobConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera"));
if (snapshotIndex == 0) {
downImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 0.0f, 0.0f))));
} else if (snapshotIndex == 1) {
frontImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 90.0f, 0.0f))));
} else if (snapshotIndex == 2) {
leftImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f))));
} else if (snapshotIndex == 3) {
backImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 270.0f, 0.0f))));
} else if (snapshotIndex == 4) {
rightImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
config->setOrientation(glm::quat(glm::radians(glm::vec3(90.0f, 0.0f, 0.0f))));
} else if (snapshotIndex == 5) {
upImage = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot();
} else {
// Reset secondary camera render config
static_cast<ToneMappingConfig*>(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCameraJob.ToneMapping"))->setCurve(1);
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);
// Process six QImages
QtConcurrent::run(convertToEquirectangular);
snapshotTimer.stop();
}
snapshotIndex++;
});
snapshotTimer.start();
} }
void Snapshot::convertToEquirectangular() { void Snapshot::convertToEquirectangular() {
// I got help from StackOverflow while writing this code: // I got help from StackOverflow while writing this code:
// https://stackoverflow.com/questions/34250742/converting-a-cubemap-into-equirectangular-panorama // https://stackoverflow.com/questions/34250742/converting-a-cubemap-into-equirectangular-panorama
@ -254,7 +271,7 @@ void Snapshot::convertToEquirectangular() {
} }
} }
emit DependencyManager::get<WindowScriptingInterface>()->equirectangularSnapshotTaken(saveSnapshot(outputImage, QString()), true); emit DependencyManager::get<WindowScriptingInterface>()->equirectangularSnapshotTaken(saveSnapshot(outputImage, Snapshot::snapshotFilename), true);
} }
QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) {

View file

@ -37,6 +37,8 @@ class Snapshot : public QObject, public Dependency {
Q_OBJECT Q_OBJECT
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
Snapshot();
static QString saveSnapshot(QImage image, const QString& filename); static QString saveSnapshot(QImage image, const QString& filename);
static void save360Snapshot(const glm::vec3& cameraPosition, const QString& filename); static void save360Snapshot(const glm::vec3& cameraPosition, const QString& filename);
static QTemporaryFile* saveTempSnapshot(QImage image); static QTemporaryFile* saveTempSnapshot(QImage image);
@ -51,11 +53,17 @@ signals:
public slots: public slots:
Q_INVOKABLE QString getSnapshotsLocation(); Q_INVOKABLE QString getSnapshotsLocation();
Q_INVOKABLE void setSnapshotsLocation(const QString& location); Q_INVOKABLE void setSnapshotsLocation(const QString& location);
private slots:
static void takeNextSnapshot();
private: private:
static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename = QString()); static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename = QString());
static QString snapshotFilename;
static QTimer snapshotTimer; static QTimer snapshotTimer;
static qint16 snapshotIndex; static qint16 snapshotIndex;
static bool oldEnabled;
static QVariant oldAttachedEntityId; static QVariant oldAttachedEntityId;
static QVariant oldOrientation; static QVariant oldOrientation;
static QVariant oldvFoV; static QVariant oldvFoV;

View file

@ -22,6 +22,7 @@ Rectangle {
HifiStylesUit.HifiConstants { id: hifi; } HifiStylesUit.HifiConstants { id: hifi; }
id: root; id: root;
property bool processing360Snapshot: false;
// Style // Style
color: hifi.colors.baseGray; color: hifi.colors.baseGray;
@ -189,8 +190,8 @@ Rectangle {
z: 999; z: 999;
id: processingSnapshot; id: processingSnapshot;
anchors.fill: parent; anchors.fill: parent;
visible: !take360SnapshotButton.enabled && cameraToggleButton.camIsOn; visible: root.processing360Snapshot;
color: Qt.rgba(0.0, 0.0, 0.0, 0.8); 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.
// This MouseArea is used to prevent a user from being // This MouseArea is used to prevent a user from being
@ -464,8 +465,7 @@ Rectangle {
width: parent.width/2 - 10; width: parent.width/2 - 10;
height: 40; height: 40;
onClicked: { onClicked: {
take360SnapshotButton.enabled = false; root.processing360Snapshot = true;
take360SnapshotButton.text = "PROCESSING...";
sendToScript({method: 'takeSecondaryCamera360Snapshot'}); sendToScript({method: 'takeSecondaryCamera360Snapshot'});
} }
} }
@ -517,9 +517,8 @@ Rectangle {
takeSnapshotFromControllerCheckBox.visible = false; takeSnapshotFromControllerCheckBox.visible = false;
} }
break; break;
case 'enable360SnapshotButton': case 'finishedProcessing360Snapshot':
take360SnapshotButton.text = "Take 360 Snapshot"; root.processing360Snapshot = false;
take360SnapshotButton.enabled = cameraToggleButton.camIsOn;
break; 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

@ -408,8 +408,11 @@
} }
} }
function onEquirectangularSnapshotTaken() { function onEquirectangularSnapshotTaken() {
if (monitorShowsCameraView) {
setDisplay(true);
}
sendToQml({ sendToQml({
method: 'enable360SnapshotButton' method: 'finishedProcessing360Snapshot'
}); });
} }
function maybeTake360Snapshot() { function maybeTake360Snapshot() {
@ -419,6 +422,9 @@
localOnly: true, localOnly: true,
volume: 1.0 volume: 1.0
}); });
if (HMD.active && monitorShowsCameraView) {
setDisplay(false);
}
Window.takeSecondaryCamera360Snapshot(Entities.getEntityProperties(camera, ["positon"]).position); Window.takeSecondaryCamera360Snapshot(Entities.getEntityProperties(camera, ["positon"]).position);
} }
} }