mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 03:53:52 +02:00
latest copy paste
This commit is contained in:
parent
377fb1e936
commit
46c6f2f9b5
9 changed files with 95 additions and 41 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -184,6 +184,8 @@ private:
|
|||
Stars _stars;
|
||||
|
||||
VoxelSystem _voxels;
|
||||
VoxelTree _clipboardTree; // if I copy/paste
|
||||
|
||||
QByteArray _voxelsFilename;
|
||||
bool _wantToKillLocalVoxels;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue