mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
Merge pull request #312 from ZappoMan/master
support for "destructive" vs "non-destructive" createVoxel()
This commit is contained in:
commit
1c2251a7d3
8 changed files with 79 additions and 52 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue