mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:07:58 +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 <PerfStat.h>
|
||||||
#include <AudioInjectionManager.h>
|
#include <AudioInjectionManager.h>
|
||||||
#include <AudioInjector.h>
|
#include <AudioInjector.h>
|
||||||
|
#include <OctalCode.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
|
@ -1319,27 +1320,77 @@ void Application::copyVoxels() {
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
selectedNode->printDebugDetails("selected voxel");
|
selectedNode->printDebugDetails("selected voxel");
|
||||||
_voxels.copySubTreeIntoNewTree(selectedNode, &_clipboardTree, true);
|
_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() {
|
void Application::pasteVoxels() {
|
||||||
VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
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);
|
printf("pasteVoxels() _mouseVoxel: %f,%f,%f-%f \n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
//selectedNode->printDebugDetails("selected voxel");
|
//selectedNode->printDebugDetails("selected voxel");
|
||||||
|
|
||||||
// First, create a temporary Paste Tree
|
// Recurse the clipboard tree, where everything is root relative, and send all the colored voxels to
|
||||||
VoxelTree _temporaryPasteTree;
|
// 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
|
// If we have voxels left in the packet, then send the packet
|
||||||
_temporaryPasteTree.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, 0, 0, 0);
|
if (args.bufferInUse > 1) {
|
||||||
|
AgentList::getInstance()->broadcastToAgents(args.messageBuffer, args.bufferInUse, &AGENT_TYPE_VOXEL, 1);
|
||||||
// Paste into the temporary tree
|
}
|
||||||
destinationNode = _temporaryPasteTree.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
|
||||||
_temporaryPasteTree.copyFromTreeIntoSubTree(&_clipboardTree, destinationNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
void Application::initMenu() {
|
||||||
QMenuBar* menuBar = new QMenuBar();
|
QMenuBar* menuBar = new QMenuBar();
|
||||||
_window->setMenuBar(menuBar);
|
_window->setMenuBar(menuBar);
|
||||||
|
|
|
@ -161,6 +161,8 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static bool sendVoxelsOperataion(VoxelNode* node, void* extraData);
|
||||||
|
|
||||||
void initMenu();
|
void initMenu();
|
||||||
void updateFrustumRenderModeAction();
|
void updateFrustumRenderModeAction();
|
||||||
void initDisplay();
|
void initDisplay();
|
||||||
|
|
|
@ -224,6 +224,25 @@ unsigned char* chopOctalCode(unsigned char* originalOctalCode, int chopLevels) {
|
||||||
return newCode;
|
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);
|
bool isDirectParentOfChild(unsigned char *parentOctalCode, unsigned char * childOctalCode);
|
||||||
int branchIndexWithDescendant(unsigned char * ancestorOctalCode, unsigned char * descendantOctalCode);
|
int branchIndexWithDescendant(unsigned char * ancestorOctalCode, unsigned char * descendantOctalCode);
|
||||||
unsigned char * childOctalCode(unsigned char * parentOctalCode, char childNumber);
|
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);
|
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
|
// Note: copyFirstVertexForCode() is preferred because it doesn't allocate memory for the return
|
||||||
// but other than that these do the same thing.
|
// but other than that these do the same thing.
|
||||||
|
|
|
@ -878,8 +878,21 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the octal code
|
// write the octal code
|
||||||
int codeLength = bytesRequiredForCodeLength(*node->getOctalCode());
|
int codeLength;
|
||||||
memcpy(outputBuffer,node->getOctalCode(),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
|
outputBuffer += codeLength; // move the pointer
|
||||||
bytesWritten += codeLength; // keep track of byte count
|
bytesWritten += codeLength; // keep track of byte count
|
||||||
|
@ -1183,6 +1196,7 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat
|
||||||
|
|
||||||
if (rebaseToRoot) {
|
if (rebaseToRoot) {
|
||||||
chopLevels = numberOfThreeBitSectionsInCode(startNode->getOctalCode());
|
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
|
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);
|
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
|
||||||
|
|
||||||
// ask destination tree to read the bitstream
|
// 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