diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 61554e5c0d..1cd5ef5591 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4184,7 +4184,7 @@ bool Application::acceptSnapshot(const QString& urlString) { QUrl url(urlString); QString snapshotPath = url.toLocalFile(); - SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath); + SnapshotMetaData* snapshotData = DependencyManager::get()->parseSnapshotData(snapshotPath); if (snapshotData) { if (!snapshotData->getURL().toString().isEmpty()) { DependencyManager::get()->handleLookupString(snapshotData->getURL().toString()); @@ -7588,7 +7588,7 @@ void Application::loadAvatarBrowser() const { void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, testSnapshotLocation); + QString path = DependencyManager::get()->saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, testSnapshotLocation); // If we're not doing an animated snapshot as well... if (!includeAnimated) { // Tell the dependency manager that the capture of the still snapshot has taken place. @@ -7602,21 +7602,21 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa void Application::takeSecondaryCameraSnapshot(const QString& filename) { postLambdaEvent([filename, this] { - QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, testSnapshotLocation); + QString snapshotPath = DependencyManager::get()->saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, testSnapshotLocation); emit DependencyManager::get()->stillSnapshotTaken(snapshotPath, true); }); } void Application::takeSecondaryCamera360Snapshot(const glm::vec3& cameraPosition, const bool& cubemapOutputFormat, const QString& filename) { - postLambdaEvent([filename, cubemapOutputFormat, cameraPosition, this] { - Snapshot::save360Snapshot(cameraPosition, cubemapOutputFormat, filename); + postLambdaEvent([filename, cubemapOutputFormat, cameraPosition] { + DependencyManager::get()->save360Snapshot(cameraPosition, cubemapOutputFormat, filename); }); } void Application::shareSnapshot(const QString& path, const QUrl& href) { postLambdaEvent([path, href] { // not much to do here, everything is done in snapshot code... - Snapshot::uploadSnapshot(path, href); + DependencyManager::get()->uploadSnapshot(path, href); }); } diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 4c233b986c..6bb35fde41 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -132,8 +132,8 @@ void setupPreferences() { // Snapshots static const QString SNAPSHOTS { "Snapshots" }; { - auto getter = []()->QString { return Snapshot::snapshotsLocation.get(); }; - auto setter = [](const QString& value) { Snapshot::snapshotsLocation.set(value); emit DependencyManager::get()->snapshotLocationSet(value); }; + auto getter = []()->QString { return DependencyManager::get()->_snapshotsLocation.get(); }; + auto setter = [](const QString& value) { DependencyManager::get()->_snapshotsLocation.set(value); emit DependencyManager::get()->snapshotLocationSet(value); }; auto preference = new BrowsePreference(SNAPSHOTS, "Put my snapshots here", getter, setter); preferences->addPreference(preference); } diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index af0b599c1a..9fc6b480ca 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -46,20 +45,24 @@ // filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg // %1 <= username, %2 <= date and time, %3 <= current location const QString FILENAME_PATH_FORMAT = "hifi-snap-by-%1-on-%2.jpg"; - const QString DATETIME_FORMAT = "yyyy-MM-dd_hh-mm-ss"; const QString SNAPSHOTS_DIRECTORY = "Snapshots"; - const QString URL = "highfidelity_url"; +static const int SNAPSHOT_360_TIMER_INTERVAL = 350; -Setting::Handle 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); + _snapshotTimer.setSingleShot(false); + _snapshotTimer.setTimerType(Qt::PreciseTimer); + _snapshotTimer.setInterval(SNAPSHOT_360_TIMER_INTERVAL); + connect(&_snapshotTimer, &QTimer::timeout, this, &Snapshot::takeNextSnapshot); + + _snapshotIndex = 0; + _oldEnabled = false; + _oldAttachedEntityId = 0; + _oldOrientation = 0; + _oldvFoV = 0; + _oldNearClipPlaneDistance = 0; + _oldFarClipPlaneDistance = 0; } SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { @@ -104,30 +107,30 @@ QString Snapshot::saveSnapshot(QImage image, const QString& filename, const QStr return snapshotPath; } -QString Snapshot::snapshotFilename; -bool Snapshot::cubemapOutputFormat; -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; static const float CUBEMAP_SIDE_PIXEL_DIMENSION = 2048.0f; +static const float SNAPSHOT_360_FOV = 90.0f; +static const float SNAPSHOT_360_NEARCLIP = 0.3f; +static const float SNAPSHOT_360_FARCLIP = 16384.0f; +static const glm::quat CAMERA_ORIENTATION_DOWN(glm::quat(glm::radians(glm::vec3(-90.0f, 0.0f, 0.0f)))); +static const glm::quat CAMERA_ORIENTATION_FRONT(glm::quat(glm::radians(glm::vec3(0.0f, 0.0f, 0.0f)))); +static const glm::quat CAMERA_ORIENTATION_LEFT(glm::quat(glm::radians(glm::vec3(0.0f, 90.0f, 0.0f)))); +static const glm::quat CAMERA_ORIENTATION_BACK(glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f)))); +static const glm::quat CAMERA_ORIENTATION_RIGHT(glm::quat(glm::radians(glm::vec3(0.0f, 270.0f, 0.0f)))); +static const glm::quat CAMERA_ORIENTATION_UP(glm::quat(glm::radians(glm::vec3(90.0f, 0.0f, 0.0f)))); void Snapshot::save360Snapshot(const glm::vec3& cameraPosition, const bool& cubemapOutputFormat, const QString& filename) { - Snapshot::snapshotFilename = filename; - Snapshot::cubemapOutputFormat = cubemapOutputFormat; + _snapshotFilename = filename; + _cubemapOutputFormat = cubemapOutputFormat; SecondaryCameraJobConfig* secondaryCameraRenderConfig = static_cast(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera")); // Save initial values of secondary camera render config - Snapshot::oldEnabled = secondaryCameraRenderConfig->isEnabled(); - Snapshot::oldAttachedEntityId = secondaryCameraRenderConfig->property("attachedEntityId"); - Snapshot::oldOrientation = secondaryCameraRenderConfig->property("orientation"); - Snapshot::oldvFoV = secondaryCameraRenderConfig->property("vFoV"); - Snapshot::oldNearClipPlaneDistance = secondaryCameraRenderConfig->property("nearClipPlaneDistance"); - Snapshot::oldFarClipPlaneDistance = secondaryCameraRenderConfig->property("farClipPlaneDistance"); + _oldEnabled = secondaryCameraRenderConfig->isEnabled(); + _oldAttachedEntityId = secondaryCameraRenderConfig->property("attachedEntityId"); + _oldOrientation = secondaryCameraRenderConfig->property("orientation"); + _oldvFoV = secondaryCameraRenderConfig->property("vFoV"); + _oldNearClipPlaneDistance = secondaryCameraRenderConfig->property("nearClipPlaneDistance"); + _oldFarClipPlaneDistance = secondaryCameraRenderConfig->property("farClipPlaneDistance"); - if (!Snapshot::oldEnabled) { + if (!_oldEnabled) { secondaryCameraRenderConfig->enableSecondaryCameraRenderConfigs(true); } @@ -137,73 +140,71 @@ void Snapshot::save360Snapshot(const glm::vec3& cameraPosition, const bool& cube secondaryCameraRenderConfig->resetSizeSpectatorCamera(static_cast(CUBEMAP_SIDE_PIXEL_DIMENSION), static_cast(CUBEMAP_SIDE_PIXEL_DIMENSION)); secondaryCameraRenderConfig->setProperty("attachedEntityId", ""); secondaryCameraRenderConfig->setPosition(cameraPosition); - secondaryCameraRenderConfig->setProperty("vFoV", 90.0f); - secondaryCameraRenderConfig->setProperty("nearClipPlaneDistance", 0.3f); - secondaryCameraRenderConfig->setProperty("farClipPlaneDistance", 16384.0f); + secondaryCameraRenderConfig->setProperty("vFoV", SNAPSHOT_360_FOV); + secondaryCameraRenderConfig->setProperty("nearClipPlaneDistance", SNAPSHOT_360_NEARCLIP); + secondaryCameraRenderConfig->setProperty("farClipPlaneDistance", SNAPSHOT_360_FARCLIP); // Setup for Down Image capture - secondaryCameraRenderConfig->setOrientation(glm::quat(glm::radians(glm::vec3(-90.0f, 0.0f, 0.0f)))); + secondaryCameraRenderConfig->setOrientation(CAMERA_ORIENTATION_DOWN); - Snapshot::snapshotIndex = 0; + _snapshotIndex = 0; - Snapshot::snapshotTimer.start(350); + _snapshotTimer.start(SNAPSHOT_360_TIMER_INTERVAL); } -// Order is: -// 0. Down -// 1. Front -// 2. Left -// 3. Back -// 4. Right -// 5. Up -QImage Snapshot::imageArray[6]; - void Snapshot::takeNextSnapshot() { SecondaryCameraJobConfig* config = static_cast(qApp->getRenderEngine()->getConfiguration()->getConfig("SecondaryCamera")); - if (snapshotIndex < 6) { - Snapshot::imageArray[snapshotIndex] = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot(); + // Order is: + // 0. Down + // 1. Front + // 2. Left + // 3. Back + // 4. Right + // 5. Up + if (_snapshotIndex < 6) { + _imageArray[_snapshotIndex] = qApp->getActiveDisplayPlugin()->getSecondaryCameraScreenshot(); } - if (snapshotIndex == 0) { + if (_snapshotIndex == 0) { // Setup for Front Image capture - config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 0.0f, 0.0f)))); - } else if (snapshotIndex == 1) { + config->setOrientation(CAMERA_ORIENTATION_FRONT); + } else if (_snapshotIndex == 1) { // Setup for Left Image capture - config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 90.0f, 0.0f)))); - } else if (snapshotIndex == 2) { + config->setOrientation(CAMERA_ORIENTATION_LEFT); + } else if (_snapshotIndex == 2) { // Setup for Back Image capture - config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f)))); - } else if (snapshotIndex == 3) { + config->setOrientation(CAMERA_ORIENTATION_BACK); + } else if (_snapshotIndex == 3) { // Setup for Right Image capture - config->setOrientation(glm::quat(glm::radians(glm::vec3(0.0f, 270.0f, 0.0f)))); - } else if (snapshotIndex == 4) { + config->setOrientation(CAMERA_ORIENTATION_RIGHT); + } else if (_snapshotIndex == 4) { // Setup for Up Image capture - config->setOrientation(glm::quat(glm::radians(glm::vec3(90.0f, 0.0f, 0.0f)))); - } else if (snapshotIndex > 5) { - Snapshot::snapshotTimer.stop(); + config->setOrientation(CAMERA_ORIENTATION_UP); + } else if (_snapshotIndex > 5) { + _snapshotTimer.stop(); // Reset secondary camera render config static_cast(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); + config->setProperty("attachedEntityId", _oldAttachedEntityId); + config->setProperty("vFoV", _oldvFoV); + config->setProperty("nearClipPlaneDistance", _oldNearClipPlaneDistance); + config->setProperty("farClipPlaneDistance", _oldFarClipPlaneDistance); - if (!Snapshot::oldEnabled) { + if (!_oldEnabled) { config->enableSecondaryCameraRenderConfigs(false); } // Process six QImages - if (Snapshot::cubemapOutputFormat) { - QtConcurrent::run(Snapshot::convertToCubemap); + if (_cubemapOutputFormat) { + QtConcurrent::run([this]() { convertToCubemap(); }); } else { - QtConcurrent::run(Snapshot::convertToEquirectangular); + QtConcurrent::run([this]() { convertToEquirectangular(); }); } } - Snapshot::snapshotIndex++; + _snapshotIndex++; } void Snapshot::convertToCubemap() { @@ -217,31 +218,31 @@ void Snapshot::convertToCubemap() { // Paint DownImage destPos = QPoint(CUBEMAP_SIDE_PIXEL_DIMENSION, CUBEMAP_SIDE_PIXEL_DIMENSION * 2.0f); - painter.drawImage(destPos, Snapshot::imageArray[0]); + painter.drawImage(destPos, _imageArray[0]); // Paint FrontImage destPos = QPoint(CUBEMAP_SIDE_PIXEL_DIMENSION, CUBEMAP_SIDE_PIXEL_DIMENSION); - painter.drawImage(destPos, Snapshot::imageArray[1]); + painter.drawImage(destPos, _imageArray[1]); // Paint LeftImage destPos = QPoint(0, CUBEMAP_SIDE_PIXEL_DIMENSION); - painter.drawImage(destPos, Snapshot::imageArray[2]); + painter.drawImage(destPos, _imageArray[2]); // Paint BackImage destPos = QPoint(CUBEMAP_SIDE_PIXEL_DIMENSION * 3.0f, CUBEMAP_SIDE_PIXEL_DIMENSION); - painter.drawImage(destPos, Snapshot::imageArray[3]); + painter.drawImage(destPos, _imageArray[3]); // Paint RightImage destPos = QPoint(CUBEMAP_SIDE_PIXEL_DIMENSION * 2.0f, CUBEMAP_SIDE_PIXEL_DIMENSION); - painter.drawImage(destPos, Snapshot::imageArray[4]); + painter.drawImage(destPos, _imageArray[4]); // Paint UpImage destPos = QPoint(CUBEMAP_SIDE_PIXEL_DIMENSION, 0); - painter.drawImage(destPos, Snapshot::imageArray[5]); + painter.drawImage(destPos, _imageArray[5]); painter.end(); - emit DependencyManager::get()->snapshot360Taken(saveSnapshot(outputImage, Snapshot::snapshotFilename), true); + emit DependencyManager::get()->snapshot360Taken(saveSnapshot(outputImage, _snapshotFilename), true); } void Snapshot::convertToEquirectangular() { @@ -263,19 +264,15 @@ void Snapshot::convertToEquirectangular() { for (int i = 0; i < outputImageWidth; i++) { phi = ((float)i / outputImageWidth) * 2.0f * PI; - float x, y, z; - x = glm::sin(phi) * glm::sin(theta) * -1.0f; - y = glm::cos(theta); - z = glm::cos(phi) * glm::sin(theta) * -1.0f; + float x = glm::sin(phi) * glm::sin(theta) * -1.0f; + float y = glm::cos(theta); + float z = glm::cos(phi) * glm::sin(theta) * -1.0f; - float xa, ya, za; - float a; + float a = std::max(std::max(std::abs(x), std::abs(y)), std::abs(z)); - a = std::max(std::max(std::abs(x), std::abs(y)), std::abs(z)); - - xa = x / a; - ya = y / a; - za = z / a; + float xa = x / a; + float ya = y / a; + float za = z / a; // Pixel in the source images int xPixel, yPixel; @@ -285,32 +282,32 @@ void Snapshot::convertToEquirectangular() { // Right image xPixel = (int)((((za + 1.0f) / 2.0f) - 1.0f) * cubeFaceWidth); yPixel = (int)((((ya + 1.0f) / 2.0f)) * cubeFaceHeight); - sourceImage = Snapshot::imageArray[4]; + sourceImage = _imageArray[4]; } else if (xa == -1) { // Left image xPixel = (int)((((za + 1.0f) / 2.0f)) * cubeFaceWidth); yPixel = (int)((((ya + 1.0f) / 2.0f)) * cubeFaceHeight); - sourceImage = Snapshot::imageArray[2]; + sourceImage = _imageArray[2]; } else if (ya == 1) { // Down image xPixel = (int)((((xa + 1.0f) / 2.0f)) * cubeFaceWidth); yPixel = (int)((((za + 1.0f) / 2.0f) - 1.0f) * cubeFaceHeight); - sourceImage = Snapshot::imageArray[0]; + sourceImage = _imageArray[0]; } else if (ya == -1) { // Up image xPixel = (int)((((xa + 1.0f) / 2.0f)) * cubeFaceWidth); yPixel = (int)((((za + 1.0f) / 2.0f)) * cubeFaceHeight); - sourceImage = Snapshot::imageArray[5]; + sourceImage = _imageArray[5]; } else if (za == 1) { // Front image xPixel = (int)((((xa + 1.0f) / 2.0f)) * cubeFaceWidth); yPixel = (int)((((ya + 1.0f) / 2.0f)) * cubeFaceHeight); - sourceImage = Snapshot::imageArray[1]; + sourceImage = _imageArray[1]; } else if (za == -1) { // Back image xPixel = (int)((((xa + 1.0f) / 2.0f) - 1.0f) * cubeFaceWidth); yPixel = (int)((((ya + 1.0f) / 2.0f)) * cubeFaceHeight); - sourceImage = Snapshot::imageArray[3]; + sourceImage = _imageArray[3]; } else { qDebug() << "Unknown face encountered when processing 360 Snapshot"; xPixel = 0; @@ -325,7 +322,7 @@ void Snapshot::convertToEquirectangular() { } } - emit DependencyManager::get()->snapshot360Taken(saveSnapshot(outputImage, Snapshot::snapshotFilename), true); + emit DependencyManager::get()->snapshot360Taken(saveSnapshot(outputImage, _snapshotFilename), true); } QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { @@ -363,12 +360,12 @@ QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QSt if (!userSelectedPathname.isNull()) { snapshotFullPath = userSelectedPathname; } else { - snapshotFullPath = snapshotsLocation.get(); + snapshotFullPath = _snapshotsLocation.get(); } if (snapshotFullPath.isEmpty()) { snapshotFullPath = OffscreenUi::getExistingDirectory(nullptr, "Choose Snapshots Directory", QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); - snapshotsLocation.set(snapshotFullPath); + _snapshotsLocation.set(snapshotFullPath); } if (!snapshotFullPath.isEmpty()) { // not cancelled @@ -450,9 +447,9 @@ void Snapshot::uploadSnapshot(const QString& filename, const QUrl& href) { } QString Snapshot::getSnapshotsLocation() { - return snapshotsLocation.get(""); + return _snapshotsLocation.get(""); } void Snapshot::setSnapshotsLocation(const QString& location) { - snapshotsLocation.set(location); + _snapshotsLocation.set(location); } diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index dca4a54ba9..ba9bd21cea 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -40,13 +41,13 @@ class Snapshot : public QObject, public Dependency { SINGLETON_DEPENDENCY public: Snapshot(); - static QString saveSnapshot(QImage image, const QString& filename, const QString& pathname = QString()); - static void save360Snapshot(const glm::vec3& cameraPosition, const bool& cubemapOutputFormat, const QString& filename); - static QTemporaryFile* saveTempSnapshot(QImage image); - static SnapshotMetaData* parseSnapshotData(QString snapshotPath); + QString saveSnapshot(QImage image, const QString& filename, const QString& pathname = QString()); + void save360Snapshot(const glm::vec3& cameraPosition, const bool& cubemapOutputFormat, const QString& filename); + QTemporaryFile* saveTempSnapshot(QImage image); + SnapshotMetaData* parseSnapshotData(QString snapshotPath); - static Setting::Handle snapshotsLocation; - static void uploadSnapshot(const QString& filename, const QUrl& href = QUrl("")); + Setting::Handle _snapshotsLocation{ "snapshotsLocation" }; + void uploadSnapshot(const QString& filename, const QUrl& href = QUrl("")); signals: void snapshotLocationSet(const QString& value); @@ -56,26 +57,26 @@ public slots: Q_INVOKABLE void setSnapshotsLocation(const QString& location); private slots: - static void takeNextSnapshot(); + void takeNextSnapshot(); private: - static QFile* savedFileForSnapshot(QImage& image, + QFile* savedFileForSnapshot(QImage& image, bool isTemporary, const QString& userSelectedFilename = QString(), const QString& userSelectedPathname = QString()); - static QString snapshotFilename; - static bool cubemapOutputFormat; - static QTimer snapshotTimer; - static qint16 snapshotIndex; - static bool oldEnabled; - static QVariant oldAttachedEntityId; - static QVariant oldOrientation; - static QVariant oldvFoV; - static QVariant oldNearClipPlaneDistance; - static QVariant oldFarClipPlaneDistance; - static QImage imageArray[6]; - static void convertToCubemap(); - static void convertToEquirectangular(); + QString _snapshotFilename; + bool _cubemapOutputFormat; + QTimer _snapshotTimer; + qint16 _snapshotIndex; + bool _oldEnabled; + QVariant _oldAttachedEntityId; + QVariant _oldOrientation; + QVariant _oldvFoV; + QVariant _oldNearClipPlaneDistance; + QVariant _oldFarClipPlaneDistance; + QImage _imageArray[6]; + void convertToCubemap(); + void convertToEquirectangular(); }; #endif // hifi_Snapshot_h