mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
more work on copy and paste
This commit is contained in:
parent
b0397e8eb9
commit
e5e200345b
5 changed files with 102 additions and 17 deletions
|
@ -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();
|
||||
|
|
|
@ -160,6 +160,8 @@ private slots:
|
|||
void pasteVoxels();
|
||||
|
||||
private:
|
||||
|
||||
static bool sendVoxelsOperataion(VoxelNode* node, void* extraData);
|
||||
|
||||
void initMenu();
|
||||
void updateFrustumRenderModeAction();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue