From 6c840a9ec3a93da9148989fd03e7f7825540fa8a Mon Sep 17 00:00:00 2001 From: atlante45 Date: Mon, 8 Jul 2013 13:37:47 +0200 Subject: [PATCH 1/6] Functionnal version of minecraft import --- interface/src/Application.cpp | 16 +- libraries/voxels/src/VoxelTree.cpp | 510 +++++++++++++++++++---------- libraries/voxels/src/VoxelTree.h | 1 + 3 files changed, 342 insertions(+), 185 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 70f7287aab..3a8bb48450 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1322,7 +1322,7 @@ void Application::exportVoxels() { void Application::importVoxels() { QString desktopLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Import Voxels"), desktopLocation, - tr("Sparse Voxel Octree Files, Square PNG (*.svo *.png)")); + tr("Sparse Voxel Octree Files, Square PNG, Schematic Files (*.svo *.png *.schematic)")); QByteArray fileNameAscii = fileNameString.toAscii(); const char* fileName = fileNameAscii.data(); @@ -1343,8 +1343,10 @@ void Application::importVoxels() { } importVoxels.readFromSquareARGB32Pixels(pixels, pngImage.height()); - } else { + } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { importVoxels.readFromSVOFile(fileName); + } else { + importVoxels.readFromSchematicsFile(fileName); } VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); @@ -1534,11 +1536,11 @@ void Application::initMenu() { _voxelPaintColor->setIcon(createSwatchIcon(paintColor)); (_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true); - voxelMenu->addAction("Export Voxels", this, SLOT(exportVoxels()), Qt::CTRL | Qt::Key_E); - voxelMenu->addAction("Import Voxels", this, SLOT(importVoxels()), Qt::CTRL | Qt::Key_I); - voxelMenu->addAction("Cut Voxels", this, SLOT(cutVoxels()), Qt::CTRL | Qt::Key_X); - voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); - voxelMenu->addAction("Paste Voxels", this, SLOT(pasteVoxels()), Qt::CTRL | Qt::Key_V); + voxelMenu->addAction("Export Voxels", this, SLOT(exportVoxels()), Qt::CTRL | Qt::Key_E); + voxelMenu->addAction("Import Voxels", this, SLOT(importVoxels()), Qt::CTRL | Qt::Key_I); + voxelMenu->addAction("Cut Voxels", this, SLOT(cutVoxels()), Qt::CTRL | Qt::Key_X); + voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); + voxelMenu->addAction("Paste Voxels", this, SLOT(pasteVoxels()), Qt::CTRL | Qt::Key_V); QMenu* debugMenu = menuBar->addMenu("Debug"); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index b16425370e..7ecba71f3c 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -24,10 +24,12 @@ #include "VoxelConstants.h" #include "CoverageMap.h" #include "SquarePixelMap.h" +#include "Tags.h" #include + int boundaryDistanceForRenderLevel(unsigned int renderLevel) { float voxelSizeScale = 50000.0f; return voxelSizeScale / powf(2, renderLevel); @@ -73,17 +75,17 @@ void VoxelTree::recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperati // Recurses voxel tree calling the RecurseVoxelTreeOperation function for each node. // stops recursion if operation function returns false. -void VoxelTree::recurseTreeWithOperationDistanceSorted(RecurseVoxelTreeOperation operation, +void VoxelTree::recurseTreeWithOperationDistanceSorted(RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData) { recurseNodeWithOperationDistanceSorted(rootNode, operation, point, extraData); } // Recurses voxel node with an operation function -void VoxelTree::recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation, +void VoxelTree::recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData) { if (operation(node, extraData)) { // determine the distance sorted order of our children - + VoxelNode* sortedChildren[NUMBER_OF_CHILDREN]; float distancesToChildren[NUMBER_OF_CHILDREN]; int indexOfChildren[NUMBER_OF_CHILDREN]; // not really needed @@ -93,15 +95,15 @@ void VoxelTree::recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseV VoxelNode* childNode = node->getChildAtIndex(i); if (childNode) { // chance to optimize, doesn't need to be actual distance!! Could be distance squared - float distanceSquared = childNode->distanceSquareToPoint(point); + float distanceSquared = childNode->distanceSquareToPoint(point); //printLog("recurseNodeWithOperationDistanceSorted() CHECKING child[%d] point=%f,%f center=%f,%f distance=%f...\n", i, point.x, point.y, center.x, center.y, distance); //childNode->printDebugDetails(""); currentCount = insertIntoSortedArrays((void*)childNode, distanceSquared, i, - (void**)&sortedChildren, (float*)&distancesToChildren, + (void**)&sortedChildren, (float*)&distancesToChildren, (int*)&indexOfChildren, currentCount, NUMBER_OF_CHILDREN); } } - + for (int i = 0; i < currentCount; i++) { VoxelNode* childNode = sortedChildren[i]; if (childNode) { @@ -114,20 +116,20 @@ void VoxelTree::recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseV } -VoxelNode* VoxelTree::nodeForOctalCode(VoxelNode* ancestorNode, +VoxelNode* VoxelTree::nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const { // find the appropriate branch index based on this ancestorNode if (*needleCode > 0) { int branchForNeedle = branchIndexWithDescendant(ancestorNode->getOctalCode(), needleCode); VoxelNode* childNode = ancestorNode->getChildAtIndex(branchForNeedle); - + if (childNode) { if (*childNode->getOctalCode() == *needleCode) { - - // If the caller asked for the parent, then give them that too... - if (parentOfFoundNode) { - *parentOfFoundNode = ancestorNode; - } + + // If the caller asked for the parent, then give them that too... + if (parentOfFoundNode) { + *parentOfFoundNode = ancestorNode; + } // the fact that the number of sections is equivalent does not always guarantee // that this is the same node, however due to the recursive traversal // we know that this is our node @@ -138,7 +140,7 @@ VoxelNode* VoxelTree::nodeForOctalCode(VoxelNode* ancestorNode, } } } - + // we've been given a code we don't have a node for // return this node as the last created parent return ancestorNode; @@ -168,7 +170,7 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char } } -int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead, +int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead, bool includeColor, bool includeExistsBits) { // give this destination node the child mask from the packet const unsigned char ALL_CHILDREN_ASSUMED_TO_EXIST = 0xFF; @@ -205,22 +207,22 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, if (!nodeWasDirty && nodeIsDirty) { _nodesChangedFromBitstream++; } - this->voxelsColored++; - this->voxelsColoredStats.updateAverage(1); + this->voxelsColored++; + this->voxelsColoredStats.updateAverage(1); } } // give this destination node the child mask from the packet - unsigned char childrenInTreeMask = includeExistsBits ? *(nodeData + bytesRead) : ALL_CHILDREN_ASSUMED_TO_EXIST; + unsigned char childrenInTreeMask = includeExistsBits ? *(nodeData + bytesRead) : ALL_CHILDREN_ASSUMED_TO_EXIST; unsigned char childMask = *(nodeData + bytesRead + (includeExistsBits ? sizeof(childrenInTreeMask) : 0)); int childIndex = 0; bytesRead += includeExistsBits ? sizeof(childrenInTreeMask) + sizeof(childMask) : sizeof(childMask); - + while (bytesLeftToRead - bytesRead > 0 && childIndex < NUMBER_OF_CHILDREN) { // check the exists mask to see if we have a child to traverse into - - if (oneAtBit(childMask, childIndex)) { + + if (oneAtBit(childMask, childIndex)) { if (!destinationNode->getChildAtIndex(childIndex)) { // add a child at that index, if it doesn't exist bool nodeWasDirty = destinationNode->isDirty(); @@ -235,14 +237,14 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, this->voxelsCreated++; this->voxelsCreatedStats.updateAverage(this->voxelsCreated); } - + // tell the child to read the subsequent data bytesRead += readNodeData(destinationNode->getChildAtIndex(childIndex), nodeData + bytesRead, bytesLeftToRead - bytesRead, includeColor, includeExistsBits); } childIndex++; } - + if (includeExistsBits) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { @@ -253,21 +255,21 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, destinationNode->safeDeepDeleteChildAtIndex(i, stagedForDeletion); _isDirty = true; // by definition! } - } + } } return bytesRead; } -void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, +void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor, bool includeExistsBits, VoxelNode* destinationNode) { int bytesRead = 0; unsigned char* bitstreamAt = bitstream; - + // If destination node is not included, set it to root if (!destinationNode) { destinationNode = rootNode; } - + _nodesChangedFromBitstream = 0; // Keep looping through the buffer calling readNodeData() this allows us to pack multiple root-relative Octal codes @@ -292,8 +294,8 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int int octalCodeBytes = bytesRequiredForCodeLength(*bitstreamAt); int theseBytesRead = 0; theseBytesRead += octalCodeBytes; - theseBytesRead += readNodeData(bitstreamRootNode, bitstreamAt + octalCodeBytes, - bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor, includeExistsBits); + theseBytesRead += readNodeData(bitstreamRootNode, bitstreamAt + octalCodeBytes, + bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor, includeExistsBits); // skip bitstream to new startPoint bitstreamAt += theseBytesRead; @@ -333,7 +335,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage, b args.lengthOfCode = numberOfThreeBitSectionsInCode(codeBuffer); args.deleteLastChild = false; args.pathChanged = false; - + VoxelNode* node = rootNode; deleteVoxelCodeFromTreeRecursion(node, &args); } @@ -343,11 +345,11 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat int lengthOfNodeCode = numberOfThreeBitSectionsInCode(node->getOctalCode()); - // Since we traverse the tree in code order, we know that if our code + // Since we traverse the tree in code order, we know that if our code // matches, then we've reached our target node. if (lengthOfNodeCode == args->lengthOfCode) { // we've reached our target, depending on how we're called we may be able to operate on it - // if we're in "stage" mode, then we can could have the node staged, otherwise we can't really delete + // if we're in "stage" mode, then we can could have the node staged, otherwise we can't really delete // it here, we need to recurse up, and delete it there. So we handle these cases the same to keep // the logic consistent. args->deleteLastChild = true; @@ -357,9 +359,9 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat // Ok, we know we haven't reached our target node yet, so keep looking int childIndex = branchIndexWithDescendant(node->getOctalCode(), args->codeBuffer); VoxelNode* childNode = node->getChildAtIndex(childIndex); - + // If there is no child at the target location, and the current parent node is a colored leaf, - // then it means we were asked to delete a child out of a larger leaf voxel. + // then it means we were asked to delete a child out of a larger leaf voxel. // We support this by breaking up the parent voxel into smaller pieces. if (!childNode && node->isLeaf() && node->isColored()) { // we need to break up ancestors until we get to the right level @@ -375,7 +377,7 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat } } int lengthOfancestorNode = numberOfThreeBitSectionsInCode(ancestorNode->getOctalCode()); - + // If we've reached the parent of the target, then stop breaking up children if (lengthOfancestorNode == (args->lengthOfCode - 1)) { break; @@ -388,11 +390,11 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat } _isDirty = true; args->pathChanged = true; - + // ends recursion, unwinds up stack return; } - + // if we don't have a child and we reach this point, then we actually know that the parent // isn't a colored leaf, and the child branch doesn't exist, so there's nothing to do below and // we can safely return, ending the recursion and unwinding @@ -415,12 +417,12 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat // track our tree dirtiness _isDirty = true; - + // track that path has changed args->pathChanged = true; // If we're in collapseEmptyTrees mode, and this was the last child of this node, then we also want - // to delete this node. This will collapse the empty tree above us. + // to delete this node. This will collapse the empty tree above us. if (args->collapseEmptyTrees && node->getChildCount() == 0) { // Can't delete the root this way. if (node == rootNode) { @@ -430,7 +432,7 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat args->deleteLastChild = false; // reset so that further up the unwinding chain we don't do anything } } - + // If the lower level did some work, then we need to let this node know, so it can // do any bookkeeping it wants to, like color re-averaging, time stamp marking, etc if (args->pathChanged) { @@ -460,9 +462,9 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char* codeColorBuffer, bool d args.destructive = destructive; args.pathChanged = false; - + VoxelNode* node = rootNode; - + readCodeColorBufferToTreeRecursion(node, &args); } @@ -472,7 +474,7 @@ void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraD int lengthOfNodeCode = numberOfThreeBitSectionsInCode(node->getOctalCode()); - // Since we traverse the tree in code order, we know that if our code + // Since we traverse the tree in code order, we know that if our code // matches, then we've reached our target node. if (lengthOfNodeCode == args->lengthOfCode) { // we've reached our target -- we might have found our node, but that node might have children. @@ -488,7 +490,7 @@ void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraD printLog("WARNING! operation would require deleting children, add Voxel ignored!\n "); } } - + // If we get here, then it means, we either had a true leaf to begin with, or we were in // destructive mode and we deleted all the child trees. So we can color. if (node->isLeaf()) { @@ -499,7 +501,7 @@ void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraD memcpy(newColor, args->codeColorBuffer + octalCodeBytes, SIZE_OF_COLOR_DATA); newColor[SIZE_OF_COLOR_DATA] = 1; node->setColor(newColor); - + // It's possible we just reset the node to it's exact same color, in // which case we don't consider this to be dirty... if (node->isDirty()) { @@ -515,7 +517,7 @@ void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraD // Ok, we know we haven't reached our target node yet, so keep looking int childIndex = branchIndexWithDescendant(node->getOctalCode(), args->codeColorBuffer); VoxelNode* childNode = node->getChildAtIndex(childIndex); - + // If the branch we need to traverse does not exist, then create it on the way down... if (!childNode) { childNode = node->addChildAtIndex(childIndex); @@ -525,7 +527,7 @@ void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraD readCodeColorBufferToTreeRecursion(childNode, args); // Unwinding... - + // If the lower level did some work, then we need to let this node know, so it can // do any bookkeeping it wants to, like color re-averaging, time stamp marking, etc if (args->pathChanged) { @@ -534,18 +536,18 @@ void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraD } void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) { - //unsigned short int itemNumber = (*((unsigned short int*)&bitstream[sizeof(PACKET_HEADER)])); - int atByte = sizeof(short int) + sizeof(PACKET_HEADER); - unsigned char* voxelCode = (unsigned char*)&bitstream[atByte]; - while (atByte < bufferSizeBytes) { - int codeLength = numberOfThreeBitSectionsInCode(voxelCode); - int voxelDataSize = bytesRequiredForCodeLength(codeLength) + SIZE_OF_COLOR_DATA; + //unsigned short int itemNumber = (*((unsigned short int*)&bitstream[sizeof(PACKET_HEADER)])); + int atByte = sizeof(short int) + sizeof(PACKET_HEADER); + unsigned char* voxelCode = (unsigned char*)&bitstream[atByte]; + while (atByte < bufferSizeBytes) { + int codeLength = numberOfThreeBitSectionsInCode(voxelCode); + int voxelDataSize = bytesRequiredForCodeLength(codeLength) + SIZE_OF_COLOR_DATA; - deleteVoxelCodeFromTree(voxelCode, ACTUALLY_DELETE, COLLAPSE_EMPTY_TREE); + deleteVoxelCodeFromTree(voxelCode, ACTUALLY_DELETE, COLLAPSE_EMPTY_TREE); - voxelCode+=voxelDataSize; - atByte+=voxelDataSize; - } + voxelCode+=voxelDataSize; + atByte+=voxelDataSize; + } } void VoxelTree::printTreeForDebugging(VoxelNode *startNode) { @@ -591,7 +593,7 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) { printTreeForDebugging(startNode->getChildAtIndex(l)); } } - } + } } // Note: this is an expensive call. Don't call it unless you really need to reaverage the entire tree (from startNode) @@ -622,15 +624,15 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { char octets; unsigned int lengthInBytes; - + int totalBytesRead = 0; if(file.is_open()) { - printLog("loading file...\n"); + printLog("loading file...\n"); bool bail = false; while (!file.eof() && !bail) { file.get(octets); totalBytesRead++; - lengthInBytes = bytesRequiredForCodeLength(octets) - 1; + lengthInBytes = bytesRequiredForCodeLength(octets) - 1; unsigned char * voxelData = new unsigned char[lengthInBytes + 1 + 3]; voxelData[0]=octets; char byte; @@ -658,7 +660,7 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { voxelData[lengthInBytes+2] = std::max(0,std::min(255,green + colorRandomizer)); voxelData[lengthInBytes+3] = std::max(0,std::min(255,blue + colorRandomizer)); printLog("voxel color after rand red:%d, green:%d, blue:%d\n", - voxelData[lengthInBytes+1], voxelData[lengthInBytes+2], voxelData[lengthInBytes+3]); + voxelData[lengthInBytes+1], voxelData[lengthInBytes+2], voxelData[lengthInBytes+3]); //printVoxelCode(voxelData); this->readCodeColorBufferToTree(voxelData); @@ -678,7 +680,7 @@ 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, +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, destructive); @@ -698,13 +700,13 @@ void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, r } } -void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float voxelSize, - bool solid, creationMode mode, bool destructive, bool debug) { - +void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float voxelSize, + bool solid, creationMode mode, bool destructive, bool debug) { + bool wantColorRandomizer = (mode == RANDOM); bool wantNaturalSurface = (mode == NATURAL); bool wantNaturalColor = (mode == NATURAL); - + // About the color of the sphere... we're going to make this sphere be a mixture of two colors // in NATURAL mode, those colors will be green dominant and blue dominant. In GRADIENT mode we // will randomly pick which color family red, green, or blue to be dominant. In RANDOM mode we @@ -729,7 +731,7 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v g2 = (dominantColor2 == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100); b2 = (dominantColor2 == 3) ? randIntInRange(200, 255) : randIntInRange(40, 100); } - + // We initialize our rgb to be either "grey" in case of randomized surface, or // the average of the gradient, in the case of the gradient sphere. unsigned char red = wantColorRandomizer ? 128 : (r1 + r2) / 2; // average of the colors @@ -737,7 +739,7 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v unsigned char blue = wantColorRandomizer ? 128 : (b1 + b2) / 2; // I want to do something smart like make these inside circles with bigger voxels, but this doesn't seem to work. - float thisVoxelSize = voxelSize; // radius / 2.0f; + float thisVoxelSize = voxelSize; // radius / 2.0f; float thisRadius = 0.0; if (!solid) { thisRadius = radius; // just the outer surface @@ -750,63 +752,63 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v while (!lastLayer) { lastLayer = (thisRadius + (voxelSize * 2.0) >= radius); - // We want to make sure that as we "sweep" through our angles we use a delta angle that voxelSize + // We want to make sure that as we "sweep" through our angles we use a delta angle that voxelSize // small enough to not skip any voxels we can calculate theta from our desired arc length // lenArc = ndeg/360deg * 2pi*R ---> lenArc = theta/2pi * 2pi*R - // lenArc = theta*R ---> theta = lenArc/R ---> theta = g/r + // lenArc = theta*R ---> theta = lenArc/R ---> theta = g/r float angleDelta = (thisVoxelSize / thisRadius); if (debug) { int percentComplete = 100 * (thisRadius/radius); - printLog("percentComplete=%d\n",percentComplete); + printLog("percentComplete=%d\n",percentComplete); } - + for (float theta=0.0; theta <= 2 * M_PI; theta += angleDelta) { for (float phi=0.0; phi <= M_PI; phi += angleDelta) { bool naturalSurfaceRendered = false; float x = xc + thisRadius * cos(theta) * sin(phi); float y = yc + thisRadius * sin(theta) * sin(phi); float z = zc + thisRadius * cos(phi); - - // if we're on the outer radius, then we do a couple of things differently. - // 1) If we're in NATURAL mode we will actually draw voxels from our surface outward (from the surface) up + + // if we're on the outer radius, then we do a couple of things differently. + // 1) If we're in NATURAL mode we will actually draw voxels from our surface outward (from the surface) up // some random height. This will give our sphere some contours. // 2) In all modes, we will use our "outer" color to draw the voxels. Otherwise we will use the average color if (lastLayer) { - if (false && debug) { + if (false && debug) { printLog("adding candy shell: theta=%f phi=%f thisRadius=%f radius=%f\n", - theta, phi, thisRadius,radius); + theta, phi, thisRadius,radius); } switch (mode) { - case RANDOM: { - red = randomColorValue(165); - green = randomColorValue(165); - blue = randomColorValue(165); - } break; - case GRADIENT: { - float gradient = (phi / M_PI); - red = r1 + ((r2 - r1) * gradient); - green = g1 + ((g2 - g1) * gradient); - blue = b1 + ((b2 - b1) * gradient); - } break; - case NATURAL: { - glm::vec3 position = glm::vec3(theta,phi,radius); - float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f) - + .125f * glm::perlin(position * 16.f); - float gradient = (1.0f + perlin)/ 2.0f; - red = (unsigned char)std::min(255, std::max(0, (int)(r1 + ((r2 - r1) * gradient)))); - green = (unsigned char)std::min(255, std::max(0, (int)(g1 + ((g2 - g1) * gradient)))); - blue = (unsigned char)std::min(255, std::max(0, (int)(b1 + ((b2 - b1) * gradient)))); - if (debug) { - printLog("perlin=%f gradient=%f color=(%d,%d,%d)\n",perlin, gradient, red, green, blue); - } - } break; + case RANDOM: { + red = randomColorValue(165); + green = randomColorValue(165); + blue = randomColorValue(165); + } break; + case GRADIENT: { + float gradient = (phi / M_PI); + red = r1 + ((r2 - r1) * gradient); + green = g1 + ((g2 - g1) * gradient); + blue = b1 + ((b2 - b1) * gradient); + } break; + case NATURAL: { + glm::vec3 position = glm::vec3(theta,phi,radius); + float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f) + + .125f * glm::perlin(position * 16.f); + float gradient = (1.0f + perlin)/ 2.0f; + red = (unsigned char)std::min(255, std::max(0, (int)(r1 + ((r2 - r1) * gradient)))); + green = (unsigned char)std::min(255, std::max(0, (int)(g1 + ((g2 - g1) * gradient)))); + blue = (unsigned char)std::min(255, std::max(0, (int)(b1 + ((b2 - b1) * gradient)))); + if (debug) { + printLog("perlin=%f gradient=%f color=(%d,%d,%d)\n",perlin, gradient, red, green, blue); + } + } break; } if (wantNaturalSurface) { // for natural surfaces, we will render up to 16 voxel's above the surface of the sphere glm::vec3 position = glm::vec3(theta,phi,radius); - float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f) - + .125f * glm::perlin(position * 16.f); + float perlin = glm::perlin(position) + .25f * glm::perlin(position * 4.f) + + .125f * glm::perlin(position * 16.f); float gradient = (1.0f + perlin)/ 2.0f; int height = (4 * gradient)+1; // make it at least 4 thick, so we get some averaging @@ -835,8 +837,8 @@ int VoxelTree::searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const // call the recursive version, this will add all found colored node roots to the bag int currentSearchLevel = 0; - - int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode, + + int levelReached = searchForColoredNodesRecursion(maxSearchLevel, currentSearchLevel, rootNode, viewFrustum, bag, deltaViewFrustum, lastViewFrustum); return levelReached; } @@ -890,7 +892,7 @@ public: bool findSpherePenetrationOp(VoxelNode* node, void* extraData) { SphereArgs* args = static_cast(extraData); - + // coarse check against bounds const AABox& box = node->getAABox(); if (!box.expandedContains(args->center, args->radius)) { @@ -904,7 +906,7 @@ bool findSpherePenetrationOp(VoxelNode* node, void* extraData) { if (box.findSpherePenetration(args->center, args->radius, nodePenetration)) { args->penetration = addPenetrations(args->penetration, nodePenetration * (float)TREE_SCALE); args->found = true; - } + } } return false; } @@ -927,7 +929,7 @@ public: bool findCapsulePenetrationOp(VoxelNode* node, void* extraData) { CapsuleArgs* args = static_cast(extraData); - + // coarse check against bounds const AABox& box = node->getAABox(); if (!box.expandedIntersectsSegment(args->start, args->end, args->radius)) { @@ -941,7 +943,7 @@ bool findCapsulePenetrationOp(VoxelNode* node, void* extraData) { if (box.findCapsulePenetration(args->start, args->end, args->radius, nodePenetration)) { args->penetration = addPenetrations(args->penetration, nodePenetration * (float)TREE_SCALE); args->found = true; - } + } } return false; } @@ -953,36 +955,36 @@ bool VoxelTree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& return args.found; } -int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, +int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) { - // Keep track of how deep we've searched. + // Keep track of how deep we've searched. currentSearchLevel++; // If we've passed our max Search Level, then stop searching. return last level searched if (currentSearchLevel > maxSearchLevel) { return currentSearchLevel-1; - } + } // If we're at a node that is out of view, then we can return, because no nodes below us will be in view! if (!node->isInView(viewFrustum)) { return currentSearchLevel; } - + // Ok, this is a little tricky, each child may have been deeper than the others, so we need to track // how deep each child went. And we actually return the maximum of each child. We use these variables below // when we recurse the children. int thisLevel = currentSearchLevel; int maxChildLevel = thisLevel; - + VoxelNode* inViewChildren[NUMBER_OF_CHILDREN]; float distancesToChildren[NUMBER_OF_CHILDREN]; int positionOfChildren[NUMBER_OF_CHILDREN]; int inViewCount = 0; int inViewNotLeafCount = 0; int inViewWithColorCount = 0; - + // for each child node, check to see if they exist, are colored, and in view, and if so // add them to our distance ordered array of children for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { @@ -992,22 +994,22 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe bool childIsLeaf = (childNode && childNode->isLeaf()); if (childIsInView) { - + // track children in view as existing and not a leaf if (!childIsLeaf) { inViewNotLeafCount++; } - + // track children with actual color if (childIsColored) { inViewWithColorCount++; } - + float distance = childNode->distanceToCamera(viewFrustum); - + if (distance < boundaryDistanceForRenderLevel(*childNode->getOctalCode() + 1)) { - inViewCount = insertIntoSortedArrays((void*)childNode, distance, i, - (void**)&inViewChildren, (float*)&distancesToChildren, + inViewCount = insertIntoSortedArrays((void*)childNode, distance, i, + (void**)&inViewChildren, (float*)&distancesToChildren, (int*)&positionOfChildren, inViewCount, NUMBER_OF_CHILDREN); } } @@ -1023,7 +1025,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe } else { // at this point, we need to iterate the children who are in view, even if not colored // and we need to determine if there's a deeper tree below them that we care about. We will iterate - // these based on which tree is closer. + // these based on which tree is closer. for (int i = 0; i < inViewCount; i++) { VoxelNode* childNode = inViewChildren[i]; thisLevel = currentSearchLevel; // reset this, since the children will munge it up @@ -1035,8 +1037,8 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe return maxChildLevel; } -int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, - EncodeBitstreamParams& params) const { +int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, + EncodeBitstreamParams& params) const { // How many bytes have we written so far at this level; int bytesWritten = 0; @@ -1062,10 +1064,10 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, codeLength = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(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 + availableBytes -= codeLength; // keep track or remaining space int currentEncodeLevel = 0; int childBytesWritten = encodeTreeBitstreamRecursion(node, outputBuffer, availableBytes, bag, params, currentEncodeLevel); @@ -1081,7 +1083,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, // if we wrote child bytes, then return our result of all bytes written if (childBytesWritten) { - bytesWritten += childBytesWritten; + bytesWritten += childBytesWritten; } else { // otherwise... if we didn't write any child bytes, then pretend like we also didn't write our octal code bytesWritten = 0; @@ -1089,7 +1091,7 @@ int VoxelTree::encodeTreeBitstream(VoxelNode* node, unsigned char* outputBuffer, return bytesWritten; } -int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, +int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, EncodeBitstreamParams& params, int& currentEncodeLevel) const { // How many bytes have we written so far at this level; @@ -1119,8 +1121,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp if (!node->isInView(*params.viewFrustum)) { return bytesAtThisLevel; } - - + + // If the user also asked for occlusion culling, check if this node is occluded, but only if it's not a leaf. // leaf occlusion is handled down below when we check child nodes if (params.wantOcclusionCulling && !node->isLeaf()) { @@ -1142,7 +1144,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp //args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1); //args->totalVoxels += (subArgs.voxelsTouched - 1); - + return bytesAtThisLevel; } } else { @@ -1153,7 +1155,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp } } } - + bool keepDiggingDeeper = true; // Assuming we're in view we have a great work ethic, we're always ready for more! // At any given point in writing the bitstream, the largest minimum we might need to flesh out the current level @@ -1168,7 +1170,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp const int BYTES_PER_COLOR = 3; const int CHILD_TREE_EXISTS_BYTES = sizeof(childrenExistInTreeBits) + sizeof(childrenExistInPacketBits); const int MAX_LEVEL_BYTES = CHILD_COLOR_MASK_BYTES + NUMBER_OF_CHILDREN * BYTES_PER_COLOR + CHILD_TREE_EXISTS_BYTES; - + // Make our local buffer large enough to handle writing at this level in case we need to. unsigned char thisLevelBuffer[MAX_LEVEL_BYTES]; unsigned char* writeToThisLevelBuffer = &thisLevelBuffer[0]; @@ -1193,14 +1195,14 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp if (params.wantOcclusionCulling) { if (childNode) { // chance to optimize, doesn't need to be actual distance!! Could be distance squared - //float distanceSquared = childNode->distanceSquareToPoint(point); + //float distanceSquared = childNode->distanceSquareToPoint(point); //printLog("recurseNodeWithOperationDistanceSorted() CHECKING child[%d] point=%f,%f center=%f,%f distance=%f...\n", i, point.x, point.y, center.x, center.y, distance); //childNode->printDebugDetails(""); float distance = params.viewFrustum ? childNode->distanceToCamera(*params.viewFrustum) : 0; currentCount = insertIntoSortedArrays((void*)childNode, distance, i, - (void**)&sortedChildren, (float*)&distancesToChildren, + (void**)&sortedChildren, (float*)&distancesToChildren, (int*)&indexOfChildren, currentCount, NUMBER_OF_CHILDREN); } } else { @@ -1218,7 +1220,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp int originalIndex = indexOfChildren[i]; bool childIsInView = (childNode && (!params.viewFrustum || childNode->isInView(*params.viewFrustum))); - + if (childIsInView) { // Before we determine consider this further, let's see if it's in our LOD scope... float distance = distancesToChildren[i]; // params.viewFrustum ? childNode->distanceToCamera(*params.viewFrustum) : 0; @@ -1226,7 +1228,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp if (distance < boundaryDistance) { inViewCount++; - + // track children in view as existing and not a leaf, if they're a leaf, // we don't care about recursing deeper on them, and we don't consider their // subtree to exist @@ -1244,13 +1246,13 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp AABox voxelBox = childNode->getAABox(); voxelBox.scale(TREE_SCALE); VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon( - params.viewFrustum->getProjectedPolygon(voxelBox)); - + params.viewFrustum->getProjectedPolygon(voxelBox)); + // In order to check occlusion culling, the shadow has to be "all in view" otherwise, we will ignore occlusion // culling and proceed as normal if (voxelPolygon->getAllInView()) { CoverageMapStorageResult result = params.map->checkMap(voxelPolygon, true); - + // In all cases where the shadow wasn't stored, we need to free our own memory. // In the case where it is stored, the CoverageMap will free memory for us later. if (result != STORED) { @@ -1269,8 +1271,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp bool childWasInView = (childNode && params.deltaViewFrustum && - (params.lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*params.lastViewFrustum))); - + (params.lastViewFrustum && ViewFrustum::INSIDE == childNode->inFrustum(*params.lastViewFrustum))); + // track children with actual color, only if the child wasn't previously in view! if (childNode && childNode->isColored() && !childWasInView && !childIsOccluded) { childrenColoredBits += (1 << (7 - originalIndex)); @@ -1309,31 +1311,31 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp // We only need to keep digging, if there is at least one child that is inView, and not a leaf. keepDiggingDeeper = (inViewNotLeafCount > 0); - + // If we have enough room to copy our local results into the buffer, then do so... if (availableBytes >= bytesAtThisLevel) { memcpy(outputBuffer, &thisLevelBuffer[0], bytesAtThisLevel); - + outputBuffer += bytesAtThisLevel; availableBytes -= bytesAtThisLevel; } else { bag.insert(node); return 0; } - + if (keepDiggingDeeper) { // at this point, we need to iterate the children who are in view, even if not colored - // and we need to determine if there's a deeper tree below them that we care about. + // and we need to determine if there's a deeper tree below them that we care about. // - // Since this recursive function assumes we're already writing, we know we've already written our + // Since this recursive function assumes we're already writing, we know we've already written our // childrenExistInPacketBits. But... we don't really know how big the child tree will be. And we don't know if // we'll have room in our buffer to actually write all these child trees. What we kinda would like to do is - // write our childExistsBits as a place holder. Then let each potential tree have a go at it. If they + // write our childExistsBits as a place holder. Then let each potential tree have a go at it. If they // write something, we keep them in the bits, if they don't, we take them out. // // we know the last thing we wrote to the outputBuffer was our childrenExistInPacketBits. Let's remember where that was! unsigned char* childExistsPlaceHolder = outputBuffer-sizeof(childrenExistInPacketBits); - + // we are also going to recurse these child trees in "distance" sorted order, but we need to pack them in the // final packet in standard order. So what we're going to do is keep track of how big each subtree was in bytes, // and then later reshuffle these sections of our output buffer back into normal order. This allows us to make @@ -1350,19 +1352,19 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp int originalIndex = indexOfChildren[indexByDistance]; if (oneAtBit(childrenExistInPacketBits, originalIndex)) { - + int thisLevel = currentEncodeLevel; - // remember this for reshuffling + // remember this for reshuffling recursiveSliceStarts[originalIndex] = outputBuffer; - - int childTreeBytesOut = encodeTreeBitstreamRecursion(childNode, outputBuffer, availableBytes, bag, + + int childTreeBytesOut = encodeTreeBitstreamRecursion(childNode, outputBuffer, availableBytes, bag, params, thisLevel); - - // remember this for reshuffling + + // remember this for reshuffling recursiveSliceSizes[originalIndex] = childTreeBytesOut; allSlicesSize += childTreeBytesOut; - + // if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space, // basically, the children below don't contain any info. @@ -1370,9 +1372,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp // byte and the child exist byte. // assert(childTreeBytesOut != 1); - + // if the child tree wrote just 2 bytes, then it means: it had no colors and no child nodes, because... - // if it had colors it would write 1 byte for the color mask, + // if it had colors it would write 1 byte for the color mask, // and at least a color's worth of bytes for the node of colors. // if it had child trees (with something in them) then it would have the 1 byte for child mask // and some number of bytes of lower children... @@ -1402,9 +1404,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp // reshuffle here... if (params.wantOcclusionCulling) { unsigned char tempReshuffleBuffer[MAX_VOXEL_PACKET_SIZE]; - + unsigned char* tempBufferTo = &tempReshuffleBuffer[0]; // this is our temporary destination - + // iterate through our childrenExistInPacketBits, these will be the sections of the packet that we copied subTree // details into. Unfortunately, they're in distance sorted order, not original index order. we need to put them // back into original distance order @@ -1417,32 +1419,32 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp tempBufferTo += thisSliceSize; } } - + // now that all slices are back in the correct order, copy them to the correct output buffer memcpy(firstRecursiveSlice, &tempReshuffleBuffer[0], allSlicesSize); } - - + + } // end keepDiggingDeeper - + return bytesAtThisLevel; } bool VoxelTree::readFromSVOFile(const char* fileName) { std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate); if(file.is_open()) { - printLog("loading file %s...\n", fileName); - - // get file length.... + printLog("loading file %s...\n", fileName); + + // get file length.... unsigned long fileLength = file.tellg(); file.seekg( 0, std::ios::beg ); - + // read the entire file into a buffer, WHAT!? Why not. unsigned char* entireFile = new unsigned char[fileLength]; file.read((char*)entireFile, fileLength); readBitstreamToTree(entireFile, fileLength, WANT_COLOR, NO_EXISTS_BITS); delete[] entireFile; - + file.close(); return true; } @@ -1455,12 +1457,164 @@ bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension return true; } +bool VoxelTree::readFromSchematicsFile(const char *fileName) { + std::stringstream ss; + int err = retrieveData(fileName, ss); + if (err && TAG_Compound != ss.get()) { + printLog("ERROR: Invalid schematics file.\n"); + return false; + } + + ss.get(); + TagCompound schematics(ss); + if (!schematics.blockId() || !schematics.blocksData()) { + printLog("ERROR: Invalid schematics file.\n"); + return false; + } + + int max = (schematics.width() > schematics.length()) ? schematics.width() : schematics.length(); + max = (max > schematics.height()) ? max : schematics.height(); + + int scale = 1; + while (max > scale) scale *= 2; + float size = 1.0f / scale; + bool create = false; + int red = 128, green = 128, blue = 128; + + for (int y = 0; y < schematics.height(); ++y) { + for (int z = 0; z < schematics.length(); ++z) { + for (int x = 0; x < schematics.width(); ++x) { + int pos = ((y * schematics.length()) + z) * schematics.width() + x; + int id = schematics.blockId()[pos]; + + create = true; + switch (id) { + case 1: + case 14: + case 15: + case 16: + case 21: + case 56: + case 73: + case 74: + case 97: + case 129: red = 128; green = 128; blue = 128; break; + case 2: red = 77; green = 117; blue = 66; break; + case 3: + case 60: red = 116; green = 83; blue = 56; break; + case 4: red = 71; green = 71; blue = 71; break; + case 5: + case 125: red = 133; green = 94; blue = 62; break; + case 7: red = 35; green = 35; blue = 35; break; + case 8: + case 9: red = 100; green = 109; blue = 185; break; + case 10: + case 11: red = 192; green = 64; blue = 8; break; + case 12: red = 209; green = 199; blue = 155; break; + case 13: red = 96; green = 94; blue = 93; break; + case 17: red = 71; green = 56; blue = 35; break; + case 18: red = 76; green = 104; blue = 64; break; + case 19: red = 119; green = 119; blue = 37; break; + case 22: red = 22; green = 44; blue = 86; break; + case 23: + case 29: + case 33: + case 61: + case 62: + case 158: red = 61; green = 61; blue = 61; break; + case 24: red = 209; green = 202; blue = 156; break; + case 25: + case 58: + case 84: + case 137: red = 57; green = 38; blue = 25; break; + case 35: + red = 255; + green = 255; + blue = 255; + break; + case 41: red = 239; green = 238; blue = 105; break; + case 42: red = 146; green = 146; blue = 146; break; + case 43: + case 98: red = 161; green = 161; blue = 161; break; + case 44: + red = 161; + green = 161; + blue = 161; + break; + case 45: red = 121; green = 67; blue = 53; break; + case 46: red = 118; green = 36; blue = 13; break; + case 47: red = 155; green = 127; blue = 76; break; + case 48: red = 61; green = 79; blue = 61; break; + case 49: red = 52; green = 41; blue = 74; break; + case 52: red = 12; green = 66; blue = 71; break; + case 53: + case 67: + case 108: + case 109: + case 114: + case 128: + case 134: + case 135: + case 136: + case 156: + red = 150; + green = 121; + blue = 74; + break; + case 54: + case 95: + case 146: red = 155; green = 105; blue = 32; break; + case 57: red = 145; green = 219; blue = 215; break; + case 79: red = 142; green = 162; blue = 195; break; + case 80: red = 255; green = 255; blue = 255; break; + case 81: red = 8; green = 64; blue = 15; break; + case 82: red = 150; green = 155; blue = 166; break; + case 86: + case 91: red = 179; green = 108; blue = 17; break; + case 87: + case 153: red = 91; green = 31; blue = 30; break; + case 88: red = 68; green = 49; blue = 38; break; + case 89: red = 180; green = 134; blue = 65; break; + case 103: red = 141; green = 143; blue = 36; break; + case 110: red = 103; green = 92; blue = 95; break; + case 112: red = 45; green = 22; blue = 26; break; + case 121: red = 183; green = 178; blue = 129; break; + case 123: red = 101; green = 59; blue = 31; break; + case 124: red = 213; green = 178; blue = 123; break; + case 130: red = 38; green = 54; blue = 56; break; + case 133: red = 53; green = 84; blue = 85; break; + case 152: red = 131; green = 22; blue = 7; break; + case 155: red = 195; green = 192; blue = 185; break; + case 159: red = 195; green = 165; blue = 150; break; + case 170: red = 168; green = 139; blue = 15; break; + case 172: red = 140; green = 86; blue = 61; break; + case 173: red = 9; green = 9; blue = 9; break; + + default: + if (0 < id && id < 160 && false) { + red = 128; blue = 128; green = 128; + } else { + create = false; + } + break; + } + + if (create) { + createVoxel(size * x, size * y, size * z, size, red, green, blue, true); + } + } + } + } + + return true; +} + void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) const { std::ofstream file(fileName, std::ios::out|std::ios::binary); if(file.is_open()) { - printLog("saving to file %s...\n", fileName); + printLog("saving to file %s...\n", fileName); VoxelNodeBag nodeBag; // If we were given a specific node, start from there, otherwise start from root @@ -1472,13 +1626,13 @@ void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) const { static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static int bytesWritten = 0; - + while (!nodeBag.isEmpty()) { VoxelNode* subTree = nodeBag.extract(); EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); bytesWritten = encodeTreeBitstream(subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, params); - + file.write((const char*)&outputBuffer[0], bytesWritten); } } @@ -1506,10 +1660,10 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static int bytesWritten = 0; - + while (!nodeBag.isEmpty()) { VoxelNode* subTree = nodeBag.extract(); - + // ask our tree to write a bitsteam EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels); bytesWritten = encodeTreeBitstream(subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, params); @@ -1523,17 +1677,17 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin VoxelNodeBag nodeBag; // If we were given a specific node, start from there, otherwise start from root nodeBag.insert(sourceTree->rootNode); - + static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static int bytesWritten = 0; - + while (!nodeBag.isEmpty()) { VoxelNode* subTree = nodeBag.extract(); - + // ask our tree to write a bitsteam EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); bytesWritten = sourceTree->encodeTreeBitstream(subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, params); - + // ask destination tree to read the bitstream readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS, destinationNode); } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 72ea9e2326..3591141549 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -135,6 +135,7 @@ public: bool readFromSVOFile(const char* filename); // reads voxels from square image with alpha as a Y-axis bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); + bool readFromSchematicsFile(const char* filename); unsigned long getVoxelCount(); From 981e4c61b5b80d4b2e01cdb3ec6012717d6c8ac5 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Mon, 8 Jul 2013 13:45:38 +0200 Subject: [PATCH 2/6] Tags files missing in last commit --- libraries/voxels/src/Tags.cpp | 218 ++++++++++++++++++++++++++++++++++ libraries/voxels/src/Tags.h | 152 ++++++++++++++++++++++++ 2 files changed, 370 insertions(+) create mode 100644 libraries/voxels/src/Tags.cpp create mode 100644 libraries/voxels/src/Tags.h diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp new file mode 100644 index 0000000000..81cf4dbe95 --- /dev/null +++ b/libraries/voxels/src/Tags.cpp @@ -0,0 +1,218 @@ +#include "Tags.h" +#include + +#include +#include + +#include + +Tag::Tag(int tagId, std::stringstream &ss) : _tagId(tagId) { + int size(ss.get() << 8 | ss.get()); + + _name.clear(); + for (int i(0); i < size; ++i) { + _name += ss.get(); + } +} + +Tag* Tag::readTag(int tagId, std::stringstream &ss) { + + switch (tagId) { + case TAG_Byte: + return new TagByte(ss); + case TAG_Short: + return new TagShort(ss); + case TAG_Int: + return new TagInt(ss); + case TAG_Long: + return new TagLong(ss); + case TAG_Byte_Array: + return new TagByteArray(ss); + case TAG_String: + return new TagString(ss); + case TAG_List: + return new TagList(ss); + case TAG_Compound: + return new TagCompound(ss); + case TAG_Int_Array: + return new TagIntArray(ss); + case TAG_Float: + case TAG_Double: + default: + //TODO + exit(EXIT_FAILURE); + break; + } +} + +TagByte::TagByte(std::stringstream &ss) : Tag(TAG_Byte, ss) { + _data = ss.get(); +} + +TagShort::TagShort(std::stringstream &ss) : Tag(TAG_Short, ss) { + _data = ss.get() << 8 | ss.get(); +} + +TagInt::TagInt(std::stringstream &ss) : Tag(TAG_Int, ss) { + _data = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); +} + +TagLong::TagLong(std::stringstream &ss) : Tag(TAG_Long, ss) { + _data = (((int64_t) ss.get()) << 56 | ((int64_t) ss.get()) << 48 + | ((int64_t) ss.get()) << 40 | ((int64_t) ss.get()) << 32 + | ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get()); +} + +TagByteArray::TagByteArray(std::stringstream &ss) : Tag(TAG_Byte_Array, ss) { + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + _data = new char[_size]; + for (int i(0); i < _size; ++i) { + _data[i] = ss.get(); + } +} + +TagString::TagString(std::stringstream &ss) : Tag(TAG_String, ss) { + _size = ss.get() << 8 | ss.get(); + + for (int i(0); i < _size; ++i) { + _data += ss.get(); + } +} + +TagList::TagList(std::stringstream &ss) : Tag(TAG_List, ss) { + _tagId = ss.get(); + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + for (int i(0); i < _size; ++i) { + ss.putback(0); + ss.putback(0); + _data.push_back(readTag(_tagId, ss)); + } +} + +TagCompound::TagCompound(std::stringstream &ss) : Tag(TAG_Compound, ss), + _size(0), + _width(0), + _length(0), + _height(0), + _blocksId(NULL), + _blocksData(NULL) { + int tagId; + + while (TAG_End != (tagId = ss.get())) { + _data.push_back(readTag(tagId, ss)); + ++_size; + + if (TAG_Short == tagId) { + if ("Width" == _data.back()->name()) { + _width = ((TagShort*) _data.back())->data(); + } else if ("Height" == _data.back()->name()) { + _height = ((TagShort*) _data.back())->data(); + } else if ("Length" == _data.back()->name()) { + _length = ((TagShort*) _data.back())->data(); + } + } else if (TAG_Byte_Array == tagId) { + if ("Blocks" == _data.back()->name()) { + _blocksId = ((TagByteArray*) _data.back())->data(); + } else if ("Data" == _data.back()->name()) { + _blocksData = ((TagByteArray*) _data.back())->data(); + } + } + } +} + +TagIntArray::TagIntArray(std::stringstream &ss) : Tag(TAG_Int_Array, ss) { + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + _data = new int[_size]; + for (int i(0); i < _size; ++i) { + _data[i] = ss.get(); + } +} + +int retrieveData(std::string filename, std::stringstream &ss) { + std::ifstream file(filename.c_str(), std::ios::binary); + + int type = file.peek(); + if (0x0A == type) { + ss.flush(); + ss << file; + return 0; + } + if (0x1F == type) { + return ungzip(file, ss); + } + + return 1; +} + +int ungzip(std::ifstream &file, std::stringstream &ss) { + std::string gzipedBytes; + gzipedBytes.clear(); + ss.flush(); + + while (!file.eof()) { + gzipedBytes += (char) file.get(); + } + file.close(); + + if ( gzipedBytes.size() == 0 ) { + ss << gzipedBytes; + return 0; + } + + unsigned int full_length = gzipedBytes.size(); + unsigned int half_length = gzipedBytes.size()/2; + unsigned int uncompLength = full_length; + + char* uncomp = (char*) calloc(sizeof(char), uncompLength); + + z_stream strm; + strm.next_in = (Bytef *) gzipedBytes.c_str(); + strm.avail_in = gzipedBytes.size(); + strm.total_out = 0; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + + bool done = false; + + if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) { + free(uncomp); + return 1; + } + + while (!done) { + // If our output buffer is too small + if (strm.total_out >= uncompLength) { + // Increase size of output buffer + char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length); + memcpy( uncomp2, uncomp, uncompLength ); + uncompLength += half_length; + free(uncomp); + uncomp = uncomp2; + } + + strm.next_out = (Bytef *) (uncomp + strm.total_out); + strm.avail_out = uncompLength - strm.total_out; + + // Inflate another chunk. + int err = inflate (&strm, Z_SYNC_FLUSH); + if (err == Z_STREAM_END) done = true; + else if (err != Z_OK) break; + } + + if (inflateEnd (&strm) != Z_OK) { + free(uncomp); + return 1; + } + + for (size_t i=0; i +#include + +#include +#include +#include + +#define TAG_End 0 +#define TAG_Byte 1 +#define TAG_Short 2 +#define TAG_Int 3 +#define TAG_Long 4 +#define TAG_Float 5 +#define TAG_Double 6 +#define TAG_Byte_Array 7 +#define TAG_String 8 +#define TAG_List 9 +#define TAG_Compound 10 +#define TAG_Int_Array 11 + +int retrieveData(std::string filename, std::stringstream &ss); +int ungzip(std::ifstream &file, std::stringstream &ss); + +class Tag { + protected: + int _tagId; + std::string _name; + + public: + Tag(int tagId, std::stringstream &ss); + + int tagId() const {return _tagId;} + std::string name () const {return _name; } + + static Tag* readTag(int tagId, std::stringstream &ss); +}; + +class TagByte : public Tag { + private: + int8_t _data; + + public: + TagByte(std::stringstream &ss); + + int8_t data() const {return _data;} +}; + +class TagShort : public Tag { + private: + int16_t _data; + + public: + TagShort(std::stringstream &ss); + + int16_t data() const {return _data;} +}; + +class TagInt : public Tag { + private: + int32_t _data; + + public: + TagInt(std::stringstream &ss); + + int32_t data() const {return _data;} +}; + +class TagLong : public Tag { + private: + int64_t _data; + + public: + TagLong(std::stringstream &ss); + + int64_t data() const {return _data;} +}; + +class TagByteArray : public Tag { + private: + int _size; + char* _data; + + public: + TagByteArray(std::stringstream &ss); + + int size() const {return _size;} + char* data() const {return _data;} +}; + +class TagString : public Tag { + private: + int _size; + std::string _data; + + public: + TagString(std::stringstream &ss); + + int size() const {return _size;} + std::string data() const {return _data;} +}; + +class TagList : public Tag { + private: + int _tagId; + int _size; + std::list _data; + + public: + TagList(std::stringstream &ss); + + int tagId() const {return _tagId;} + int size () const {return _size; } + std::list data () const {return _data; } +}; + +class TagCompound : public Tag { + private: + int _size; + std::list _data; + + // Specific to schematics file + int _width; + int _length; + int _height; + char* _blocksData; + char* _blocksId; + + public: + TagCompound(std::stringstream &ss); + + int size () const {return _size; } + std::list data () const {return _data; } + + int width () const {return _width; } + int length () const {return _length; } + int height () const {return _height; } + char* blockId () const {return _blocksId; } + char* blocksData() const {return _blocksData;} +}; + +class TagIntArray : public Tag { + private: + int _size; + int* _data; + + public: + TagIntArray(std::stringstream &ss); + ~TagIntArray() {delete _data;} + + int size() const {return _size;} + int* data() const {return _data;} +}; From 4899f77a0cb9a782402681c6cd5583176afc52c6 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Mon, 8 Jul 2013 16:11:50 +0200 Subject: [PATCH 3/6] Complete color handling in minecraft import --- libraries/voxels/src/VoxelTree.cpp | 114 ++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 18 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 7ecba71f3c..e0cc6c985b 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1461,14 +1461,14 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { std::stringstream ss; int err = retrieveData(fileName, ss); if (err && TAG_Compound != ss.get()) { - printLog("ERROR: Invalid schematics file.\n"); + printLog("ERROR: Invalid schematic file.\n"); return false; } ss.get(); TagCompound schematics(ss); - if (!schematics.blockId() || !schematics.blocksData()) { - printLog("ERROR: Invalid schematics file.\n"); + if (!schematics.blockId()) { + printLog("ERROR: Can't read schematic data.\n"); return false; } @@ -1478,8 +1478,10 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { int scale = 1; while (max > scale) scale *= 2; float size = 1.0f / scale; + bool create = false; int red = 128, green = 128, blue = 128; + int count = 0; for (int y = 0; y < schematics.height(); ++y) { for (int z = 0; z < schematics.length(); ++z) { @@ -1528,18 +1530,55 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { case 84: case 137: red = 57; green = 38; blue = 25; break; case 35: - red = 255; - green = 255; - blue = 255; + switch (schematics.blocksData()[pos]) { + case 0: red = 234; green = 234; blue = 234; break; + case 1: red = 224; green = 140; blue = 84; break; + case 2: red = 185; green = 90; blue = 194; break; + case 3: red = 124; green = 152; blue = 208; break; + case 4: red = 165; green = 154; blue = 35; break; + case 5: red = 70; green = 187; blue = 61; break; + case 6: red = 206; green = 124; blue = 145; break; + case 7: red = 66; green = 66; blue = 66; break; + case 8: red = 170; green = 176; blue = 176; break; + case 9: red = 45; green = 108; blue = 35; break; + case 10: red = 130; green = 62; blue = 8; break; + case 11: red = 43; green = 51; blue = 29; break; + case 12: red = 73; green = 47; blue = 29; break; + case 13: red = 57; green = 76; blue = 36; break; + case 14: red = 165; green = 58; blue = 53; break; + case 15: red = 24; green = 24; blue = 24; break; + default: + create = false; + break; + } break; case 41: red = 239; green = 238; blue = 105; break; case 42: red = 146; green = 146; blue = 146; break; case 43: case 98: red = 161; green = 161; blue = 161; break; case 44: - red = 161; - green = 161; - blue = 161; + switch (schematics.blocksData()[pos]) { + case 0: red = 161; green = 161; blue = 161; break; + case 1: red = 209; green = 202; blue = 156; break; + case 2: red = 133; green = 94; blue = 62; break; + case 3: red = 71; green = 71; blue = 71; break; + case 4: red = 121; green = 67; blue = 53; break; + case 5: red = 161; green = 161; blue = 161; break; + case 6: red = 45; green = 22; blue = 26; break; + case 7: red = 195; green = 192; blue = 185; break; + default: + create = false; + break; + } + + if (create) { + createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); + count += 4; + create = false; + } break; case 45: red = 121; green = 67; blue = 53; break; case 46: red = 118; green = 36; blue = 13; break; @@ -1557,9 +1596,50 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { case 135: case 136: case 156: - red = 150; - green = 121; - blue = 74; + switch (id) { + case 53: + case 134: + case 135: + case 136: red = 133; green = 94; blue = 62; break; + case 67: red = 71; green = 71; blue = 71; break; + case 108: red = 121; green = 67; blue = 53; break; + case 109: red = 161; green = 161; blue = 161; break; + case 114: red = 45; green = 22; blue = 26; break; + case 128: red = 209; green = 202; blue = 156; break; + case 156: red = 195; green = 192; blue = 185; break; + default: + create = false; + break; + } + + if (create) { + createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); + + switch (schematics.blocksData()[pos]) { + case 0: + createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 1: + createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 2: + createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 3: + createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + break; + } + + count += 6; + create = false; + } break; case 54: case 95: @@ -1589,23 +1669,21 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { case 170: red = 168; green = 139; blue = 15; break; case 172: red = 140; green = 86; blue = 61; break; case 173: red = 9; green = 9; blue = 9; break; - default: - if (0 < id && id < 160 && false) { - red = 128; blue = 128; green = 128; - } else { - create = false; - } + create = false; break; } if (create) { createVoxel(size * x, size * y, size * z, size, red, green, blue, true); + ++count; } } } } + printLog("Created %d voxels frome minecraft import.\n", count); + return true; } From 4dda71e830dc8f6023f9c771749b220c2ef08f05 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Tue, 9 Jul 2013 12:41:44 +0200 Subject: [PATCH 4/6] Final code for minecraft import to review --- libraries/voxels/src/Tags.cpp | 168 ++++++------ libraries/voxels/src/Tags.h | 60 +++-- libraries/voxels/src/VoxelTree.cpp | 400 +++++++++++++++-------------- libraries/voxels/src/VoxelTree.h | 1 + 4 files changed, 331 insertions(+), 298 deletions(-) diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index 81cf4dbe95..13e8795197 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -7,42 +7,42 @@ #include Tag::Tag(int tagId, std::stringstream &ss) : _tagId(tagId) { - int size(ss.get() << 8 | ss.get()); + int size = ss.get() << 8 | ss.get(); - _name.clear(); - for (int i(0); i < size; ++i) { - _name += ss.get(); - } + _name.clear(); + for (int i = 0; i < size; ++i) { + _name += ss.get(); + } } Tag* Tag::readTag(int tagId, std::stringstream &ss) { - - switch (tagId) { - case TAG_Byte: - return new TagByte(ss); - case TAG_Short: - return new TagShort(ss); - case TAG_Int: - return new TagInt(ss); - case TAG_Long: - return new TagLong(ss); - case TAG_Byte_Array: - return new TagByteArray(ss); - case TAG_String: - return new TagString(ss); - case TAG_List: - return new TagList(ss); - case TAG_Compound: - return new TagCompound(ss); - case TAG_Int_Array: - return new TagIntArray(ss); - case TAG_Float: - case TAG_Double: - default: - //TODO - exit(EXIT_FAILURE); - break; - } + + switch (tagId) { + case TAG_Byte: + return new TagByte(ss); + case TAG_Short: + return new TagShort(ss); + case TAG_Int: + return new TagInt(ss); + case TAG_Long: + return new TagLong(ss); + case TAG_Float: + return new TagFloat(ss); + case TAG_Double: + return new TagDouble(ss); + case TAG_Byte_Array: + return new TagByteArray(ss); + case TAG_String: + return new TagString(ss); + case TAG_List: + return new TagList(ss); + case TAG_Compound: + return new TagCompound(ss); + case TAG_Int_Array: + return new TagIntArray(ss); + default: + return NULL; + } } TagByte::TagByte(std::stringstream &ss) : Tag(TAG_Byte, ss) { @@ -59,15 +59,25 @@ TagInt::TagInt(std::stringstream &ss) : Tag(TAG_Int, ss) { TagLong::TagLong(std::stringstream &ss) : Tag(TAG_Long, ss) { _data = (((int64_t) ss.get()) << 56 | ((int64_t) ss.get()) << 48 - | ((int64_t) ss.get()) << 40 | ((int64_t) ss.get()) << 32 - | ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get()); + |((int64_t) ss.get()) << 40 | ((int64_t) ss.get()) << 32 + | ss.get() << 24 | ss.get() << 16 + | ss.get() << 8 | ss.get()); +} + +// We don't need Float and double, so we just ignore the bytes +TagFloat::TagFloat(std::stringstream &ss) : Tag(TAG_Float, ss) { + ss.seekg(4, ss.cur); +} + +TagDouble::TagDouble(std::stringstream &ss) : Tag(TAG_Double, ss) { + ss.seekg(8, ss.cur); } TagByteArray::TagByteArray(std::stringstream &ss) : Tag(TAG_Byte_Array, ss) { _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); _data = new char[_size]; - for (int i(0); i < _size; ++i) { + for (int i = 0; i < _size; ++i) { _data[i] = ss.get(); } } @@ -75,58 +85,64 @@ TagByteArray::TagByteArray(std::stringstream &ss) : Tag(TAG_Byte_Array, ss) { TagString::TagString(std::stringstream &ss) : Tag(TAG_String, ss) { _size = ss.get() << 8 | ss.get(); - for (int i(0); i < _size; ++i) { + for (int i = 0; i < _size; ++i) { _data += ss.get(); } } -TagList::TagList(std::stringstream &ss) : Tag(TAG_List, ss) { +TagList::TagList(std::stringstream &ss) : + Tag(TAG_List, ss) { _tagId = ss.get(); _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); - for (int i(0); i < _size; ++i) { - ss.putback(0); - ss.putback(0); + for (int i = 0; i < _size; ++i) { + ss.putback(0); ss.putback(0); _data.push_back(readTag(_tagId, ss)); } } -TagCompound::TagCompound(std::stringstream &ss) : Tag(TAG_Compound, ss), - _size(0), - _width(0), - _length(0), - _height(0), - _blocksId(NULL), - _blocksData(NULL) { - int tagId; +TagCompound::TagCompound(std::stringstream &ss) : + Tag(TAG_Compound, ss), + _size(0), + _width(0), + _length(0), + _height(0), + _blocksId(NULL), + _blocksData(NULL) +{ + int tagId; - while (TAG_End != (tagId = ss.get())) { - _data.push_back(readTag(tagId, ss)); - ++_size; + while (TAG_End != (tagId = ss.get())) { + _data.push_back(readTag(tagId, ss)); + ++_size; - if (TAG_Short == tagId) { - if ("Width" == _data.back()->name()) { - _width = ((TagShort*) _data.back())->data(); - } else if ("Height" == _data.back()->name()) { - _height = ((TagShort*) _data.back())->data(); - } else if ("Length" == _data.back()->name()) { - _length = ((TagShort*) _data.back())->data(); - } - } else if (TAG_Byte_Array == tagId) { - if ("Blocks" == _data.back()->name()) { - _blocksId = ((TagByteArray*) _data.back())->data(); - } else if ("Data" == _data.back()->name()) { - _blocksData = ((TagByteArray*) _data.back())->data(); + if (NULL == _data.back()) { + _blocksId = NULL; + _blocksData = NULL; + return; + } else if (TAG_Short == tagId) { + if ("Width" == _data.back()->getName()) { + _width = ((TagShort*) _data.back())->getData(); + } else if ("Height" == _data.back()->getName()) { + _height = ((TagShort*) _data.back())->getData(); + } else if ("Length" == _data.back()->getName()) { + _length = ((TagShort*) _data.back())->getData(); + } + } else if (TAG_Byte_Array == tagId) { + if ("Blocks" == _data.back()->getName()) { + _blocksId = ((TagByteArray*) _data.back())->getData(); + } else if ("Data" == _data.back()->getName()) { + _blocksData = ((TagByteArray*) _data.back())->getData(); + } } } - } } TagIntArray::TagIntArray(std::stringstream &ss) : Tag(TAG_Int_Array, ss) { _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); _data = new int[_size]; - for (int i(0); i < _size; ++i) { + for (int i = 0; i < _size; ++i) { _data[i] = ss.get(); } } @@ -162,22 +178,22 @@ int ungzip(std::ifstream &file, std::stringstream &ss) { return 0; } - unsigned int full_length = gzipedBytes.size(); - unsigned int half_length = gzipedBytes.size()/2; + unsigned int full_length = gzipedBytes.size(); + unsigned int half_length = gzipedBytes.size()/2; unsigned int uncompLength = full_length; char* uncomp = (char*) calloc(sizeof(char), uncompLength); z_stream strm; - strm.next_in = (Bytef *) gzipedBytes.c_str(); - strm.avail_in = gzipedBytes.size(); + strm.next_in = (Bytef *) gzipedBytes.c_str(); + strm.avail_in = full_length; strm.total_out = 0; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; bool done = false; - if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) { + if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) { free(uncomp); return 1; } @@ -187,13 +203,13 @@ int ungzip(std::ifstream &file, std::stringstream &ss) { if (strm.total_out >= uncompLength) { // Increase size of output buffer char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length); - memcpy( uncomp2, uncomp, uncompLength ); + memcpy(uncomp2, uncomp, uncompLength); uncompLength += half_length; free(uncomp); uncomp = uncomp2; } - strm.next_out = (Bytef *) (uncomp + strm.total_out); + strm.next_out = (Bytef *) (uncomp + strm.total_out); strm.avail_out = uncompLength - strm.total_out; // Inflate another chunk. @@ -207,7 +223,7 @@ int ungzip(std::ifstream &file, std::stringstream &ss) { return 1; } - for (size_t i=0; i _data; public: TagList(std::stringstream &ss); - int tagId() const {return _tagId;} - int size () const {return _size; } - std::list data () const {return _data; } + int getTagId() const {return _tagId;} + int getSize () const {return _size; } + std::list getData () const {return _data; } }; class TagCompound : public Tag { private: - int _size; + int _size; std::list _data; // Specific to schematics file @@ -128,14 +138,14 @@ class TagCompound : public Tag { public: TagCompound(std::stringstream &ss); - int size () const {return _size; } - std::list data () const {return _data; } + int getSize () const {return _size; } + std::list getData () const {return _data; } - int width () const {return _width; } - int length () const {return _length; } - int height () const {return _height; } - char* blockId () const {return _blocksId; } - char* blocksData() const {return _blocksData;} + int getWidth () const {return _width; } + int getLength () const {return _length; } + int getHeight () const {return _height; } + char* getBlocksId () const {return _blocksId; } + char* getBlocksData() const {return _blocksData;} }; class TagIntArray : public Tag { @@ -147,6 +157,6 @@ class TagIntArray : public Tag { TagIntArray(std::stringstream &ss); ~TagIntArray() {delete _data;} - int size() const {return _size;} - int* data() const {return _data;} + int getSize() const {return _size;} + int* getData() const {return _data;} }; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index e0cc6c985b..6189c04cbb 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1461,228 +1461,77 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { std::stringstream ss; int err = retrieveData(fileName, ss); if (err && TAG_Compound != ss.get()) { - printLog("ERROR: Invalid schematic file.\n"); + printLog("[ERROR] Invalid schematic file.\n"); return false; } ss.get(); TagCompound schematics(ss); - if (!schematics.blockId()) { - printLog("ERROR: Can't read schematic data.\n"); + if (!schematics.getBlocksId() || !schematics.getBlocksData()) { + printLog("[ERROR] Invalid schematic file.\n"); return false; } - int max = (schematics.width() > schematics.length()) ? schematics.width() : schematics.length(); - max = (max > schematics.height()) ? max : schematics.height(); + int max = (schematics.getWidth() > schematics.getLength()) ? schematics.getWidth() : schematics.getLength(); + max = (max > schematics.getHeight()) ? max : schematics.getHeight(); int scale = 1; while (max > scale) scale *= 2; float size = 1.0f / scale; - bool create = false; + int create = 1; int red = 128, green = 128, blue = 128; int count = 0; - for (int y = 0; y < schematics.height(); ++y) { - for (int z = 0; z < schematics.length(); ++z) { - for (int x = 0; x < schematics.width(); ++x) { - int pos = ((y * schematics.length()) + z) * schematics.width() + x; - int id = schematics.blockId()[pos]; + for (int y = 0; y < schematics.getHeight(); ++y) { + for (int z = 0; z < schematics.getLength(); ++z) { + for (int x = 0; x < schematics.getWidth(); ++x) { + int pos = ((y * schematics.getLength()) + z) * schematics.getWidth() + x; + int id = schematics.getBlocksId()[pos]; + int data = schematics.getBlocksData()[pos]; - create = true; - switch (id) { - case 1: - case 14: - case 15: - case 16: - case 21: - case 56: - case 73: - case 74: - case 97: - case 129: red = 128; green = 128; blue = 128; break; - case 2: red = 77; green = 117; blue = 66; break; - case 3: - case 60: red = 116; green = 83; blue = 56; break; - case 4: red = 71; green = 71; blue = 71; break; - case 5: - case 125: red = 133; green = 94; blue = 62; break; - case 7: red = 35; green = 35; blue = 35; break; - case 8: - case 9: red = 100; green = 109; blue = 185; break; - case 10: - case 11: red = 192; green = 64; blue = 8; break; - case 12: red = 209; green = 199; blue = 155; break; - case 13: red = 96; green = 94; blue = 93; break; - case 17: red = 71; green = 56; blue = 35; break; - case 18: red = 76; green = 104; blue = 64; break; - case 19: red = 119; green = 119; blue = 37; break; - case 22: red = 22; green = 44; blue = 86; break; - case 23: - case 29: - case 33: - case 61: - case 62: - case 158: red = 61; green = 61; blue = 61; break; - case 24: red = 209; green = 202; blue = 156; break; - case 25: - case 58: - case 84: - case 137: red = 57; green = 38; blue = 25; break; - case 35: - switch (schematics.blocksData()[pos]) { - case 0: red = 234; green = 234; blue = 234; break; - case 1: red = 224; green = 140; blue = 84; break; - case 2: red = 185; green = 90; blue = 194; break; - case 3: red = 124; green = 152; blue = 208; break; - case 4: red = 165; green = 154; blue = 35; break; - case 5: red = 70; green = 187; blue = 61; break; - case 6: red = 206; green = 124; blue = 145; break; - case 7: red = 66; green = 66; blue = 66; break; - case 8: red = 170; green = 176; blue = 176; break; - case 9: red = 45; green = 108; blue = 35; break; - case 10: red = 130; green = 62; blue = 8; break; - case 11: red = 43; green = 51; blue = 29; break; - case 12: red = 73; green = 47; blue = 29; break; - case 13: red = 57; green = 76; blue = 36; break; - case 14: red = 165; green = 58; blue = 53; break; - case 15: red = 24; green = 24; blue = 24; break; - default: - create = false; - break; - } - break; - case 41: red = 239; green = 238; blue = 105; break; - case 42: red = 146; green = 146; blue = 146; break; - case 43: - case 98: red = 161; green = 161; blue = 161; break; - case 44: - switch (schematics.blocksData()[pos]) { - case 0: red = 161; green = 161; blue = 161; break; - case 1: red = 209; green = 202; blue = 156; break; - case 2: red = 133; green = 94; blue = 62; break; - case 3: red = 71; green = 71; blue = 71; break; - case 4: red = 121; green = 67; blue = 53; break; - case 5: red = 161; green = 161; blue = 161; break; - case 6: red = 45; green = 22; blue = 26; break; - case 7: red = 195; green = 192; blue = 185; break; - default: - create = false; - break; - } + create = 1; + computeBlockColor(id, data, &red, &green, &blue, &create); - if (create) { - createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); - createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); - count += 4; - create = false; - } - break; - case 45: red = 121; green = 67; blue = 53; break; - case 46: red = 118; green = 36; blue = 13; break; - case 47: red = 155; green = 127; blue = 76; break; - case 48: red = 61; green = 79; blue = 61; break; - case 49: red = 52; green = 41; blue = 74; break; - case 52: red = 12; green = 66; blue = 71; break; - case 53: - case 67: - case 108: - case 109: - case 114: - case 128: - case 134: - case 135: - case 136: - case 156: - switch (id) { - case 53: - case 134: - case 135: - case 136: red = 133; green = 94; blue = 62; break; - case 67: red = 71; green = 71; blue = 71; break; - case 108: red = 121; green = 67; blue = 53; break; - case 109: red = 161; green = 161; blue = 161; break; - case 114: red = 45; green = 22; blue = 26; break; - case 128: red = 209; green = 202; blue = 156; break; - case 156: red = 195; green = 192; blue = 185; break; - default: - create = false; - break; - } - - if (create) { - createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); - createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); - - switch (schematics.blocksData()[pos]) { - case 0: - createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - break; - case 1: - createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); - createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - break; - case 2: - createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - break; - case 3: - createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); - break; - } - - count += 6; - create = false; - } - break; - case 54: - case 95: - case 146: red = 155; green = 105; blue = 32; break; - case 57: red = 145; green = 219; blue = 215; break; - case 79: red = 142; green = 162; blue = 195; break; - case 80: red = 255; green = 255; blue = 255; break; - case 81: red = 8; green = 64; blue = 15; break; - case 82: red = 150; green = 155; blue = 166; break; - case 86: - case 91: red = 179; green = 108; blue = 17; break; - case 87: - case 153: red = 91; green = 31; blue = 30; break; - case 88: red = 68; green = 49; blue = 38; break; - case 89: red = 180; green = 134; blue = 65; break; - case 103: red = 141; green = 143; blue = 36; break; - case 110: red = 103; green = 92; blue = 95; break; - case 112: red = 45; green = 22; blue = 26; break; - case 121: red = 183; green = 178; blue = 129; break; - case 123: red = 101; green = 59; blue = 31; break; - case 124: red = 213; green = 178; blue = 123; break; - case 130: red = 38; green = 54; blue = 56; break; - case 133: red = 53; green = 84; blue = 85; break; - case 152: red = 131; green = 22; blue = 7; break; - case 155: red = 195; green = 192; blue = 185; break; - case 159: red = 195; green = 165; blue = 150; break; - case 170: red = 168; green = 139; blue = 15; break; - case 172: red = 140; green = 86; blue = 61; break; - case 173: red = 9; green = 9; blue = 9; break; - default: - create = false; - break; - } - - if (create) { + switch (create) { + case 1: createVoxel(size * x, size * y, size * z, size, red, green, blue, true); ++count; + break; + case 2: + switch (data) { + case 0: + createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 1: + createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 2: + createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 3: + createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + break; + } + count += 2; + // There's no break on purpose. + case 3: + createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); + count += 4; + break; } } } } - printLog("Created %d voxels frome minecraft import.\n", count); + printLog("Created %d voxels from minecraft import.\n", count); return true; } @@ -1771,3 +1620,160 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin } } +void VoxelTree::computeBlockColor(int id, int data, int* r, int* g, int* b, int* create) { + int red = *r, green = *g, blue = *b; + + switch (id) { + case 1: + case 14: + case 15: + case 16: + case 21: + case 56: + case 73: + case 74: + case 97: + case 129: red = 128; green = 128; blue = 128; break; + case 2: red = 77; green = 117; blue = 66; break; + case 3: + case 60: red = 116; green = 83; blue = 56; break; + case 4: red = 71; green = 71; blue = 71; break; + case 5: + case 125: red = 133; green = 94; blue = 62; break; + case 7: red = 35; green = 35; blue = 35; break; + case 8: + case 9: red = 100; green = 109; blue = 185; break; + case 10: + case 11: red = 192; green = 64; blue = 8; break; + case 12: red = 209; green = 199; blue = 155; break; + case 13: red = 96; green = 94; blue = 93; break; + case 17: red = 71; green = 56; blue = 35; break; + case 18: red = 76; green = 104; blue = 64; break; + case 19: red = 119; green = 119; blue = 37; break; + case 22: red = 22; green = 44; blue = 86; break; + case 23: + case 29: + case 33: + case 61: + case 62: + case 158: red = 61; green = 61; blue = 61; break; + case 24: red = 209; green = 202; blue = 156; break; + case 25: + case 58: + case 84: + case 137: red = 57; green = 38; blue = 25; break; + case 35: + switch (data) { + case 0: red = 234; green = 234; blue = 234; break; + case 1: red = 224; green = 140; blue = 84; break; + case 2: red = 185; green = 90; blue = 194; break; + case 3: red = 124; green = 152; blue = 208; break; + case 4: red = 165; green = 154; blue = 35; break; + case 5: red = 70; green = 187; blue = 61; break; + case 6: red = 206; green = 124; blue = 145; break; + case 7: red = 66; green = 66; blue = 66; break; + case 8: red = 170; green = 176; blue = 176; break; + case 9: red = 45; green = 108; blue = 35; break; + case 10: red = 130; green = 62; blue = 8; break; + case 11: red = 43; green = 51; blue = 29; break; + case 12: red = 73; green = 47; blue = 29; break; + case 13: red = 57; green = 76; blue = 36; break; + case 14: red = 165; green = 58; blue = 53; break; + case 15: red = 24; green = 24; blue = 24; break; + default: + *create = 0; + break; + } + break; + case 41: red = 239; green = 238; blue = 105; break; + case 42: red = 146; green = 146; blue = 146; break; + case 43: + case 98: red = 161; green = 161; blue = 161; break; + case 44: + *create = 3; + + switch (data) { + case 0: red = 161; green = 161; blue = 161; break; + case 1: red = 209; green = 202; blue = 156; break; + case 2: red = 133; green = 94; blue = 62; break; + case 3: red = 71; green = 71; blue = 71; break; + case 4: red = 121; green = 67; blue = 53; break; + case 5: red = 161; green = 161; blue = 161; break; + case 6: red = 45; green = 22; blue = 26; break; + case 7: red = 195; green = 192; blue = 185; break; + default: + *create = 0; + break; + } + break; + case 45: red = 121; green = 67; blue = 53; break; + case 46: red = 118; green = 36; blue = 13; break; + case 47: red = 155; green = 127; blue = 76; break; + case 48: red = 61; green = 79; blue = 61; break; + case 49: red = 52; green = 41; blue = 74; break; + case 52: red = 12; green = 66; blue = 71; break; + case 53: + case 67: + case 108: + case 109: + case 114: + case 128: + case 134: + case 135: + case 136: + case 156: + *create = 2; + + switch (id) { + case 53: + case 134: + case 135: + case 136: red = 133; green = 94; blue = 62; break; + case 67: red = 71; green = 71; blue = 71; break; + case 108: red = 121; green = 67; blue = 53; break; + case 109: red = 161; green = 161; blue = 161; break; + case 114: red = 45; green = 22; blue = 26; break; + case 128: red = 209; green = 202; blue = 156; break; + case 156: red = 195; green = 192; blue = 185; break; + default: + *create = 0; + break; + } + break; + case 54: + case 95: + case 146: red = 155; green = 105; blue = 32; break; + case 57: red = 145; green = 219; blue = 215; break; + case 79: red = 142; green = 162; blue = 195; break; + case 80: red = 255; green = 255; blue = 255; break; + case 81: red = 8; green = 64; blue = 15; break; + case 82: red = 150; green = 155; blue = 166; break; + case 86: + case 91: red = 179; green = 108; blue = 17; break; + case 87: + case 153: red = 91; green = 31; blue = 30; break; + case 88: red = 68; green = 49; blue = 38; break; + case 89: red = 180; green = 134; blue = 65; break; + case 103: red = 141; green = 143; blue = 36; break; + case 110: red = 103; green = 92; blue = 95; break; + case 112: red = 45; green = 22; blue = 26; break; + case 121: red = 183; green = 178; blue = 129; break; + case 123: red = 101; green = 59; blue = 31; break; + case 124: red = 213; green = 178; blue = 123; break; + case 130: red = 38; green = 54; blue = 56; break; + case 133: red = 53; green = 84; blue = 85; break; + case 152: red = 131; green = 22; blue = 7; break; + case 155: red = 195; green = 192; blue = 185; break; + case 159: red = 195; green = 165; blue = 150; break; + case 170: red = 168; green = 139; blue = 15; break; + case 172: red = 140; green = 86; blue = 61; break; + case 173: red = 9; green = 9; blue = 9; break; + default: + *create = 0; + break; + } + + *r = red; + *g = green; + *b = blue; +} diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 3591141549..56d0e1120e 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -136,6 +136,7 @@ public: // reads voxels from square image with alpha as a Y-axis bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); bool readFromSchematicsFile(const char* filename); + void computeBlockColor(int id, int data, int* r, int* g, int* b, int* create); unsigned long getVoxelCount(); From dbdbd7a8c4161f7d28f8b0da96c4ab4fbb1ae8b0 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Tue, 9 Jul 2013 17:55:55 +0200 Subject: [PATCH 5/6] Incorporating comments for code review (minecraft import) --- interface/src/Application.cpp | 6 +- libraries/voxels/src/Tags.cpp | 211 +++++++++-------- libraries/voxels/src/Tags.h | 213 +++++++++-------- libraries/voxels/src/VoxelTree.cpp | 351 ++++++++++++++--------------- libraries/voxels/src/VoxelTree.h | 2 +- 5 files changed, 402 insertions(+), 381 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fc72aa63bd..95d40eec12 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1363,8 +1363,10 @@ void Application::exportVoxels() { void Application::importVoxels() { QString desktopLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); - QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Import Voxels"), desktopLocation, - tr("Sparse Voxel Octree Files, Square PNG, Schematic Files (*.svo *.png *.schematic)")); + QString fileNameString = QFileDialog::getOpenFileName( + _glWidget, tr("Import Voxels"), desktopLocation, + tr("Sparse Voxel Octree Files, Square PNG, Schematic Files (*.svo *.png *.schematic)")); + QByteArray fileNameAscii = fileNameString.toAscii(); const char* fileName = fileNameAscii.data(); diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index 13e8795197..0cbfa1a37c 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -1,3 +1,11 @@ +// +// Tags.h +// hifi +// +// Created by Clement Brisset on 7/3/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + #include "Tags.h" #include @@ -8,10 +16,9 @@ Tag::Tag(int tagId, std::stringstream &ss) : _tagId(tagId) { int size = ss.get() << 8 | ss.get(); - + _name.clear(); - for (int i = 0; i < size; ++i) { - _name += ss.get(); + for (int i = 0; i < size; ++i) { _name += ss.get(); } } @@ -46,22 +53,22 @@ Tag* Tag::readTag(int tagId, std::stringstream &ss) { } TagByte::TagByte(std::stringstream &ss) : Tag(TAG_Byte, ss) { - _data = ss.get(); + _data = ss.get(); } TagShort::TagShort(std::stringstream &ss) : Tag(TAG_Short, ss) { - _data = ss.get() << 8 | ss.get(); + _data = ss.get() << 8 | ss.get(); } TagInt::TagInt(std::stringstream &ss) : Tag(TAG_Int, ss) { - _data = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + _data = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); } TagLong::TagLong(std::stringstream &ss) : Tag(TAG_Long, ss) { - _data = (((int64_t) ss.get()) << 56 | ((int64_t) ss.get()) << 48 - |((int64_t) ss.get()) << 40 | ((int64_t) ss.get()) << 32 - | ss.get() << 24 | ss.get() << 16 - | ss.get() << 8 | ss.get()); + _data = (((int64_t) ss.get()) << 56 | ((int64_t) ss.get()) << 48 + |((int64_t) ss.get()) << 40 | ((int64_t) ss.get()) << 32 + | ss.get() << 24 | ss.get() << 16 + | ss.get() << 8 | ss.get()); } // We don't need Float and double, so we just ignore the bytes @@ -74,31 +81,32 @@ TagDouble::TagDouble(std::stringstream &ss) : Tag(TAG_Double, ss) { } TagByteArray::TagByteArray(std::stringstream &ss) : Tag(TAG_Byte_Array, ss) { - _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); - - _data = new char[_size]; - for (int i = 0; i < _size; ++i) { - _data[i] = ss.get(); - } + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + _data = new char[_size]; + for (int i = 0; i < _size; ++i) { + _data[i] = ss.get(); + } } TagString::TagString(std::stringstream &ss) : Tag(TAG_String, ss) { - _size = ss.get() << 8 | ss.get(); - - for (int i = 0; i < _size; ++i) { - _data += ss.get(); - } + _size = ss.get() << 8 | ss.get(); + + for (int i = 0; i < _size; ++i) { + _data += ss.get(); + } } TagList::TagList(std::stringstream &ss) : Tag(TAG_List, ss) { - _tagId = ss.get(); - _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + _tagId = ss.get(); + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); - for (int i = 0; i < _size; ++i) { - ss.putback(0); ss.putback(0); - _data.push_back(readTag(_tagId, ss)); - } + for (int i = 0; i < _size; ++i) { + ss.putback(0); + ss.putback(0); + _data.push_back(readTag(_tagId, ss)); + } } TagCompound::TagCompound(std::stringstream &ss) : @@ -139,96 +147,99 @@ TagCompound::TagCompound(std::stringstream &ss) : } TagIntArray::TagIntArray(std::stringstream &ss) : Tag(TAG_Int_Array, ss) { - _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); - - _data = new int[_size]; - for (int i = 0; i < _size; ++i) { - _data[i] = ss.get(); - } + _size = ss.get() << 24 | ss.get() << 16 | ss.get() << 8 | ss.get(); + + _data = new int[_size]; + for (int i = 0; i < _size; ++i) { + _data[i] = ss.get(); + } } int retrieveData(std::string filename, std::stringstream &ss) { std::ifstream file(filename.c_str(), std::ios::binary); - int type = file.peek(); - if (0x0A == type) { - ss.flush(); - ss << file; - return 0; - } - if (0x1F == type) { - return ungzip(file, ss); - } + int type = file.peek(); + if (type == 0x0A) { + ss.flush(); + ss << file; + return 0; + } + if (type == 0x1F) { + return ungzip(file, ss); + } - return 1; + return 1; } int ungzip(std::ifstream &file, std::stringstream &ss) { - std::string gzipedBytes; - gzipedBytes.clear(); - ss.flush(); + std::string gzipedBytes; + gzipedBytes.clear(); + ss.flush(); - while (!file.eof()) { - gzipedBytes += (char) file.get(); - } - file.close(); + while (!file.eof()) { + gzipedBytes += (char) file.get(); + } + file.close(); - if ( gzipedBytes.size() == 0 ) { - ss << gzipedBytes; - return 0; - } - - unsigned int full_length = gzipedBytes.size(); - unsigned int half_length = gzipedBytes.size()/2; - unsigned int uncompLength = full_length; - - char* uncomp = (char*) calloc(sizeof(char), uncompLength); - - z_stream strm; - strm.next_in = (Bytef *) gzipedBytes.c_str(); - strm.avail_in = full_length; - strm.total_out = 0; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - - bool done = false; - - if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) { - free(uncomp); - return 1; - } - - while (!done) { - // If our output buffer is too small - if (strm.total_out >= uncompLength) { - // Increase size of output buffer - char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length); - memcpy(uncomp2, uncomp, uncompLength); - uncompLength += half_length; - free(uncomp); - uncomp = uncomp2; + if (gzipedBytes.size() == 0) { + ss << gzipedBytes; + return 0; } - strm.next_out = (Bytef *) (uncomp + strm.total_out); - strm.avail_out = uncompLength - strm.total_out; + unsigned int full_length = gzipedBytes.size(); + unsigned int half_length = gzipedBytes.size()/2; + unsigned int uncompLength = full_length; - // Inflate another chunk. - int err = inflate (&strm, Z_SYNC_FLUSH); - if (err == Z_STREAM_END) done = true; - else if (err != Z_OK) break; - } + char* uncomp = (char*) calloc(sizeof(char), uncompLength); - if (inflateEnd (&strm) != Z_OK) { + z_stream strm; + strm.next_in = (Bytef *) gzipedBytes.c_str(); + strm.avail_in = full_length; + strm.total_out = 0; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + + bool done = false; + + if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) { + free(uncomp); + return 1; + } + + while (!done) { + // If our output buffer is too small + if (strm.total_out >= uncompLength) { + // Increase size of output buffer + char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length); + memcpy(uncomp2, uncomp, uncompLength); + uncompLength += half_length; + free(uncomp); + uncomp = uncomp2; + } + + strm.next_out = (Bytef *) (uncomp + strm.total_out); + strm.avail_out = uncompLength - strm.total_out; + + // Inflate another chunk. + int err = inflate (&strm, Z_SYNC_FLUSH); + if (err == Z_STREAM_END) { + done = true; + } else if (err != Z_OK) { + break; + } + } + + if (inflateEnd (&strm) != Z_OK) { + free(uncomp); + return 1; + } + + for (size_t i = 0; i < strm.total_out; ++i) { + ss << uncomp[i]; + } free(uncomp); - return 1; - } - for (size_t i = 0; i < strm.total_out; ++i) { - ss << uncomp[i]; - } - free(uncomp); - - return 0; + return 0; } diff --git a/libraries/voxels/src/Tags.h b/libraries/voxels/src/Tags.h index be45e2dc86..a005095142 100644 --- a/libraries/voxels/src/Tags.h +++ b/libraries/voxels/src/Tags.h @@ -1,3 +1,14 @@ +// +// Tags.h +// hifi +// +// Created by Clement Brisset on 7/3/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__Tags__ +#define __hifi__Tags__ + #include #include @@ -22,141 +33,143 @@ int retrieveData(std::string filename, std::stringstream &ss); int ungzip(std::ifstream &file, std::stringstream &ss); class Tag { - protected: - int _tagId; - std::string _name; - - public: - Tag(int tagId, std::stringstream &ss); - - int getTagId() const {return _tagId;} - std::string getName () const {return _name; } - - static Tag* readTag(int tagId, std::stringstream &ss); +public: + Tag(int tagId, std::stringstream &ss); + + int getTagId() const {return _tagId;} + std::string getName () const {return _name; } + + static Tag* readTag(int tagId, std::stringstream &ss); + +protected: + int _tagId; + std::string _name; }; class TagByte : public Tag { - private: - int8_t _data; - - public: - TagByte(std::stringstream &ss); - - int8_t getData() const {return _data;} +public: + TagByte(std::stringstream &ss); + + int8_t getData() const {return _data;} + +private: + int8_t _data; }; class TagShort : public Tag { - private: - int16_t _data; - - public: - TagShort(std::stringstream &ss); - - int16_t getData() const {return _data;} +public: + TagShort(std::stringstream &ss); + + int16_t getData() const {return _data;} + +private: + int16_t _data; }; class TagInt : public Tag { - private: - int32_t _data; - - public: - TagInt(std::stringstream &ss); - - int32_t getData() const {return _data;} +public: + TagInt(std::stringstream &ss); + + int32_t getData() const {return _data;} + +private: + int32_t _data; }; class TagLong : public Tag { - private: - int64_t _data; - - public: - TagLong(std::stringstream &ss); - - int64_t getData() const {return _data;} +public: + TagLong(std::stringstream &ss); + + int64_t getData() const {return _data;} + +private: + int64_t _data; }; class TagFloat : public Tag { - public: - TagFloat(std::stringstream &ss); +public: + TagFloat(std::stringstream &ss); }; class TagDouble : public Tag { - public: - TagDouble(std::stringstream &ss); +public: + TagDouble(std::stringstream &ss); }; class TagByteArray : public Tag { - private: - int _size; - char* _data; - - public: - TagByteArray(std::stringstream &ss); - - int getSize() const {return _size;} - char* getData() const {return _data;} +public: + TagByteArray(std::stringstream &ss); + + int getSize() const {return _size;} + char* getData() const {return _data;} + +private: + int _size; + char* _data; }; class TagString : public Tag { - private: - int _size; - std::string _data; +public: + TagString(std::stringstream &ss); - public: - TagString(std::stringstream &ss); - - int getSize() const {return _size;} - std::string getData() const {return _data;} + int getSize() const {return _size;} + std::string getData() const {return _data;} + +private: + int _size; + std::string _data; }; class TagList : public Tag { - private: - int _tagId; - int _size; - std::list _data; - - public: - TagList(std::stringstream &ss); - - int getTagId() const {return _tagId;} - int getSize () const {return _size; } - std::list getData () const {return _data; } +public: + TagList(std::stringstream &ss); + + int getTagId() const {return _tagId;} + int getSize () const {return _size; } + std::list getData () const {return _data; } + +private: + int _tagId; + int _size; + std::list _data; }; class TagCompound : public Tag { - private: - int _size; - std::list _data; - - // Specific to schematics file - int _width; - int _length; - int _height; - char* _blocksData; - char* _blocksId; +public: + TagCompound(std::stringstream &ss); - public: - TagCompound(std::stringstream &ss); - - int getSize () const {return _size; } - std::list getData () const {return _data; } + int getSize () const {return _size; } + std::list getData () const {return _data; } - int getWidth () const {return _width; } - int getLength () const {return _length; } - int getHeight () const {return _height; } - char* getBlocksId () const {return _blocksId; } - char* getBlocksData() const {return _blocksData;} + int getWidth () const {return _width; } + int getLength () const {return _length; } + int getHeight () const {return _height; } + char* getBlocksId () const {return _blocksId; } + char* getBlocksData() const {return _blocksData;} + +private: + int _size; + std::list _data; + + // Specific to schematics file + int _width; + int _length; + int _height; + char* _blocksData; + char* _blocksId; }; class TagIntArray : public Tag { - private: - int _size; - int* _data; +public: + TagIntArray(std::stringstream &ss); + ~TagIntArray() {delete _data;} - public: - TagIntArray(std::stringstream &ss); - ~TagIntArray() {delete _data;} - - int getSize() const {return _size;} - int* getData() const {return _data;} + int getSize() const {return _size;} + int* getData() const {return _data;} + +private: + int _size; + int* _data; }; + +#endif /* defined(__hifi__Tags__) */ diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 6189c04cbb..d4b7ec831e 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -802,7 +802,7 @@ void VoxelTree::createSphere(float radius, float xc, float yc, float zc, float v if (debug) { printLog("perlin=%f gradient=%f color=(%d,%d,%d)\n",perlin, gradient, red, green, blue); } - } break; + } break; } if (wantNaturalSurface) { // for natural surfaces, we will render up to 16 voxel's above the surface of the sphere @@ -1460,7 +1460,7 @@ bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension bool VoxelTree::readFromSchematicsFile(const char *fileName) { std::stringstream ss; int err = retrieveData(fileName, ss); - if (err && TAG_Compound != ss.get()) { + if (err && ss.get() != TAG_Compound) { printLog("[ERROR] Invalid schematic file.\n"); return false; } @@ -1476,7 +1476,7 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { max = (max > schematics.getHeight()) ? max : schematics.getHeight(); int scale = 1; - while (max > scale) scale *= 2; + while (max > scale) {scale *= 2;} float size = 1.0f / scale; int create = 1; @@ -1491,41 +1491,41 @@ bool VoxelTree::readFromSchematicsFile(const char *fileName) { int data = schematics.getBlocksData()[pos]; create = 1; - computeBlockColor(id, data, &red, &green, &blue, &create); + computeBlockColor(id, data, red, green, blue, create); switch (create) { - case 1: - createVoxel(size * x, size * y, size * z, size, red, green, blue, true); - ++count; - break; - case 2: - switch (data) { - case 0: - createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - break; case 1: - createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); - createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x, size * y, size * z, size, red, green, blue, true); + ++count; break; case 2: - createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); - break; + switch (data) { + case 0: + createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 1: + createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 2: + createVoxel(size * x , size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z + size / 2, size / 2, red, green, blue, true); + break; + case 3: + createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + break; + } + count += 2; + // There's no break on purpose. case 3: - createVoxel(size * x , size * y + size / 2, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y + size / 2, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); + createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); + createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); + count += 4; break; - } - count += 2; - // There's no break on purpose. - case 3: - createVoxel(size * x , size * y, size * z , size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y, size * z , size / 2, red, green, blue, true); - createVoxel(size * x , size * y, size * z + size / 2, size / 2, red, green, blue, true); - createVoxel(size * x + size / 2, size * y, size * z + size / 2, size / 2, red, green, blue, true); - count += 4; - break; } } } @@ -1620,160 +1620,155 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin } } -void VoxelTree::computeBlockColor(int id, int data, int* r, int* g, int* b, int* create) { - int red = *r, green = *g, blue = *b; +void VoxelTree::computeBlockColor(int id, int data, int& red, int& green, int& blue, int& create) { switch (id) { - case 1: - case 14: - case 15: - case 16: - case 21: - case 56: - case 73: - case 74: - case 97: - case 129: red = 128; green = 128; blue = 128; break; - case 2: red = 77; green = 117; blue = 66; break; - case 3: - case 60: red = 116; green = 83; blue = 56; break; - case 4: red = 71; green = 71; blue = 71; break; - case 5: - case 125: red = 133; green = 94; blue = 62; break; - case 7: red = 35; green = 35; blue = 35; break; - case 8: - case 9: red = 100; green = 109; blue = 185; break; - case 10: - case 11: red = 192; green = 64; blue = 8; break; - case 12: red = 209; green = 199; blue = 155; break; - case 13: red = 96; green = 94; blue = 93; break; - case 17: red = 71; green = 56; blue = 35; break; - case 18: red = 76; green = 104; blue = 64; break; - case 19: red = 119; green = 119; blue = 37; break; - case 22: red = 22; green = 44; blue = 86; break; - case 23: - case 29: - case 33: - case 61: - case 62: - case 158: red = 61; green = 61; blue = 61; break; - case 24: red = 209; green = 202; blue = 156; break; - case 25: - case 58: - case 84: - case 137: red = 57; green = 38; blue = 25; break; - case 35: - switch (data) { - case 0: red = 234; green = 234; blue = 234; break; - case 1: red = 224; green = 140; blue = 84; break; - case 2: red = 185; green = 90; blue = 194; break; - case 3: red = 124; green = 152; blue = 208; break; - case 4: red = 165; green = 154; blue = 35; break; - case 5: red = 70; green = 187; blue = 61; break; - case 6: red = 206; green = 124; blue = 145; break; - case 7: red = 66; green = 66; blue = 66; break; - case 8: red = 170; green = 176; blue = 176; break; - case 9: red = 45; green = 108; blue = 35; break; - case 10: red = 130; green = 62; blue = 8; break; - case 11: red = 43; green = 51; blue = 29; break; - case 12: red = 73; green = 47; blue = 29; break; - case 13: red = 57; green = 76; blue = 36; break; - case 14: red = 165; green = 58; blue = 53; break; - case 15: red = 24; green = 24; blue = 24; break; - default: - *create = 0; + case 1: + case 14: + case 15: + case 16: + case 21: + case 56: + case 73: + case 74: + case 97: + case 129: red = 128; green = 128; blue = 128; break; + case 2: red = 77; green = 117; blue = 66; break; + case 3: + case 60: red = 116; green = 83; blue = 56; break; + case 4: red = 71; green = 71; blue = 71; break; + case 5: + case 125: red = 133; green = 94; blue = 62; break; + case 7: red = 35; green = 35; blue = 35; break; + case 8: + case 9: red = 100; green = 109; blue = 185; break; + case 10: + case 11: red = 192; green = 64; blue = 8; break; + case 12: red = 209; green = 199; blue = 155; break; + case 13: red = 96; green = 94; blue = 93; break; + case 17: red = 71; green = 56; blue = 35; break; + case 18: red = 76; green = 104; blue = 64; break; + case 19: red = 119; green = 119; blue = 37; break; + case 22: red = 22; green = 44; blue = 86; break; + case 23: + case 29: + case 33: + case 61: + case 62: + case 158: red = 61; green = 61; blue = 61; break; + case 24: red = 209; green = 202; blue = 156; break; + case 25: + case 58: + case 84: + case 137: red = 57; green = 38; blue = 25; break; + case 35: + switch (data) { + case 0: red = 234; green = 234; blue = 234; break; + case 1: red = 224; green = 140; blue = 84; break; + case 2: red = 185; green = 90; blue = 194; break; + case 3: red = 124; green = 152; blue = 208; break; + case 4: red = 165; green = 154; blue = 35; break; + case 5: red = 70; green = 187; blue = 61; break; + case 6: red = 206; green = 124; blue = 145; break; + case 7: red = 66; green = 66; blue = 66; break; + case 8: red = 170; green = 176; blue = 176; break; + case 9: red = 45; green = 108; blue = 35; break; + case 10: red = 130; green = 62; blue = 8; break; + case 11: red = 43; green = 51; blue = 29; break; + case 12: red = 73; green = 47; blue = 29; break; + case 13: red = 57; green = 76; blue = 36; break; + case 14: red = 165; green = 58; blue = 53; break; + case 15: red = 24; green = 24; blue = 24; break; + default: + create = 0; + break; + } break; - } - break; - case 41: red = 239; green = 238; blue = 105; break; - case 42: red = 146; green = 146; blue = 146; break; - case 43: - case 98: red = 161; green = 161; blue = 161; break; - case 44: - *create = 3; + case 41: red = 239; green = 238; blue = 105; break; + case 42: red = 146; green = 146; blue = 146; break; + case 43: + case 98: red = 161; green = 161; blue = 161; break; + case 44: + create = 3; - switch (data) { - case 0: red = 161; green = 161; blue = 161; break; - case 1: red = 209; green = 202; blue = 156; break; - case 2: red = 133; green = 94; blue = 62; break; - case 3: red = 71; green = 71; blue = 71; break; - case 4: red = 121; green = 67; blue = 53; break; - case 5: red = 161; green = 161; blue = 161; break; - case 6: red = 45; green = 22; blue = 26; break; - case 7: red = 195; green = 192; blue = 185; break; - default: - *create = 0; + switch (data) { + case 0: red = 161; green = 161; blue = 161; break; + case 1: red = 209; green = 202; blue = 156; break; + case 2: red = 133; green = 94; blue = 62; break; + case 3: red = 71; green = 71; blue = 71; break; + case 4: red = 121; green = 67; blue = 53; break; + case 5: red = 161; green = 161; blue = 161; break; + case 6: red = 45; green = 22; blue = 26; break; + case 7: red = 195; green = 192; blue = 185; break; + default: + create = 0; + break; + } break; - } - break; - case 45: red = 121; green = 67; blue = 53; break; - case 46: red = 118; green = 36; blue = 13; break; - case 47: red = 155; green = 127; blue = 76; break; - case 48: red = 61; green = 79; blue = 61; break; - case 49: red = 52; green = 41; blue = 74; break; - case 52: red = 12; green = 66; blue = 71; break; - case 53: - case 67: - case 108: - case 109: - case 114: - case 128: - case 134: - case 135: - case 136: - case 156: - *create = 2; - - switch (id) { + case 45: red = 121; green = 67; blue = 53; break; + case 46: red = 118; green = 36; blue = 13; break; + case 47: red = 155; green = 127; blue = 76; break; + case 48: red = 61; green = 79; blue = 61; break; + case 49: red = 52; green = 41; blue = 74; break; + case 52: red = 12; green = 66; blue = 71; break; case 53: + case 67: + case 108: + case 109: + case 114: + case 128: case 134: case 135: - case 136: red = 133; green = 94; blue = 62; break; - case 67: red = 71; green = 71; blue = 71; break; - case 108: red = 121; green = 67; blue = 53; break; - case 109: red = 161; green = 161; blue = 161; break; - case 114: red = 45; green = 22; blue = 26; break; - case 128: red = 209; green = 202; blue = 156; break; - case 156: red = 195; green = 192; blue = 185; break; - default: - *create = 0; - break; - } - break; - case 54: - case 95: - case 146: red = 155; green = 105; blue = 32; break; - case 57: red = 145; green = 219; blue = 215; break; - case 79: red = 142; green = 162; blue = 195; break; - case 80: red = 255; green = 255; blue = 255; break; - case 81: red = 8; green = 64; blue = 15; break; - case 82: red = 150; green = 155; blue = 166; break; - case 86: - case 91: red = 179; green = 108; blue = 17; break; - case 87: - case 153: red = 91; green = 31; blue = 30; break; - case 88: red = 68; green = 49; blue = 38; break; - case 89: red = 180; green = 134; blue = 65; break; - case 103: red = 141; green = 143; blue = 36; break; - case 110: red = 103; green = 92; blue = 95; break; - case 112: red = 45; green = 22; blue = 26; break; - case 121: red = 183; green = 178; blue = 129; break; - case 123: red = 101; green = 59; blue = 31; break; - case 124: red = 213; green = 178; blue = 123; break; - case 130: red = 38; green = 54; blue = 56; break; - case 133: red = 53; green = 84; blue = 85; break; - case 152: red = 131; green = 22; blue = 7; break; - case 155: red = 195; green = 192; blue = 185; break; - case 159: red = 195; green = 165; blue = 150; break; - case 170: red = 168; green = 139; blue = 15; break; - case 172: red = 140; green = 86; blue = 61; break; - case 173: red = 9; green = 9; blue = 9; break; - default: - *create = 0; - break; - } + case 136: + case 156: + create = 2; - *r = red; - *g = green; - *b = blue; + switch (id) { + case 53: + case 134: + case 135: + case 136: red = 133; green = 94; blue = 62; break; + case 67: red = 71; green = 71; blue = 71; break; + case 108: red = 121; green = 67; blue = 53; break; + case 109: red = 161; green = 161; blue = 161; break; + case 114: red = 45; green = 22; blue = 26; break; + case 128: red = 209; green = 202; blue = 156; break; + case 156: red = 195; green = 192; blue = 185; break; + default: + create = 0; + break; + } + break; + case 54: + case 95: + case 146: red = 155; green = 105; blue = 32; break; + case 57: red = 145; green = 219; blue = 215; break; + case 79: red = 142; green = 162; blue = 195; break; + case 80: red = 255; green = 255; blue = 255; break; + case 81: red = 8; green = 64; blue = 15; break; + case 82: red = 150; green = 155; blue = 166; break; + case 86: + case 91: red = 179; green = 108; blue = 17; break; + case 87: + case 153: red = 91; green = 31; blue = 30; break; + case 88: red = 68; green = 49; blue = 38; break; + case 89: red = 180; green = 134; blue = 65; break; + case 103: red = 141; green = 143; blue = 36; break; + case 110: red = 103; green = 92; blue = 95; break; + case 112: red = 45; green = 22; blue = 26; break; + case 121: red = 183; green = 178; blue = 129; break; + case 123: red = 101; green = 59; blue = 31; break; + case 124: red = 213; green = 178; blue = 123; break; + case 130: red = 38; green = 54; blue = 56; break; + case 133: red = 53; green = 84; blue = 85; break; + case 152: red = 131; green = 22; blue = 7; break; + case 155: red = 195; green = 192; blue = 185; break; + case 159: red = 195; green = 165; blue = 150; break; + case 170: red = 168; green = 139; blue = 15; break; + case 172: red = 140; green = 86; blue = 61; break; + case 173: red = 9; green = 9; blue = 9; break; + default: + create = 0; + break; + } } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 56d0e1120e..d4fe888535 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -136,7 +136,7 @@ public: // reads voxels from square image with alpha as a Y-axis bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); bool readFromSchematicsFile(const char* filename); - void computeBlockColor(int id, int data, int* r, int* g, int* b, int* create); + void computeBlockColor(int id, int data, int& r, int& g, int& b, int& create); unsigned long getVoxelCount(); From 7d94f65448658bc6120ce3dc2a38fd9a53dee504 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 10 Jul 2013 13:00:16 -0700 Subject: [PATCH 6/6] Linked ZLIB to voxels library --- interface/src/Application.cpp | 2 +- libraries/voxels/CMakeLists.txt | 7 ++++++- libraries/voxels/src/VoxelTree.cpp | 2 +- libraries/voxels/src/VoxelTree.h | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9c72a94f5d..6480a39539 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1390,7 +1390,7 @@ void Application::importVoxels() { } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { importVoxels.readFromSVOFile(fileName); } else { - importVoxels.readFromSchematicsFile(fileName); + importVoxels.readFromSchematicFile(fileName); } VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index d873320064..861001ed35 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -15,4 +15,9 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} ${ROOT_DIR}) include(${MACRO_DIR}/LinkHifiLibrary.cmake) -link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) + +# link ZLIB +find_package(ZLIB) +include_directories(${ZLIB_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index d4b7ec831e..f17919bce9 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1457,7 +1457,7 @@ bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension return true; } -bool VoxelTree::readFromSchematicsFile(const char *fileName) { +bool VoxelTree::readFromSchematicFile(const char *fileName) { std::stringstream ss; int err = retrieveData(fileName, ss); if (err && ss.get() != TAG_Compound) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index d4fe888535..e46ac4c2cb 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -135,7 +135,7 @@ public: bool readFromSVOFile(const char* filename); // reads voxels from square image with alpha as a Y-axis bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); - bool readFromSchematicsFile(const char* filename); + bool readFromSchematicFile(const char* filename); void computeBlockColor(int id, int data, int& r, int& g, int& b, int& create); unsigned long getVoxelCount();