first cut at local voxel cache

This commit is contained in:
Brad Hefta-Gaub 2014-01-09 12:05:09 -08:00
parent 03794f7218
commit c181d0a849
9 changed files with 416 additions and 344 deletions

View file

@ -86,6 +86,8 @@ const float MIRROR_FULLSCREEN_DISTANCE = 0.35f;
const float MIRROR_REARVIEW_DISTANCE = 0.65f; const float MIRROR_REARVIEW_DISTANCE = 0.65f;
const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f; const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f;
const char* LOCAL_VOXEL_CACHE = "/Users/brad/local_voxel_cache.svo";
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) { void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) {
fprintf(stdout, "%s", message.toLocal8Bit().constData()); fprintf(stdout, "%s", message.toLocal8Bit().constData());
@ -143,7 +145,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_resetRecentMaxPacketsSoon(true), _resetRecentMaxPacketsSoon(true),
_swatch(NULL), _swatch(NULL),
_pasteMode(false), _pasteMode(false),
_logger(new FileLogger()) _logger(new FileLogger()),
_persistThread(NULL)
{ {
_applicationStartupTime = startup_time; _applicationStartupTime = startup_time;
@ -250,6 +253,14 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
// Set the sixense filtering // Set the sixense filtering
_sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense)); _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() { Application::~Application() {
@ -1436,6 +1447,8 @@ void Application::terminate() {
_voxelHideShowThread.terminate(); _voxelHideShowThread.terminate();
_voxelEditSender.terminate(); _voxelEditSender.terminate();
_particleEditSender.terminate(); _particleEditSender.terminate();
_persistThread->terminate();
_persistThread = NULL;
} }
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) { static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
@ -2400,6 +2413,7 @@ void Application::updateThreads(float deltaTime) {
_voxelHideShowThread.threadRoutine(); _voxelHideShowThread.threadRoutine();
_voxelEditSender.threadRoutine(); _voxelEditSender.threadRoutine();
_particleEditSender.threadRoutine(); _particleEditSender.threadRoutine();
_persistThread->threadRoutine();
} }
} }
@ -4536,3 +4550,8 @@ void Application::toggleLogDialog() {
_logDialog->close(); _logDialog->close();
} }
} }
void Application::initAvatarAndViewFrustum() {
updateAvatar(0.f);
}

View file

@ -10,7 +10,7 @@
#define __interface__Application__ #define __interface__Application__
#include <map> #include <map>
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#include <QApplication> #include <QApplication>
@ -108,14 +108,14 @@ public:
~Application(); ~Application();
void restoreSizeAndPosition(); void restoreSizeAndPosition();
void storeSizeAndPosition(); void storeSizeAndPosition();
void initializeGL(); void initializeGL();
void paintGL(); void paintGL();
void resizeGL(int width, int height); void resizeGL(int width, int height);
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event);
void mouseMoveEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event);
@ -123,27 +123,27 @@ public:
void touchBeginEvent(QTouchEvent* event); void touchBeginEvent(QTouchEvent* event);
void touchEndEvent(QTouchEvent* event); void touchEndEvent(QTouchEvent* event);
void touchUpdateEvent(QTouchEvent* event); void touchUpdateEvent(QTouchEvent* event);
void updateWindowTitle(); void updateWindowTitle();
void wheelEvent(QWheelEvent* event); void wheelEvent(QWheelEvent* event);
void shootParticle(); // shoots a particle in the direction you're looking void shootParticle(); // shoots a particle in the direction you're looking
ParticleEditHandle* newParticleEditHandle(uint32_t id = NEW_PARTICLE); ParticleEditHandle* newParticleEditHandle(uint32_t id = NEW_PARTICLE);
ParticleEditHandle* makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, ParticleEditHandle* makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity,
glm::vec3 gravity, float damping, bool inHand, QString updateScript); glm::vec3 gravity, float damping, bool inHand, QString updateScript);
void makeVoxel(glm::vec3 position, void makeVoxel(glm::vec3 position,
float scale, float scale,
unsigned char red, unsigned char red,
unsigned char green, unsigned char green,
unsigned char blue, unsigned char blue,
bool isDestructive); bool isDestructive);
void removeVoxel(glm::vec3 position, float scale); void removeVoxel(glm::vec3 position, float scale);
const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel); const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel);
QGLWidget* getGLWidget() { return _glWidget; } QGLWidget* getGLWidget() { return _glWidget; }
MyAvatar* getAvatar() { return &_myAvatar; } MyAvatar* getAvatar() { return &_myAvatar; }
Audio* getAudio() { return &_audio; } Audio* getAudio() { return &_audio; }
@ -166,24 +166,24 @@ public:
NodeToVoxelSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } NodeToVoxelSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); } void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); }
void unlockVoxelSceneStats() { _voxelSceneStatsLock.unlock(); } void unlockVoxelSceneStats() { _voxelSceneStatsLock.unlock(); }
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; } QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
GeometryCache* getGeometryCache() { return &_geometryCache; } GeometryCache* getGeometryCache() { return &_geometryCache; }
TextureCache* getTextureCache() { return &_textureCache; } TextureCache* getTextureCache() { return &_textureCache; }
GlowEffect* getGlowEffect() { return &_glowEffect; } GlowEffect* getGlowEffect() { return &_glowEffect; }
Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; } Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; }
Profile* getProfile() { return &_profile; } Profile* getProfile() { return &_profile; }
void resetProfile(const QString& username); void resetProfile(const QString& username);
static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes, static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
const char* nodeTypes, int numNodeTypes); const char* nodeTypes, int numNodeTypes);
void setupWorldLight(); void setupWorldLight();
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); void displaySide(Camera& whichCamera, bool selfAvatarOnly = false);
/// Loads a view matrix that incorporates the specified model translation without the precision issues that can /// Loads a view matrix that incorporates the specified model translation without the precision issues that can
/// result from matrix multiplication at high translation magnitudes. /// result from matrix multiplication at high translation magnitudes.
void loadTranslatedViewMatrix(const glm::vec3& translation); void loadTranslatedViewMatrix(const glm::vec3& translation);
@ -197,9 +197,9 @@ public:
virtual void nodeAdded(Node* node); virtual void nodeAdded(Node* node);
virtual void nodeKilled(Node* node); virtual void nodeKilled(Node* node);
virtual void packetSentNotification(ssize_t length); virtual void packetSentNotification(ssize_t length);
virtual void domainChanged(QString domain); virtual void domainChanged(QString domain);
VoxelShader& getVoxelShader() { return _voxelShader; } VoxelShader& getVoxelShader() { return _voxelShader; }
PointShader& getPointShader() { return _pointShader; } PointShader& getPointShader() { return _pointShader; }
FileLogger* getLogger() { return _logger; } FileLogger* getLogger() { return _logger; }
@ -208,7 +208,7 @@ public:
NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; } NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; }
NodeToJurisdictionMap& getParticleServerJurisdictions() { return _particleServerJurisdictions; } NodeToJurisdictionMap& getParticleServerJurisdictions() { return _particleServerJurisdictions; }
void pasteVoxelsToOctalCode(const unsigned char* octalCodeDestination); void pasteVoxelsToOctalCode(const unsigned char* octalCodeDestination);
/// set a voxel which is to be rendered with a highlight /// set a voxel which is to be rendered with a highlight
void setHighlightVoxel(const VoxelDetail& highlightVoxel) { _highlightVoxel = highlightVoxel; } void setHighlightVoxel(const VoxelDetail& highlightVoxel) { _highlightVoxel = highlightVoxel; }
void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; } void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; }
@ -222,25 +222,26 @@ public slots:
void pasteVoxels(); void pasteVoxels();
void nudgeVoxels(); void nudgeVoxels();
void deleteVoxels(); void deleteVoxels();
void setRenderVoxels(bool renderVoxels); void setRenderVoxels(bool renderVoxels);
void doKillLocalVoxels(); void doKillLocalVoxels();
void decreaseVoxelSize(); void decreaseVoxelSize();
void increaseVoxelSize(); void increaseVoxelSize();
void loadScript(); void loadScript();
void toggleLogDialog(); void toggleLogDialog();
void initAvatarAndViewFrustum();
private slots: private slots:
void timer(); void timer();
void idle(); void idle();
void terminate(); void terminate();
void setFullscreen(bool fullscreen); void setFullscreen(bool fullscreen);
void renderThrustAtVoxel(const glm::vec3& thrust); void renderThrustAtVoxel(const glm::vec3& thrust);
void renderLineToTouchedVoxel(); void renderLineToTouchedVoxel();
void renderCoverageMap(); void renderCoverageMap();
void renderCoverageMapsRecursively(CoverageMap* map); void renderCoverageMapsRecursively(CoverageMap* map);
@ -250,7 +251,7 @@ private slots:
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint); glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
void toggleFollowMode(); void toggleFollowMode();
void closeMirrorView(); void closeMirrorView();
void restoreMirrorView(); void restoreMirrorView();
void shrinkMirrorView(); void shrinkMirrorView();
@ -265,17 +266,17 @@ private:
static void processAvatarURLsMessage(unsigned char* packetData, size_t dataBytes); static void processAvatarURLsMessage(unsigned char* packetData, size_t dataBytes);
static void processAvatarFaceVideoMessage(unsigned char* packetData, size_t dataBytes); static void processAvatarFaceVideoMessage(unsigned char* packetData, size_t dataBytes);
static void sendPingPackets(); static void sendPingPackets();
void initDisplay(); void initDisplay();
void init(); void init();
void update(float deltaTime); void update(float deltaTime);
// Various helper functions called during update() // Various helper functions called during update()
void updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection); void updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection);
void updateFaceshift(); void updateFaceshift();
void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3& lookAtRayOrigin, glm::vec3& lookAtRayDirection); void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3& lookAtRayOrigin, glm::vec3& lookAtRayDirection);
void updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, void updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
float& distance, BoxFace& face); float& distance, BoxFace& face);
void updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, void updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
float& distance, BoxFace& face); float& distance, BoxFace& face);
@ -298,32 +299,32 @@ private:
Avatar* findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection, Avatar* findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
glm::vec3& eyePosition, QUuid &nodeUUID); glm::vec3& eyePosition, QUuid &nodeUUID);
bool isLookingAtMyAvatar(Avatar* avatar); bool isLookingAtMyAvatar(Avatar* avatar);
void renderLookatIndicator(glm::vec3 pointOfInterest); void renderLookatIndicator(glm::vec3 pointOfInterest);
void renderFollowIndicator(); void renderFollowIndicator();
void renderHighlightVoxel(VoxelDetail voxel); void renderHighlightVoxel(VoxelDetail voxel);
void updateAvatar(float deltaTime); void updateAvatar(float deltaTime);
void updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection); void updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection);
void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions); void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
glm::vec3 getSunDirection(); glm::vec3 getSunDirection();
void updateShadowMap(); void updateShadowMap();
void displayOverlay(); void displayOverlay();
void displayStats(); void displayStats();
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false); void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
void renderViewFrustum(ViewFrustum& viewFrustum); void renderViewFrustum(ViewFrustum& viewFrustum);
void checkBandwidthMeterClick(); void checkBandwidthMeterClick();
bool maybeEditVoxelUnderCursor(); bool maybeEditVoxelUnderCursor();
void deleteVoxelUnderCursor(); void deleteVoxelUnderCursor();
void eyedropperVoxelUnderCursor(); void eyedropperVoxelUnderCursor();
void setMenuShortcutsEnabled(bool enabled); void setMenuShortcutsEnabled(bool enabled);
static void attachNewHeadToNode(Node *newNode); static void attachNewHeadToNode(Node *newNode);
static void* networkReceive(void* args); // network receive thread static void* networkReceive(void* args); // network receive thread
@ -333,18 +334,18 @@ private:
QMainWindow* _window; QMainWindow* _window;
QGLWidget* _glWidget; QGLWidget* _glWidget;
QAction* _followMode; QAction* _followMode;
BandwidthMeter _bandwidthMeter; BandwidthMeter _bandwidthMeter;
SerialInterface _serialHeadSensor; SerialInterface _serialHeadSensor;
QNetworkAccessManager* _networkAccessManager; QNetworkAccessManager* _networkAccessManager;
QSettings* _settings; QSettings* _settings;
bool _displayLevels; bool _displayLevels;
glm::vec3 _gravity; glm::vec3 _gravity;
// Frame Rate Measurement // Frame Rate Measurement
int _frameCount; int _frameCount;
float _fps; float _fps;
@ -354,55 +355,55 @@ private:
bool _justStarted; bool _justStarted;
Stars _stars; Stars _stars;
Cloud _cloud; Cloud _cloud;
VoxelSystem _voxels; VoxelSystem _voxels;
VoxelTree _clipboard; // if I copy/paste VoxelTree _clipboard; // if I copy/paste
VoxelImporter _voxelImporter; VoxelImporter _voxelImporter;
VoxelSystem _sharedVoxelSystem; VoxelSystem _sharedVoxelSystem;
ViewFrustum _sharedVoxelSystemViewFrustum; ViewFrustum _sharedVoxelSystemViewFrustum;
ParticleTreeRenderer _particles; ParticleTreeRenderer _particles;
ParticleCollisionSystem _particleCollisionSystem; ParticleCollisionSystem _particleCollisionSystem;
QByteArray _voxelsFilename; QByteArray _voxelsFilename;
bool _wantToKillLocalVoxels; bool _wantToKillLocalVoxels;
MetavoxelSystem _metavoxels; MetavoxelSystem _metavoxels;
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
Oscilloscope _audioScope; Oscilloscope _audioScope;
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
MyAvatar _myAvatar; // The rendered avatar of oneself MyAvatar _myAvatar; // The rendered avatar of oneself
Profile _profile; // The data-server linked profile for this user Profile _profile; // The data-server linked profile for this user
Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar
Webcam _webcam; // The webcam interface Webcam _webcam; // The webcam interface
Faceshift _faceshift; Faceshift _faceshift;
SixenseManager _sixenseManager; SixenseManager _sixenseManager;
Camera _myCamera; // My view onto the world Camera _myCamera; // My view onto the world
Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
Camera _mirrorCamera; // Cammera for mirror view Camera _mirrorCamera; // Cammera for mirror view
QRect _mirrorViewRect; QRect _mirrorViewRect;
RearMirrorTools* _rearMirrorTools; RearMirrorTools* _rearMirrorTools;
glm::mat4 _untranslatedViewMatrix; glm::mat4 _untranslatedViewMatrix;
glm::vec3 _viewMatrixTranslation; glm::vec3 _viewMatrixTranslation;
glm::mat4 _shadowMatrix; glm::mat4 _shadowMatrix;
Environment _environment; Environment _environment;
int _headMouseX, _headMouseY; int _headMouseX, _headMouseY;
int _mouseX; int _mouseX;
int _mouseY; int _mouseY;
int _mouseDragStartedX; int _mouseDragStartedX;
@ -420,7 +421,7 @@ private:
bool _isTouchPressed; // true if multitouch has been pressed (clear when finished) bool _isTouchPressed; // true if multitouch has been pressed (clear when finished)
float _yawFromTouch; float _yawFromTouch;
float _pitchFromTouch; float _pitchFromTouch;
VoxelDetail _mouseVoxelDragging; VoxelDetail _mouseVoxelDragging;
bool _mousePressed; // true if mouse has been pressed (clear when finished) bool _mousePressed; // true if mouse has been pressed (clear when finished)
@ -428,7 +429,7 @@ private:
bool _isHoverVoxel; bool _isHoverVoxel;
bool _isHoverVoxelSounding; bool _isHoverVoxelSounding;
nodeColor _hoverVoxelOriginalColor; nodeColor _hoverVoxelOriginalColor;
VoxelDetail _mouseVoxel; // details of the voxel to be edited VoxelDetail _mouseVoxel; // details of the voxel to be edited
float _mouseVoxelScale; // the scale for adding/removing voxels float _mouseVoxelScale; // the scale for adding/removing voxels
bool _mouseVoxelScaleInitialized; bool _mouseVoxelScaleInitialized;
@ -437,7 +438,7 @@ private:
VoxelDetail _highlightVoxel; VoxelDetail _highlightVoxel;
bool _isHighlightVoxel; bool _isHighlightVoxel;
VoxelDetail _nudgeVoxel; // details of the voxel to be nudged VoxelDetail _nudgeVoxel; // details of the voxel to be nudged
bool _nudgeStarted; bool _nudgeStarted;
bool _lookingAlongX; bool _lookingAlongX;
@ -447,46 +448,46 @@ private:
Avatar* _lookatTargetAvatar; Avatar* _lookatTargetAvatar;
glm::vec3 _lookatOtherPosition; glm::vec3 _lookatOtherPosition;
float _lookatIndicatorScale; float _lookatIndicatorScale;
glm::vec3 _transmitterPickStart; glm::vec3 _transmitterPickStart;
glm::vec3 _transmitterPickEnd; glm::vec3 _transmitterPickEnd;
bool _perfStatsOn; // Do we want to display perfStats? bool _perfStatsOn; // Do we want to display perfStats?
ChatEntry _chatEntry; // chat entry field ChatEntry _chatEntry; // chat entry field
bool _chatEntryOn; // Whether to show the chat entry bool _chatEntryOn; // Whether to show the chat entry
GeometryCache _geometryCache; GeometryCache _geometryCache;
TextureCache _textureCache; TextureCache _textureCache;
GlowEffect _glowEffect; GlowEffect _glowEffect;
AmbientOcclusionEffect _ambientOcclusionEffect; AmbientOcclusionEffect _ambientOcclusionEffect;
VoxelShader _voxelShader; VoxelShader _voxelShader;
PointShader _pointShader; PointShader _pointShader;
#ifndef _WIN32 #ifndef _WIN32
Audio _audio; Audio _audio;
#endif #endif
bool _enableNetworkThread; bool _enableNetworkThread;
pthread_t _networkReceiveThread; pthread_t _networkReceiveThread;
bool _stopNetworkReceiveThread; bool _stopNetworkReceiveThread;
bool _enableProcessVoxelsThread; bool _enableProcessVoxelsThread;
VoxelPacketProcessor _voxelProcessor; VoxelPacketProcessor _voxelProcessor;
VoxelHideShowThread _voxelHideShowThread; VoxelHideShowThread _voxelHideShowThread;
VoxelEditPacketSender _voxelEditSender; VoxelEditPacketSender _voxelEditSender;
ParticleEditPacketSender _particleEditSender; ParticleEditPacketSender _particleEditSender;
unsigned char _incomingPacket[MAX_PACKET_SIZE]; unsigned char _incomingPacket[MAX_PACKET_SIZE];
int _packetCount; int _packetCount;
int _packetsPerSecond; int _packetsPerSecond;
int _bytesPerSecond; int _bytesPerSecond;
int _bytesCount; int _bytesCount;
int _recentMaxPackets; // recent max incoming voxel packets to process int _recentMaxPackets; // recent max incoming voxel packets to process
bool _resetRecentMaxPacketsSoon; bool _resetRecentMaxPacketsSoon;
StDev _idleLoopStdev; StDev _idleLoopStdev;
float _idleLoopMeasuredJitter; float _idleLoopMeasuredJitter;
@ -496,22 +497,24 @@ private:
bool _pasteMode; bool _pasteMode;
PieMenu _pieMenu; PieMenu _pieMenu;
int parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress); int parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress);
void trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength, void trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength,
const HifiSockAddr& senderSockAddr, bool wasStatsPacket); const HifiSockAddr& senderSockAddr, bool wasStatsPacket);
NodeToJurisdictionMap _voxelServerJurisdictions; NodeToJurisdictionMap _voxelServerJurisdictions;
NodeToJurisdictionMap _particleServerJurisdictions; NodeToJurisdictionMap _particleServerJurisdictions;
NodeToVoxelSceneStats _octreeServerSceneStats; NodeToVoxelSceneStats _octreeServerSceneStats;
QReadWriteLock _voxelSceneStatsLock; QReadWriteLock _voxelSceneStatsLock;
std::vector<VoxelFade> _voxelFades; std::vector<VoxelFade> _voxelFades;
std::vector<Avatar*> _avatarFades; std::vector<Avatar*> _avatarFades;
ControllerScriptingInterface _controllerScriptingInterface; ControllerScriptingInterface _controllerScriptingInterface;
QPointer<LogDialog> _logDialog; QPointer<LogDialog> _logDialog;
FileLogger* _logger; FileLogger* _logger;
OctreePersistThread* _persistThread;
}; };
#endif /* defined(__interface__Application__) */ #endif /* defined(__interface__Application__) */

View file

@ -35,12 +35,12 @@ bool VoxelHideShowThread::process() {
if (showExtraDebugging && elapsed > USECS_PER_FRAME) { if (showExtraDebugging && elapsed > USECS_PER_FRAME) {
qDebug() << "VoxelHideShowThread::process()... checkForCulling took " << elapsed << "\n"; qDebug() << "VoxelHideShowThread::process()... checkForCulling took " << elapsed << "\n";
} }
if (isStillRunning()) { if (isStillRunning()) {
if (elapsed < USECS_PER_FRAME) { if (elapsed < USECS_PER_FRAME) {
uint64_t sleepFor = USECS_PER_FRAME - elapsed; uint64_t sleepFor = USECS_PER_FRAME - elapsed;
usleep(sleepFor); usleep(sleepFor);
} }
} }
return isStillRunning(); // keep running till they terminate us return isStillRunning(); // keep running till they terminate us
} }

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,7 @@
#include <NodeData.h> #include <NodeData.h>
#include <ViewFrustum.h> #include <ViewFrustum.h>
#include <VoxelTree.h> #include <VoxelTree.h>
#include <OctreePersistThread.h>
#include "Camera.h" #include "Camera.h"
#include "Util.h" #include "Util.h"
@ -36,7 +37,7 @@ struct VoxelShaderVBOData
}; };
class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook, class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook,
public NodeListHook, public DomainChangeListener { public NodeListHook, public DomainChangeListener {
Q_OBJECT Q_OBJECT
@ -48,9 +49,9 @@ public:
void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; } void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; }
const QUuid& getDataSourceUUID() const { return _dataSourceUUID; } const QUuid& getDataSourceUUID() const { return _dataSourceUUID; }
int parseData(unsigned char* sourceBuffer, int numBytes); int parseData(unsigned char* sourceBuffer, int numBytes);
virtual void init(); virtual void init();
void simulate(float deltaTime) { } void simulate(float deltaTime) { }
void render(bool texture); void render(bool texture);
@ -85,19 +86,19 @@ public:
virtual void hideOutOfView(bool forceFullFrustum = false); virtual void hideOutOfView(bool forceFullFrustum = false);
bool hasViewChanged(); bool hasViewChanged();
bool isViewChanging(); bool isViewChanging();
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
VoxelDetail& detail, float& distance, BoxFace& face); VoxelDetail& detail, float& distance, BoxFace& face);
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration); bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration);
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration); bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration);
void deleteVoxelAt(float x, float y, float z, float s); void deleteVoxelAt(float x, float y, float z, float s);
VoxelTreeElement* getVoxelAt(float x, float y, float z, float s) const; VoxelTreeElement* getVoxelAt(float x, float y, float z, float s) const;
void createVoxel(float x, float y, float z, float s, void createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive = false); unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false); void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
creationMode mode, bool destructive = false, bool debug = false); creationMode mode, bool destructive = false, bool debug = false);
void copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destinationTree, bool rebaseToRoot); void copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destinationTree, bool rebaseToRoot);
@ -114,18 +115,18 @@ public:
virtual void nodeAdded(Node* node); virtual void nodeAdded(Node* node);
virtual void nodeKilled(Node* node); virtual void nodeKilled(Node* node);
virtual void domainChanged(QString domain); virtual void domainChanged(QString domain);
bool treeIsBusy() const { return _treeIsBusy; } bool treeIsBusy() const { return _treeIsBusy; }
VoxelTreeElement* getVoxelEnclosing(const glm::vec3& point); VoxelTreeElement* getVoxelEnclosing(const glm::vec3& point);
signals: signals:
void importSize(float x, float y, float z); void importSize(float x, float y, float z);
void importProgress(int progress); void importProgress(int progress);
public slots: public slots:
void collectStatsForTreesAndVBOs(); void collectStatsForTreesAndVBOs();
// Methods that recurse tree // Methods that recurse tree
void showAllLocalVoxels(); void showAllLocalVoxels();
void randomizeVoxelColors(); void randomizeVoxelColors();
@ -141,24 +142,27 @@ public slots:
void clearAllNodesBufferIndex(); void clearAllNodesBufferIndex();
void cancelImport(); void cancelImport();
void setDisableFastVoxelPipeline(bool disableFastVoxelPipeline); void setDisableFastVoxelPipeline(bool disableFastVoxelPipeline);
void setUseVoxelShader(bool useVoxelShader); void setUseVoxelShader(bool useVoxelShader);
void setVoxelsAsPoints(bool voxelsAsPoints); void setVoxelsAsPoints(bool voxelsAsPoints);
void localVoxelCacheLoaded();
void beginLoadingLocalVoxelCache();
protected: protected:
float _treeScale; float _treeScale;
int _maxVoxels; int _maxVoxels;
VoxelTree* _tree; VoxelTree* _tree;
void setupNewVoxelsForDrawing(); void setupNewVoxelsForDrawing();
static const bool DONT_BAIL_EARLY; // by default we will bail early, if you want to force not bailing, then use this static const bool DONT_BAIL_EARLY; // by default we will bail early, if you want to force not bailing, then use this
void setupNewVoxelsForDrawingSingleNode(bool allowBailEarly = true); void setupNewVoxelsForDrawingSingleNode(bool allowBailEarly = true);
void checkForCulling(); void checkForCulling();
glm::vec3 computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const; glm::vec3 computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const;
virtual void updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex, virtual void updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
float voxelScale, const nodeColor& color); float voxelScale, const nodeColor& color);
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd); virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
@ -170,7 +174,7 @@ private:
// disallow copying of VoxelSystem objects // disallow copying of VoxelSystem objects
VoxelSystem(const VoxelSystem&); VoxelSystem(const VoxelSystem&);
VoxelSystem& operator= (const VoxelSystem&); VoxelSystem& operator= (const VoxelSystem&);
bool _initialized; bool _initialized;
int _callsToTreesToArrays; int _callsToTreesToArrays;
OctreeElementBag _removedVoxels; OctreeElementBag _removedVoxels;
@ -223,10 +227,10 @@ private:
unsigned long _voxelsInReadArrays; unsigned long _voxelsInReadArrays;
unsigned long _voxelsInWriteArrays; unsigned long _voxelsInWriteArrays;
unsigned long _abandonedVBOSlots; unsigned long _abandonedVBOSlots;
bool _writeRenderFullVBO; bool _writeRenderFullVBO;
bool _readRenderFullVBO; bool _readRenderFullVBO;
int _setupNewVoxelsForDrawingLastElapsed; int _setupNewVoxelsForDrawingLastElapsed;
uint64_t _setupNewVoxelsForDrawingLastFinished; uint64_t _setupNewVoxelsForDrawingLastFinished;
uint64_t _lastViewCulling; uint64_t _lastViewCulling;
@ -234,7 +238,7 @@ private:
uint64_t _lastAudit; uint64_t _lastAudit;
int _lastViewCullingElapsed; int _lastViewCullingElapsed;
bool _hasRecentlyChanged; bool _hasRecentlyChanged;
void initVoxelMemory(); void initVoxelMemory();
void cleanupVoxelMemory(); void cleanupVoxelMemory();
@ -246,7 +250,7 @@ private:
GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes
VoxelShaderVBOData* _writeVoxelShaderData; VoxelShaderVBOData* _writeVoxelShaderData;
VoxelShaderVBOData* _readVoxelShaderData; VoxelShaderVBOData* _readVoxelShaderData;
GLuint _vboVerticesID; GLuint _vboVerticesID;
GLuint _vboColorsID; GLuint _vboColorsID;
@ -269,11 +273,11 @@ private:
void setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndices[]); void setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndices[]);
int newTreeToArrays(VoxelTreeElement *currentNode); int newTreeToArrays(VoxelTreeElement* currentNode);
void cleanupRemovedVoxels(); void cleanupRemovedVoxels();
void copyWrittenDataToReadArrays(bool fullVBOs); void copyWrittenDataToReadArrays(bool fullVBOs);
void updateFullVBOs(); // all voxels in the VBO void updateFullVBOs(); // all voxels in the VBO
void updatePartialVBOs(); // multiple segments, only dirty voxels void updatePartialVBOs(); // multiple segments, only dirty voxels
@ -281,7 +285,7 @@ private:
static ProgramObject _perlinModulateProgram; static ProgramObject _perlinModulateProgram;
static ProgramObject _shadowMapProgram; static ProgramObject _shadowMapProgram;
int _hookID; int _hookID;
std::vector<glBufferIndex> _freeIndexes; std::vector<glBufferIndex> _freeIndexes;
pthread_mutex_t _freeIndexLock; pthread_mutex_t _freeIndexLock;
@ -289,22 +293,22 @@ private:
void freeBufferIndex(glBufferIndex index); void freeBufferIndex(glBufferIndex index);
void clearFreeBufferIndexes(); void clearFreeBufferIndexes();
glBufferIndex getNextBufferIndex(); glBufferIndex getNextBufferIndex();
bool _falseColorizeBySource; bool _falseColorizeBySource;
QUuid _dataSourceUUID; QUuid _dataSourceUUID;
int _voxelServerCount; int _voxelServerCount;
unsigned long _memoryUsageRAM; unsigned long _memoryUsageRAM;
unsigned long _memoryUsageVBO; unsigned long _memoryUsageVBO;
unsigned long _initialMemoryUsageGPU; unsigned long _initialMemoryUsageGPU;
bool _hasMemoryUsageGPU; bool _hasMemoryUsageGPU;
bool _inSetupNewVoxelsForDrawing; bool _inSetupNewVoxelsForDrawing;
bool _useFastVoxelPipeline; bool _useFastVoxelPipeline;
bool _inhideOutOfView; bool _inhideOutOfView;
bool _treeIsBusy; // is the tree mutex locked? if so, it's busy, and if you can avoid it, don't access the tree bool _treeIsBusy; // is the tree mutex locked? if so, it's busy, and if you can avoid it, don't access the tree
void lockTree(); void lockTree();
void unlockTree(); void unlockTree();
}; };

View file

@ -13,7 +13,6 @@
#include <SharedUtil.h> #include <SharedUtil.h>
#include "OctreePersistThread.h" #include "OctreePersistThread.h"
#include "OctreeServer.h"
OctreePersistThread::OctreePersistThread(Octree* tree, const char* filename, int persistInterval) : OctreePersistThread::OctreePersistThread(Octree* tree, const char* filename, int persistInterval) :
_tree(tree), _tree(tree),
@ -41,41 +40,45 @@ bool OctreePersistThread::process() {
_loadCompleted = time(0); _loadCompleted = time(0);
uint64_t loadDone = usecTimestampNow(); uint64_t loadDone = usecTimestampNow();
_loadTimeUSecs = loadDone - loadStarted; _loadTimeUSecs = loadDone - loadStarted;
_tree->clearDirtyBit(); // the tree is clean since we just loaded it _tree->clearDirtyBit(); // the tree is clean since we just loaded it
qDebug("DONE loading Octrees from file... fileRead=%s\n", debug::valueOf(persistantFileRead)); qDebug("DONE loading Octrees from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
unsigned long nodeCount = OctreeElement::getNodeCount(); unsigned long nodeCount = OctreeElement::getNodeCount();
unsigned long internalNodeCount = OctreeElement::getInternalNodeCount(); unsigned long internalNodeCount = OctreeElement::getInternalNodeCount();
unsigned long leafNodeCount = OctreeElement::getLeafNodeCount(); unsigned long leafNodeCount = OctreeElement::getLeafNodeCount();
qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount); qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls(); double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls();
qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls() qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls()
<< " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet << " \n"; << " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet << " \n";
double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls(); double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls();
qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls() qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls()
<< " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perset=" << usecPerSet << " \n"; << " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perset=" << usecPerSet << " \n";
_initialLoadComplete = true; _initialLoadComplete = true;
_lastCheck = usecTimestampNow(); // we just loaded, no need to save again _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()) { if (isStillRunning()) {
uint64_t MSECS_TO_USECS = 1000; uint64_t MSECS_TO_USECS = 1000;
uint64_t USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms uint64_t USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
usleep(USECS_TO_SLEEP); usleep(USECS_TO_SLEEP);
// do our updates then check to save... // do our updates then check to save...
_tree->lockForWrite(); _tree->lockForWrite();
_tree->update(); _tree->update();
_tree->unlock(); _tree->unlock();
uint64_t now = usecTimestampNow(); uint64_t now = usecTimestampNow();
uint64_t sinceLastSave = now - _lastCheck; uint64_t sinceLastSave = now - _lastCheck;
uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS; uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS;
if (sinceLastSave > intervalToCheck) { if (sinceLastSave > intervalToCheck) {
// check the dirty bit and persist here... // check the dirty bit and persist here...
_lastCheck = usecTimestampNow(); _lastCheck = usecTimestampNow();
@ -86,6 +89,6 @@ bool OctreePersistThread::process() {
qDebug("DONE saving Octrees to file...\n"); qDebug("DONE saving Octrees to file...\n");
} }
} }
} }
return isStillRunning(); // keep running till they terminate us return isStillRunning(); // keep running till they terminate us
} }

View file

@ -12,20 +12,24 @@
#define __Octree_server__OctreePersistThread__ #define __Octree_server__OctreePersistThread__
#include <GenericThread.h> #include <GenericThread.h>
#include <Octree.h> #include "Octree.h"
/// Generalized threaded processor for handling received inbound packets. /// Generalized threaded processor for handling received inbound packets.
class OctreePersistThread : public virtual GenericThread { class OctreePersistThread : public GenericThread {
Q_OBJECT
public: public:
static const int DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds 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 char* filename, int persistInterval = DEFAULT_PERSIST_INTERVAL);
bool isInitialLoadComplete() const { return _initialLoadComplete; } bool isInitialLoadComplete() const { return _initialLoadComplete; }
time_t* getLoadCompleted() { return &_loadCompleted; } time_t* getLoadCompleted() { return &_loadCompleted; }
uint64_t getLoadElapsedTime() const { return _loadTimeUSecs; } uint64_t getLoadElapsedTime() const { return _loadTimeUSecs; }
signals:
void loadCompleted();
protected: protected:
/// Implements generic processing behavior for this thread. /// Implements generic processing behavior for this thread.
virtual bool process(); virtual bool process();

View file

@ -11,22 +11,25 @@
#ifndef __shared__GenericThread__ #ifndef __shared__GenericThread__
#define __shared__GenericThread__ #define __shared__GenericThread__
#include <QtCore/QObject>
#include <pthread.h> #include <pthread.h>
/// A basic generic "thread" class. Handles a single thread of control within the application. Can operate in non-threaded /// A basic generic "thread" class. Handles a single thread of control within the application. Can operate in non-threaded
/// mode but caller must regularly call threadRoutine() method. /// mode but caller must regularly call threadRoutine() method.
class GenericThread { class GenericThread : public QObject {
Q_OBJECT
public: public:
GenericThread(); GenericThread();
virtual ~GenericThread(); virtual ~GenericThread();
/// Call to start the thread. /// Call to start the thread.
/// \param bool isThreaded true by default. false for non-threaded mode and caller must call threadRoutine() regularly. /// \param bool isThreaded true by default. false for non-threaded mode and caller must call threadRoutine() regularly.
void initialize(bool isThreaded = true); void initialize(bool isThreaded = true);
/// Call to stop the thread /// Call to stop the thread
void terminate(); void terminate();
/// If you're running in non-threaded mode, you must call this regularly /// If you're running in non-threaded mode, you must call this regularly
void* threadRoutine(); void* threadRoutine();
@ -42,7 +45,7 @@ protected:
/// Unlocks all the resources of the thread. /// Unlocks all the resources of the thread.
void unlock() { pthread_mutex_unlock(&_mutex); } void unlock() { pthread_mutex_unlock(&_mutex); }
bool isStillRunning() const { return !_stopThread; } bool isStillRunning() const { return !_stopThread; }
private: private:

View file

@ -14,7 +14,7 @@
#include "VoxelTreeElement.h" #include "VoxelTreeElement.h"
#include "VoxelTree.h" #include "VoxelTree.h"
VoxelTreeElement::VoxelTreeElement(unsigned char* octalCode) : OctreeElement() { VoxelTreeElement::VoxelTreeElement(unsigned char* octalCode) : OctreeElement() {
init(octalCode); init(octalCode);
}; };
@ -23,7 +23,7 @@ VoxelTreeElement::~VoxelTreeElement() {
} }
// This will be called primarily on addChildAt(), which means we're adding a child of our // This will be called primarily on addChildAt(), which means we're adding a child of our
// own type to our own tree. This means we should initialize that child with any tree and type // own type to our own tree. This means we should initialize that child with any tree and type
// specific settings that our children must have. One example is out VoxelSystem, which // specific settings that our children must have. One example is out VoxelSystem, which
// we know must match ours. // we know must match ours.
OctreeElement* VoxelTreeElement::createNewElement(unsigned char* octalCode) const { OctreeElement* VoxelTreeElement::createNewElement(unsigned char* octalCode) const {
@ -63,10 +63,10 @@ bool VoxelTreeElement::appendElementData(OctreePacketData* packetData) const {
} }
int VoxelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead, int VoxelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args) { ReadBitstreamToTreeParams& args) {
const int BYTES_PER_COLOR = 3; const int BYTES_PER_COLOR = 3;
// pull the color for this child // pull the color for this child
nodeColor newColor = { 128, 128, 128, 1}; nodeColor newColor = { 128, 128, 128, 1};
if (args.includeColor) { if (args.includeColor) {
@ -82,11 +82,11 @@ uint8_t VoxelTreeElement::_nextIndex = INDEX_FOR_NULL + 1; // start at 1, 0 is r
std::map<VoxelSystem*, uint8_t> VoxelTreeElement::_mapVoxelSystemPointersToIndex; std::map<VoxelSystem*, uint8_t> VoxelTreeElement::_mapVoxelSystemPointersToIndex;
std::map<uint8_t, VoxelSystem*> VoxelTreeElement::_mapIndexToVoxelSystemPointers; std::map<uint8_t, VoxelSystem*> VoxelTreeElement::_mapIndexToVoxelSystemPointers;
VoxelSystem* VoxelTreeElement::getVoxelSystem() const { VoxelSystem* VoxelTreeElement::getVoxelSystem() const {
if (_voxelSystemIndex > INDEX_FOR_NULL) { if (_voxelSystemIndex > INDEX_FOR_NULL) {
if (_mapIndexToVoxelSystemPointers.end() != _mapIndexToVoxelSystemPointers.find(_voxelSystemIndex)) { if (_mapIndexToVoxelSystemPointers.end() != _mapIndexToVoxelSystemPointers.find(_voxelSystemIndex)) {
VoxelSystem* voxelSystem = _mapIndexToVoxelSystemPointers[_voxelSystemIndex]; VoxelSystem* voxelSystem = _mapIndexToVoxelSystemPointers[_voxelSystemIndex];
return voxelSystem; return voxelSystem;
} }
} }
@ -129,7 +129,7 @@ void VoxelTreeElement::setFalseColored(bool isFalseColored) {
if (_falseColored && !isFalseColored) { if (_falseColored && !isFalseColored) {
memcpy(&_currentColor,&_trueColor,sizeof(nodeColor)); memcpy(&_currentColor,&_trueColor,sizeof(nodeColor));
} }
_falseColored = isFalseColored; _falseColored = isFalseColored;
_isDirty = true; _isDirty = true;
_density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed. _density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed.
markWithChangedTime(); markWithChangedTime();
@ -167,7 +167,7 @@ void VoxelTreeElement::calculateAverageFromChildren() {
density += childAt->getDensity(); density += childAt->getDensity();
} }
} }
density /= (float) NUMBER_OF_CHILDREN; density /= (float) NUMBER_OF_CHILDREN;
// //
// The VISIBLE_ABOVE_DENSITY sets the density of matter above which an averaged color voxel will // The VISIBLE_ABOVE_DENSITY sets the density of matter above which an averaged color voxel will
// be set. It is an important physical constant in our universe. A number below 0.5 will cause // be set. It is an important physical constant in our universe. A number below 0.5 will cause
@ -175,9 +175,9 @@ void VoxelTreeElement::calculateAverageFromChildren() {
// less data, which is (probably) going to be preferable because it gives a sense that there is // less data, which is (probably) going to be preferable because it gives a sense that there is
// something out there to go investigate. A number above 0.5 would cause the world to become // something out there to go investigate. A number above 0.5 would cause the world to become
// more 'empty' at a distance. Exactly 0.5 would match the physical world, at least for materials // more 'empty' at a distance. Exactly 0.5 would match the physical world, at least for materials
// that are not shiny and have equivalent ambient reflectance. // that are not shiny and have equivalent ambient reflectance.
// //
const float VISIBLE_ABOVE_DENSITY = 0.10f; const float VISIBLE_ABOVE_DENSITY = 0.10f;
nodeColor newColor = { 0, 0, 0, 0}; nodeColor newColor = { 0, 0, 0, 0};
if (density > VISIBLE_ABOVE_DENSITY) { if (density > VISIBLE_ABOVE_DENSITY) {
// The density of material in the space of the voxel sets whether it is actually colored // The density of material in the space of the voxel sets whether it is actually colored
@ -188,14 +188,14 @@ void VoxelTreeElement::calculateAverageFromChildren() {
// set the alpha to 1 to indicate that this isn't transparent // set the alpha to 1 to indicate that this isn't transparent
newColor[3] = 1; newColor[3] = 1;
} }
// Set the color from the average of the child colors, and update the density // Set the color from the average of the child colors, and update the density
setColor(newColor); setColor(newColor);
setDensity(density); setDensity(density);
} }
// will detect if children are leaves AND the same color // will detect if children are leaves AND the same color
// and in that case will delete the children and make this node // and in that case will delete the children and make this node
// a leaf, returns TRUE if all the leaves are collapsed into a // a leaf, returns TRUE if all the leaves are collapsed into a
// single node // single node
bool VoxelTreeElement::collapseChildren() { bool VoxelTreeElement::collapseChildren() {
// scan children, verify that they are ALL present and accounted for // scan children, verify that they are ALL present and accounted for
@ -213,15 +213,15 @@ bool VoxelTreeElement::collapseChildren() {
red = childAt->getColor()[0]; red = childAt->getColor()[0];
green = childAt->getColor()[1]; green = childAt->getColor()[1];
blue = childAt->getColor()[2]; blue = childAt->getColor()[2];
} else if (red != childAt->getColor()[0] || } else if (red != childAt->getColor()[0] ||
green != childAt->getColor()[1] || blue != childAt->getColor()[2]) { green != childAt->getColor()[1] || blue != childAt->getColor()[2]) {
allChildrenMatch=false; allChildrenMatch=false;
break; break;
} }
} }
} }
if (allChildrenMatch) { if (allChildrenMatch) {
//qDebug("allChildrenMatch: pruning tree\n"); //qDebug("allChildrenMatch: pruning tree\n");
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
@ -230,9 +230,9 @@ bool VoxelTreeElement::collapseChildren() {
setChildAtIndex(i, NULL); // set it to NULL setChildAtIndex(i, NULL); // set it to NULL
} }
nodeColor collapsedColor; nodeColor collapsedColor;
collapsedColor[0]=red; collapsedColor[0]=red;
collapsedColor[1]=green; collapsedColor[1]=green;
collapsedColor[2]=blue; collapsedColor[2]=blue;
collapsedColor[3]=1; // color is set collapsedColor[3]=1; // color is set
setColor(collapsedColor); setColor(collapsedColor);
} }
@ -240,7 +240,7 @@ bool VoxelTreeElement::collapseChildren() {
} }
bool VoxelTreeElement::findSpherePenetration(const glm::vec3& center, float radius, bool VoxelTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const { glm::vec3& penetration, void** penetratedObject) const {
if (_box.findSpherePenetration(center, radius, penetration)) { if (_box.findSpherePenetration(center, radius, penetration)) {
@ -254,7 +254,7 @@ bool VoxelTreeElement::findSpherePenetration(const glm::vec3& center, float radi
voxelDetails->red = getTrueColor()[RED_INDEX]; voxelDetails->red = getTrueColor()[RED_INDEX];
voxelDetails->green = getTrueColor()[GREEN_INDEX]; voxelDetails->green = getTrueColor()[GREEN_INDEX];
voxelDetails->blue = getTrueColor()[BLUE_INDEX]; voxelDetails->blue = getTrueColor()[BLUE_INDEX];
*penetratedObject = (void*)voxelDetails; *penetratedObject = (void*)voxelDetails;
} }
return true; return true;