// License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2021 Intel Corporation. All Rights Reserved. #include #include #include // memcpy #include #include #include #include #define STB_IMAGE_IMPLEMENTATION #include #define RS_EMBED_VERSION "0.0.0.2" struct float3 { float x, y, z; }; struct short3 { uint16_t x, y, z; }; using namespace std; using namespace TCLAP; bool file_exists(const std::string& name) { std::ifstream f(name.c_str()); return f.good(); } struct int6 { int x, y, z, a, b, c; }; bool ends_with(const std::string& s, const std::string& suffix) { auto i = s.rbegin(), j = suffix.rbegin(); for (; i != s.rend() && j != suffix.rend() && *i == *j; i++, j++); return j == suffix.rend(); } std::string get_current_time() { auto t = time(nullptr); char buffer[20] = {}; const tm* time = localtime(&t); if (nullptr != time) strftime(buffer, sizeof(buffer), "%m/%d/%Y %H:%M:%S", time); return std::string(buffer); } std::string get_current_year() { auto t = time(nullptr); char buffer[20] = {}; const tm* time = localtime(&t); if (nullptr != time) strftime(buffer, sizeof(buffer), "%Y", time); return std::string(buffer); } int main(int argc, char** argv) try { // Parse command line arguments CmdLine cmd("librealsense rs-embed tool", ' ', RS_EMBED_VERSION); ValueArg inputFilename("i", "input", "Input filename", true, "", "input-file"); ValueArg outputFilename("o", "output", "Output filename", false, "", "output-file"); ValueArg objectName("n", "name", "Name", false, "", "object-name"); cmd.add(inputFilename); cmd.add(outputFilename); cmd.add(objectName); cmd.parse(argc, argv); auto input = inputFilename.getValue(); auto output = outputFilename.getValue(); auto name = objectName.getValue(); if (ends_with(input, ".obj")) { std::vector vertex_data; std::vector normals_raw_data; std::vector normals_data; std::vector index_raw_data; std::vector index_data; if (file_exists(input)) { std::ifstream file(input); std::string str; while (std::getline(file, str)) { if (str.size()) { if (str[0] == 'v') { float a, b, c; if (str[1] == 'n') { sscanf(str.c_str(), "vn %f %f %f", &a, &b, &c); normals_raw_data.push_back({ a, b, c }); } else { sscanf(str.c_str(), "v %f %f %f", &a, &b, &c); vertex_data.push_back({ a, b, c }); } } if (str[0] == 'f') { int x, y, z, a, b, c; sscanf(str.c_str(), "f %d//%d %d//%d %d//%d", &x, &a, &y, &b, &z, &c); index_raw_data.push_back({ x, y, z, a, b, c }); } } } } else { std::cout << "file: " << input << " could not be found!" << std::endl; return EXIT_FAILURE; } normals_data.resize(vertex_data.size()); for (auto& idx : index_raw_data) { // TODO - normals data are currently disabled // normals_data[idx.x] = normals_raw_data[idx.a]; // normals_data[idx.y] = normals_raw_data[idx.b]; // normals_data[idx.z] = normals_raw_data[idx.c]; index_data.push_back({ static_cast(idx.x - 1), static_cast(idx.y - 1), static_cast(idx.z - 1) }); } size_t vertex_data_size = vertex_data.size() * sizeof(float3); size_t index_data_size = index_data.size() * sizeof(short3); //size_t normals_data_size = normals_data.size() * sizeof(float3); std::vector data(vertex_data_size + index_data_size, 0); memcpy(data.data(), vertex_data.data(), vertex_data_size); memcpy(data.data() + vertex_data_size, index_data.data(), index_data_size); //memcpy(data.data() + vertex_data_size + index_data_size, normals_data.data(), normals_data_size); // compress szSource into pchCompressed auto rawDataSize = (int)data.size(); auto compressBufSize = LZ4_compressBound(rawDataSize); auto four_byte_mul_size = compressBufSize + ( 4 - compressBufSize % 4 ); char * pchCompressed = new char[four_byte_mul_size]; memset( pchCompressed, 0, four_byte_mul_size ); int nCompressedSize = LZ4_compress_default((const char*)data.data(), pchCompressed, rawDataSize, compressBufSize); ofstream myfile; myfile.open(output); myfile << "// License: Apache 2.0. See LICENSE file in root directory.\n"; myfile << "// Copyright(c) " << get_current_year() << " Intel Corporation. All Rights Reserved.\n\n"; myfile << "// This file is auto-generated from " << name << ".obj using rs-embed tool version: " << RS_EMBED_VERSION <<"\n"; myfile << "// Generation time: " << get_current_time() << ".\n\n"; myfile << "#pragma once\n"; myfile << "static uint32_t " << name << "_obj_data [] { "; auto nAllignedCompressedSize = nCompressedSize; auto leftover = nCompressedSize % 4; nAllignedCompressedSize += (4 - leftover); for (int i = 0; i < nAllignedCompressedSize; i += 4) { uint32_t* ptr = (uint32_t*)(pchCompressed + i); myfile << "0x" << std::hex << (int)(*ptr); if (i < nAllignedCompressedSize - 1) myfile << ","; } myfile << "};\n"; myfile << "#include \n"; myfile << "#include \n"; myfile << "inline void uncompress_" << name << "_obj(std::vector& vertex_data, std::vector& normals, std::vector& index_data)\n"; myfile << "{\n"; myfile << " std::vector uncompressed(0x" << std::hex << rawDataSize << ", 0);\n"; myfile << " (void)LZ4_decompress_safe((const char*)" << name << "_obj_data, uncompressed.data(), 0x" << std::hex << nCompressedSize << ", 0x" << std::hex << rawDataSize << ");\n"; myfile << " const int vertex_size = 0x" << std::hex << vertex_data.size() << " * sizeof(float3);\n"; myfile << " const int index_size = 0x" << std::hex << index_data.size() << " * sizeof(short3);\n"; myfile << " vertex_data.resize(0x" << std::hex << vertex_data.size() << ");\n"; myfile << " memcpy(vertex_data.data(), uncompressed.data(), vertex_size);\n"; myfile << " index_data.resize(0x" << std::hex << index_data.size() << ");\n"; myfile << " memcpy(index_data.data(), uncompressed.data() + vertex_size, index_size);\n"; myfile << " //normals.resize(0x" << std::hex << vertex_data.size() << ");\n"; myfile << " //memcpy(normals.data(), uncompressed.data() + vertex_size + index_size, vertex_size);\n"; myfile << "}\n"; myfile.close(); } if (ends_with(input, ".png")) { ifstream ifs(input, ios::binary | ios::ate); ifstream::pos_type pos = ifs.tellg(); std::vector buffer(pos); ifs.seekg(0, ios::beg); ifs.read(&buffer[0], pos); ofstream myfile; myfile.open(output); myfile << "// License: Apache 2.0. See LICENSE file in root directory.\n"; myfile << "// Copyright(c) " << get_current_year() << " Intel Corporation. All Rights Reserved.\n\n"; myfile << "// This file is auto-generated from " << name << ".png using rs-embed tool version: " << RS_EMBED_VERSION << "\n"; myfile << "// Generation time: " << get_current_time() << ".\n\n"; myfile << "static uint32_t " << name << "_png_size = 0x" << std::hex << buffer.size() << ";\n"; myfile << "static uint8_t " << name << "_png_data [] { "; for (int i = 0; i < buffer.size(); i++) { uint8_t byte = buffer[i]; myfile << "0x" << std::hex << (int)byte; if (i < buffer.size() - 1) myfile << ","; } myfile << "};\n"; myfile.close(); } return EXIT_SUCCESS; } catch (const exception& e) { cerr << e.what() << endl; return EXIT_FAILURE; } catch (...) { cerr << "some error" << endl; return EXIT_FAILURE; }