overte-HifiExperiments/libraries/voxels/src/VoxelNode.h
2013-09-03 17:16:06 -07:00

146 lines
5.9 KiB
C++

//
// VoxelNode.h
// hifi
//
// Created by Stephen Birarda on 3/13/13.
//
//
#ifndef __hifi__VoxelNode__
#define __hifi__VoxelNode__
#include <SharedUtil.h>
#include "AABox.h"
#include "ViewFrustum.h"
#include "VoxelConstants.h"
class VoxelTree; // forward declaration
class VoxelNode; // forward declaration
class VoxelSystem; // forward declaration
typedef unsigned char colorPart;
typedef unsigned char nodeColor[4];
typedef unsigned char rgbColor[3];
// Callers who want delete hook callbacks should implement this class
class VoxelNodeDeleteHook {
public:
virtual void nodeDeleted(VoxelNode* node) = 0;
};
class VoxelNode {
public:
VoxelNode(); // root node constructor
VoxelNode(unsigned char * octalCode); // regular constructor
~VoxelNode();
unsigned char* getOctalCode() const { return _octalCode; }
VoxelNode* getChildAtIndex(int childIndex) const { return _children[childIndex]; }
void deleteChildAtIndex(int childIndex);
VoxelNode* removeChildAtIndex(int childIndex);
VoxelNode* addChildAtIndex(int childIndex);
void safeDeepDeleteChildAtIndex(int childIndex); // handles deletion of all descendents
void setColorFromAverageOfChildren();
void setRandomColor(int minimumBrightness);
bool collapseIdenticalLeaves();
const AABox& getAABox() const { return _box; }
const glm::vec3& getCenter() const { return _box.getCenter(); }
const glm::vec3& getCorner() const { return _box.getCorner(); }
float getScale() const { return _box.getSize().x; } // voxelScale = (1 / powf(2, *node->getOctalCode())); }
int getLevel() const { return *_octalCode + 1; } // one based or zero based? this doesn't correctly handle 2 byte case
float getEnclosingRadius() const;
bool isColored() const { return (_trueColor[3]==1); }
bool isInView(const ViewFrustum& viewFrustum) const;
ViewFrustum::location inFrustum(const ViewFrustum& viewFrustum) const;
float distanceToCamera(const ViewFrustum& viewFrustum) const;
float furthestDistanceToCamera(const ViewFrustum& viewFrustum) const;
bool calculateShouldRender(const ViewFrustum* viewFrustum, int boundaryLevelAdjust = 0) const;
// points are assumed to be in Voxel Coordinates (not TREE_SCALE'd)
float distanceSquareToPoint(const glm::vec3& point) const; // when you don't need the actual distance, use this.
float distanceToPoint(const glm::vec3& point) const;
bool isLeaf() const { return _childCount == 0; }
int getChildCount() const { return _childCount; }
void printDebugDetails(const char* label) const;
bool isDirty() const { return _isDirty; }
void clearDirtyBit() { _isDirty = false; }
bool hasChangedSince(uint64_t time) const { return (_lastChanged > time); }
void markWithChangedTime() { _lastChanged = usecTimestampNow(); }
uint64_t getLastChanged() const { return _lastChanged; }
void handleSubtreeChanged(VoxelTree* myTree);
glBufferIndex getBufferIndex() const { return _glBufferIndex; }
bool isKnownBufferIndex() const { return (_glBufferIndex != GLBUFFER_INDEX_UNKNOWN); }
void setBufferIndex(glBufferIndex index) { _glBufferIndex = index; }
VoxelSystem* getVoxelSystem() const { return _voxelSystem; }
void setVoxelSystem(VoxelSystem* voxelSystem) { _voxelSystem = voxelSystem; }
// Used by VoxelSystem for rendering in/out of view and LOD
void setShouldRender(bool shouldRender);
bool getShouldRender() const { return _shouldRender; }
#ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color
void setFalseColor(colorPart red, colorPart green, colorPart blue);
void setFalseColored(bool isFalseColored);
bool getFalseColored() { return _falseColored; }
void setColor(const nodeColor& color);
const nodeColor& getTrueColor() const { return _trueColor; }
const nodeColor& getColor() const { return _currentColor; }
#else
void setFalseColor(colorPart red, colorPart green, colorPart blue) { /* no op */ };
void setFalseColored(bool isFalseColored) { /* no op */ };
bool getFalseColored() { return false; };
void setColor(const nodeColor& color) { memcpy(_trueColor,color,sizeof(nodeColor)); };
void setDensity(const float density) { _density = density; };
const nodeColor& getTrueColor() const { return _trueColor; };
const nodeColor& getColor() const { return _trueColor; };
#endif
void setDensity(float density) { _density = density; }
float getDensity() const { return _density; }
void setSourceID(uint16_t sourceID) { _sourceID = sourceID; }
uint16_t getSourceID() const { return _sourceID; }
static void addDeleteHook(VoxelNodeDeleteHook* hook);
static void removeDeleteHook(VoxelNodeDeleteHook* hook);
void recalculateSubTreeNodeCount();
unsigned long getSubTreeNodeCount() const { return _subtreeNodeCount; }
unsigned long getSubTreeInternalNodeCount() const { return _subtreeNodeCount - _subtreeLeafNodeCount; }
unsigned long getSubTreeLeafNodeCount() const { return _subtreeLeafNodeCount; }
private:
void calculateAABox();
void init(unsigned char * octalCode);
void notifyDeleteHooks();
nodeColor _trueColor;
#ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color
nodeColor _currentColor;
bool _falseColored;
#endif
glBufferIndex _glBufferIndex;
VoxelSystem* _voxelSystem;
bool _isDirty;
uint64_t _lastChanged;
bool _shouldRender;
AABox _box;
unsigned char* _octalCode;
VoxelNode* _children[8];
int _childCount;
unsigned long _subtreeNodeCount;
unsigned long _subtreeLeafNodeCount;
float _density; // If leaf: density = 1, if internal node: 0-1 density of voxels inside
uint16_t _sourceID;
static std::vector<VoxelNodeDeleteHook*> _hooks;
};
#endif /* defined(__hifi__VoxelNode__) */