/// encodes the voxel details portion of a voxel edit message bool encodeVoxelEditMessageDetails(PacketType, int voxelCount, VoxelDetail* voxelDetails, unsigned char* bufferOut, int sizeIn, int& sizeOut) { bool success = true; // assume the best unsigned char* copyAt = bufferOut; sizeOut = 0; for (int i = 0; i < voxelCount && success; i++) { // get the coded voxel unsigned char* voxelData = pointToVoxel(voxelDetails[i].x,voxelDetails[i].y,voxelDetails[i].z, voxelDetails[i].s,voxelDetails[i].red,voxelDetails[i].green,voxelDetails[i].blue); int lengthOfVoxelData = bytesRequiredForCodeLength(*voxelData)+SIZE_OF_COLOR_DATA; // make sure we have room to copy this voxel if (sizeOut + lengthOfVoxelData > sizeIn) { success = false; } else { // add it to our message memcpy(copyAt, voxelData, lengthOfVoxelData); copyAt += lengthOfVoxelData; sizeOut += lengthOfVoxelData; } // cleanup delete[] voxelData; } return success; }
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); //int length = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(voxelData)) + BYTES_PER_COLOR; //printf("createVoxel()..."); //outputBufferBits(voxelData,length); this->readCodeColorBufferToTree(voxelData, destructive); delete[] voxelData; }
/// creates an "insert" or "remove" voxel message for a voxel code corresponding to the closest voxel which encloses a cube /// with lower corners at x,y,z, having side of length S. The input values x,y,z range 0.0 <= v < 1.0 message should be either /// PacketTypeVoxelSet, PacketTypeVoxelSetDestructive, or PacketTypeVoxelErase. The buffer is returned to caller becomes /// responsibility of caller and MUST be deleted by caller. bool createVoxelEditMessage(PacketType command, short int sequence, int voxelCount, const VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut) { bool success = true; // assume the best int messageSize = MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE; // just a guess for now unsigned char* messageBuffer = new unsigned char[messageSize]; int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(messageBuffer), command); unsigned short int* sequenceAt = (unsigned short int*) &messageBuffer[numBytesPacketHeader]; *sequenceAt = sequence; // pack in timestamp quint64 now = usecTimestampNow(); quint64* timeAt = (quint64*)&messageBuffer[numBytesPacketHeader + sizeof(sequence)]; *timeAt = now; unsigned char* copyAt = &messageBuffer[numBytesPacketHeader + sizeof(sequence) + sizeof(now)]; int actualMessageSize = numBytesPacketHeader + sizeof(sequence) + sizeof(now); for (int i = 0; i < voxelCount && success; i++) { // get the coded voxel unsigned char* voxelData = pointToVoxel(voxelDetails[i].x,voxelDetails[i].y,voxelDetails[i].z, voxelDetails[i].s,voxelDetails[i].red,voxelDetails[i].green,voxelDetails[i].blue); int lengthOfVoxelData = bytesRequiredForCodeLength(*voxelData)+SIZE_OF_COLOR_DATA; // make sure we have room to copy this voxel if (actualMessageSize + lengthOfVoxelData > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) { success = false; } else { // add it to our message memcpy(copyAt, voxelData, lengthOfVoxelData); copyAt += lengthOfVoxelData; actualMessageSize += lengthOfVoxelData; } // cleanup delete[] voxelData; } if (success) { // finally, copy the result to the output bufferOut = new unsigned char[actualMessageSize]; sizeOut = actualMessageSize; memcpy(bufferOut, messageBuffer, actualMessageSize); } delete[] messageBuffer; // clean up our temporary buffer return success; }
int main(int argc, const char * argv[]) { VoxelTree myTree; qInstallMessageHandler(sharedMessageHandler); unitTest(&myTree); const char* GET_OCTCODE = "--getOctCode"; const char* octcodeParams = getCmdOption(argc, argv, GET_OCTCODE); if (octcodeParams) { QString octcodeParamsString(octcodeParams); QStringList octcodeParamsList = octcodeParamsString.split(QString(",")); enum { X_AT, Y_AT, Z_AT, S_AT, EXPECTED_PARAMS }; if (octcodeParamsList.size() == EXPECTED_PARAMS) { QString xStr = octcodeParamsList.at(X_AT); QString yStr = octcodeParamsList.at(Y_AT); QString zStr = octcodeParamsList.at(Z_AT); QString sStr = octcodeParamsList.at(S_AT); float x = xStr.toFloat()/TREE_SCALE; // 0.14745788574219; float y = yStr.toFloat()/TREE_SCALE; // 0.01502178955078; float z = zStr.toFloat()/TREE_SCALE; // 0.56540045166016; float s = sStr.toFloat()/TREE_SCALE; // 0.015625; qDebug() << "Get Octal Code for:\n"; qDebug() << " x:" << xStr << " [" << x << "] \n"; qDebug() << " y:" << yStr << " [" << y << "] \n"; qDebug() << " z:" << zStr << " [" << z << "] \n"; qDebug() << " s:" << sStr << " [" << s << "] \n"; unsigned char* octalCode = pointToVoxel(x, y, z, s); QString octalCodeStr = octalCodeToHexString(octalCode); qDebug() << "octal code: " << octalCodeStr << "\n"; } else { qDebug() << "Unexpected number of parameters for getOctCode\n"; } return 0; } const char* DECODE_OCTCODE = "--decodeOctCode"; const char* decodeParam = getCmdOption(argc, argv, DECODE_OCTCODE); if (decodeParam) { QString decodeParamsString(decodeParam); unsigned char* octalCodeToDecode = hexStringToOctalCode(decodeParamsString); VoxelPositionSize details; voxelDetailsForCode(octalCodeToDecode, details); delete[] octalCodeToDecode; qDebug() << "octal code to decode: " << decodeParamsString << "\n"; qDebug() << "Details for Octal Code:\n"; qDebug() << " x:" << details.x << "[" << details.x * TREE_SCALE << "]" << "\n"; qDebug() << " y:" << details.y << "[" << details.y * TREE_SCALE << "]" << "\n"; qDebug() << " z:" << details.z << "[" << details.z * TREE_SCALE << "]" << "\n"; qDebug() << " s:" << details.s << "[" << details.s * TREE_SCALE << "]" << "\n"; return 0; } // Handles taking and SVO and splitting it into multiple SVOs based on // jurisdiction details const char* SPLIT_SVO = "--splitSVO"; const char* splitSVOFile = getCmdOption(argc, argv, SPLIT_SVO); const char* SPLIT_JURISDICTION_ROOT = "--splitJurisdictionRoot"; const char* SPLIT_JURISDICTION_ENDNODES = "--splitJurisdictionEndNodes"; const char* splitJurisdictionRoot = getCmdOption(argc, argv, SPLIT_JURISDICTION_ROOT); const char* splitJurisdictionEndNodes = getCmdOption(argc, argv, SPLIT_JURISDICTION_ENDNODES); if (splitSVOFile && splitJurisdictionRoot && splitJurisdictionEndNodes) { processSplitSVOFile(splitSVOFile, splitJurisdictionRoot, splitJurisdictionEndNodes); return 0; } // Handles taking an SVO and filling in the empty space below the voxels to make it solid. const char* FILL_SVO = "--fillSVO"; const char* fillSVOFile = getCmdOption(argc, argv, FILL_SVO); if (fillSVOFile) { processFillSVOFile(fillSVOFile); return 0; } const char* DONT_CREATE_FILE = "--dontCreateSceneFile"; bool dontCreateFile = cmdOptionExists(argc, argv, DONT_CREATE_FILE); if (dontCreateFile) { printf("You asked us not to create a scene file, so we will not.\n"); } else { printf("Creating Scene File...\n"); const char* RUN_TUTORIAL = "--runTutorial"; if (cmdOptionExists(argc, argv, RUN_TUTORIAL)) { voxelTutorial(&myTree); } const char* ADD_CORNERS_AND_AXIS_LINES = "--addCornersAndAxisLines"; if (cmdOptionExists(argc, argv, ADD_CORNERS_AND_AXIS_LINES)) { addCornersAndAxisLines(&myTree); } const char* ADD_SPHERE_SCENE = "--addSphereScene"; if (cmdOptionExists(argc, argv, ADD_SPHERE_SCENE)) { addSphereScene(&myTree); } const char* ADD_SURFACE_SCENE = "--addSurfaceScene"; if (cmdOptionExists(argc, argv, ADD_SURFACE_SCENE)) { addSurfaceScene(&myTree); } unsigned long nodeCount = myTree.getOctreeElementsCount(); printf("Nodes after adding scenes: %ld nodes\n", nodeCount); myTree.writeToSVOFile("voxels.svo"); } return 0; }