mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 17:03:58 +02:00
Merge pull request #4436 from sethalves/persist-entities-as-json
Optionally persist entities as json
This commit is contained in:
commit
a5294ae3fa
20 changed files with 439 additions and 25 deletions
|
@ -1036,6 +1036,13 @@ void OctreeServer::readConfiguration() {
|
|||
strcpy(_persistFilename, qPrintable(persistFilename));
|
||||
qDebug("persistFilename=%s", _persistFilename);
|
||||
|
||||
QString persistAsFileType;
|
||||
if (!readOptionString(QString("persistAsFileType"), settingsSectionObject, persistAsFileType)) {
|
||||
persistAsFileType = "svo";
|
||||
}
|
||||
_persistAsFileType = persistAsFileType;
|
||||
qDebug() << "persistAsFileType=" << _persistAsFileType;
|
||||
|
||||
_persistInterval = OctreePersistThread::DEFAULT_PERSIST_INTERVAL;
|
||||
readOptionInt(QString("persistInterval"), settingsSectionObject, _persistInterval);
|
||||
qDebug() << "persistInterval=" << _persistInterval;
|
||||
|
@ -1131,7 +1138,7 @@ void OctreeServer::run() {
|
|||
|
||||
// now set up PersistThread
|
||||
_persistThread = new OctreePersistThread(_tree, _persistFilename, _persistInterval,
|
||||
_wantBackup, _settings, _debugTimestampNow);
|
||||
_wantBackup, _settings, _debugTimestampNow, _persistAsFileType);
|
||||
if (_persistThread) {
|
||||
_persistThread->initialize(true);
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ protected:
|
|||
QString _statusHost;
|
||||
|
||||
char _persistFilename[MAX_FILENAME_LENGTH];
|
||||
QString _persistAsFileType;
|
||||
int _packetsPerClientPerInterval;
|
||||
int _packetsTotalPerInterval;
|
||||
Octree* _tree; // this IS a reaveraging tree
|
||||
|
|
|
@ -325,6 +325,24 @@
|
|||
"default": "resources/models.svo",
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
"name": "persistAsFileType",
|
||||
"label": "File format for entity server's persistent data",
|
||||
"help": "This defines how the entity server will save entities to disk.",
|
||||
"default": "svo",
|
||||
"type": "select",
|
||||
"options": [
|
||||
{
|
||||
"value": "svo",
|
||||
"label": "Entity server persists data as SVO"
|
||||
},
|
||||
{
|
||||
"value": "json",
|
||||
"label": "Entity server persists data as JSON"
|
||||
}
|
||||
],
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
"name": "persistInterval",
|
||||
"label": "Save Check Interval",
|
||||
|
|
|
@ -1798,7 +1798,7 @@ bool Application::importEntities(const QString& urlOrFilename) {
|
|||
url = QUrl::fromLocalFile(urlOrFilename);
|
||||
}
|
||||
|
||||
bool success = _entityClipboard.readFromSVOURL(url.toString());
|
||||
bool success = _entityClipboard.readFromURL(url.toString());
|
||||
if (success) {
|
||||
_entityClipboard.reaverageOctreeElements();
|
||||
}
|
||||
|
|
|
@ -187,7 +187,9 @@ void buildStringToShapeTypeLookup() {
|
|||
}
|
||||
|
||||
QString EntityItemProperties::getShapeTypeAsString() const {
|
||||
return QString(shapeTypeNames[_shapeType]);
|
||||
if (_shapeType < sizeof(shapeTypeNames) / sizeof(char *))
|
||||
return QString(shapeTypeNames[_shapeType]);
|
||||
return QString("none");
|
||||
}
|
||||
|
||||
void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) {
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <VariantMapToScriptValue.h>
|
||||
|
||||
#include "EntityScriptingInterface.h"
|
||||
#include "EntityTree.h"
|
||||
#include "LightEntityItem.h"
|
||||
|
|
|
@ -10,13 +10,18 @@
|
|||
//
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <QDateTime>
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include "EntityTree.h"
|
||||
#include "EntitySimulation.h"
|
||||
#include "VariantMapToScriptValue.h"
|
||||
|
||||
#include "AddEntityOperator.h"
|
||||
#include "MovingEntitiesOperator.h"
|
||||
#include "UpdateEntityOperator.h"
|
||||
#include "QVariantGLM.h"
|
||||
#include "RecurseOctreeToMapOperator.h"
|
||||
|
||||
EntityTree::EntityTree(bool shouldReaverage) :
|
||||
Octree(shouldReaverage),
|
||||
|
@ -466,7 +471,7 @@ bool EntityTree::findNearPointOperation(OctreeElement* element, void* extraData)
|
|||
return true; // keep searching in case children have closer entities
|
||||
}
|
||||
|
||||
// if this element doesn't contain the point, then none of it's children can contain the point, so stop searching
|
||||
// if this element doesn't contain the point, then none of its children can contain the point, so stop searching
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1080,3 +1085,41 @@ bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElement* element) {
|
||||
entityDescription["Entities"] = QVariantList();
|
||||
QScriptEngine scriptEngine;
|
||||
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine);
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntityTree::readFromMap(QVariantMap& map) {
|
||||
// map will have a top-level list keyed as "Entities". This will be extracted
|
||||
// and iterated over. Each member of this list is converted to a QVariantMap, then
|
||||
// to a QScriptValue, and then to EntityItemProperties. These properties are used
|
||||
// to add the new entity to the EnitytTree.
|
||||
QVariantList entitiesQList = map["Entities"].toList();
|
||||
QScriptEngine scriptEngine;
|
||||
|
||||
foreach (QVariant entityVariant, entitiesQList) {
|
||||
// QVariantMap --> QScriptValue --> EntityItemProperties --> Entity
|
||||
QVariantMap entityMap = entityVariant.toMap();
|
||||
QScriptValue entityScriptValue = variantMapToScriptValue(entityMap, scriptEngine);
|
||||
EntityItemProperties properties;
|
||||
EntityItemPropertiesFromScriptValue(entityScriptValue, properties);
|
||||
|
||||
EntityItemID entityItemID;
|
||||
if (entityMap.contains("id")) {
|
||||
entityItemID = EntityItemID(QUuid(entityMap["id"].toString()));
|
||||
} else {
|
||||
entityItemID = EntityItemID(QUuid::createUuid());
|
||||
}
|
||||
|
||||
EntityItem* entity = addEntity(entityItemID, properties);
|
||||
if (!entity) {
|
||||
qDebug() << "adding Entity failed:" << entityItemID << entity->getType();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -164,6 +164,9 @@ public:
|
|||
bool wantEditLogging() const { return _wantEditLogging; }
|
||||
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
||||
|
||||
bool writeToMap(QVariantMap& entityDescription, OctreeElement* element);
|
||||
bool readFromMap(QVariantMap& entityDescription);
|
||||
|
||||
signals:
|
||||
void deletingEntity(const EntityItemID& entityID);
|
||||
void addingEntity(const EntityItemID& entityID);
|
||||
|
|
54
libraries/entities/src/RecurseOctreeToMapOperator.cpp
Normal file
54
libraries/entities/src/RecurseOctreeToMapOperator.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// RecurseOctreeToMapOperator.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 3/16/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "RecurseOctreeToMapOperator.h"
|
||||
|
||||
|
||||
RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine) :
|
||||
RecurseOctreeOperator(),
|
||||
_map(map),
|
||||
_top(top),
|
||||
_engine(engine)
|
||||
{
|
||||
// if some element "top" was given, only save information for that element and it's children.
|
||||
if (_top) {
|
||||
_withinTop = false;
|
||||
} else {
|
||||
// top was NULL, export entire tree.
|
||||
_withinTop = true;
|
||||
}
|
||||
};
|
||||
|
||||
bool RecurseOctreeToMapOperator::preRecursion(OctreeElement* element) {
|
||||
if (element == _top) {
|
||||
_withinTop = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
||||
|
||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
||||
|
||||
QVariantList entitiesQList = qvariant_cast<QVariantList>(_map["Entities"]);
|
||||
|
||||
foreach (EntityItem* entityItem, entities) {
|
||||
EntityItemProperties properties = entityItem->getProperties();
|
||||
QScriptValue qScriptValues = EntityItemPropertiesToScriptValue(_engine, properties);
|
||||
entitiesQList << qScriptValues.toVariant();
|
||||
}
|
||||
_map["Entities"] = entitiesQList;
|
||||
if (element == _top) {
|
||||
_withinTop = false;
|
||||
}
|
||||
return true;
|
||||
}
|
24
libraries/entities/src/RecurseOctreeToMapOperator.h
Normal file
24
libraries/entities/src/RecurseOctreeToMapOperator.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// RecurseOctreeToMapOperator.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 3/16/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityTree.h"
|
||||
|
||||
class RecurseOctreeToMapOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine);
|
||||
bool preRecursion(OctreeElement* element);
|
||||
bool postRecursion(OctreeElement* element);
|
||||
private:
|
||||
QVariantMap& _map;
|
||||
OctreeElement *_top;
|
||||
QScriptEngine *_engine;
|
||||
bool _withinTop;
|
||||
};
|
|
@ -27,6 +27,10 @@
|
|||
#include <QNetworkReply>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QVector>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
|
||||
#include <GeometryUtil.h>
|
||||
#include <LogHandler.h>
|
||||
|
@ -35,6 +39,7 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <Shape.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "CoverageMap.h"
|
||||
#include "OctreeConstants.h"
|
||||
|
@ -42,6 +47,9 @@
|
|||
#include "Octree.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
|
||||
QVector<QString> PERSIST_EXTENSIONS = {"svo", "json"};
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) {
|
||||
return voxelSizeScale / powf(2, renderLevel);
|
||||
}
|
||||
|
@ -1841,21 +1849,22 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
|||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
bool Octree::readFromSVOFile(const char* fileName) {
|
||||
bool Octree::readFromFile(const char* fileName) {
|
||||
bool fileOk = false;
|
||||
|
||||
QFile file(fileName);
|
||||
QString qFileName = findMostRecentFileExtension(fileName, PERSIST_EXTENSIONS);
|
||||
QFile file(qFileName);
|
||||
fileOk = file.open(QIODevice::ReadOnly);
|
||||
|
||||
if(fileOk) {
|
||||
QDataStream fileInputStream(&file);
|
||||
QFileInfo fileInfo(fileName);
|
||||
QFileInfo fileInfo(qFileName);
|
||||
unsigned long fileLength = fileInfo.size();
|
||||
|
||||
emit importSize(1.0f, 1.0f, 1.0f);
|
||||
emit importProgress(0);
|
||||
|
||||
qDebug("Loading file %s...", fileName);
|
||||
qDebug() << "Loading file" << qFileName << "...";
|
||||
|
||||
fileOk = readFromStream(fileLength, fileInputStream);
|
||||
|
||||
|
@ -1866,14 +1875,14 @@ bool Octree::readFromSVOFile(const char* fileName) {
|
|||
return fileOk;
|
||||
}
|
||||
|
||||
bool Octree::readFromSVOURL(const QString& urlString) {
|
||||
bool Octree::readFromURL(const QString& urlString) {
|
||||
bool readOk = false;
|
||||
|
||||
// determine if this is a local file or a network resource
|
||||
QUrl url(urlString);
|
||||
|
||||
if (url.isLocalFile()) {
|
||||
readOk = readFromSVOFile(qPrintable(url.toLocalFile()));
|
||||
readOk = readFromFile(qPrintable(url.toLocalFile()));
|
||||
} else {
|
||||
QNetworkRequest request;
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
|
@ -1899,6 +1908,23 @@ bool Octree::readFromSVOURL(const QString& urlString) {
|
|||
|
||||
|
||||
bool Octree::readFromStream(unsigned long streamLength, QDataStream& inputStream) {
|
||||
|
||||
// decide if this is SVO or JSON
|
||||
QIODevice *device = inputStream.device();
|
||||
char firstChar;
|
||||
device->getChar(&firstChar);
|
||||
device->ungetChar(firstChar);
|
||||
|
||||
if (firstChar == (char) PacketTypeEntityData) {
|
||||
return readSVOFromStream(streamLength, inputStream);
|
||||
} else {
|
||||
return readJSONFromStream(streamLength, inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStream) {
|
||||
|
||||
bool fileOk = false;
|
||||
|
||||
PacketVersion gotVersion = 0;
|
||||
|
@ -2026,6 +2052,53 @@ bool Octree::readFromStream(unsigned long streamLength, QDataStream& inputStream
|
|||
return fileOk;
|
||||
}
|
||||
|
||||
bool Octree::readJSONFromStream(unsigned long streamLength, QDataStream& inputStream) {
|
||||
char *rawData = new char[streamLength];
|
||||
inputStream.readRawData(rawData, streamLength);
|
||||
QJsonDocument d = QJsonDocument::fromJson(rawData);
|
||||
QVariant v = d.toVariant();
|
||||
QVariantMap m = v.toMap();
|
||||
readFromMap(m);
|
||||
delete rawData;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Octree::writeToFile(const char* fileName, OctreeElement* element, QString persistAsFileType) {
|
||||
// make the sure file extension makes sense
|
||||
QString qFileName = fileNameWithoutExtension(QString(fileName), PERSIST_EXTENSIONS) + "." + persistAsFileType;
|
||||
QByteArray byteArray = qFileName.toUtf8();
|
||||
const char* cFileName = byteArray.constData();
|
||||
|
||||
if (persistAsFileType == "svo") {
|
||||
writeToSVOFile(fileName, element);
|
||||
} else if (persistAsFileType == "json") {
|
||||
writeToJSONFile(cFileName, element);
|
||||
} else {
|
||||
qDebug() << "unable to write octree to file of type" << persistAsFileType;
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) {
|
||||
QFile persistFile(fileName);
|
||||
QVariantMap entityDescription;
|
||||
|
||||
qDebug("Saving to file %s...", fileName);
|
||||
|
||||
OctreeElement* top;
|
||||
if (element) {
|
||||
top = element;
|
||||
} else {
|
||||
top = _rootElement;
|
||||
}
|
||||
|
||||
bool entityDescriptionSuccess = writeToMap(entityDescription, top);
|
||||
if (entityDescriptionSuccess && persistFile.open(QIODevice::WriteOnly)) {
|
||||
persistFile.write(QJsonDocument::fromVariant(entityDescription).toJson());
|
||||
} else {
|
||||
qCritical("Could not write to JSON description of entities.");
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) {
|
||||
std::ofstream file(fileName, std::ios::out|std::ios::binary);
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@ class Shape;
|
|||
#include <QObject>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
|
||||
extern QVector<QString> PERSIST_EXTENSIONS;
|
||||
|
||||
/// derive from this class to use the Octree::recurseTreeWithOperator() method
|
||||
class RecurseOctreeOperator {
|
||||
public:
|
||||
|
@ -324,13 +327,19 @@ public:
|
|||
// Note: this assumes the fileFormat is the HIO individual voxels code files
|
||||
void loadOctreeFile(const char* fileName, bool wantColorRandomizer);
|
||||
|
||||
// these will read/write files that match the wireformat, excluding the 'V' leading
|
||||
// Octree exporters
|
||||
void writeToFile(const char* filename, OctreeElement* element = NULL, QString persistAsFileType = "svo");
|
||||
void writeToJSONFile(const char* filename, OctreeElement* element = NULL);
|
||||
void writeToSVOFile(const char* filename, OctreeElement* element = NULL);
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElement* element) = 0;
|
||||
|
||||
bool readFromSVOFile(const char* filename);
|
||||
bool readFromSVOURL(const QString& url); // will support file urls as well...
|
||||
// Octree importers
|
||||
bool readFromFile(const char* filename);
|
||||
bool readFromURL(const QString& url); // will support file urls as well...
|
||||
bool readFromStream(unsigned long streamLength, QDataStream& inputStream);
|
||||
|
||||
bool readSVOFromStream(unsigned long streamLength, QDataStream& inputStream);
|
||||
bool readJSONFromStream(unsigned long streamLength, QDataStream& inputStream);
|
||||
virtual bool readFromMap(QVariantMap& entityDescription) = 0;
|
||||
|
||||
unsigned long getOctreeElementsCount();
|
||||
|
||||
|
|
|
@ -20,16 +20,19 @@
|
|||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "OctreePersistThread.h"
|
||||
|
||||
const int OctreePersistThread::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds
|
||||
|
||||
OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval,
|
||||
bool wantBackup, const QJsonObject& settings, bool debugTimestampNow) :
|
||||
bool wantBackup, const QJsonObject& settings, bool debugTimestampNow,
|
||||
QString persistAsFileType) :
|
||||
_tree(tree),
|
||||
_filename(filename),
|
||||
_persistInterval(persistInterval),
|
||||
|
@ -38,9 +41,14 @@ OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename,
|
|||
_lastCheck(0),
|
||||
_wantBackup(wantBackup),
|
||||
_debugTimestampNow(debugTimestampNow),
|
||||
_lastTimeDebug(0)
|
||||
_lastTimeDebug(0),
|
||||
_persistAsFileType(persistAsFileType)
|
||||
{
|
||||
parseSettings(settings);
|
||||
|
||||
// in case the persist filename has an extension that doesn't match the file type
|
||||
QString sansExt = fileNameWithoutExtension(_filename, PERSIST_EXTENSIONS);
|
||||
_filename = sansExt + "." + _persistAsFileType;
|
||||
}
|
||||
|
||||
void OctreePersistThread::parseSettings(const QJsonObject& settings) {
|
||||
|
@ -140,7 +148,7 @@ bool OctreePersistThread::process() {
|
|||
qDebug() << "Loading Octree... lock file removed:" << lockFileName;
|
||||
}
|
||||
|
||||
persistantFileRead = _tree->readFromSVOFile(_filename.toLocal8Bit().constData());
|
||||
persistantFileRead = _tree->readFromFile(qPrintable(_filename.toLocal8Bit()));
|
||||
_tree->pruneTree();
|
||||
}
|
||||
_tree->unlock();
|
||||
|
@ -242,9 +250,7 @@ void OctreePersistThread::persist() {
|
|||
if(lockFile.is_open()) {
|
||||
qDebug() << "saving Octree lock file created at:" << lockFileName;
|
||||
|
||||
qDebug() << "saving Octree to file " << _filename << "...";
|
||||
|
||||
_tree->writeToSVOFile(qPrintable(_filename));
|
||||
_tree->writeToFile(qPrintable(_filename), NULL, _persistAsFileType);
|
||||
time(&_lastPersistTime);
|
||||
_tree->clearDirtyBit(); // tree is clean after saving
|
||||
qDebug() << "DONE saving Octree to file...";
|
||||
|
@ -346,8 +352,8 @@ void OctreePersistThread::rollOldBackupVersions(const BackupRule& rule) {
|
|||
QString backupExtensionNplusOne = rule.extensionFormat;
|
||||
backupExtensionN.replace(QString("%N"), QString::number(n));
|
||||
backupExtensionNplusOne.replace(QString("%N"), QString::number(n+1));
|
||||
|
||||
QString backupFilenameN = _filename + backupExtensionN;
|
||||
|
||||
QString backupFilenameN = findMostRecentFileExtension(_filename, PERSIST_EXTENSIONS) + backupExtensionN;
|
||||
QString backupFilenameNplusOne = _filename + backupExtensionNplusOne;
|
||||
|
||||
QFile backupFileN(backupFilenameN);
|
||||
|
|
|
@ -34,8 +34,8 @@ public:
|
|||
static const int DEFAULT_PERSIST_INTERVAL;
|
||||
|
||||
OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL,
|
||||
bool wantBackup = false, const QJsonObject& settings = QJsonObject(),
|
||||
bool debugTimestampNow = false);
|
||||
bool wantBackup = false, const QJsonObject& settings = QJsonObject(),
|
||||
bool debugTimestampNow = false, QString persistAsFileType="svo");
|
||||
|
||||
bool isInitialLoadComplete() const { return _initialLoadComplete; }
|
||||
quint64 getLoadElapsedTime() const { return _loadTimeUSecs; }
|
||||
|
@ -72,6 +72,8 @@ private:
|
|||
|
||||
bool _debugTimestampNow;
|
||||
quint64 _lastTimeDebug;
|
||||
|
||||
QString _persistAsFileType;
|
||||
};
|
||||
|
||||
#endif // hifi_OctreePersistThread_h
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "PathUtils.h"
|
||||
|
||||
|
@ -23,3 +26,30 @@ QString& PathUtils::resourcesPath() {
|
|||
#endif
|
||||
return staticResourcePath;
|
||||
}
|
||||
|
||||
|
||||
QString fileNameWithoutExtension(const QString& fileName, const QVector<QString> possibleExtensions) {
|
||||
foreach (const QString possibleExtension, possibleExtensions) {
|
||||
if (fileName.endsWith(possibleExtension) ||
|
||||
fileName.endsWith(possibleExtension.toUpper()) ||
|
||||
fileName.endsWith(possibleExtension.toLower())) {
|
||||
return fileName.left(fileName.count() - possibleExtension.count() - 1);
|
||||
}
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
QString findMostRecentFileExtension(const QString& originalFileName, QVector<QString> possibleExtensions) {
|
||||
QString sansExt = fileNameWithoutExtension(originalFileName, possibleExtensions);
|
||||
QString newestFileName = originalFileName;
|
||||
QDateTime newestTime = QDateTime::fromMSecsSinceEpoch(0);
|
||||
foreach (QString possibleExtension, possibleExtensions) {
|
||||
QString fileName = sansExt + "." + possibleExtension;
|
||||
QFileInfo fileInfo(fileName);
|
||||
if (fileInfo.exists() && fileInfo.lastModified() > newestTime) {
|
||||
newestFileName = fileName;
|
||||
newestTime = fileInfo.lastModified();
|
||||
}
|
||||
}
|
||||
return newestFileName;
|
||||
}
|
||||
|
|
|
@ -19,4 +19,7 @@ namespace PathUtils {
|
|||
QString& resourcesPath();
|
||||
}
|
||||
|
||||
#endif // hifi_PathUtils_h
|
||||
QString fileNameWithoutExtension(const QString& fileName, const QVector<QString> possibleExtensions);
|
||||
QString findMostRecentFileExtension(const QString& originalFileName, QVector<QString> possibleExtensions);
|
||||
|
||||
#endif // hifi_PathUtils_h
|
||||
|
|
48
libraries/shared/src/QVariantGLM.cpp
Normal file
48
libraries/shared/src/QVariantGLM.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// QVariantGLM.cpp
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Seth Alves on 3/9/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "QVariantGLM.h"
|
||||
#include "OctalCode.h"
|
||||
|
||||
QVariantList glmToQList(const glm::vec3& g) {
|
||||
return QVariantList() << g[0] << g[1] << g[2];
|
||||
}
|
||||
|
||||
QVariantList glmToQList(const glm::quat& g) {
|
||||
return QVariantList() << g.x << g.y << g.z << g.w;
|
||||
}
|
||||
|
||||
QVariantList rgbColorToQList(rgbColor& v) {
|
||||
return QVariantList() << (int)(v[0]) << (int)(v[1]) << (int)(v[2]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
glm::vec3 qListToGlmVec3(const QVariant q) {
|
||||
QVariantList qList = q.toList();
|
||||
return glm::vec3(qList[RED_INDEX].toFloat(), qList[GREEN_INDEX].toFloat(), qList[BLUE_INDEX].toFloat());
|
||||
}
|
||||
|
||||
glm::quat qListToGlmQuat(const QVariant q) {
|
||||
QVariantList qList = q.toList();
|
||||
float x = qList[0].toFloat();
|
||||
float y = qList[1].toFloat();
|
||||
float z = qList[2].toFloat();
|
||||
float w = qList[3].toFloat();
|
||||
return glm::quat(w, x, y, z);
|
||||
}
|
||||
|
||||
void qListtoRgbColor(const QVariant q, rgbColor returnValue) {
|
||||
QVariantList qList = q.toList();
|
||||
returnValue[RED_INDEX] = qList[RED_INDEX].toInt();
|
||||
returnValue[GREEN_INDEX] = qList[GREEN_INDEX].toInt();
|
||||
returnValue[BLUE_INDEX] = qList[BLUE_INDEX].toInt();
|
||||
}
|
26
libraries/shared/src/QVariantGLM.h
Normal file
26
libraries/shared/src/QVariantGLM.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// QVariantGLM.h
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Seth Alves on 3/9/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QVariantList>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
|
||||
QVariantList glmToQList(const glm::vec3& g);
|
||||
QVariantList glmToQList(const glm::quat& g);
|
||||
QVariantList rgbColorToQList(rgbColor& v);
|
||||
|
||||
glm::vec3 qListToGlmVec3(const QVariant q);
|
||||
glm::quat qListToGlmQuat(const QVariant q);
|
||||
void qListtoRgbColor(const QVariant q, rgbColor returnValue);
|
47
libraries/shared/src/VariantMapToScriptValue.cpp
Normal file
47
libraries/shared/src/VariantMapToScriptValue.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// VariantMapToScriptValue.cpp
|
||||
// libraries/shared/src/
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QDebug>
|
||||
#include "VariantMapToScriptValue.h"
|
||||
|
||||
QScriptValue variantMapToScriptValue(QVariantMap& variantMap, QScriptEngine& scriptEngine) {
|
||||
QScriptValue scriptValue = scriptEngine.newObject();
|
||||
|
||||
for (QVariantMap::const_iterator iter = variantMap.begin(); iter != variantMap.end(); ++iter) {
|
||||
QString key = iter.key();
|
||||
QVariant qValue = iter.value();
|
||||
|
||||
switch(qValue.type()) {
|
||||
case QVariant::Bool:
|
||||
scriptValue.setProperty(key, qValue.toBool());
|
||||
break;
|
||||
case QVariant::Int:
|
||||
scriptValue.setProperty(key, qValue.toInt());
|
||||
break;
|
||||
case QVariant::Double:
|
||||
scriptValue.setProperty(key, qValue.toDouble());
|
||||
break;
|
||||
case QVariant::String: {
|
||||
scriptValue.setProperty(key, scriptEngine.newVariant(qValue));
|
||||
break;
|
||||
}
|
||||
case QVariant::Map: {
|
||||
QVariantMap childMap = qValue.toMap();
|
||||
scriptValue.setProperty(key, variantMapToScriptValue(childMap, scriptEngine));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qDebug() << "unhandled QScript type" << qValue.type();
|
||||
}
|
||||
}
|
||||
|
||||
return scriptValue;
|
||||
}
|
16
libraries/shared/src/VariantMapToScriptValue.h
Normal file
16
libraries/shared/src/VariantMapToScriptValue.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// VariantMapToScriptValue.h
|
||||
// libraries/shared/src/
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QVariant>
|
||||
#include <QScriptValue>
|
||||
#include <QScriptEngine>
|
||||
|
||||
QScriptValue variantMapToScriptValue(QVariantMap& variantMap, QScriptEngine& scriptEngine);
|
Loading…
Reference in a new issue