#include "TriangleFactory.h" #include "spdlog/spdlog.h" #include "Companion.h" #include "utils/Decompressor.h" #include "utils/TorchUtils.h" #include #define NUM(x, w) std::dec << std::setfill(' ') << std::setw(w) << x #define FORMAT_FLOAT(x, w, p) std::dec << std::setfill(' ') << std::fixed << std::setprecision(p) << std::setw(w) << x #define STRIP_SEGMENT(offset) (IS_SEGMENTED(offset) ? SEGMENT_OFFSET(offset) : (offset)) SF64::TriangleData::TriangleData(std::vector tris, std::vector meshNodes): mTris(tris), mMeshNodes(meshNodes) { } void SF64::TriangleHeaderExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement) { const auto symbol = GetSafeNode(node, "symbol", entryName); if(Companion::Instance->IsOTRMode()){ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; return; } write << "extern Triangle " << symbol << "[];\n"; } void SF64::TriangleCodeExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { const auto symbol = GetSafeNode(node, "symbol", entryName); const auto offset = GetSafeNode(node, "offset"); auto triData = std::static_pointer_cast(raw); const auto meshSize = GetSafeNode(triData->mMeshNodes[0], "count", 0); auto off = offset; auto segment = 0; int i; if(IS_SEGMENTED(off)) { off = SEGMENT_OFFSET(off); } if (Companion::Instance->IsDebug()) { write << "// 0x" << std::uppercase << std::hex << STRIP_SEGMENT(offset) << "\n"; } write << "Triangle " << symbol << "[] = {"; int width = std::log10(meshSize) + 1; i = 0; for(Vec3s tri : triData->mTris) { if((i++ % 6) == 0) { write << "\n" << fourSpaceTab; } write << NUM(tri, width) << ", "; } write << "\n};\n"; if (Companion::Instance->IsDebug()) { write << "// Triangle count: " << triData->mTris.size() << "\n"; write << "// 0x" << std::uppercase << std::hex << off + triData->mTris.size() * sizeof(Vec3s) << "\n"; } write << "\n"; } void SF64::TriangleBinaryExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { } std::optional> SF64::TriangleFactory::parse(std::vector& buffer, YAML::Node& node) { const auto offset = GetSafeNode(node, "offset"); const auto count = GetSafeNode(node, "count"); const auto meshCount = GetSafeNode(node, "mesh_count", 1); std::vector tris; std::vector meshNodes; int meshSize = 0; auto [_, segment] = Decompressor::AutoDecode(node, buffer, count * sizeof(Vec3s)); LUS::BinaryReader reader(segment.data, segment.size); reader.SetEndianness(LUS::Endianness::Big); for(int i = 0; i < count; i++) { Vec3s tri; tri.x = reader.ReadInt16(); meshSize = std::max(meshSize, (int)tri.x); tri.y = reader.ReadInt16(); meshSize = std::max(meshSize, (int)tri.y); tri.z = reader.ReadInt16(); meshSize = std::max(meshSize, (int)tri.z); tris.push_back(tri); } meshSize++; auto meshOffset = GetSafeNode(node, "mesh_offset", offset + count * sizeof(Vec3s)); for(int j = 0; j < meshCount; j++) { YAML::Node meshNode; if(node["mesh_symbol"]) { auto meshSymbol = GetSafeNode(node, "mesh_symbol"); if (meshSymbol.find("OFFSET") == std::string::npos) { if(meshCount > 1) { meshSymbol += "_" + std::to_string(j); } } else { std::ostringstream offsetSeg; std::string replaceOff = "OFFSET"; std::string off; offsetSeg << std::uppercase << std::hex << meshOffset; off = offsetSeg.str(); meshSymbol = std::regex_replace(meshSymbol, std::regex(R"(OFFSET)"), offsetSeg.str()); } meshNode["symbol"] = meshSymbol; } meshNode["type"] = "VEC3F"; meshNode["count"] = meshSize; meshNode["offset"] = meshOffset; meshNode = Companion::Instance->AddAsset(meshNode).value(); meshNodes.push_back(meshNode); meshOffset += meshSize * sizeof(Vec3f); } return std::make_shared(tris, meshNodes); }