Merge pull request #312 from ZappoMan/master

support for "destructive" vs "non-destructive" createVoxel()
This commit is contained in:
Philip Rosedale 2013-05-14 14:36:47 -07:00
commit 1c2251a7d3
8 changed files with 79 additions and 52 deletions

View file

@ -147,6 +147,7 @@ Application::Application(int& argc, char** argv) :
_paintOn(false),
_dominantColor(0),
_perfStatsOn(false),
_destructiveAddVoxel(false),
_chatEntryOn(false),
_oculusTextureID(0),
_oculusProgram(0),
@ -989,6 +990,10 @@ void Application::cycleFrustumRenderMode() {
updateFrustumRenderModeAction();
}
void Application::setDestructivePaint(bool destructive) {
_destructiveAddVoxel = destructive;
}
void Application::setRenderWarnings(bool renderWarnings) {
_voxels.setRenderPipelineWarnings(renderWarnings);
}
@ -1075,6 +1080,7 @@ void Application::initMenu() {
_renderStatsOn->setShortcut(Qt::Key_Slash);
(_logOn = toolsMenu->addAction("Log"))->setCheckable(true);
_logOn->setChecked(true);
toolsMenu->addAction("Create Voxel is Destructive", this, SLOT(setDestructivePaint(bool)))->setCheckable(true);
QMenu* frustumMenu = menuBar->addMenu("Frustum");
(_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true);
@ -1295,7 +1301,8 @@ void Application::updateAvatar(float deltaTime) {
_paintingVoxel.y >= 0.0 && _paintingVoxel.y <= 1.0 &&
_paintingVoxel.z >= 0.0 && _paintingVoxel.z <= 1.0) {
sendVoxelEditMessage(PACKET_HEADER_SET_VOXEL, _paintingVoxel);
PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
sendVoxelEditMessage(message, _paintingVoxel);
}
}
}
@ -1876,19 +1883,21 @@ void Application::addVoxelInFrontOfAvatar() {
detail.green = 128;
detail.blue = 128;
sendVoxelEditMessage(PACKET_HEADER_SET_VOXEL, detail);
PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
sendVoxelEditMessage(message, detail);
// create the voxel locally so it appears immediately
_voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue);
_voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue, _destructiveAddVoxel);
}
void Application::addVoxelUnderCursor() {
if (_mouseVoxel.s != 0) {
sendVoxelEditMessage(PACKET_HEADER_SET_VOXEL, _mouseVoxel);
PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
sendVoxelEditMessage(message, _mouseVoxel);
// create the voxel locally so it appears immediately
_voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s,
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue);
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel);
}
}

View file

@ -76,6 +76,7 @@ private slots:
void setFrustumOffset(bool frustumOffset);
void cycleFrustumRenderMode();
void setDestructivePaint(bool destructive);
void setRenderWarnings(bool renderWarnings);
void doKillLocalVoxels();
void doRandomizeVoxelColors();
@ -200,6 +201,7 @@ private:
VoxelDetail _paintingVoxel; // The voxel we're painting if we're painting
bool _perfStatsOn; // Do we want to display perfStats?
bool _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive
ChatEntry _chatEntry; // chat entry field
bool _chatEntryOn; // Whether to show the chat entry

View file

@ -1020,22 +1020,24 @@ VoxelNode* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const {
return _tree->getVoxelAt(x, y, z, s);
};
void VoxelSystem::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue) {
void VoxelSystem::createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
pthread_mutex_lock(&_treeLock);
//printLog("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);
_tree->createVoxel(x, y, z, s, red, green, blue);
_tree->createVoxel(x, y, z, s, red, green, blue, destructive);
setupNewVoxelsForDrawing();
pthread_mutex_unlock(&_treeLock);
};
void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color) {
_tree->createLine(point1, point2, unitSize, color);
void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
_tree->createLine(point1, point2, unitSize, color, destructive);
setupNewVoxelsForDrawing();
};
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug) {
_tree->createSphere(r, xc, yc, zc, s, solid, mode, debug);
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid,
creationMode mode, bool destructive, bool debug) {
_tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug);
setupNewVoxelsForDrawing();
};

View file

@ -73,9 +73,11 @@ public:
void deleteVoxelAt(float x, float y, float z, float s);
VoxelNode* getVoxelAt(float x, float y, float z, float s) const;
void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue);
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug = false);
void createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
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);
private:
int _callsToTreesToArrays;

View file

@ -21,6 +21,7 @@ const PACKET_HEADER PACKET_HEADER_HEAD_DATA = 'H';
const PACKET_HEADER PACKET_HEADER_Z_COMMAND = 'Z';
const PACKET_HEADER PACKET_HEADER_INJECT_AUDIO = 'I';
const PACKET_HEADER PACKET_HEADER_SET_VOXEL = 'S';
const PACKET_HEADER PACKET_HEADER_SET_VOXEL_DESTRUCTIVE = 'O';
const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v';

View file

@ -287,7 +287,7 @@ void VoxelTree::eraseAllVoxels() {
_isDirty = true;
}
void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive) {
VoxelNode* lastCreatedNode = nodeForOctalCode(rootNode, codeColorBuffer, NULL);
// create the node if it does not exist
@ -297,19 +297,27 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
} else {
// if it does exist, make sure it has no children
for (int i = 0; i < 8; i++) {
lastCreatedNode->deleteChildAtIndex(i);
if (lastCreatedNode->getChildAtIndex(i)) {
if (destructive) {
lastCreatedNode->deleteChildAtIndex(i);
} else {
printLog("WARNING! operation would require deleting child at index %d, add Voxel ignored!\n ", i);
}
}
}
}
// give this node its color
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer);
if (lastCreatedNode->isLeaf()) {
// give this node its color
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer);
nodeColor newColor;
memcpy(newColor, codeColorBuffer + octalCodeBytes, 3);
newColor[3] = 1;
lastCreatedNode->setColor(newColor);
if (lastCreatedNode->isDirty()) {
_isDirty = true;
nodeColor newColor;
memcpy(newColor, codeColorBuffer + octalCodeBytes, 3);
newColor[3] = 1;
lastCreatedNode->setColor(newColor);
if (lastCreatedNode->isDirty()) {
_isDirty = true;
}
}
}
@ -463,14 +471,15 @@ VoxelNode* VoxelTree::getVoxelAt(float x, float y, float z, float s) const {
return node;
}
void VoxelTree::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue) {
void VoxelTree::createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
this->readCodeColorBufferToTree(voxelData);
this->readCodeColorBufferToTree(voxelData, destructive);
delete voxelData;
}
void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color) {
void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
glm::vec3 distance = point2 - point1;
glm::vec3 items = distance / unitSize;
int maxItems = std::max(items.x, std::max(items.y, items.z));
@ -478,14 +487,12 @@ void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, r
glm::vec3 pointAt = point1;
for (int i = 0; i <= maxItems; i++ ) {
pointAt += increment;
unsigned char* voxelData = pointToVoxel(pointAt.x,pointAt.y,pointAt.z,unitSize,color[0],color[1],color[2]);
readCodeColorBufferToTree(voxelData);
delete voxelData;
createVoxel(pointAt.x, pointAt.y, pointAt.z, unitSize, color[0], color[1], color[2], destructive);
}
}
void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float voxelSize,
bool solid, creationMode mode, bool debug) {
bool solid, creationMode mode, bool destructive, bool debug) {
bool wantColorRandomizer = (mode == RANDOM);
bool wantNaturalSurface = (mode == NATURAL);
@ -601,13 +608,13 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v
x = xc + (thisRadius + i * subVoxelScale) * cos(theta) * sin(phi);
y = yc + (thisRadius + i * subVoxelScale) * sin(theta) * sin(phi);
z = zc + (thisRadius + i * subVoxelScale) * cos(phi);
this->createVoxel(x, y, z, subVoxelScale, red, green, blue);
this->createVoxel(x, y, z, subVoxelScale, red, green, blue, destructive);
}
naturalSurfaceRendered = true;
}
}
if (!naturalSurfaceRendered) {
this->createVoxel(x, y, z, thisVoxelSize, red, green, blue);
this->createVoxel(x, y, z, thisVoxelSize, red, green, blue, destructive);
}
}
}

View file

@ -22,36 +22,38 @@ typedef enum {GRADIENT, RANDOM, NATURAL} creationMode;
class VoxelTree {
public:
// when a voxel is created in the tree (object new'd)
long voxelsCreated;
long voxelsCreated;
// when a voxel is colored/set in the tree (object may have already existed)
long voxelsColored;
long voxelsBytesRead;
long voxelsColored;
long voxelsBytesRead;
SimpleMovingAverage voxelsCreatedStats;
SimpleMovingAverage voxelsColoredStats;
SimpleMovingAverage voxelsBytesReadStats;
SimpleMovingAverage voxelsColoredStats;
SimpleMovingAverage voxelsBytesReadStats;
VoxelTree();
~VoxelTree();
VoxelNode *rootNode;
int leavesWrittenToBitstream;
void eraseAllVoxels();
void eraseAllVoxels();
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor = true);
void readCodeColorBufferToTree(unsigned char *codeColorBuffer);
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false);
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
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;
void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue);
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color);
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool debug = false);
void createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
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 recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
@ -70,7 +72,7 @@ public:
VoxelNode*& node, float& distance, BoxFace& face);
// Note: this assumes the fileFormat is the HIO individual voxels code files
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
// these will read/write files that match the wireformat, excluding the 'V' leading
void writeToFileV2(const char* filename) const;

View file

@ -503,9 +503,11 @@ int main(int argc, const char * argv[])
if (agentList->getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) {
// XXXBHG: Hacked in support for 'S' SET command
if (packetData[0] == PACKET_HEADER_SET_VOXEL) {
if (packetData[0] == PACKET_HEADER_SET_VOXEL || packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) {
bool destructive = (packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE);
unsigned short int itemNumber = (*((unsigned short int*)&packetData[1]));
printf("got I - insert voxels - command from client receivedBytes=%ld itemNumber=%d\n",
printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n",
destructive ? "PACKET_HEADER_SET_VOXEL_DESTRUCTIVE" : "PACKET_HEADER_SET_VOXEL",
receivedBytes,itemNumber);
int atByte = 3;
unsigned char* pVoxelData = (unsigned char*)&packetData[3];
@ -534,7 +536,7 @@ int main(int argc, const char * argv[])
printf("inserting voxel at: %f,%f,%f\n",vertices[0],vertices[1],vertices[2]);
delete []vertices;
randomTree.readCodeColorBufferToTree(pVoxelData);
randomTree.readCodeColorBufferToTree(pVoxelData, destructive);
// skip to next
pVoxelData+=voxelDataSize;
atByte+=voxelDataSize;