// // VoxelSystem.h // interface // // Created by Philip on 12/31/12. // Copyright (c) 2012 High Fidelity, Inc. All rights reserved. // #ifndef __interface__VoxelSystem__ #define __interface__VoxelSystem__ #include "InterfaceConfig.h" #include #include #include #include #include #include #include #include "Camera.h" #include "Util.h" #include "world.h" #include "renderer/VoxelShader.h" class ProgramObject; const int NUM_CHILDREN = 8; struct VoxelShaderVBOData { float x, y, z; // position float s; // size unsigned char r,g,b; // color }; class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public NodeListHook { Q_OBJECT public: VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM); ~VoxelSystem(); void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; } int getDataSourceID() const { return _dataSourceID; } int parseData(unsigned char* sourceBuffer, int numBytes); virtual void init(); void simulate(float deltaTime) { } void render(bool texture); void changeTree(VoxelTree* newTree); VoxelTree* getTree() const { return _tree; } ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } unsigned long getVoxelsUpdated() const { return _voxelsUpdated; } unsigned long getVoxelsRendered() const { return _voxelsInReadArrays; } void loadVoxelsFile(const char* fileName,bool wantColorRandomizer); void writeToSVOFile(const char* filename, VoxelNode* node) const; bool readFromSVOFile(const char* filename); bool readFromSquareARGB32Pixels(const char* filename); bool readFromSchematicFile(const char* filename); void setUseVoxelShader(bool useVoxelShader); void setMaxVoxels(int maxVoxels); long int getMaxVoxels() const { return _maxVoxels; } unsigned long getVoxelMemoryUsageRAM() const { return _memoryUsageRAM; } unsigned long getVoxelMemoryUsageVBO() const { return _memoryUsageVBO; } bool hasVoxelMemoryUsageGPU() const { return _hasMemoryUsageGPU; } unsigned long getVoxelMemoryUsageGPU(); long int getVoxelsCreated(); long int getVoxelsColored(); long int getVoxelsBytesRead(); float getVoxelsCreatedPerSecondAverage(); float getVoxelsColoredPerSecondAverage(); float getVoxelsBytesReadPerSecondAverage(); void killLocalVoxels(); virtual void removeOutOfView(); 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); VoxelNode* getVoxelAt(float x, float y, float z, float s) const; 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, creationMode mode, bool destructive = false, bool debug = false); void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destinationTree, bool rebaseToRoot); void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot); void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode); void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); CoverageMapV2 myCoverageMapV2; CoverageMap myCoverageMap; virtual void nodeDeleted(VoxelNode* node); virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); signals: void importSize(float x, float y, float z); void importProgress(int progress); public slots: void collectStatsForTreesAndVBOs(); // Methods that recurse tree void randomizeVoxelColors(); void falseColorizeRandom(); void trueColorize(); void falseColorizeInView(); void falseColorizeDistanceFromView(); void falseColorizeRandomEveryOther(); void falseColorizeOccluded(); void falseColorizeOccludedV2(); void falseColorizeBySource(); void forceRedrawEntireTree(); void clearAllNodesBufferIndex(); void cancelImport(); void setUseByteNormals(bool useByteNormals); protected: float _treeScale; int _maxVoxels; VoxelTree* _tree; void setupNewVoxelsForDrawing(); glm::vec3 computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const; virtual void updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex, float voxelScale, const nodeColor& color); virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd); virtual void updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd); virtual void applyScaleAndBindProgram(bool texture); virtual void removeScaleAndReleaseProgram(bool texture); private: // disallow copying of VoxelSystem objects VoxelSystem(const VoxelSystem&); VoxelSystem& operator= (const VoxelSystem&); bool _initialized; int _callsToTreesToArrays; VoxelNodeBag _removedVoxels; // Operation functions for tree recursion methods static int _nodeCount; static bool randomColorOperation(VoxelNode* node, void* extraData); static bool falseColorizeRandomOperation(VoxelNode* node, void* extraData); static bool trueColorizeOperation(VoxelNode* node, void* extraData); static bool falseColorizeInViewOperation(VoxelNode* node, void* extraData); static bool falseColorizeDistanceFromViewOperation(VoxelNode* node, void* extraData); static bool getDistanceFromViewRangeOperation(VoxelNode* node, void* extraData); static bool removeOutOfViewOperation(VoxelNode* node, void* extraData); static bool falseColorizeRandomEveryOtherOperation(VoxelNode* node, void* extraData); static bool collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData); static bool falseColorizeOccludedOperation(VoxelNode* node, void* extraData); static bool falseColorizeSubTreeOperation(VoxelNode* node, void* extraData); static bool falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData); static bool falseColorizeBySourceOperation(VoxelNode* node, void* extraData); static bool killSourceVoxelsOperation(VoxelNode* node, void* extraData); static bool forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData); static bool clearAllNodesBufferIndexOperation(VoxelNode* node, void* extraData); int updateNodeInArraysAsFullVBO(VoxelNode* node); int updateNodeInArraysAsPartialVBO(VoxelNode* node); void copyWrittenDataToReadArraysFullVBOs(); void copyWrittenDataToReadArraysPartialVBOs(); void updateVBOs(); unsigned long getFreeMemoryGPU(); // these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here static float _maxDistance; static float _minDistance; GLfloat* _readVerticesArray; GLubyte* _readColorsArray; GLfloat* _writeVerticesArray; GLubyte* _writeColorsArray; bool* _writeVoxelDirtyArray; bool* _readVoxelDirtyArray; unsigned long _voxelsUpdated; unsigned long _voxelsInReadArrays; unsigned long _voxelsInWriteArrays; unsigned long _abandonedVBOSlots; bool _writeRenderFullVBO; bool _readRenderFullVBO; int _setupNewVoxelsForDrawingLastElapsed; uint64_t _setupNewVoxelsForDrawingLastFinished; uint64_t _lastViewCulling; int _lastViewCullingElapsed; void initVoxelMemory(); void cleanupVoxelMemory(); bool _useByteNormals; bool _useVoxelShader; GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes VoxelShaderVBOData* _writeVoxelShaderData; VoxelShaderVBOData* _readVoxelShaderData; GLuint _vboVerticesID; GLuint _vboNormalsID; GLuint _vboColorsID; GLuint _vboIndicesID; pthread_mutex_t _bufferWriteLock; pthread_mutex_t _treeLock; ViewFrustum _lastKnowViewFrustum; ViewFrustum _lastStableViewFrustum; ViewFrustum* _viewFrustum; int newTreeToArrays(VoxelNode *currentNode); void cleanupRemovedVoxels(); void copyWrittenDataToReadArrays(bool fullVBOs); void updateFullVBOs(); // all voxels in the VBO void updatePartialVBOs(); // multiple segments, only dirty voxels bool _voxelsDirty; static ProgramObject _perlinModulateProgram; int _hookID; std::vector _freeIndexes; void freeBufferIndex(glBufferIndex index); void clearFreeBufferIndexes(); glBufferIndex getNextBufferIndex(); bool _falseColorizeBySource; int _dataSourceID; int _voxelServerCount; unsigned long _memoryUsageRAM; unsigned long _memoryUsageVBO; unsigned long _initialMemoryUsageGPU; bool _hasMemoryUsageGPU; }; #endif