latest copy paste

This commit is contained in:
ZappoMan 2013-05-29 15:02:28 -07:00
parent 377fb1e936
commit 46c6f2f9b5
9 changed files with 95 additions and 41 deletions

View file

@ -1159,6 +1159,7 @@ void Application::copyVoxels() {
printf("copyVoxels() _mouseVoxel: %f,%f,%f-%f \n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
if (selectedNode) {
selectedNode->printDebugDetails("selected voxel");
_voxels.copySubTreeIntoNewTree(selectedNode, &_clipboardTree, true);
}
}
@ -1166,7 +1167,17 @@ void Application::pasteVoxels() {
VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
printf("pasteVoxels() _mouseVoxel: %f,%f,%f-%f \n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
if (selectedNode) {
selectedNode->printDebugDetails("selected voxel");
//selectedNode->printDebugDetails("selected voxel");
// First, create a temporary Paste Tree
VoxelTree _temporaryPasteTree;
// Create a destination node to paste into
_temporaryPasteTree.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, 0, 0, 0);
// Paste into the temporary tree
destinationNode = _temporaryPasteTree.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
_temporaryPasteTree.copyFromTreeIntoSubTree(&_clipboardTree, destinationNode);
}
}

View file

@ -184,6 +184,8 @@ private:
Stars _stars;
VoxelSystem _voxels;
VoxelTree _clipboardTree; // if I copy/paste
QByteArray _voxelsFilename;
bool _wantToKillLocalVoxels;

View file

@ -1156,3 +1156,12 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo
_tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug);
setupNewVoxelsForDrawing();
};
void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) {
_tree->copySubTreeIntoNewTree(startNode, destinationTree, rebaseToRoot);
}
void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) {
_tree->copyFromTreeIntoSubTree(sourceTree, destinationNode);
}

View file

@ -85,6 +85,10 @@ public:
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, VoxelTree* destinationTree, bool rebaseToRoot);
void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode);
private:
// disallow copying of VoxelSystem objects
VoxelSystem(const VoxelSystem&);

View file

@ -21,19 +21,6 @@
#include <OctalCode.h>
int main(int argc, const char * argv[]) {
unsigned char test1[2] = {2, 0xE0 };
unsigned char test2[2] = {2, 0xFC };
unsigned char* result1 = chopOctalCode((unsigned char*)&test1, 1);
printOctalCode((unsigned char*)&test1);
printOctalCode(result1);
unsigned char* result2 = chopOctalCode((unsigned char*)&test2, 1);
printOctalCode((unsigned char*)&test2);
printOctalCode(result2);
timeval startup_time;
gettimeofday(&startup_time, NULL);

View file

@ -170,14 +170,18 @@ OctalCodeComparison compareOctalCodes(unsigned char* codeA, unsigned char* codeB
char getOctalCodeSectionValue(unsigned char* octalCode, int section) {
return sectionValue(octalCode + 1 + (3 * section / 8), (3 * section) % 8);
int startAtByte = 1 + (3 * section / 8);
char startIndexInByte = (3 * section) % 8;
unsigned char* startByte = octalCode + startAtByte;
return sectionValue(startByte, startIndexInByte);
}
void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectionValue) {
unsigned char* byteAt = octalCode + 1 + (3 * section / 8);
char bitInByte = (3 * section) % 8;
char shiftBy = 8 - bitInByte - 3;
const unsigned char UNSHIFTED_MASK = 0x03;
const unsigned char UNSHIFTED_MASK = 0x07;
unsigned char shiftedMask;
unsigned char shiftedValue;
@ -190,13 +194,17 @@ void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectio
shiftedValue = sectionValue >> -shiftBy;
}
byteAt[0] = byteAt[0] & (shiftedMask | shiftedValue);
unsigned char oldValue = *byteAt & ~shiftedMask;
unsigned char newValue = oldValue | shiftedValue;
*byteAt = newValue;
if (bitInByte >= 6) {
shiftBy = bitInByte + 1;
shiftedMask = UNSHIFTED_MASK << shiftBy;
shiftedValue = sectionValue << shiftBy;
byteAt[1] = byteAt[1] & (shiftedMask | shiftedValue);
oldValue = byteAt[1] & ~shiftedMask;
newValue = oldValue | shiftedValue;
byteAt[1] = newValue;
}
}

View file

@ -19,6 +19,7 @@ unsigned char * childOctalCode(unsigned char * parentOctalCode, char childNumber
unsigned char* chopOctalCode(unsigned char* originalOctalCode, int chopLevels);
unsigned char* rebaseOctalCode(unsigned char* originalOctalCode, unsigned char* newParentOctalCode);
int numberOfThreeBitSectionsInCode(unsigned char * octalCode);
// Note: copyFirstVertexForCode() is preferred because it doesn't allocate memory for the return

View file

@ -212,10 +212,15 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
}
void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes,
bool includeColor, bool includeExistsBits) {
bool includeColor, bool includeExistsBits, VoxelNode* destinationNode) {
int bytesRead = 0;
unsigned char* bitstreamAt = bitstream;
// If destination node is not included, set it to root
if (!destinationNode) {
destinationNode = rootNode;
}
_nodesChangedFromBitstream = 0;
// Keep looping through the buffer calling readNodeData() this allows us to pack multiple root-relative Octal codes
@ -223,14 +228,14 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int
// if there are more bytes after that, it's assumed to be another root relative tree
while (bitstreamAt < bitstream + bufferSizeBytes) {
VoxelNode* bitstreamRootNode = nodeForOctalCode(rootNode, (unsigned char *)bitstreamAt, NULL);
VoxelNode* bitstreamRootNode = nodeForOctalCode(destinationNode, (unsigned char *)bitstreamAt, NULL);
if (*bitstreamAt != *bitstreamRootNode->getOctalCode()) {
// if the octal code returned is not on the same level as
// the code being searched for, we have VoxelNodes to create
// Note: we need to create this node relative to root, because we're assuming that the bitstream for the initial
// octal code is always relative to root!
bitstreamRootNode = createMissingNode(rootNode, (unsigned char*) bitstreamAt);
bitstreamRootNode = createMissingNode(destinationNode, (unsigned char*) bitstreamAt);
if (bitstreamRootNode->isDirty()) {
_isDirty = true;
_nodesChangedFromBitstream++;
@ -862,7 +867,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
// How many bytes have we written so far at this level;
int bytesWritten = 0;
@ -882,7 +887,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int currentEncodeLevel = 0;
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, node, outputBuffer, availableBytes,
bag, viewFrustum, includeColor, includeExistsBits,
bag, viewFrustum, includeColor, includeExistsBits, chopLevels,
deltaViewFrustum, lastViewFrustum);
// if childBytesWritten == 1 then something went wrong... that's not possible
@ -907,7 +912,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node,
unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
// How many bytes have we written so far at this level;
int bytesAtThisLevel = 0;
@ -1062,7 +1067,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
int thisLevel = currentEncodeLevel;
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
outputBuffer, availableBytes, bag,
viewFrustum, includeColor, includeExistsBits,
viewFrustum, includeColor, includeExistsBits, chopLevels,
deltaViewFrustum, lastViewFrustum);
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
@ -1173,6 +1178,12 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat
VoxelNodeBag nodeBag;
// If we were given a specific node, start from there, otherwise start from root
nodeBag.insert(startNode);
int chopLevels = 0;
if (rebaseToRoot) {
chopLevels = numberOfThreeBitSectionsInCode(startNode->getOctalCode());
}
static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static
int bytesWritten = 0;
@ -1182,11 +1193,32 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat
// ask our tree to write a bitsteam
bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0],
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels);
// ask destination tree to read the bitstream
destinationTree->readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS);
}
}
void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) {
printLog("copyFromTreeIntoSubTree()...\n");
VoxelNodeBag nodeBag;
// If we were given a specific node, start from there, otherwise start from root
nodeBag.insert(sourceTree->rootNode);
static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static
int bytesWritten = 0;
while (!nodeBag.isEmpty()) {
VoxelNode* subTree = nodeBag.extract();
// ask our tree to write a bitsteam
bytesWritten = sourceTree->encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0],
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
// ask destination tree to read the bitstream
readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS);
}
}

View file

@ -44,19 +44,20 @@ public:
VoxelTree(bool shouldReaverage = false);
~VoxelTree();
VoxelNode *rootNode;
VoxelNode* rootNode;
int leavesWrittenToBitstream;
void eraseAllVoxels();
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes,
bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS);
void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false);
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = ACTUALLY_DELETE,
void processRemoveVoxelBitstream(unsigned char* bitstream, int bufferSizeBytes);
void readBitstreamToTree(unsigned char* bitstream, unsigned long int bufferSizeBytes,
bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS,
VoxelNode* destinationNode = NULL);
void readCodeColorBufferToTree(unsigned char* codeColorBuffer, bool destructive = false);
void deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage = ACTUALLY_DELETE,
bool collapseEmptyTrees = DONT_COLLAPSE);
void printTreeForDebugging(VoxelNode *startNode);
void reaverageVoxelColors(VoxelNode *startNode);
void printTreeForDebugging(VoxelNode* startNode);
void reaverageVoxelColors(VoxelNode* startNode);
void deleteVoxelAt(float x, float y, float z, float s, bool stage = false);
VoxelNode* getVoxelAt(float x, float y, float z, float s) const;
@ -70,7 +71,7 @@ public:
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
VoxelNodeBag& bag, const ViewFrustum* viewFrustum,
bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS,
bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, int chopLevels = 0,
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const;
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
@ -97,20 +98,19 @@ public:
unsigned long getVoxelCount();
void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot);
void copyNodeIntoTree(VoxelNode* node);
void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode);
private:
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum);
static bool countVoxelsOperation(VoxelNode* node, void* extraData);
static bool copySubTreeIntoNewTreeOperation(VoxelNode* node, void* extraData);
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;