main
Brett 2025-07-11 01:35:47 -04:00
parent 260d40772e
commit a52157239f
4 changed files with 99 additions and 22 deletions

View File

@ -88,17 +88,21 @@ struct model_data_t
struct namespace_data_t struct namespace_data_t
{ {
blt::hashmap_t<std::string, model_data_t> models; blt::hashmap_t<std::string, model_data_t> models;
std::string asset_namespace_folder;
std::string data_namespace_folder;
std::string model_folder;
std::string tag_folder;
std::string texture_folder;
blt::hashmap_t<std::string, std::string> textures;
}; };
struct asset_data_t struct asset_data_t
{ {
blt::hashmap_t<std::string, namespace_data_t> json_data; blt::hashmap_t<std::string, namespace_data_t> json_data;
blt::hashmap_t<std::string, std::string> solid_textures_to_load; blt::hashmap_t<std::string, blt::hashset_t<std::string>> solid_textures_to_load;
blt::hashmap_t<std::string, std::string> non_solid_textures_to_load; blt::hashmap_t<std::string, blt::hashset_t<std::string>> non_solid_textures_to_load;
blt::hashmap_t<std::string, std::string> namespace_asset_folders;
blt::hashmap_t<std::string, std::string> namespace_data_folders;
blt::hashmap_t<std::string, std::string> namespace_texture_folders;
[[nodiscard]] std::vector<namespaced_object> resolve_parents(const namespaced_object& model) const; [[nodiscard]] std::vector<namespaced_object> resolve_parents(const namespaced_object& model) const;
}; };
@ -110,9 +114,11 @@ public:
std::optional<load_failure_t> load_assets(const std::string& asset_folder, const std::optional<std::string>& data_folder = {}); std::optional<load_failure_t> load_assets(const std::string& asset_folder, const std::optional<std::string>& data_folder = {});
asset_data_t& load_textures(); database_t& load_textures();
private: private:
void process_texture(const statement_t& stmt, const std::string& namespace_str, const std::string& texture);
asset_data_t data; asset_data_t data;
database_t db; database_t db;
std::string name; std::string name;

View File

@ -145,7 +145,7 @@ public:
return sqlite3_bind_text(statement, col, type, -1, nullptr); return sqlite3_bind_text(statement, col, type, -1, nullptr);
} else } else
{ {
return sqlite3_bind_blob64(statement, col, type.data(), type.data(), nullptr); return sqlite3_bind_blob64(statement, col, type.data(), type.size(), nullptr);
} }
} }

View File

@ -24,6 +24,7 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <blt/logging/logging.h> #include <blt/logging/logging.h>
#include <blt/std/hashmap.h> #include <blt/std/hashmap.h>
#include <blt/std/ranges.h>
#include <blt/std/string.h> #include <blt/std/string.h>
using json = nlohmann::json; using json = nlohmann::json;
@ -92,10 +93,14 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
return load_failure_t::TAGS_FOLDER_NOT_FOUND; return load_failure_t::TAGS_FOLDER_NOT_FOUND;
if (data_folder) if (data_folder)
data.namespace_data_folders[namespace_name] = data_folder->parent_path().string(); {
data.json_data[namespace_name.string()].tag_folder = tags_folder->string();
data.json_data[namespace_name.string()].data_namespace_folder = tags_folder->parent_path().string();
}
data.namespace_asset_folders[namespace_name] = model_folder->parent_path().string(); data.json_data[namespace_name.string()].asset_namespace_folder = model_folder->parent_path().string();
data.namespace_texture_folders[namespace_name] = texture_folder->string(); data.json_data[namespace_name.string()].model_folder = model_folder->string();
data.json_data[namespace_name.string()].texture_folder = texture_folder->string();
BLT_INFO("Loading assets '{}' for namespace '{}'", name, namespace_name.string()); BLT_INFO("Loading assets '{}' for namespace '{}'", name, namespace_name.string());
if (texture_folder->parent_path().filename() != namespace_name) if (texture_folder->parent_path().filename() != namespace_name)
@ -163,6 +168,35 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
model_data_t{parent, textures.empty() ? std::optional<std::vector<namespaced_object>>{} : std::optional{std::move(textures)}} model_data_t{parent, textures.empty() ? std::optional<std::vector<namespaced_object>>{} : std::optional{std::move(textures)}}
}); });
} }
BLT_INFO("Found {} models in namespace {}", data.json_data[namespace_name.string()].models.size(), namespace_name.string());
for (const auto& entry : std::filesystem::recursive_directory_iterator(*texture_folder / "block"))
{
if (!entry.path().has_extension())
continue;
if (!entry.is_regular_file())
continue;
if (entry.path().extension().compare(".png") != 0 &&
entry.path().extension().compare(".jpg") != 0 &&
entry.path().extension().compare(".jpeg") != 0 &&
entry.path().extension().compare(".bmp") != 0)
continue;
std::filesystem::path relative_path;
{
auto p_begin = entry.path().begin();
auto p_end = entry.path().end();
auto m_begin = texture_folder->begin();
while (p_begin != p_end && m_begin != texture_folder->end() && *p_begin == *m_begin)
{
++p_begin;
++m_begin;
}
for (; p_begin != p_end; ++p_begin)
relative_path /= p_begin->stem();
}
data.json_data[namespace_name.string()].textures[relative_path.string()] = entry.path().string();
}
BLT_INFO("Found {} textures in namespace {}", data.json_data[namespace_name.string()].textures.size(), namespace_name.string());
auto& map = data.json_data[namespace_name.string()]; auto& map = data.json_data[namespace_name.string()];
@ -179,7 +213,7 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
if (model.textures) if (model.textures)
{ {
for (auto& texture : *model.textures) for (auto& texture : *model.textures)
data.solid_textures_to_load[texture.namespace_str] = texture.key_str; data.solid_textures_to_load[texture.namespace_str].insert(texture.key_str);
} }
solid = true; solid = true;
break; break;
@ -190,7 +224,7 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
if (model.textures) if (model.textures)
{ {
for (auto& texture : *model.textures) for (auto& texture : *model.textures)
data.non_solid_textures_to_load[texture.namespace_str] = texture.key_str; data.non_solid_textures_to_load[texture.namespace_str].insert(texture.key_str);
} }
} }
} }
@ -198,24 +232,59 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
return {}; return {};
} }
asset_data_t& asset_loader_t::load_textures() database_t& asset_loader_t::load_textures()
{ {
auto texture_table = db.builder().create_table("solid_textures"); auto texture_table = db.builder().create_table("solid_textures");
texture_table.with_column<std::string>("namespace").primary_key(); texture_table.with_column<std::string>("namespace").primary_key();
texture_table.with_column<std::string>("name").primary_key(); texture_table.with_column<std::string>("name").primary_key();
texture_table.with_column<blt::u32>("width").not_null(); texture_table.with_column<blt::i32>("width").not_null();
texture_table.with_column<blt::u32>("height").not_null(); texture_table.with_column<blt::i32>("height").not_null();
texture_table.with_column<std::byte*>("data").not_null(); texture_table.with_column<std::byte*>("data").not_null();
texture_table.build().execute(); texture_table.build().execute();
for (const auto& [namespace_str, texture] : data.solid_textures_to_load) auto non_texture_table = db.builder().create_table("non_solid_textures");
{ non_texture_table.with_column<std::string>("namespace").primary_key();
auto texture_path = std::filesystem::path(data.namespace_texture_folders.at(namespace_str)); non_texture_table.with_column<std::string>("name").primary_key();
texture_path /= texture; non_texture_table.with_column<blt::i32>("width").not_null();
non_texture_table.with_column<blt::i32>("height").not_null();
non_texture_table.with_column<std::byte*>("data").not_null();
non_texture_table.build().execute();
const static auto insert_solid_sql = "INSERT INTO solid_textures VALUES (?, ?, ?, ?, ?)";
const static auto insert_non_solid_sql = "INSERT INTO non_solid_textures VALUES (?, ?, ?, ?, ?)";
const auto insert_solid_stmt = db.prepare(insert_solid_sql);
const auto insert_non_solid_stmt = db.prepare(insert_non_solid_sql);
for (const auto& [namespace_str, textures] : data.solid_textures_to_load)
{
for (const auto& texture : textures)
process_texture(insert_solid_stmt, namespace_str, texture);
} }
return data; for (const auto& [namespace_str, textures] : data.non_solid_textures_to_load)
{
for (const auto& texture : textures)
process_texture(insert_non_solid_stmt, namespace_str, texture);
}
return db;
}
void asset_loader_t::process_texture(const statement_t& stmt, const std::string& namespace_str, const std::string& texture)
{
const auto texture_path = data.json_data[namespace_str].textures[texture];
if (!std::filesystem::exists(texture_path))
return;
int width, height, channels;
const auto data = stbi_load(texture_path.c_str(), &width, &height, &channels, 4);
if (data == nullptr)
return;
stmt.bind().bind_all(namespace_str, texture, width, height, blt::span{data, static_cast<blt::size_t>(width * height * 4)});
if (!stmt.execute())
{
BLT_WARN("Failed to insert texture '{}:{}' into database. Error: '{}'", namespace_str, texture, db.get_error());
}
stbi_image_free(data);
} }
std::vector<namespaced_object> asset_data_t::resolve_parents(const namespaced_object& model) const std::vector<namespaced_object> asset_data_t::resolve_parents(const namespaced_object& model) const

View File

@ -15,6 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <asset_loader.h> #include <asset_loader.h>
#include <filesystem>
#include <blt/gfx/window.h> #include <blt/gfx/window.h>
#include "blt/gfx/renderer/resource_manager.h" #include "blt/gfx/renderer/resource_manager.h"
#include "blt/gfx/renderer/batch_2d_renderer.h" #include "blt/gfx/renderer/batch_2d_renderer.h"
@ -58,6 +59,7 @@ void destroy(const blt::gfx::window_data&)
int main() int main()
{ {
std::filesystem::remove("1.21.5.assets");
// blt::gfx::init(blt::gfx::window_data{"Minecraft Color Picker", init, update, destroy}.setSyncInterval(1)); // blt::gfx::init(blt::gfx::window_data{"Minecraft Color Picker", init, update, destroy}.setSyncInterval(1));
asset_loader_t loader{"1.21.5"}; asset_loader_t loader{"1.21.5"};
@ -68,7 +70,7 @@ int main()
return 1; return 1;
} }
auto asset_data = loader.load_textures(); auto& asset_data = loader.load_textures();
return 0; return 0;
} }