diff options
| author | petrie911 <69443847+petrie911@users.noreply.github.com> | 2024-03-16 15:37:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-16 14:37:37 -0600 |
| commit | 3330d5bd39bd4e0da8c8530290aba59fda849c17 (patch) | |
| tree | dbce6b7876b018f6b8cc5bd0faaad86666a42400 | |
| parent | 02f2c2f03c5fb386258e62c377a0fcd686b57690 (diff) | |
Add Vec3f factory and AddAsset (#44)
* 3D
* and env
* so much to fix
* Everything can be solved with triangles
* fixes
* initfix
* stuff
| -rw-r--r-- | TemplateFactory.cpp | 3 | ||||
| -rw-r--r-- | src/Companion.cpp | 55 | ||||
| -rw-r--r-- | src/Companion.h | 1 | ||||
| -rw-r--r-- | src/factories/Vec3fFactory.cpp | 89 | ||||
| -rw-r--r-- | src/factories/Vec3fFactory.h | 41 | ||||
| -rw-r--r-- | src/factories/sf64/ColPolyFactory.cpp | 11 | ||||
| -rw-r--r-- | src/factories/sf64/SkeletonFactory.cpp | 62 | ||||
| -rw-r--r-- | src/factories/sf64/TriangleFactory.cpp | 158 | ||||
| -rw-r--r-- | src/factories/sf64/TriangleFactory.h | 8 | ||||
| -rw-r--r-- | src/types/Vec3D.cpp | 100 | ||||
| -rw-r--r-- | src/types/Vec3D.h | 9 |
11 files changed, 433 insertions, 104 deletions
diff --git a/TemplateFactory.cpp b/TemplateFactory.cpp index 1d89a6f..60e03fc 100644 --- a/TemplateFactory.cpp +++ b/TemplateFactory.cpp @@ -33,6 +33,9 @@ void TypeBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData } std::optional<std::shared_ptr<IParsedData>> TypeFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + auto [root, segment] = Decompressor::AutoDecode(node, buffer, 0x1000); + LUS::BinaryReader reader(segment.data, segment.size); + reader.SetEndianness(LUS::Endianness::Big); return std::make_shared<TypeData>(); } diff --git a/src/Companion.cpp b/src/Companion.cpp index 9bbef7e..4f87364 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -18,6 +18,7 @@ #include "factories/DisplayListOverrides.h" #include "factories/BlobFactory.h" #include "factories/LightsFactory.h" +#include "factories/Vec3fFactory.h" #include "factories/mk64/CourseVtx.h" #include "factories/mk64/Waypoints.h" #include "factories/mk64/TrackSections.h" @@ -39,6 +40,7 @@ #include "factories/sf64/ObjInitFactory.h" #include "factories/sf64/TriangleFactory.h" #include <regex> +#include "utils/TorchUtils.h" using namespace std::chrono; namespace fs = std::filesystem; @@ -61,6 +63,7 @@ void Companion::Init(const ExportType type) { this->RegisterFactory("SEQUENCE", std::make_shared<SequenceFactory>()); this->RegisterFactory("SAMPLE", std::make_shared<SampleFactory>()); this->RegisterFactory("BANK", std::make_shared<BankFactory>()); + this->RegisterFactory("VEC3F", std::make_shared<Vec3fFactory>()); // SM64 specific this->RegisterFactory("SM64:DIALOG", std::make_shared<SM64::DialogFactory>()); @@ -966,4 +969,54 @@ std::string Companion::NormalizeAsset(const std::string& name) const { std::string Companion::CalculateHash(const std::vector<uint8_t>& data) { return Chocobo1::SHA1().addData(data).finalize().toString(); -}
\ No newline at end of file +} + +static std::string ConvertType(std::string type) { + int index; + + if((index = type.find(':')) != std::string::npos) { + type = type.substr(index + 1); + } + type = std::regex_replace(type, std::regex(R"([^_A-Za-z0-9]*)"), ""); + std::transform(type.begin(), type.end(), type.begin(), ::tolower); + return type; +} + +std::optional<YAML::Node> Companion::AddAsset(YAML::Node asset) { + if(!asset["offset"] || !asset["type"]) { + return std::nullopt; + } + const auto type = GetSafeNode<std::string>(asset, "type"); + const auto offset = GetSafeNode<uint32_t>(asset, "offset"); + const auto symbol = GetSafeNode<std::string>(asset, "symbol", ""); + const auto decl = this->GetNodeByAddr(offset); + + if(decl.has_value()) { + return std::get<1>(decl.value()); + } + + auto rom = this->GetRomData(); + auto factory = this->GetFactory(type)->get(); + + std::string output; + std::string typeId = ConvertType(type); + int index; + + if(symbol != "") { + output = symbol; + } else if(Decompressor::IsSegmented(offset)){ + output = this->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(offset)) +"_" + typeId + "_" + Torch::to_hex(SEGMENT_OFFSET(offset), false)); + } else { + output = this->NormalizeAsset(typeId + "_" + Torch::to_hex(offset, false)); + } + asset["autogen"] = true; + asset["symbol"] = output; + + auto result = factory->parse(rom, asset); + + if(result.has_value()){ + return std::get<1>(this->RegisterAsset(output, asset).value()); + } + + return std::nullopt; +} diff --git a/src/Companion.h b/src/Companion.h index 754befa..7e38fea 100644 --- a/src/Companion.h +++ b/src/Companion.h @@ -110,6 +110,7 @@ public: TorchConfig& GetConfig() { return this->gConfig; } std::optional<std::tuple<std::string, YAML::Node>> RegisterAsset(const std::string& name, YAML::Node& node); + std::optional<YAML::Node> AddAsset(YAML::Node asset); private: TorchConfig gConfig; YAML::Node gModdingConfig; diff --git a/src/factories/Vec3fFactory.cpp b/src/factories/Vec3fFactory.cpp new file mode 100644 index 0000000..e6dbf2b --- /dev/null +++ b/src/factories/Vec3fFactory.cpp @@ -0,0 +1,89 @@ +#include "Vec3fFactory.h" +#include "spdlog/spdlog.h" + +#include "Companion.h" +#include "utils/Decompressor.h" +#include "utils/TorchUtils.h" + +#define FORMAT_FLOAT(x, w, p) std::dec << std::setfill(' ') << std::fixed << std::setprecision(p) << std::setw(w) << x + +Vec3fData::Vec3fData(std::vector<Vec3f> vecs): mVecs(vecs) { + mMaxPrec = 1; + mMaxWidth = 3; + for(Vec3f v : vecs) { + mMaxPrec = std::max(mMaxPrec, v.precision()); + mMaxWidth = std::max(mMaxWidth, v.width()); + } +} + +void Vec3fHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> 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 Vec3f " << symbol << "[];\n"; +} + + +int GetPrecision(Vec3f v) { + return std::max(std::max(GetPrecision(v.x), GetPrecision(v.y)), GetPrecision(v.z)); +} + +void Vec3fCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + const auto symbol = GetSafeNode(node, "symbol", entryName); + const auto offset = GetSafeNode<uint32_t>(node, "offset"); + auto vecData = std::static_pointer_cast<Vec3fData>(raw); + auto off = offset; + int i; + + if(IS_SEGMENTED(off)) { + off = SEGMENT_OFFSET(off); + } + if (Companion::Instance->IsDebug()) { + write << "// 0x" << std::uppercase << std::hex << off << "\n"; + } + + write << "Vec3f " << symbol << "[] = {"; + + int cols = 120 / (3 * vecData->mMaxWidth + 8); + i = 0; + for(Vec3f v : vecData->mVecs) { + if((i++ % cols) == 0) { + write << "\n" << fourSpaceTab; + } + write << FORMAT_FLOAT(v, vecData->mMaxWidth, vecData->mMaxPrec) << ", "; + } + + write << "\n};\n"; + if (Companion::Instance->IsDebug()) { + write << "// Count: " << vecData->mVecs.size() << " Vec3fs\n"; + write << "// 0x" << std::uppercase << std::hex << off + vecData->mVecs.size() * sizeof(Vec3f) << "\n"; + } + write << "\n"; + +} + +void Vec3fBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + +} + +std::optional<std::shared_ptr<IParsedData>> Vec3fFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + std::vector<Vec3f> vecs; + const auto count = GetSafeNode<int>(node, "count"); + auto [root, segment] = Decompressor::AutoDecode(node, buffer, 0x1000); + LUS::BinaryReader reader(segment.data, segment.size); + reader.SetEndianness(LUS::Endianness::Big); + + for(int i = 0; i < count; i++) { + auto vx = reader.ReadFloat(); + auto vy = reader.ReadFloat(); + auto vz = reader.ReadFloat(); + + vecs.push_back(Vec3f(vx, vy, vz)); + } + + return std::make_shared<Vec3fData>(vecs); +} diff --git a/src/factories/Vec3fFactory.h b/src/factories/Vec3fFactory.h new file mode 100644 index 0000000..9d9dd4a --- /dev/null +++ b/src/factories/Vec3fFactory.h @@ -0,0 +1,41 @@ +#pragma once + +#include "BaseFactory.h" +#include "types/Vec3D.h" + +class Vec3fData : public IParsedData { +public: + std::vector<Vec3f> mVecs; + int mMaxWidth; + int mMaxPrec; + + explicit Vec3fData(std::vector<Vec3f> vecs); +}; + +class Vec3fHeaderExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class Vec3fBinaryExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class Vec3fCodeExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class Vec3fFactory : public BaseFactory { +public: + std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override; + std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override { + return std::nullopt; + } + inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override { + return { + REGISTER(Code, Vec3fCodeExporter) + REGISTER(Header, Vec3fHeaderExporter) + REGISTER(Binary, Vec3fBinaryExporter) + }; + } + bool SupportModdedAssets() override { return false; } +}; diff --git a/src/factories/sf64/ColPolyFactory.cpp b/src/factories/sf64/ColPolyFactory.cpp index 96c81eb..b2c6c45 100644 --- a/src/factories/sf64/ColPolyFactory.cpp +++ b/src/factories/sf64/ColPolyFactory.cpp @@ -4,6 +4,7 @@ #include "Companion.h" #include "utils/Decompressor.h" #include "utils/TorchUtils.h" +#include <regex> #define NUM(x, w) std::dec << std::setfill(' ') << std::setw(w) << x @@ -78,7 +79,15 @@ void SF64::ColPolyCodeExporter::Export(std::ostream &write, std::shared_ptr<IPar off = SEGMENT_OFFSET(off); } defaultMeshSymbol << symbol << "_mesh_" << std::uppercase << std::hex << off; - const auto meshSymbol = GetSafeNode(node, "mesh_symbol", defaultMeshSymbol.str()); + auto meshSymbol = GetSafeNode(node, "mesh_symbol", defaultMeshSymbol.str()); + + if (meshSymbol.find("OFFSET") != std::string::npos) { + std::ostringstream offsetSeg; + + offsetSeg << std::uppercase << std::hex << meshOffset; + meshSymbol = std::regex_replace(meshSymbol, std::regex(R"(OFFSET)"), offsetSeg.str()); + } + if (Companion::Instance->IsDebug()) { write << "// 0x" << std::uppercase << std::hex << off << "\n"; } diff --git a/src/factories/sf64/SkeletonFactory.cpp b/src/factories/sf64/SkeletonFactory.cpp index 31d402b..da4e638 100644 --- a/src/factories/sf64/SkeletonFactory.cpp +++ b/src/factories/sf64/SkeletonFactory.cpp @@ -5,9 +5,9 @@ #include "utils/Decompressor.h" #include "utils/TorchUtils.h" -#define NUM(x) std::dec << std::setfill(' ') << std::setw(7) << x -#define NUM_JOINT(x) std::dec << std::setfill(' ') << std::setw(5) << x - +#define NUM(x, w) std::dec << std::setfill(' ') << std::setw(w) << x +// #define NUM_JOINT(x) std::dec << std::setfill(' ') << std::setw(5) << x +#define FLOAT(x, w, p) std::dec << std::setfill(' ') << std::setw(w) << std::fixed << std::setprecision(p) << x SF64::LimbData::LimbData(uint32_t addr, uint32_t dList, Vec3f trans, Vec3s rot, uint32_t sibling, uint32_t child, int index): mAddr(addr), mDList(dList), mTrans(trans), mRot(rot), mSibling(sibling), mChild(child), mIndex(index) { } @@ -23,6 +23,16 @@ void SF64::SkeletonHeaderExporter::Export(std::ostream &write, std::shared_ptr<I write << "extern Limb* " << symbol << "[];\n"; } +int GetPrecision(float f) { + int prec = 0; + + while(f != (int)f && prec < 8 ){ + f *= 10; + prec++; + } + return prec; +} + void SF64::SkeletonCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { const auto symbol = GetSafeNode(node, "symbol", entryName); const auto offset = GetSafeNode<uint32_t>(node, "offset"); @@ -64,7 +74,8 @@ void SF64::SkeletonCodeExporter::Export(std::ostream &write, std::shared_ptr<IPa write << "0x" << std::uppercase << std::hex << limb.mDList << ", "; } } - write << limb.mTrans << ", "; + // auto p = std::max(std::max(GetPrecision(limb.mTrans.x), GetPrecision(limb.mTrans.y)), GetPrecision(limb.mTrans.z)); + write << FLOAT(limb.mTrans, 0, limb.mTrans.precision()) << ", "; write << std::dec << limb.mRot << ", "; write << ((limb.mSibling != 0) ? "&" : "") << limbDict[limb.mSibling] << ", "; write << ((limb.mChild != 0) ? "&" : "") << limbDict[limb.mChild] << ",\n"; @@ -100,7 +111,6 @@ void SF64::SkeletonBinaryExporter::Export(std::ostream &write, std::shared_ptr<I } std::optional<std::shared_ptr<IParsedData>> SF64::SkeletonFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - YAML::Node limbNode; std::vector<SF64::LimbData> skeleton; std::map<std::string, std::string> limbDict; auto [root, segment] = Decompressor::AutoDecode(node, buffer, 0x1000); @@ -111,9 +121,10 @@ std::optional<std::shared_ptr<IParsedData>> SF64::SkeletonFactory::parse(std::ve while(limbAddr != 0) { - limbNode["offset"] = limbAddr; + YAML::Node limbNode; Vec3f trans; Vec3s rot; + limbNode["offset"] = limbAddr; DecompressedData limbDataRaw = Decompressor::AutoDecode(limbNode, buffer, 0x20); LUS::BinaryReader limbReader(limbDataRaw.segment.data, limbDataRaw.segment.size); limbReader.SetEndianness(LUS::Endianness::Big); @@ -130,41 +141,10 @@ std::optional<std::shared_ptr<IParsedData>> SF64::SkeletonFactory::parse(std::ve auto childAddr = limbReader.ReadUInt32(); if(dListAddr != 0 && (SEGMENT_NUMBER(dListAddr) == SEGMENT_NUMBER(limbAddr))) { - const auto decl = Companion::Instance->GetNodeByAddr(dListAddr); - - if(!decl.has_value()){ - SPDLOG_INFO("Addr to Display list command at 0x{:X} not in yaml, autogenerating it", dListAddr); - - auto rom = Companion::Instance->GetRomData(); - auto factory = Companion::Instance->GetFactory("GFX")->get(); - - std::string output; - YAML::Node dl; - uint32_t ptr = dListAddr; - - if(Decompressor::IsSegmented(dListAddr)){ - SPDLOG_INFO("Found segmented display list at 0x{:X}", dListAddr); - output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(ptr)) +"_dl_" + Torch::to_hex(SEGMENT_OFFSET(ptr), false)); - } else { - SPDLOG_INFO("Found display list at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("dl_" + Torch::to_hex(ptr, false)); - } - - dl["type"] = "GFX"; - dl["offset"] = ptr; - dl["symbol"] = output; - dl["autogen"] = true; - - auto result = factory->parse(rom, dl); - - if(!result.has_value()){ - continue; - } - - Companion::Instance->RegisterAsset(output, dl); - } else { - SPDLOG_WARN("Could not find display list at 0x{:X}", dListAddr); - } + YAML::Node dListNode; + dListNode["type"] = "GFX"; + dListNode["offset"] = dListAddr; + Companion::Instance->AddAsset(dListNode); } skeleton.push_back(LimbData(limbAddr, dListAddr, trans, rot, siblingAddr, childAddr, limbIndex)); diff --git a/src/factories/sf64/TriangleFactory.cpp b/src/factories/sf64/TriangleFactory.cpp index 9e50879..ea098e5 100644 --- a/src/factories/sf64/TriangleFactory.cpp +++ b/src/factories/sf64/TriangleFactory.cpp @@ -4,13 +4,18 @@ #include "Companion.h" #include "utils/Decompressor.h" #include "utils/TorchUtils.h" +#include <regex> #define NUM(x, w) std::dec << std::setfill(' ') << std::setw(w) << x -// #define FLOAT(x, w) std::dec << std::setfill(' ') << (((int) x == x) ? "" : " ") << std::setw(w - 2) << x << (((int) x == x) ? ".0f" : "f") +#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<Vec3s> tris, std::vector<std::vector<Vec3f>> meshes): mTris(tris), mMeshes(meshes) { +// SF64::TriangleData::TriangleData(std::vector<Vec3s> tris, std::vector<std::vector<Vec3f>> meshes): mTris(tris), mMeshes(meshes) { +// } + +SF64::TriangleData::TriangleData(std::vector<Vec3s> tris, std::vector<YAML::Node> meshNodes): mTris(tris), mMeshNodes(meshNodes) { } void SF64::TriangleHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { @@ -28,17 +33,19 @@ void SF64::TriangleCodeExporter::Export(std::ostream &write, std::shared_ptr<IPa const auto symbol = GetSafeNode(node, "symbol", entryName); const auto offset = GetSafeNode<uint32_t>(node, "offset"); auto triData = std::static_pointer_cast<SF64::TriangleData>(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 << off << "\n"; + write << "// 0x" << std::uppercase << std::hex << STRIP_SEGMENT(offset) << "\n"; } write << "Triangle " << symbol << "[] = {"; - int width = std::log10(triData->mMeshes[0].size()) + 1; + int width = std::log10(meshSize) + 1; i = 0; for(Vec3s tri : triData->mTris) { if((i++ % 6) == 0) { @@ -57,43 +64,46 @@ void SF64::TriangleCodeExporter::Export(std::ostream &write, std::shared_ptr<IPa write << "\n"; - auto meshOffset = offset + triData->mTris.size() * sizeof(Vec3s); - off = meshOffset; - if(IS_SEGMENTED(off)) { - off = SEGMENT_OFFSET(off); - } - for(int j = 0; j < triData->mMeshes.size(); j++) { - std::string indexTag = ""; - std::ostringstream defaultMeshSymbol; - if(triData->mMeshes.size() != 1) { - indexTag = std::to_string(j) + "_"; - } - defaultMeshSymbol << symbol << "_mesh_" << indexTag << std::uppercase << std::hex << off; - const auto meshSymbol = GetSafeNode(node, "mesh_symbol", defaultMeshSymbol.str()); - if (Companion::Instance->IsDebug()) { - write << "// 0x" << std::uppercase << std::hex << off << "\n"; - } - - write << "Vec3f " << meshSymbol << "[] = {"; - i = 0; - for(Vec3f vtx : triData->mMeshes[j]) { - if((i++ % 4) == 0) { - write << "\n" << fourSpaceTab; - } - write << NUM(vtx, 5) << ", "; - } - - write << "\n};\n"; - off += triData->mMeshes[j].size() * sizeof(Vec3f); - if (Companion::Instance->IsDebug()) { - write << "// Mesh vertex count: " << triData->mMeshes[j].size() << "\n"; - write << "// 0x" << std::uppercase << std::hex << off << "\n"; - } - write << "\n"; - } - - - + // auto meshOffset = offset + triData->mTris.size() * sizeof(Vec3s); + + // for(int j = 0; j < triData->mMeshes.size(); j++) { + // std::string indexTag = ""; + // std::ostringstream offsetStr; + // std::string meshSymbol; + // if(triData->mMeshes.size() != 1) { + // indexTag = std::to_string(j) + "_"; + // } + // offsetStr << std::uppercase << std::hex << STRIP_SEGMENT(meshOffset); + // if(!node["mesh_symbol"]) { + // meshSymbol = symbol + "_mesh_" + indexTag + offsetStr.str(); + // } else { + // meshSymbol = GetSafeNode<std::string>(node, "mesh_symbol"); + // if(!ReplaceOffset(meshSymbol, meshOffset)) { + // meshSymbol += indexTag; + // } + // } + + // if (Companion::Instance->IsDebug()) { + // write << "// 0x" << std::uppercase << std::hex << off << "\n"; + // } + + // write << "Vec3f " << meshSymbol << "[] = {"; + // i = 0; + // for(Vec3f vtx : triData->mMeshes[j]) { + // if((i++ % 4) == 0) { + // write << "\n" << fourSpaceTab; + // } + // write << NUM(vtx, 5) << ", "; + // } + + // write << "\n};\n"; + // off += triData->mMeshes[j].size() * sizeof(Vec3f); + // if (Companion::Instance->IsDebug()) { + // write << "// Mesh vertex count: " << triData->mMeshes[j].size() << "\n"; + // write << "// 0x" << std::uppercase << std::hex << off << "\n"; + // } + // write << "\n"; + // } } void SF64::TriangleBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { @@ -105,6 +115,7 @@ std::optional<std::shared_ptr<IParsedData>> SF64::TriangleFactory::parse(std::ve const auto count = GetSafeNode<uint32_t>(node, "count"); const auto meshCount = GetSafeNode<uint32_t>(node, "mesh_count", 1); std::vector<Vec3s> tris; + std::vector<YAML::Node> meshNodes; int meshSize = 0; auto [_, segment] = Decompressor::AutoDecode(node, buffer, count * sizeof(Vec3s)); LUS::BinaryReader reader(segment.data, segment.size); @@ -123,24 +134,57 @@ std::optional<std::shared_ptr<IParsedData>> SF64::TriangleFactory::parse(std::ve tris.push_back(tri); } meshSize++; - const auto meshOffset = GetSafeNode<uint32_t>(node, "mesh_offset", offset + count * sizeof(Vec3s)); - YAML::Node meshNode; - meshNode["offset"] = meshOffset; - auto [__, meshSegment] = Decompressor::AutoDecode(meshNode, buffer, meshSize * meshCount * sizeof(Vec3f)); - LUS::BinaryReader meshReader(meshSegment.data, meshSegment.size); - meshReader.SetEndianness(LUS::Endianness::Big); - std::vector<std::vector<Vec3f>> meshes; + auto meshOffset = GetSafeNode<uint32_t>(node, "mesh_offset", offset + count * sizeof(Vec3s)); for(int j = 0; j < meshCount; j++) { - std::vector<Vec3f> mesh; - Vec3f vtx; - for(int i = 0; i < meshSize; i++) { - vtx.x = meshReader.ReadFloat(); - vtx.y = meshReader.ReadFloat(); - vtx.z = meshReader.ReadFloat(); - mesh.push_back(vtx); + YAML::Node meshNode; + + if(node["mesh_symbol"]) { + auto meshSymbol = GetSafeNode<std::string>(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()); + // std::replace(meshSymbol.begin(), meshSymbol.end(), replaceOff, off); + } + meshNode["symbol"] = meshSymbol; } - meshes.push_back(mesh); + 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<SF64::TriangleData>(tris, meshes); + + + + // YAML::Node meshNode; + // meshNode["offset"] = meshOffset; + // auto [__, meshSegment] = Decompressor::AutoDecode(meshNode, buffer, meshSize * meshCount * sizeof(Vec3f)); + // LUS::BinaryReader meshReader(meshSegment.data, meshSegment.size); + // meshReader.SetEndianness(LUS::Endianness::Big); + // std::vector<std::vector<Vec3f>> meshes; + + // for(int j = 0; j < meshCount; j++) { + // std::vector<Vec3f> mesh; + // Vec3f vtx; + // for(int i = 0; i < meshSize; i++) { + // vtx.x = meshReader.ReadFloat(); + // vtx.y = meshReader.ReadFloat(); + // vtx.z = meshReader.ReadFloat(); + // mesh.push_back(vtx); + // } + // meshes.push_back(mesh); + // } + + return std::make_shared<SF64::TriangleData>(tris, meshNodes); } diff --git a/src/factories/sf64/TriangleFactory.h b/src/factories/sf64/TriangleFactory.h index 1e3bf6d..2ed0c5c 100644 --- a/src/factories/sf64/TriangleFactory.h +++ b/src/factories/sf64/TriangleFactory.h @@ -1,6 +1,6 @@ #pragma once -#include "../BaseFactory.h" +#include "factories/BaseFactory.h" #include "types/Vec3D.h" namespace SF64 { @@ -8,9 +8,11 @@ namespace SF64 { class TriangleData : public IParsedData { public: std::vector<Vec3s> mTris; - std::vector<std::vector<Vec3f>> mMeshes; + // std::vector<std::vector<Vec3f>> mMeshes; + std::vector<YAML::Node> mMeshNodes; - TriangleData(std::vector<Vec3s> tris, std::vector<std::vector<Vec3f>> meshes); + // TriangleData(std::vector<Vec3s> tris, std::vector<std::vector<Vec3f>> meshes); + TriangleData(std::vector<Vec3s> tris, std::vector<YAML::Node> meshNodes); }; class TriangleHeaderExporter : public BaseExporter { diff --git a/src/types/Vec3D.cpp b/src/types/Vec3D.cpp index 0d75e88..c70e540 100644 --- a/src/types/Vec3D.cpp +++ b/src/types/Vec3D.cpp @@ -1,18 +1,67 @@ #include "Vec3D.h" #include <iomanip> +static int GetPrecision(float f) { + int p = 0; + int shift = 1; + float approx = std::round(f); + + while(f != approx && p < 12 ){ + shift *= 10; + p++; + approx = std::round(f * shift) / shift; + } + return p; +} + +static int GetMagnitude(float f) { + int w = 1; + float a = std::abs(f); + + if(a >= 1) { + w += std::log10(a); + } + if(f < 0) { + w++; + } + return w; +} + Vec3f::Vec3f(float xv, float yv, float zv) : x(xv), y(yv), z(zv) {} +int Vec3f::precision() { + auto px = GetPrecision(this->x); + auto py = GetPrecision(this->y); + auto pz = GetPrecision(this->z); + + return std::max(px, std::max(py, pz)); +} + +int Vec3f::width() { + auto wx = GetMagnitude(this->x); + auto wy = GetMagnitude(this->y); + auto wz = GetMagnitude(this->z); + + return std::max(wx, std::max(wy, wz)) + 1 + this->precision(); +} + std::ostream& operator<< (std::ostream& stream, const Vec3f& vec) { int width = stream.width(); stream << std::setw(0) << "{" << std::setw(width) << vec.x << ", " << std::setw(width) << vec.y << ", " << std::setw(width) << vec.z << "}"; - return stream; } Vec3s::Vec3s(int16_t xv, int16_t yv, int16_t zv) : x(xv), y(yv), z(zv) {} +int Vec3s::width() { + auto wx = GetMagnitude(this->x); + auto wy = GetMagnitude(this->y); + auto wz = GetMagnitude(this->z); + + return std::max(wx, std::max(wy, wz)); +} + std::ostream& operator<< (std::ostream& stream, const Vec3s& vec) { int width = stream.width(); @@ -22,6 +71,14 @@ std::ostream& operator<< (std::ostream& stream, const Vec3s& vec) { Vec3i::Vec3i(int32_t xv, int32_t yv, int32_t zv) : x(xv), y(yv), z(zv) {} +int Vec3i::width() { + auto wx = GetMagnitude(this->x); + auto wy = GetMagnitude(this->y); + auto wz = GetMagnitude(this->z); + + return std::max(wx, std::max(wy, wz)); +} + std::ostream& operator<< (std::ostream& stream, const Vec3i& vec) { int width = stream.width(); @@ -31,6 +88,20 @@ std::ostream& operator<< (std::ostream& stream, const Vec3i& vec) { Vec2f::Vec2f(float xv, float zv) : x(xv), z(zv) {} +int Vec2f::precision() { + auto px = GetPrecision(this->x); + auto pz = GetPrecision(this->z); + + return std::max(px, pz); +} + +int Vec2f::width() { + auto wx = GetMagnitude(this->x) + 1 + GetPrecision(this->x); + auto wz = GetMagnitude(this->z) + 1 + GetPrecision(this->z); + + return std::max(wx, wz); +} + std::ostream& operator<< (std::ostream& stream, const Vec2f& vec) { int width = stream.width(); @@ -40,6 +111,24 @@ std::ostream& operator<< (std::ostream& stream, const Vec2f& vec) { Vec4f::Vec4f(float xv, float yv, float zv, float wv) : x(xv), y(yv), z(zv), w(wv) {} +int Vec4f::width() { + auto wx = GetMagnitude(this->x) + 1 + GetPrecision(this->x); + auto wy = GetMagnitude(this->y) + 1 + GetPrecision(this->y); + auto wz = GetMagnitude(this->z) + 1 + GetPrecision(this->z); + auto ww = GetMagnitude(this->w) + 1 + GetPrecision(this->w); + + return std::max(std::max(wy, ww), std::max(wx, wz)); +} + +int Vec4f::precision() { + auto px = GetPrecision(this->x); + auto py = GetPrecision(this->y); + auto pz = GetPrecision(this->z); + auto pw = GetPrecision(this->w); + + return std::max(std::max(px, pw), std::max(py, pz)); +} + std::ostream& operator<< (std::ostream& stream, const Vec4f& vec) { int width = stream.width(); @@ -49,6 +138,15 @@ std::ostream& operator<< (std::ostream& stream, const Vec4f& vec) { Vec4s::Vec4s(int16_t xv, int16_t yv, int16_t zv, int16_t wv) : x(xv), y(yv), z(zv), w(wv) {} +int Vec4s::width() { + auto wx = GetMagnitude(this->x); + auto wy = GetMagnitude(this->y); + auto wz = GetMagnitude(this->z); + auto ww = GetMagnitude(this->w); + + return std::max(std::max(wx, ww), std::max(wy, wz)); +} + std::ostream& operator<< (std::ostream& stream, const Vec4s& vec) { int width = stream.width(); diff --git a/src/types/Vec3D.h b/src/types/Vec3D.h index e861f12..8215730 100644 --- a/src/types/Vec3D.h +++ b/src/types/Vec3D.h @@ -9,6 +9,8 @@ public: float z; Vec3f(float xv = 0, float yv = 0, float zv = 0); + int width(); + int precision(); friend std::ostream& operator<< (std::ostream& stream, const Vec3f& vec); }; @@ -19,6 +21,7 @@ public: int16_t z; Vec3s(int16_t xv = 0, int16_t yv = 0, int16_t zv = 0); + int width(); friend std::ostream& operator<< (std::ostream& stream, const Vec3s& vec); }; @@ -29,6 +32,7 @@ public: int32_t z; Vec3i(int32_t xv = 0, int32_t yv = 0, int32_t zv = 0); + int width(); friend std::ostream& operator<< (std::ostream& stream, const Vec3i& vec); }; @@ -38,6 +42,8 @@ public: float z; Vec2f(float xv = 0, float zv = 0); + int precision(); + int width(); friend std::ostream& operator<< (std::ostream& stream, const Vec2f& vec); }; @@ -49,6 +55,8 @@ public: float w; Vec4f(float xv = 0, float yv = 0, float zv = 0, float wv = 0); + int precision(); + int width(); friend std::ostream& operator<< (std::ostream& stream, const Vec4f& vec); }; @@ -60,5 +68,6 @@ public: int16_t w; Vec4s(int16_t xv = 0, int16_t yv = 0, int16_t zv = 0, int16_t wv = 0); + int width(); friend std::ostream& operator<< (std::ostream& stream, const Vec4s& vec); };
\ No newline at end of file |
