more work on copy and paste

This commit is contained in:
ZappoMan 2013-05-31 11:52:18 -07:00
parent b0397e8eb9
commit e5e200345b
5 changed files with 102 additions and 17 deletions

View file

@ -40,6 +40,7 @@
#include <PerfStat.h>
#include <AudioInjectionManager.h>
#include <AudioInjector.h>
#include <OctalCode.h>
#include "Application.h"
#include "InterfaceConfig.h"
@ -1319,26 +1320,76 @@ void Application::copyVoxels() {
if (selectedNode) {
selectedNode->printDebugDetails("selected voxel");
_voxels.copySubTreeIntoNewTree(selectedNode, &_clipboardTree, true);
// debug tree
_clipboardTree.printTreeForDebugging(_clipboardTree.rootNode);
}
}
const int MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE = 1500;
struct SendVoxelsOperataionArgs {
unsigned char* newBaseOctCode;
unsigned char messageBuffer[MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE];
int bufferInUse;
};
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");
// First, create a temporary Paste Tree
VoxelTree _temporaryPasteTree;
// Recurse the clipboard tree, where everything is root relative, and send all the colored voxels to
// the server as an set voxel message, this will also rebase the voxels to the new location
SendVoxelsOperataionArgs args;
args.messageBuffer[0] = PACKET_HEADER_SET_VOXEL_DESTRUCTIVE;
unsigned short int* sequenceAt = (unsigned short int*)&args.messageBuffer[sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE)];
*sequenceAt = 0;
args.bufferInUse = sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int); // set to command + sequence
args.newBaseOctCode = selectedNode->getOctalCode();
_clipboardTree.recurseTreeWithOperation(sendVoxelsOperataion, &args);
// 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);
// If we have voxels left in the packet, then send the packet
if (args.bufferInUse > 1) {
AgentList::getInstance()->broadcastToAgents(args.messageBuffer, args.bufferInUse, &AGENT_TYPE_VOXEL, 1);
}
}
}
bool Application::sendVoxelsOperataion(VoxelNode* node, void* extraData) {
SendVoxelsOperataionArgs* args = (SendVoxelsOperataionArgs*)extraData;
if (node->isColored()) {
const int SIZE_OF_COLOR_DATA = 3;
const int RED_INDEX = 0;
const int GREEN_INDEX = 1;
const int BLUE_INDEX = 2;
unsigned char* nodeOctalCode = node->getOctalCode();
printOctalCode(nodeOctalCode);
unsigned char* rebasedCodeColorBuffer = rebaseOctalCode(nodeOctalCode, args->newBaseOctCode, true);
printOctalCode(rebasedCodeColorBuffer);
int rebasedCodeLength = numberOfThreeBitSectionsInCode(rebasedCodeColorBuffer);
int bytesInRebasedCode = bytesRequiredForCodeLength(rebasedCodeLength);
int codeAndColorLength = bytesInRebasedCode + SIZE_OF_COLOR_DATA;
// copy the colors over
rebasedCodeColorBuffer[bytesInRebasedCode + RED_INDEX ] = node->getColor()[RED_INDEX ];
rebasedCodeColorBuffer[bytesInRebasedCode + GREEN_INDEX] = node->getColor()[GREEN_INDEX];
rebasedCodeColorBuffer[bytesInRebasedCode + BLUE_INDEX ] = node->getColor()[BLUE_INDEX ];
// if we have room don't have room in the buffer, then send the previously generated message first
if (args->bufferInUse + codeAndColorLength > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) {
AgentList::getInstance()->broadcastToAgents(args->messageBuffer, args->bufferInUse, &AGENT_TYPE_VOXEL, 1);
args->bufferInUse = sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(int); // reset to command + sequence
}
// copy this node's code color details into our buffer.
memcpy(&args->messageBuffer[args->bufferInUse], rebasedCodeColorBuffer, codeAndColorLength);
args->bufferInUse += codeAndColorLength;
}
return true; // keep going
}
void Application::initMenu() {
QMenuBar* menuBar = new QMenuBar();

View file

@ -160,6 +160,8 @@ private slots:
void pasteVoxels();
private:
static bool sendVoxelsOperataion(VoxelNode* node, void* extraData);
void initMenu();
void updateFrustumRenderModeAction();

View file

@ -224,6 +224,25 @@ unsigned char* chopOctalCode(unsigned char* originalOctalCode, int chopLevels) {
return newCode;
}
unsigned char* rebaseOctalCode(unsigned char* originalOctalCode, unsigned char* newParentOctalCode) {
unsigned char* rebaseOctalCode(unsigned char* originalOctalCode, unsigned char* newParentOctalCode, bool includeColorSpace) {
int oldCodeLength = numberOfThreeBitSectionsInCode(originalOctalCode);
int newParentCodeLength = numberOfThreeBitSectionsInCode(newParentOctalCode);
int newCodeLength = newParentCodeLength + oldCodeLength;
const int COLOR_SPACE = 3;
int bufferLength = newCodeLength + (includeColorSpace ? COLOR_SPACE : 0);
unsigned char* newCode = new unsigned char[bufferLength];
*newCode = newCodeLength; // set the length byte
// copy parent code section first
for (int sectionFromParent = 0; sectionFromParent < newParentCodeLength; sectionFromParent++) {
char sectionValue = getOctalCodeSectionValue(newParentOctalCode, sectionFromParent);
setOctalCodeSectionValue(newCode, sectionFromParent, sectionValue);
}
// copy original code section next
for (int sectionFromOriginal = 0; sectionFromOriginal < oldCodeLength; sectionFromOriginal++) {
char sectionValue = getOctalCodeSectionValue(originalOctalCode, sectionFromOriginal);
setOctalCodeSectionValue(newCode, sectionFromOriginal + newParentCodeLength, sectionValue);
}
return newCode;
}

View file

@ -16,11 +16,10 @@ int bytesRequiredForCodeLength(unsigned char threeBitCodes);
bool isDirectParentOfChild(unsigned char *parentOctalCode, unsigned char * childOctalCode);
int branchIndexWithDescendant(unsigned char * ancestorOctalCode, unsigned char * descendantOctalCode);
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);
unsigned char* chopOctalCode(unsigned char* originalOctalCode, int chopLevels);
unsigned char* rebaseOctalCode(unsigned char* originalOctalCode, unsigned char* newParentOctalCode,
bool includeColorSpace = false);
// Note: copyFirstVertexForCode() is preferred because it doesn't allocate memory for the return
// but other than that these do the same thing.

View file

@ -878,9 +878,22 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
}
// write the octal code
int codeLength = bytesRequiredForCodeLength(*node->getOctalCode());
memcpy(outputBuffer,node->getOctalCode(),codeLength);
int codeLength;
if (chopLevels) {
unsigned char* newCode = chopOctalCode(node->getOctalCode(), chopLevels);
if (newCode) {
codeLength = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(newCode));
memcpy(outputBuffer, newCode, codeLength);
delete newCode;
} else {
codeLength = 1; // chopped to root!
*outputBuffer = 0; // root
}
} else {
codeLength = bytesRequiredForCodeLength(*node->getOctalCode());
memcpy(outputBuffer, node->getOctalCode(), codeLength);
}
outputBuffer += codeLength; // move the pointer
bytesWritten += codeLength; // keep track of byte count
availableBytes -= codeLength; // keep track or remaining space
@ -1183,6 +1196,7 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat
if (rebaseToRoot) {
chopLevels = numberOfThreeBitSectionsInCode(startNode->getOctalCode());
printLog("copySubTreeIntoNewTree()...rebaseToRoot=true, chopLevels=%d\n", chopLevels);
}
static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static
@ -1218,7 +1232,7 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin
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);
readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS,destinationNode);
}
}