mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 02:16:51 +02:00
Tons of stability and clarity improvements
This commit is contained in:
parent
c115f2bd36
commit
249e2a2bac
5 changed files with 97 additions and 67 deletions
|
@ -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}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue