asset changes
Some checks failed
CI / build-test-release (push) Failing after 15m11s

This commit is contained in:
Jorijn van der Graaf 2026-05-19 00:50:06 +02:00
commit f442caa888
6 changed files with 224 additions and 11 deletions

View file

@ -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
}
}