This commit is contained in:
parent
c466d90eec
commit
f442caa888
6 changed files with 224 additions and 11 deletions
|
|
@ -29,9 +29,15 @@ namespace fs = std::filesystem;
|
|||
namespace Crafter {
|
||||
std::string CompressAsset(const fs::path& input, const fs::path& output) {
|
||||
std::string ext = input.extension().string();
|
||||
// Case-insensitive extension match — Sponza's textures dir mixes
|
||||
// case (.tga and .TGA both appear in the wild).
|
||||
for (char& c : ext) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
#ifdef CRAFTER_BUILD_HAS_ASSET
|
||||
try {
|
||||
if (ext == ".png") {
|
||||
// stb_image (the loader behind LoadPNG) handles all of these,
|
||||
// so a single branch covers every raster format we ship. The
|
||||
// function is misnamed for historical reasons.
|
||||
if (ext == ".png" || ext == ".tga" || ext == ".jpg" || ext == ".jpeg" || ext == ".bmp") {
|
||||
auto tex = TextureAsset<Vector<std::uint8_t, 4, 4>>::LoadPNG<std::uint8_t>(input);
|
||||
tex.SaveCompressed(output);
|
||||
} else if (ext == ".obj") {
|
||||
|
|
@ -50,6 +56,65 @@ namespace Crafter {
|
|||
"rebuild via `./bin/crafter-build` so the self-host pass picks up the "
|
||||
"Crafter.Asset dep declared in project.cpp",
|
||||
input.string());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string BuildOBJBundle(
|
||||
const fs::path& objPath,
|
||||
const fs::path& mtlPath,
|
||||
const fs::path& outDir,
|
||||
std::uint16_t albedoSize)
|
||||
{
|
||||
#ifdef CRAFTER_BUILD_HAS_ASSET
|
||||
const fs::path manifest = outDir / "scene.txt";
|
||||
if (fs::exists(manifest)) return {};
|
||||
try {
|
||||
fs::create_directories(outDir);
|
||||
auto materials = LoadMTL(mtlPath);
|
||||
auto meshes = MeshAsset<VertexNormalTangentUVPacked>::LoadOBJSplit(objPath);
|
||||
|
||||
std::vector<std::string> uniqueAlbedos;
|
||||
std::unordered_map<std::string, std::uint32_t> albedoIndex;
|
||||
for (auto& [matName, _] : meshes) {
|
||||
auto matIt = materials.find(matName);
|
||||
if (matIt == materials.end() || matIt->second.mapKd.empty()) continue;
|
||||
const std::string& kd = matIt->second.mapKd;
|
||||
if (!albedoIndex.contains(kd)) {
|
||||
albedoIndex.emplace(kd, static_cast<std::uint32_t>(uniqueAlbedos.size()));
|
||||
uniqueAlbedos.push_back(kd);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::int32_t> meshAlbedoIdx;
|
||||
std::uint32_t emitted = 0;
|
||||
for (auto& [matName, mesh] : meshes) {
|
||||
if (mesh.vertexes.empty() || mesh.indexes.empty()) continue;
|
||||
mesh.SaveCompressed(outDir / std::format("mesh_{}.cmesh", emitted));
|
||||
std::int32_t a = -1;
|
||||
if (auto it = materials.find(matName);
|
||||
it != materials.end() && !it->second.mapKd.empty())
|
||||
a = static_cast<std::int32_t>(albedoIndex.at(it->second.mapKd));
|
||||
meshAlbedoIdx.push_back(a);
|
||||
++emitted;
|
||||
}
|
||||
|
||||
for (std::uint32_t i = 0; i < uniqueAlbedos.size(); ++i) {
|
||||
const fs::path texPath = mtlPath.parent_path() / uniqueAlbedos[i];
|
||||
auto tex = TextureAsset<Vector<std::uint8_t, 4, 4>>::LoadPNG<std::uint8_t>(texPath);
|
||||
tex.Resize(albedoSize, albedoSize);
|
||||
tex.SaveCompressed(outDir / std::format("tex_{}.ctex", i));
|
||||
}
|
||||
|
||||
std::ofstream m(manifest);
|
||||
m << uniqueAlbedos.size() << "\n" << emitted << "\n";
|
||||
for (std::int32_t a : meshAlbedoIdx) m << a << "\n";
|
||||
} catch (const std::exception& e) {
|
||||
return std::format("BuildOBJBundle: {}", e.what());
|
||||
}
|
||||
return {};
|
||||
#else
|
||||
return "BuildOBJBundle: crafter-build was bootstrapped without Crafter.Asset linkage; "
|
||||
"rebuild via crafter-build itself to pick up the Crafter.Asset dep";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue