You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
8.7 KiB
247 lines
8.7 KiB
2 months ago
|
// License: Apache 2.0. See LICENSE file in root directory.
|
||
|
// Copyright(c) 2021 Intel Corporation. All Rights Reserved.
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <string>
|
||
|
#include <string.h> // memcpy
|
||
|
#include <fstream>
|
||
|
#include <vector>
|
||
|
|
||
|
#include <tclap/CmdLine.h>
|
||
|
#include <lz4.h>
|
||
|
|
||
|
#define STB_IMAGE_IMPLEMENTATION
|
||
|
#include <stb_image.h>
|
||
|
|
||
|
|
||
|
#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<string> inputFilename("i", "input", "Input filename", true, "", "input-file");
|
||
|
ValueArg<string> outputFilename("o", "output", "Output filename", false, "", "output-file");
|
||
|
ValueArg<string> 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<float3> vertex_data;
|
||
|
std::vector<float3> normals_raw_data;
|
||
|
std::vector<float3> normals_data;
|
||
|
std::vector<int6> index_raw_data;
|
||
|
std::vector<short3> 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<uint16_t>(idx.x - 1),
|
||
|
static_cast<uint16_t>(idx.y - 1),
|
||
|
static_cast<uint16_t>(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<uint8_t> 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 <lz4.h>\n";
|
||
|
myfile << "#include <vector>\n";
|
||
|
|
||
|
myfile << "inline void uncompress_" << name << "_obj(std::vector<float3>& vertex_data, std::vector<float3>& normals, std::vector<short3>& index_data)\n";
|
||
|
myfile << "{\n";
|
||
|
myfile << " std::vector<char> 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<char> 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;
|
||
|
}
|