126 lines
4.6 KiB
C++
126 lines
4.6 KiB
C++
#include <std_include.hpp>
|
|
|
|
#include "assets/assets.hpp"
|
|
#include "iphyscollmap.hpp"
|
|
|
|
#include <utils/io.hpp>
|
|
#include <utils/string.hpp>
|
|
|
|
#include <utils/json.hpp>
|
|
#include <rapidjson/prettywriter.h>
|
|
|
|
#define IW4X_PHYS_COLLMAP_VERSION 1
|
|
|
|
namespace iw4of::interfaces
|
|
{
|
|
bool iphyscollmap::write_internal(const native::XAssetHeader& header) const
|
|
{
|
|
rapidjson::Document output(rapidjson::kObjectType);
|
|
auto& allocator = output.GetAllocator();
|
|
|
|
auto asset = header.physCollmap;
|
|
assert(asset);
|
|
|
|
output.AddMember("version", IW4X_PHYS_COLLMAP_VERSION, allocator);
|
|
output.AddMember("name", RAPIDJSON_STR(asset->name), allocator);
|
|
|
|
rapidjson::Value geoms(rapidjson::kArrayType);
|
|
for (size_t i = 0; i < asset->count; i++)
|
|
{
|
|
rapidjson::Value geom_info(rapidjson::kObjectType);
|
|
const auto geom = &asset->geoms[i];
|
|
|
|
{
|
|
rapidjson::Value json_brush_wrapper(rapidjson::kObjectType);
|
|
const auto brush_wrapper = geom->brushWrapper;
|
|
|
|
json_brush_wrapper.AddMember("bounds", utils::json::to_json(brush_wrapper->bounds, allocator), allocator);
|
|
json_brush_wrapper.AddMember("planes", utils::json::to_json(brush_wrapper->planes, brush_wrapper->brush.numsides, allocator), allocator);
|
|
|
|
geom_info.AddMember("brushwrapper", json_brush_wrapper, allocator);
|
|
}
|
|
|
|
rapidjson::Value orientation(rapidjson::kArrayType);
|
|
for (size_t j = 0; j < 3; j++)
|
|
{
|
|
orientation.PushBack(utils::json::make_json_array(geom->orientation[j], 3, allocator), allocator);
|
|
}
|
|
|
|
geom_info.AddMember("type", static_cast<int>(geom->type), allocator);
|
|
geom_info.AddMember("orientation", orientation, allocator);
|
|
geom_info.AddMember("bounds", utils::json::to_json(geom->bounds, allocator), allocator);
|
|
}
|
|
|
|
rapidjson::StringBuffer buff;
|
|
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buff);
|
|
output.Accept(writer);
|
|
|
|
const auto& dump = buff.GetString();
|
|
|
|
return utils::io::write_file(get_work_path(header).string(), dump);
|
|
}
|
|
|
|
void* iphyscollmap::read_internal(const std::string& name) const
|
|
{
|
|
const auto& path = get_work_path(name).string();
|
|
|
|
if (utils::io::file_exists(path))
|
|
{
|
|
auto asset = local_allocator.allocate<native::PhysPreset>();
|
|
rapidjson::Document physPresetJson;
|
|
|
|
try
|
|
{
|
|
const auto& content = utils::io::read_file(path);
|
|
physPresetJson.Parse(content.data());
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
print_error("Invalid JSON for physpreset {}! {}", name, e.what());
|
|
return nullptr;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Must NOT be null!
|
|
assert(!physPresetJson["sndAliasPrefix"].IsNull());
|
|
|
|
asset->name = local_allocator.duplicate_string(physPresetJson["name"].GetString());
|
|
asset->type = physPresetJson["type"].Get<int32_t>();
|
|
asset->bounce = physPresetJson["bounce"].Get<float>();
|
|
asset->mass = physPresetJson["mass"].Get<float>();
|
|
asset->friction = physPresetJson["friction"].Get<float>();
|
|
asset->bulletForceScale = physPresetJson["bulletForceScale"].Get<float>();
|
|
asset->explosiveForceScale = physPresetJson["explosiveForceScale"].Get<float>();
|
|
asset->sndAliasPrefix = local_allocator.duplicate_string(physPresetJson["sndAliasPrefix"].GetString());
|
|
asset->piecesSpreadFraction = physPresetJson["piecesSpreadFraction"].Get<float>();
|
|
asset->piecesUpwardVelocity = physPresetJson["piecesUpwardVelocity"].Get<float>();
|
|
asset->tempDefaultToCylinder = physPresetJson["tempDefaultToCylinder"].Get<bool>();
|
|
asset->perSurfaceSndAlias = physPresetJson["perSurfaceSndAlias"].Get<bool>();
|
|
|
|
assert(asset->mass > FLT_EPSILON);
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
print_error("Malformed JSON for physpreset {}! {}", name, e.what());
|
|
return nullptr;
|
|
}
|
|
|
|
return asset;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
std::filesystem::path iphyscollmap::get_file_name(const std::string& basename) const
|
|
{
|
|
return std::format("{}.iw4x.json", basename);
|
|
}
|
|
|
|
std::filesystem::path iphyscollmap::get_folder_name() const
|
|
{
|
|
return "physcollmap";
|
|
}
|
|
|
|
} // namespace iw4of::interfaces
|