diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 572f42bdee..19510693d9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -86,7 +86,7 @@ const float MIRROR_FULLSCREEN_DISTANCE = 0.35f; const float MIRROR_REARVIEW_DISTANCE = 0.65f; const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f; -const char* LOCAL_VOXEL_CACHE = "/Users/brad/local_voxel_cache.svo"; +//const char* LOCAL_VOXEL_CACHE = "/Users/brad/local_voxel_cache.svo"; void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) { @@ -181,7 +181,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : nodeList->addHook(&_voxels); nodeList->addHook(this); nodeList->addDomainListener(this); - nodeList->addDomainListener(&_voxels); // network receive thread and voxel parsing thread are both controlled by the --nonblocking command line _enableProcessVoxelsThread = _enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking"); @@ -254,13 +253,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // Set the sixense filtering _sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense)); - _persistThread = new OctreePersistThread(_voxels.getTree(), LOCAL_VOXEL_CACHE); - - if (_persistThread) { - _voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates - connect(_persistThread, SIGNAL(loadCompleted()), &_voxels, SLOT(localVoxelCacheLoaded())); - _persistThread->initialize(true); - } } Application::~Application() { @@ -1950,6 +1942,9 @@ void Application::init() { connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView())); connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView())); connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors())); + + + updateLocalOctreeCache(true); } void Application::closeMirrorView() { @@ -4215,6 +4210,10 @@ void Application::domainChanged(QString domain) { _voxelServerJurisdictions.clear(); _octreeServerSceneStats.clear(); _particleServerJurisdictions.clear(); + + // reset our persist thread + qDebug() << "domainChanged()... domain=" << domain << " swapping persist cache\n"; + updateLocalOctreeCache(); } void Application::nodeAdded(Node* node) { @@ -4554,4 +4553,43 @@ void Application::toggleLogDialog() { void Application::initAvatarAndViewFrustum() { updateAvatar(0.f); +} + +QString Application::getLocalVoxelCacheFileName() { + QString fileName = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + QDir logDir(fileName); + if (!logDir.exists(fileName)) { + logDir.mkdir(fileName); + } + + fileName.append(QString("/hifi.voxelscache.")); + fileName.append(_profile.getLastDomain()); + fileName.append(QString(".svo")); + + return fileName; +} + + +void Application::updateLocalOctreeCache(bool firstTime) { + // only do this if we've already got a persistThread or we're told this is the first time + if (firstTime || _persistThread) { + + if (_persistThread) { + _persistThread->terminate(); + _persistThread = NULL; + } + + QString localVoxelCacheFileName = getLocalVoxelCacheFileName(); + const int LOCAL_CACHE_PERSIST_INTERVAL = 1000 * 10; // every 10 seconds + _persistThread = new OctreePersistThread(_voxels.getTree(), + localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL); + + qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName << "\n"; + + if (_persistThread) { + _voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates + connect(_persistThread, SIGNAL(loadCompleted()), &_voxels, SLOT(localVoxelCacheLoaded())); + _persistThread->initialize(true); + } + } } \ No newline at end of file diff --git a/interface/src/Application.h b/interface/src/Application.h index f36ad28a5d..19f9a74a3b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -515,6 +515,9 @@ private: FileLogger* _logger; OctreePersistThread* _persistThread; + + QString getLocalVoxelCacheFileName(); + void updateLocalOctreeCache(bool firstTime = false); }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index e0b2decfaf..ede9a8e15d 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -117,7 +117,6 @@ void VoxelSystem::elementDeleted(OctreeElement* element) { VoxelTreeElement* voxel = (VoxelTreeElement*)element; if (voxel->getVoxelSystem() == this) { if (_voxelsInWriteArrays != 0) { -qDebug() << "elementDeleted()... about to call forceRemoveNodeFromArrays()\n"; forceRemoveNodeFromArrays(voxel); } else { if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { @@ -706,6 +705,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { bool extraDebugging = Application::getInstance()->getLogger()->extraDebugging(); if (extraDebugging) { qDebug("setupNewVoxelsForDrawing()... _voxelsUpdated=%lu...\n",_voxelsUpdated); + _viewFrustum->printDebugDetails(); } } @@ -2712,11 +2712,6 @@ void VoxelSystem::nodeKilled(Node* node) { } } -void VoxelSystem::domainChanged(QString domain) { - killLocalVoxels(); -} - - unsigned long VoxelSystem::getFreeMemoryGPU() { // We can't ask all GPUs how much memory they have in use, but we can ask them about how much is free. // So, we can record the free memory before we create our VBOs and the free memory after, and get a basic @@ -2787,7 +2782,9 @@ void VoxelSystem::localVoxelCacheLoaded() { // Make sure that the application has properly set up the view frustum for our loaded state Application::getInstance()->initAvatarAndViewFrustum(); - _tree->setDirtyBit(); + _tree->setDirtyBit(); // make sure the tree thinks it's dirty + _setupNewVoxelsForDrawingLastFinished = 0; // don't allow the setupNewVoxelsForDrawing() shortcuts + _writeRenderFullVBO = true; // this will disable individual node updates, was reset by killLocalVoxels() setupNewVoxelsForDrawing(); _inhideOutOfView = false; // reenable hideOutOfView behavior } @@ -2796,6 +2793,8 @@ void VoxelSystem::beginLoadingLocalVoxelCache() { qDebug() << "beginLoadingLocalVoxelCache()\n"; _writeRenderFullVBO = true; // this will disable individual node updates _inhideOutOfView = true; // this will disable hidOutOfView which we want to do until local cache is loaded + killLocalVoxels(); + qDebug() << "DONE beginLoadingLocalVoxelCache()\n"; } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 8173652e55..e9f0cc47ab 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -38,7 +38,7 @@ struct VoxelShaderVBOData class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook, - public NodeListHook, public DomainChangeListener { + public NodeListHook { Q_OBJECT friend class VoxelHideShowThread; @@ -114,7 +114,6 @@ public: virtual void elementUpdated(OctreeElement* element); virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); - virtual void domainChanged(QString domain); bool treeIsBusy() const { return _treeIsBusy; } diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index 08a7cffbb8..b986f457bc 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -14,7 +14,7 @@ #include "OctreePersistThread.h" -OctreePersistThread::OctreePersistThread(Octree* tree, const char* filename, int persistInterval) : +OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval) : _tree(tree), _filename(filename), _persistInterval(persistInterval), @@ -26,14 +26,14 @@ bool OctreePersistThread::process() { if (!_initialLoadComplete) { uint64_t loadStarted = usecTimestampNow(); - qDebug("loading Octrees from file: %s...\n", _filename); + qDebug() << "loading Octrees from file: " << _filename << "...\n"; bool persistantFileRead; _tree->lockForWrite(); { PerformanceWarning warn(true, "Loading Octree File", true); - persistantFileRead = _tree->readFromSVOFile(_filename); + persistantFileRead = _tree->readFromSVOFile(_filename.toLocal8Bit().constData()); } _tree->unlock(); @@ -60,9 +60,7 @@ bool OctreePersistThread::process() { _initialLoadComplete = true; _lastCheck = usecTimestampNow(); // we just loaded, no need to save again -qDebug() << "about to emit loadCompleted();\n"; emit loadCompleted(); -qDebug() << "after emit loadCompleted();\n"; } if (isStillRunning()) { @@ -83,8 +81,8 @@ qDebug() << "after emit loadCompleted();\n"; // check the dirty bit and persist here... _lastCheck = usecTimestampNow(); if (_tree->isDirty()) { - qDebug("saving Octrees to file %s...\n",_filename); - _tree->writeToSVOFile(_filename); + qDebug() << "saving Octrees to file " << _filename << "...\n"; + _tree->writeToSVOFile(_filename.toLocal8Bit().constData()); _tree->clearDirtyBit(); // tree is clean after saving qDebug("DONE saving Octrees to file...\n"); } diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index 5032bcbf02..297387c2fa 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -11,6 +11,7 @@ #ifndef __Octree_server__OctreePersistThread__ #define __Octree_server__OctreePersistThread__ +#include #include #include "Octree.h" @@ -20,7 +21,7 @@ class OctreePersistThread : public GenericThread { public: static const int DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds - OctreePersistThread(Octree* tree, const char* filename, int persistInterval = DEFAULT_PERSIST_INTERVAL); + OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL); bool isInitialLoadComplete() const { return _initialLoadComplete; } @@ -35,7 +36,7 @@ protected: virtual bool process(); private: Octree* _tree; - const char* _filename; + QString _filename; int _persistInterval; bool _initialLoadComplete;