Merge pull request #699 from ZappoMan/voxel_animation

Fix crashing bug in voxel-server related to animation
This commit is contained in:
Philip Rosedale 2013-07-17 13:48:26 -07:00
commit 0550bc643b
6 changed files with 95 additions and 33 deletions

View file

@ -54,6 +54,8 @@ void VoxelNode::init(unsigned char * octalCode) {
}
VoxelNode::~VoxelNode() {
notifyDeleteHooks();
delete[] _octalCode;
// delete all of this node's children
@ -387,3 +389,44 @@ float VoxelNode::distanceToPoint(const glm::vec3& point) const {
float distance = sqrtf(glm::dot(temp, temp));
return distance;
}
VoxelNodeDeleteHook VoxelNode::_hooks[VOXEL_NODE_MAX_DELETE_HOOKS];
void* VoxelNode::_hooksExtraData[VOXEL_NODE_MAX_DELETE_HOOKS];
int VoxelNode::_hooksInUse = 0;
int VoxelNode::addDeleteHook(VoxelNodeDeleteHook hook, void* extraData) {
// If first use, initialize the _hooks array
if (_hooksInUse == 0) {
memset(_hooks, 0, sizeof(_hooks));
memset(_hooksExtraData, 0, sizeof(_hooksExtraData));
}
// find first available slot
for (int i = 0; i < VOXEL_NODE_MAX_DELETE_HOOKS; i++) {
if (!_hooks[i]) {
_hooks[i] = hook;
_hooksExtraData[i] = extraData;
_hooksInUse++;
return i;
}
}
// if we got here, then we're out of room in our hooks, return error
return VOXEL_NODE_NO_MORE_HOOKS_AVAILABLE;
}
void VoxelNode::removeDeleteHook(int hookID) {
if (_hooks[hookID]) {
_hooks[hookID] = NULL;
_hooksExtraData[hookID] = NULL;
_hooksInUse--;
}
}
void VoxelNode::notifyDeleteHooks() {
if (_hooksInUse > 0) {
for (int i = 0; i < VOXEL_NODE_MAX_DELETE_HOOKS; i++) {
if (_hooks[i]) {
_hooks[i](this, _hooksExtraData[i]);
}
}
}
}

View file

@ -15,33 +15,19 @@
#include "VoxelConstants.h"
class VoxelTree; // forward delclaration
class VoxelNode; // forward delclaration
typedef unsigned char colorPart;
typedef unsigned char nodeColor[4];
typedef unsigned char rgbColor[3];
// Callback function, for delete hook
typedef void (*VoxelNodeDeleteHook)(VoxelNode* node, void* extraData);
const int VOXEL_NODE_MAX_DELETE_HOOKS = 100;
const int VOXEL_NODE_NO_MORE_HOOKS_AVAILABLE = -1;
class VoxelNode {
private:
nodeColor _trueColor;
#ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color
nodeColor _currentColor;
bool _falseColored;
#endif
glBufferIndex _glBufferIndex;
bool _isDirty;
uint64_t _lastChanged;
bool _shouldRender;
bool _isStagedForDeletion;
AABox _box;
unsigned char* _octalCode;
VoxelNode* _children[8];
int _childCount;
float _density; // If leaf: density = 1, if internal node: 0-1 density of voxels inside
void calculateAABox();
void init(unsigned char * octalCode);
public:
VoxelNode(); // root node constructor
VoxelNode(unsigned char * octalCode); // regular constructor
@ -118,6 +104,33 @@ public:
const nodeColor& getTrueColor() const { return _trueColor; };
const nodeColor& getColor() const { return _trueColor; };
#endif
static int addDeleteHook(VoxelNodeDeleteHook hook, void* extraData = NULL);
static void removeDeleteHook(int hookID);
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;
bool _isDirty;
uint64_t _lastChanged;
bool _shouldRender;
bool _isStagedForDeletion;
AABox _box;
unsigned char* _octalCode;
VoxelNode* _children[8];
int _childCount;
float _density; // If leaf: density = 1, if internal node: 0-1 density of voxels inside
static VoxelNodeDeleteHook _hooks[VOXEL_NODE_MAX_DELETE_HOOKS];
static void* _hooksExtraData[VOXEL_NODE_MAX_DELETE_HOOKS];
static int _hooksInUse;
};
#endif /* defined(__hifi__VoxelNode__) */

View file

@ -9,7 +9,15 @@
#include "VoxelNodeBag.h"
#include <OctalCode.h>
VoxelNodeBag::VoxelNodeBag() :
_bagElements(NULL),
_elementsInUse(0),
_sizeOfElementsArray(0) {
_hookID = VoxelNode::addDeleteHook(voxelNodeDeleteHook, (void*)this);
};
VoxelNodeBag::~VoxelNodeBag() {
VoxelNode::removeDeleteHook(_hookID);
deleteAll();
}
@ -118,3 +126,9 @@ void VoxelNodeBag::remove(VoxelNode* node) {
}
}
void VoxelNodeBag::voxelNodeDeleteHook(VoxelNode* node, void* extraData) {
VoxelNodeBag* theBag = (VoxelNodeBag*)extraData;
theBag->remove(node); // note: remove can safely handle nodes that aren't in it, so we don't need to check contains()
}

View file

@ -19,11 +19,7 @@
class VoxelNodeBag {
public:
VoxelNodeBag() :
_bagElements(NULL),
_elementsInUse(0),
_sizeOfElementsArray(0) {};
VoxelNodeBag();
~VoxelNodeBag();
void insert(VoxelNode* node); // put a node into the bag
@ -36,11 +32,14 @@ public:
void deleteAll();
static void voxelNodeDeleteHook(VoxelNode* node, void* extraData);
private:
VoxelNode** _bagElements;
int _elementsInUse;
int _sizeOfElementsArray;
int _hookID;
};
#endif /* defined(__hifi__VoxelNodeBag__) */

View file

@ -1011,12 +1011,6 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer,
// How many bytes have we written so far at this level;
int bytesWritten = 0;
// These two cases should not ever happen... but if they do, we don't want to crash.
if (!node || !node->getOctalCode()) {
qDebug("VoxelTree::encodeTreeBitstream() BAD VoxelNode! Bailing!");
return bytesWritten;
}
// If we're at a node that is out of view, then we can return, because no nodes below us will be in view!
if (params.viewFrustum && !node->isInView(*params.viewFrustum)) {
return bytesWritten;

View file

@ -384,7 +384,6 @@ void attachVoxelNodeDataToNode(Node* newNode) {
}
int main(int argc, const char * argv[]) {
pthread_mutex_init(&::treeLock, NULL);
qInstallMsgHandler(sharedMessageHandler);