jak-project/goalc/build_level/common/build_level.cpp
Hat Kid 62ef9fe49d
[wip] build actor tool (#3266)
This does a couple of things:

- The `custom_levels` folder was renamed to `custom_assets` and contains
`levels`, `models` and `texture_replacements` folders for Jak 1, 2 and 3
in order to keep everything regarding custom stuff in one place.
- With this, texture replacements now use separate folders for all games
- A build actor tool was added that generates art groups for custom
actors
- Custom levels can now specify what custom models from the `models`
folder they want to import, this will add them to the level's FR3.
- A `test-zone-obs.gc` file was added, containing a `test-actor` process
that uses a custom model as an example.

The build actor tool is still very WIP, the joints and the default
animation are hardcoded, but it allows for importing any GLB file as a
merc model.
2024-05-18 18:18:25 +02:00

63 lines
2.8 KiB
C++

#include "build_level.h"
void save_pc_data(const std::string& nickname,
tfrag3::Level& data,
const fs::path& fr3_output_dir) {
Serializer ser;
data.serialize(ser);
auto compressed =
compression::compress_zstd(ser.get_save_result().first, ser.get_save_result().second);
lg::print("stats for {}\n", data.level_name);
print_memory_usage(data, ser.get_save_result().second);
lg::print("compressed: {} -> {} ({:.2f}%)\n", ser.get_save_result().second, compressed.size(),
100.f * compressed.size() / ser.get_save_result().second);
file_util::write_binary_file(fr3_output_dir / fmt::format("{}.fr3", nickname), compressed.data(),
compressed.size());
}
std::vector<std::string> get_build_level_deps(const std::string& input_file) {
auto level_json = parse_commented_json(
file_util::read_text_file(file_util::get_file_path({input_file})), input_file);
return {level_json.at("gltf_file").get<std::string>()};
}
// Find all art groups the custom level needs in a list of object files,
// skipping any that we already found in other dgos before
std::vector<decompiler::ObjectFileRecord> find_art_groups(
std::vector<std::string>& processed_ags,
const std::vector<std::string>& custom_level_ag,
const std::vector<decompiler::ObjectFileRecord>& dgo_files) {
std::vector<decompiler::ObjectFileRecord> art_groups;
for (const auto& file : dgo_files) {
// skip any art groups we already added from other dgos
if (std::find(processed_ags.begin(), processed_ags.end(), file.name) != processed_ags.end()) {
continue;
}
if (std::find(custom_level_ag.begin(), custom_level_ag.end(), file.name) !=
custom_level_ag.end()) {
art_groups.push_back(file);
processed_ags.push_back(file.name);
}
}
return art_groups;
}
void add_model_to_level(GameVersion version, const std::string& name, tfrag3::Level& lvl) {
lg::info("custom level: adding custom model {}", name);
auto glb = name + ".glb";
auto merc_data = load_merc_model(lvl.merc_data.indices.size(), lvl.merc_data.vertices.size(),
lvl.textures.size(),
fs::path(file_util::get_jak_project_dir() / "custom_assets" /
game_version_names[version] / "models" / glb)
.string(),
name + "-lod0");
for (auto& idx : merc_data.new_indices) {
lvl.merc_data.indices.push_back(idx);
}
for (auto& vert : merc_data.new_vertices) {
lvl.merc_data.vertices.push_back(vert);
}
lvl.merc_data.models.push_back(merc_data.new_model);
lvl.textures.insert(lvl.textures.end(), merc_data.new_textures.begin(),
merc_data.new_textures.end());
}