mirror of
https://github.com/overte-org/overte.git
synced 2025-04-17 08:56:36 +02:00
first cut at local voxel cache
This commit is contained in:
parent
03794f7218
commit
c181d0a849
9 changed files with 416 additions and 344 deletions
|
@ -86,6 +86,8 @@ 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";
|
||||
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) {
|
||||
fprintf(stdout, "%s", message.toLocal8Bit().constData());
|
||||
|
@ -143,7 +145,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_resetRecentMaxPacketsSoon(true),
|
||||
_swatch(NULL),
|
||||
_pasteMode(false),
|
||||
_logger(new FileLogger())
|
||||
_logger(new FileLogger()),
|
||||
_persistThread(NULL)
|
||||
{
|
||||
_applicationStartupTime = startup_time;
|
||||
|
||||
|
@ -250,6 +253,14 @@ 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() {
|
||||
|
@ -1436,6 +1447,8 @@ void Application::terminate() {
|
|||
_voxelHideShowThread.terminate();
|
||||
_voxelEditSender.terminate();
|
||||
_particleEditSender.terminate();
|
||||
_persistThread->terminate();
|
||||
_persistThread = NULL;
|
||||
}
|
||||
|
||||
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
|
||||
|
@ -2400,6 +2413,7 @@ void Application::updateThreads(float deltaTime) {
|
|||
_voxelHideShowThread.threadRoutine();
|
||||
_voxelEditSender.threadRoutine();
|
||||
_particleEditSender.threadRoutine();
|
||||
_persistThread->threadRoutine();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4536,3 +4550,8 @@ void Application::toggleLogDialog() {
|
|||
_logDialog->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Application::initAvatarAndViewFrustum() {
|
||||
updateAvatar(0.f);
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
#define __interface__Application__
|
||||
|
||||
#include <map>
|
||||
#include <pthread.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <QApplication>
|
||||
|
@ -108,14 +108,14 @@ public:
|
|||
~Application();
|
||||
|
||||
void restoreSizeAndPosition();
|
||||
void storeSizeAndPosition();
|
||||
void storeSizeAndPosition();
|
||||
void initializeGL();
|
||||
void paintGL();
|
||||
void resizeGL(int width, int height);
|
||||
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
@ -123,27 +123,27 @@ public:
|
|||
void touchBeginEvent(QTouchEvent* event);
|
||||
void touchEndEvent(QTouchEvent* event);
|
||||
void touchUpdateEvent(QTouchEvent* event);
|
||||
|
||||
|
||||
void updateWindowTitle();
|
||||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
void shootParticle(); // shoots a particle in the direction you're looking
|
||||
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);
|
||||
|
||||
|
||||
void makeVoxel(glm::vec3 position,
|
||||
float scale,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
bool isDestructive);
|
||||
|
||||
|
||||
void removeVoxel(glm::vec3 position, float scale);
|
||||
|
||||
|
||||
const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel);
|
||||
|
||||
|
||||
QGLWidget* getGLWidget() { return _glWidget; }
|
||||
MyAvatar* getAvatar() { return &_myAvatar; }
|
||||
Audio* getAudio() { return &_audio; }
|
||||
|
@ -166,24 +166,24 @@ public:
|
|||
NodeToVoxelSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
||||
void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); }
|
||||
void unlockVoxelSceneStats() { _voxelSceneStatsLock.unlock(); }
|
||||
|
||||
|
||||
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
|
||||
GeometryCache* getGeometryCache() { return &_geometryCache; }
|
||||
TextureCache* getTextureCache() { return &_textureCache; }
|
||||
GlowEffect* getGlowEffect() { return &_glowEffect; }
|
||||
|
||||
|
||||
Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; }
|
||||
|
||||
|
||||
Profile* getProfile() { return &_profile; }
|
||||
void resetProfile(const QString& username);
|
||||
|
||||
|
||||
static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
|
||||
const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
|
||||
void setupWorldLight();
|
||||
|
||||
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false);
|
||||
|
||||
|
||||
/// Loads a view matrix that incorporates the specified model translation without the precision issues that can
|
||||
/// result from matrix multiplication at high translation magnitudes.
|
||||
void loadTranslatedViewMatrix(const glm::vec3& translation);
|
||||
|
@ -197,9 +197,9 @@ public:
|
|||
virtual void nodeAdded(Node* node);
|
||||
virtual void nodeKilled(Node* node);
|
||||
virtual void packetSentNotification(ssize_t length);
|
||||
|
||||
|
||||
virtual void domainChanged(QString domain);
|
||||
|
||||
|
||||
VoxelShader& getVoxelShader() { return _voxelShader; }
|
||||
PointShader& getPointShader() { return _pointShader; }
|
||||
FileLogger* getLogger() { return _logger; }
|
||||
|
@ -208,7 +208,7 @@ public:
|
|||
NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; }
|
||||
NodeToJurisdictionMap& getParticleServerJurisdictions() { return _particleServerJurisdictions; }
|
||||
void pasteVoxelsToOctalCode(const unsigned char* octalCodeDestination);
|
||||
|
||||
|
||||
/// set a voxel which is to be rendered with a highlight
|
||||
void setHighlightVoxel(const VoxelDetail& highlightVoxel) { _highlightVoxel = highlightVoxel; }
|
||||
void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; }
|
||||
|
@ -222,25 +222,26 @@ public slots:
|
|||
void pasteVoxels();
|
||||
void nudgeVoxels();
|
||||
void deleteVoxels();
|
||||
|
||||
|
||||
void setRenderVoxels(bool renderVoxels);
|
||||
void doKillLocalVoxels();
|
||||
void decreaseVoxelSize();
|
||||
void increaseVoxelSize();
|
||||
void loadScript();
|
||||
void toggleLogDialog();
|
||||
|
||||
void initAvatarAndViewFrustum();
|
||||
|
||||
private slots:
|
||||
|
||||
|
||||
void timer();
|
||||
void idle();
|
||||
void terminate();
|
||||
|
||||
|
||||
void setFullscreen(bool fullscreen);
|
||||
|
||||
|
||||
void renderThrustAtVoxel(const glm::vec3& thrust);
|
||||
void renderLineToTouchedVoxel();
|
||||
|
||||
|
||||
void renderCoverageMap();
|
||||
void renderCoverageMapsRecursively(CoverageMap* map);
|
||||
|
||||
|
@ -250,7 +251,7 @@ private slots:
|
|||
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
|
||||
|
||||
void toggleFollowMode();
|
||||
|
||||
|
||||
void closeMirrorView();
|
||||
void restoreMirrorView();
|
||||
void shrinkMirrorView();
|
||||
|
@ -265,17 +266,17 @@ private:
|
|||
static void processAvatarURLsMessage(unsigned char* packetData, size_t dataBytes);
|
||||
static void processAvatarFaceVideoMessage(unsigned char* packetData, size_t dataBytes);
|
||||
static void sendPingPackets();
|
||||
|
||||
|
||||
void initDisplay();
|
||||
void init();
|
||||
|
||||
|
||||
void update(float deltaTime);
|
||||
|
||||
// Various helper functions called during update()
|
||||
void updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection);
|
||||
void updateFaceshift();
|
||||
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);
|
||||
void updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||
float& distance, BoxFace& face);
|
||||
|
@ -298,32 +299,32 @@ private:
|
|||
Avatar* findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
||||
glm::vec3& eyePosition, QUuid &nodeUUID);
|
||||
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||
|
||||
|
||||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||
void renderFollowIndicator();
|
||||
void renderHighlightVoxel(VoxelDetail voxel);
|
||||
|
||||
|
||||
void updateAvatar(float deltaTime);
|
||||
void updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection);
|
||||
void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
|
||||
|
||||
glm::vec3 getSunDirection();
|
||||
|
||||
|
||||
void updateShadowMap();
|
||||
void displayOverlay();
|
||||
void displayStats();
|
||||
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
|
||||
void renderViewFrustum(ViewFrustum& viewFrustum);
|
||||
|
||||
|
||||
void checkBandwidthMeterClick();
|
||||
|
||||
|
||||
bool maybeEditVoxelUnderCursor();
|
||||
void deleteVoxelUnderCursor();
|
||||
void eyedropperVoxelUnderCursor();
|
||||
|
||||
|
||||
void setMenuShortcutsEnabled(bool enabled);
|
||||
|
||||
|
||||
static void attachNewHeadToNode(Node *newNode);
|
||||
static void* networkReceive(void* args); // network receive thread
|
||||
|
||||
|
@ -333,18 +334,18 @@ private:
|
|||
|
||||
QMainWindow* _window;
|
||||
QGLWidget* _glWidget;
|
||||
|
||||
|
||||
QAction* _followMode;
|
||||
|
||||
|
||||
BandwidthMeter _bandwidthMeter;
|
||||
|
||||
SerialInterface _serialHeadSensor;
|
||||
QNetworkAccessManager* _networkAccessManager;
|
||||
QSettings* _settings;
|
||||
bool _displayLevels;
|
||||
|
||||
|
||||
glm::vec3 _gravity;
|
||||
|
||||
|
||||
// Frame Rate Measurement
|
||||
int _frameCount;
|
||||
float _fps;
|
||||
|
@ -354,55 +355,55 @@ private:
|
|||
bool _justStarted;
|
||||
|
||||
Stars _stars;
|
||||
|
||||
|
||||
Cloud _cloud;
|
||||
|
||||
|
||||
VoxelSystem _voxels;
|
||||
VoxelTree _clipboard; // if I copy/paste
|
||||
VoxelImporter _voxelImporter;
|
||||
VoxelSystem _sharedVoxelSystem;
|
||||
ViewFrustum _sharedVoxelSystemViewFrustum;
|
||||
|
||||
|
||||
ParticleTreeRenderer _particles;
|
||||
ParticleCollisionSystem _particleCollisionSystem;
|
||||
|
||||
QByteArray _voxelsFilename;
|
||||
bool _wantToKillLocalVoxels;
|
||||
|
||||
|
||||
MetavoxelSystem _metavoxels;
|
||||
|
||||
|
||||
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
|
||||
Oscilloscope _audioScope;
|
||||
|
||||
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
|
||||
|
||||
|
||||
MyAvatar _myAvatar; // The rendered avatar of oneself
|
||||
Profile _profile; // The data-server linked profile for this user
|
||||
|
||||
|
||||
Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar
|
||||
|
||||
|
||||
Webcam _webcam; // The webcam interface
|
||||
|
||||
|
||||
Faceshift _faceshift;
|
||||
|
||||
|
||||
SixenseManager _sixenseManager;
|
||||
|
||||
|
||||
Camera _myCamera; // My view onto the world
|
||||
Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
||||
Camera _mirrorCamera; // Cammera for mirror view
|
||||
QRect _mirrorViewRect;
|
||||
RearMirrorTools* _rearMirrorTools;
|
||||
|
||||
|
||||
glm::mat4 _untranslatedViewMatrix;
|
||||
glm::vec3 _viewMatrixTranslation;
|
||||
|
||||
|
||||
glm::mat4 _shadowMatrix;
|
||||
|
||||
|
||||
Environment _environment;
|
||||
|
||||
|
||||
int _headMouseX, _headMouseY;
|
||||
|
||||
|
||||
int _mouseX;
|
||||
int _mouseY;
|
||||
int _mouseDragStartedX;
|
||||
|
@ -420,7 +421,7 @@ private:
|
|||
bool _isTouchPressed; // true if multitouch has been pressed (clear when finished)
|
||||
float _yawFromTouch;
|
||||
float _pitchFromTouch;
|
||||
|
||||
|
||||
VoxelDetail _mouseVoxelDragging;
|
||||
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
||||
|
||||
|
@ -428,7 +429,7 @@ private:
|
|||
bool _isHoverVoxel;
|
||||
bool _isHoverVoxelSounding;
|
||||
nodeColor _hoverVoxelOriginalColor;
|
||||
|
||||
|
||||
VoxelDetail _mouseVoxel; // details of the voxel to be edited
|
||||
float _mouseVoxelScale; // the scale for adding/removing voxels
|
||||
bool _mouseVoxelScaleInitialized;
|
||||
|
@ -437,7 +438,7 @@ private:
|
|||
|
||||
VoxelDetail _highlightVoxel;
|
||||
bool _isHighlightVoxel;
|
||||
|
||||
|
||||
VoxelDetail _nudgeVoxel; // details of the voxel to be nudged
|
||||
bool _nudgeStarted;
|
||||
bool _lookingAlongX;
|
||||
|
@ -447,46 +448,46 @@ private:
|
|||
Avatar* _lookatTargetAvatar;
|
||||
glm::vec3 _lookatOtherPosition;
|
||||
float _lookatIndicatorScale;
|
||||
|
||||
|
||||
glm::vec3 _transmitterPickStart;
|
||||
glm::vec3 _transmitterPickEnd;
|
||||
|
||||
bool _perfStatsOn; // Do we want to display perfStats?
|
||||
|
||||
ChatEntry _chatEntry; // chat entry field
|
||||
bool _chatEntryOn; // Whether to show the chat entry
|
||||
|
||||
|
||||
bool _perfStatsOn; // Do we want to display perfStats?
|
||||
|
||||
ChatEntry _chatEntry; // chat entry field
|
||||
bool _chatEntryOn; // Whether to show the chat entry
|
||||
|
||||
GeometryCache _geometryCache;
|
||||
TextureCache _textureCache;
|
||||
|
||||
|
||||
GlowEffect _glowEffect;
|
||||
AmbientOcclusionEffect _ambientOcclusionEffect;
|
||||
VoxelShader _voxelShader;
|
||||
PointShader _pointShader;
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
Audio _audio;
|
||||
#endif
|
||||
|
||||
|
||||
bool _enableNetworkThread;
|
||||
pthread_t _networkReceiveThread;
|
||||
bool _stopNetworkReceiveThread;
|
||||
|
||||
|
||||
bool _enableProcessVoxelsThread;
|
||||
VoxelPacketProcessor _voxelProcessor;
|
||||
VoxelHideShowThread _voxelHideShowThread;
|
||||
VoxelEditPacketSender _voxelEditSender;
|
||||
ParticleEditPacketSender _particleEditSender;
|
||||
|
||||
|
||||
unsigned char _incomingPacket[MAX_PACKET_SIZE];
|
||||
int _packetCount;
|
||||
int _packetsPerSecond;
|
||||
int _bytesPerSecond;
|
||||
int _bytesCount;
|
||||
|
||||
|
||||
int _recentMaxPackets; // recent max incoming voxel packets to process
|
||||
bool _resetRecentMaxPacketsSoon;
|
||||
|
||||
|
||||
StDev _idleLoopStdev;
|
||||
float _idleLoopMeasuredJitter;
|
||||
|
||||
|
@ -496,22 +497,24 @@ private:
|
|||
bool _pasteMode;
|
||||
|
||||
PieMenu _pieMenu;
|
||||
|
||||
|
||||
int parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress);
|
||||
void trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength,
|
||||
const HifiSockAddr& senderSockAddr, bool wasStatsPacket);
|
||||
|
||||
|
||||
NodeToJurisdictionMap _voxelServerJurisdictions;
|
||||
NodeToJurisdictionMap _particleServerJurisdictions;
|
||||
NodeToVoxelSceneStats _octreeServerSceneStats;
|
||||
QReadWriteLock _voxelSceneStatsLock;
|
||||
|
||||
|
||||
std::vector<VoxelFade> _voxelFades;
|
||||
std::vector<Avatar*> _avatarFades;
|
||||
ControllerScriptingInterface _controllerScriptingInterface;
|
||||
QPointer<LogDialog> _logDialog;
|
||||
|
||||
FileLogger* _logger;
|
||||
|
||||
OctreePersistThread* _persistThread;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__Application__) */
|
||||
|
|
|
@ -35,12 +35,12 @@ bool VoxelHideShowThread::process() {
|
|||
if (showExtraDebugging && elapsed > USECS_PER_FRAME) {
|
||||
qDebug() << "VoxelHideShowThread::process()... checkForCulling took " << elapsed << "\n";
|
||||
}
|
||||
|
||||
|
||||
if (isStillRunning()) {
|
||||
if (elapsed < USECS_PER_FRAME) {
|
||||
uint64_t sleepFor = USECS_PER_FRAME - elapsed;
|
||||
usleep(sleepFor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return isStillRunning(); // keep running till they terminate us
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,6 +18,7 @@
|
|||
#include <NodeData.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <VoxelTree.h>
|
||||
#include <OctreePersistThread.h>
|
||||
|
||||
#include "Camera.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 {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -48,9 +49,9 @@ public:
|
|||
|
||||
void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; }
|
||||
const QUuid& getDataSourceUUID() const { return _dataSourceUUID; }
|
||||
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
|
||||
virtual void init();
|
||||
void simulate(float deltaTime) { }
|
||||
void render(bool texture);
|
||||
|
@ -85,19 +86,19 @@ public:
|
|||
virtual void hideOutOfView(bool forceFullFrustum = false);
|
||||
bool hasViewChanged();
|
||||
bool isViewChanging();
|
||||
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
VoxelDetail& detail, float& distance, BoxFace& face);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
void deleteVoxelAt(float x, float y, float z, float s);
|
||||
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);
|
||||
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);
|
||||
|
||||
void copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destinationTree, bool rebaseToRoot);
|
||||
|
@ -114,18 +115,18 @@ public:
|
|||
virtual void nodeAdded(Node* node);
|
||||
virtual void nodeKilled(Node* node);
|
||||
virtual void domainChanged(QString domain);
|
||||
|
||||
|
||||
bool treeIsBusy() const { return _treeIsBusy; }
|
||||
|
||||
|
||||
VoxelTreeElement* getVoxelEnclosing(const glm::vec3& point);
|
||||
|
||||
|
||||
signals:
|
||||
void importSize(float x, float y, float z);
|
||||
void importProgress(int progress);
|
||||
|
||||
public slots:
|
||||
void collectStatsForTreesAndVBOs();
|
||||
|
||||
|
||||
// Methods that recurse tree
|
||||
void showAllLocalVoxels();
|
||||
void randomizeVoxelColors();
|
||||
|
@ -141,24 +142,27 @@ public slots:
|
|||
void clearAllNodesBufferIndex();
|
||||
|
||||
void cancelImport();
|
||||
|
||||
|
||||
void setDisableFastVoxelPipeline(bool disableFastVoxelPipeline);
|
||||
void setUseVoxelShader(bool useVoxelShader);
|
||||
void setVoxelsAsPoints(bool voxelsAsPoints);
|
||||
|
||||
|
||||
void localVoxelCacheLoaded();
|
||||
void beginLoadingLocalVoxelCache();
|
||||
|
||||
protected:
|
||||
float _treeScale;
|
||||
int _maxVoxels;
|
||||
float _treeScale;
|
||||
int _maxVoxels;
|
||||
VoxelTree* _tree;
|
||||
|
||||
void setupNewVoxelsForDrawing();
|
||||
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 checkForCulling();
|
||||
|
||||
|
||||
glm::vec3 computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const;
|
||||
|
||||
|
||||
|
||||
virtual void updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||
float voxelScale, const nodeColor& color);
|
||||
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
|
@ -170,7 +174,7 @@ private:
|
|||
// disallow copying of VoxelSystem objects
|
||||
VoxelSystem(const VoxelSystem&);
|
||||
VoxelSystem& operator= (const VoxelSystem&);
|
||||
|
||||
|
||||
bool _initialized;
|
||||
int _callsToTreesToArrays;
|
||||
OctreeElementBag _removedVoxels;
|
||||
|
@ -223,10 +227,10 @@ private:
|
|||
unsigned long _voxelsInReadArrays;
|
||||
unsigned long _voxelsInWriteArrays;
|
||||
unsigned long _abandonedVBOSlots;
|
||||
|
||||
|
||||
bool _writeRenderFullVBO;
|
||||
bool _readRenderFullVBO;
|
||||
|
||||
|
||||
int _setupNewVoxelsForDrawingLastElapsed;
|
||||
uint64_t _setupNewVoxelsForDrawingLastFinished;
|
||||
uint64_t _lastViewCulling;
|
||||
|
@ -234,7 +238,7 @@ private:
|
|||
uint64_t _lastAudit;
|
||||
int _lastViewCullingElapsed;
|
||||
bool _hasRecentlyChanged;
|
||||
|
||||
|
||||
void initVoxelMemory();
|
||||
void cleanupVoxelMemory();
|
||||
|
||||
|
@ -246,7 +250,7 @@ private:
|
|||
GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes
|
||||
VoxelShaderVBOData* _writeVoxelShaderData;
|
||||
VoxelShaderVBOData* _readVoxelShaderData;
|
||||
|
||||
|
||||
GLuint _vboVerticesID;
|
||||
GLuint _vboColorsID;
|
||||
|
||||
|
@ -269,11 +273,11 @@ private:
|
|||
|
||||
void setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndices[]);
|
||||
|
||||
int newTreeToArrays(VoxelTreeElement *currentNode);
|
||||
int newTreeToArrays(VoxelTreeElement* currentNode);
|
||||
void cleanupRemovedVoxels();
|
||||
|
||||
void copyWrittenDataToReadArrays(bool fullVBOs);
|
||||
|
||||
|
||||
void updateFullVBOs(); // all voxels in the VBO
|
||||
void updatePartialVBOs(); // multiple segments, only dirty voxels
|
||||
|
||||
|
@ -281,7 +285,7 @@ private:
|
|||
|
||||
static ProgramObject _perlinModulateProgram;
|
||||
static ProgramObject _shadowMapProgram;
|
||||
|
||||
|
||||
int _hookID;
|
||||
std::vector<glBufferIndex> _freeIndexes;
|
||||
pthread_mutex_t _freeIndexLock;
|
||||
|
@ -289,22 +293,22 @@ private:
|
|||
void freeBufferIndex(glBufferIndex index);
|
||||
void clearFreeBufferIndexes();
|
||||
glBufferIndex getNextBufferIndex();
|
||||
|
||||
|
||||
bool _falseColorizeBySource;
|
||||
QUuid _dataSourceUUID;
|
||||
|
||||
|
||||
int _voxelServerCount;
|
||||
unsigned long _memoryUsageRAM;
|
||||
unsigned long _memoryUsageVBO;
|
||||
unsigned long _initialMemoryUsageGPU;
|
||||
bool _hasMemoryUsageGPU;
|
||||
|
||||
|
||||
bool _inSetupNewVoxelsForDrawing;
|
||||
bool _useFastVoxelPipeline;
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
void lockTree();
|
||||
void unlockTree();
|
||||
};
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <SharedUtil.h>
|
||||
|
||||
#include "OctreePersistThread.h"
|
||||
#include "OctreeServer.h"
|
||||
|
||||
OctreePersistThread::OctreePersistThread(Octree* tree, const char* filename, int persistInterval) :
|
||||
_tree(tree),
|
||||
|
@ -41,41 +40,45 @@ bool OctreePersistThread::process() {
|
|||
_loadCompleted = time(0);
|
||||
uint64_t loadDone = usecTimestampNow();
|
||||
_loadTimeUSecs = loadDone - loadStarted;
|
||||
|
||||
|
||||
_tree->clearDirtyBit(); // the tree is clean since we just loaded it
|
||||
qDebug("DONE loading Octrees from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
|
||||
|
||||
|
||||
unsigned long nodeCount = OctreeElement::getNodeCount();
|
||||
unsigned long internalNodeCount = OctreeElement::getInternalNodeCount();
|
||||
unsigned long leafNodeCount = OctreeElement::getLeafNodeCount();
|
||||
qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
|
||||
|
||||
double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls();
|
||||
qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls()
|
||||
qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls()
|
||||
<< " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet << " \n";
|
||||
|
||||
|
||||
double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls();
|
||||
qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls()
|
||||
qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls()
|
||||
<< " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perset=" << usecPerSet << " \n";
|
||||
|
||||
_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()) {
|
||||
uint64_t MSECS_TO_USECS = 1000;
|
||||
uint64_t USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
|
||||
usleep(USECS_TO_SLEEP);
|
||||
|
||||
|
||||
// do our updates then check to save...
|
||||
_tree->lockForWrite();
|
||||
_tree->update();
|
||||
_tree->unlock();
|
||||
|
||||
|
||||
uint64_t now = usecTimestampNow();
|
||||
uint64_t sinceLastSave = now - _lastCheck;
|
||||
uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS;
|
||||
|
||||
|
||||
if (sinceLastSave > intervalToCheck) {
|
||||
// check the dirty bit and persist here...
|
||||
_lastCheck = usecTimestampNow();
|
||||
|
@ -86,6 +89,6 @@ bool OctreePersistThread::process() {
|
|||
qDebug("DONE saving Octrees to file...\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isStillRunning(); // keep running till they terminate us
|
||||
}
|
|
@ -12,20 +12,24 @@
|
|||
#define __Octree_server__OctreePersistThread__
|
||||
|
||||
#include <GenericThread.h>
|
||||
#include <Octree.h>
|
||||
#include "Octree.h"
|
||||
|
||||
/// Generalized threaded processor for handling received inbound packets.
|
||||
class OctreePersistThread : public virtual GenericThread {
|
||||
/// Generalized threaded processor for handling received inbound packets.
|
||||
class OctreePersistThread : public GenericThread {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const int DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds
|
||||
|
||||
OctreePersistThread(Octree* tree, const char* filename, int persistInterval = DEFAULT_PERSIST_INTERVAL);
|
||||
|
||||
|
||||
bool isInitialLoadComplete() const { return _initialLoadComplete; }
|
||||
|
||||
time_t* getLoadCompleted() { return &_loadCompleted; }
|
||||
uint64_t getLoadElapsedTime() const { return _loadTimeUSecs; }
|
||||
|
||||
signals:
|
||||
void loadCompleted();
|
||||
|
||||
protected:
|
||||
/// Implements generic processing behavior for this thread.
|
||||
virtual bool process();
|
|
@ -11,22 +11,25 @@
|
|||
#ifndef __shared__GenericThread__
|
||||
#define __shared__GenericThread__
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/// 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.
|
||||
class GenericThread {
|
||||
class GenericThread : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
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.
|
||||
void initialize(bool isThreaded = true);
|
||||
|
||||
/// Call to stop the thread
|
||||
void terminate();
|
||||
|
||||
|
||||
/// If you're running in non-threaded mode, you must call this regularly
|
||||
void* threadRoutine();
|
||||
|
||||
|
@ -42,7 +45,7 @@ protected:
|
|||
|
||||
/// Unlocks all the resources of the thread.
|
||||
void unlock() { pthread_mutex_unlock(&_mutex); }
|
||||
|
||||
|
||||
bool isStillRunning() const { return !_stopThread; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "VoxelTreeElement.h"
|
||||
#include "VoxelTree.h"
|
||||
|
||||
VoxelTreeElement::VoxelTreeElement(unsigned char* octalCode) : OctreeElement() {
|
||||
VoxelTreeElement::VoxelTreeElement(unsigned char* octalCode) : OctreeElement() {
|
||||
init(octalCode);
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@ VoxelTreeElement::~VoxelTreeElement() {
|
|||
}
|
||||
|
||||
// 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
|
||||
// we know must match ours.
|
||||
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,
|
||||
ReadBitstreamToTreeParams& args) {
|
||||
const int BYTES_PER_COLOR = 3;
|
||||
|
||||
int VoxelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args) {
|
||||
const int BYTES_PER_COLOR = 3;
|
||||
|
||||
// pull the color for this child
|
||||
nodeColor newColor = { 128, 128, 128, 1};
|
||||
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<uint8_t, VoxelSystem*> VoxelTreeElement::_mapIndexToVoxelSystemPointers;
|
||||
|
||||
VoxelSystem* VoxelTreeElement::getVoxelSystem() const {
|
||||
VoxelSystem* VoxelTreeElement::getVoxelSystem() const {
|
||||
if (_voxelSystemIndex > INDEX_FOR_NULL) {
|
||||
if (_mapIndexToVoxelSystemPointers.end() != _mapIndexToVoxelSystemPointers.find(_voxelSystemIndex)) {
|
||||
|
||||
VoxelSystem* voxelSystem = _mapIndexToVoxelSystemPointers[_voxelSystemIndex];
|
||||
VoxelSystem* voxelSystem = _mapIndexToVoxelSystemPointers[_voxelSystemIndex];
|
||||
return voxelSystem;
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ void VoxelTreeElement::setFalseColored(bool isFalseColored) {
|
|||
if (_falseColored && !isFalseColored) {
|
||||
memcpy(&_currentColor,&_trueColor,sizeof(nodeColor));
|
||||
}
|
||||
_falseColored = isFalseColored;
|
||||
_falseColored = isFalseColored;
|
||||
_isDirty = true;
|
||||
_density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed.
|
||||
markWithChangedTime();
|
||||
|
@ -167,7 +167,7 @@ void VoxelTreeElement::calculateAverageFromChildren() {
|
|||
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
|
||||
// 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
|
||||
// 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
|
||||
// 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};
|
||||
if (density > VISIBLE_ABOVE_DENSITY) {
|
||||
// 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
|
||||
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);
|
||||
setDensity(density);
|
||||
}
|
||||
|
||||
// will detect if children are leaves AND the same color
|
||||
// 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
|
||||
bool VoxelTreeElement::collapseChildren() {
|
||||
// scan children, verify that they are ALL present and accounted for
|
||||
|
@ -213,15 +213,15 @@ bool VoxelTreeElement::collapseChildren() {
|
|||
red = childAt->getColor()[0];
|
||||
green = childAt->getColor()[1];
|
||||
blue = childAt->getColor()[2];
|
||||
} else if (red != childAt->getColor()[0] ||
|
||||
} else if (red != childAt->getColor()[0] ||
|
||||
green != childAt->getColor()[1] || blue != childAt->getColor()[2]) {
|
||||
allChildrenMatch=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (allChildrenMatch) {
|
||||
//qDebug("allChildrenMatch: pruning tree\n");
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
|
@ -230,9 +230,9 @@ bool VoxelTreeElement::collapseChildren() {
|
|||
setChildAtIndex(i, NULL); // set it to NULL
|
||||
}
|
||||
nodeColor collapsedColor;
|
||||
collapsedColor[0]=red;
|
||||
collapsedColor[1]=green;
|
||||
collapsedColor[2]=blue;
|
||||
collapsedColor[0]=red;
|
||||
collapsedColor[1]=green;
|
||||
collapsedColor[2]=blue;
|
||||
collapsedColor[3]=1; // color is set
|
||||
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 {
|
||||
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->green = getTrueColor()[GREEN_INDEX];
|
||||
voxelDetails->blue = getTrueColor()[BLUE_INDEX];
|
||||
|
||||
|
||||
*penetratedObject = (void*)voxelDetails;
|
||||
}
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue