diff options
| author | petrie911 <69443847+petrie911@users.noreply.github.com> | 2024-03-13 17:49:25 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-13 16:49:25 -0600 |
| commit | 2dd431eedf38c8872d96bd635c7b0e19b84eae62 (patch) | |
| tree | dfa786d42e344e16d2ec3b6cbbcaf37855035f44 | |
| parent | 92e7076647d2da64e8f90aa66974c4a3dba03a06 (diff) | |
SF64 Triangle factory, fixed a bug in ColPolys (#40)
* 3D
* and env
* so much to fix
* Everything can be solved with triangles
| -rw-r--r-- | src/Companion.cpp | 2 | ||||
| -rw-r--r-- | src/factories/sf64/ColPolyFactory.cpp | 16 | ||||
| -rw-r--r-- | src/factories/sf64/TriangleFactory.cpp | 142 | ||||
| -rw-r--r-- | src/factories/sf64/TriangleFactory.h | 43 |
4 files changed, 196 insertions, 7 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp index 3ab7267..bb55a2f 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -37,6 +37,7 @@ #include "factories/sf64/HitboxFactory.h" #include "factories/sf64/EnvSettingsFactory.h" #include "factories/sf64/ObjInitFactory.h" +#include "factories/sf64/TriangleFactory.h" #include <regex> using namespace std::chrono; @@ -84,6 +85,7 @@ void Companion::Init(const ExportType type) { this->RegisterFactory("SF64:ENV_SETTINGS", std::make_shared<SF64::EnvSettingsFactory>()); this->RegisterFactory("SF64:OBJECT_INIT", std::make_shared<SF64::ObjInitFactory>()); this->RegisterFactory("SF64:COLPOLY", std::make_shared<SF64::ColPolyFactory>()); + this->RegisterFactory("SF64:TRIANGLE", std::make_shared<SF64::TriangleFactory>()); this->Process(); } diff --git a/src/factories/sf64/ColPolyFactory.cpp b/src/factories/sf64/ColPolyFactory.cpp index 3cff5c6..b98ce3f 100644 --- a/src/factories/sf64/ColPolyFactory.cpp +++ b/src/factories/sf64/ColPolyFactory.cpp @@ -112,18 +112,18 @@ std::optional<std::shared_ptr<IParsedData>> SF64::ColPolyFactory::parse(std::vec const auto count = GetSafeNode<uint32_t>(node, "count"); std::vector<SF64::CollisionPoly> polys; std::vector<Vec3s> mesh; - int meshCount = 0; + int meshSize = 0; auto [_, segment] = Decompressor::AutoDecode(node, buffer, count * sizeof(SF64::CollisionPoly)); LUS::BinaryReader reader(segment.data, segment.size); reader.SetEndianness(LUS::Endianness::Big); for(int i = 0; i < count; i++) { int16_t v0 = reader.ReadInt16(); - meshCount = std::max(meshCount, (int)v0); + meshSize = std::max(meshSize, (int)v0); int16_t v1 = reader.ReadInt16(); - meshCount = std::max(meshCount, (int)v1); + meshSize = std::max(meshSize, (int)v1); int16_t v2 = reader.ReadInt16(); - meshCount = std::max(meshCount, (int)v2); + meshSize = std::max(meshSize, (int)v2); int16_t pad1 = reader.ReadInt16(); int16_t nx = reader.ReadInt16(); int16_t ny = reader.ReadInt16(); @@ -133,13 +133,15 @@ std::optional<std::shared_ptr<IParsedData>> SF64::ColPolyFactory::parse(std::vec polys.push_back(CollisionPoly({{v0, v1, v2}, pad1, {nx, ny, nz}, pad2, dist})); } - + meshSize++; const auto meshOffset = GetSafeNode<uint32_t>(node, "mesh_offset", offset + count * sizeof(SF64::CollisionPoly)); - auto [__, meshSegment] = Decompressor::AutoDecode(node, buffer, meshCount * sizeof(Vec3s)); + YAML::Node meshNode; + meshNode["offset"] = meshOffset; + auto [__, meshSegment] = Decompressor::AutoDecode(meshNode, buffer, meshSize * sizeof(Vec3s)); LUS::BinaryReader meshReader(meshSegment.data, meshSegment.size); meshReader.SetEndianness(LUS::Endianness::Big); - for(int i = 0; i < meshCount; i++) { + for(int i = 0; i < meshSize; i++) { mesh.push_back(Vec3s(meshReader.ReadInt16(), meshReader.ReadInt16(), meshReader.ReadInt16())); } diff --git a/src/factories/sf64/TriangleFactory.cpp b/src/factories/sf64/TriangleFactory.cpp new file mode 100644 index 0000000..c3ada96 --- /dev/null +++ b/src/factories/sf64/TriangleFactory.cpp @@ -0,0 +1,142 @@ +#include "TriangleFactory.h" +#include "spdlog/spdlog.h" + +#include "Companion.h" +#include "utils/Decompressor.h" +#include "utils/TorchUtils.h" + + +#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") + +SF64::TriangleData::TriangleData(std::vector<Vec3s> tris, std::vector<std::vector<Vec3f>> meshes): mTris(tris), mMeshes(meshes) { + +} + +void SF64::TriangleHeaderExporter::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 Triangle " << symbol << "[];\n"; +} + +void SF64::TriangleCodeExporter::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 triData = std::static_pointer_cast<SF64::TriangleData>(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 << "Triangle " << symbol << "[] = {"; + int width = std::log10(triData->mMeshes[0].size()) + 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"; + + + 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"; + } + + + +} + +void SF64::TriangleBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + +} + +std::optional<std::shared_ptr<IParsedData>> SF64::TriangleFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + const auto offset = GetSafeNode<uint32_t>(node, "offset"); + const auto count = GetSafeNode<uint32_t>(node, "count"); + const auto meshCount = GetSafeNode<uint32_t>(node, "mesh_count", 1); + std::vector<Vec3s> tris; + 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++; + 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; + for(int j = 0; j < meshCount; j++) { + std::vector<Vec3f> mesh; + for(int i = 0; i < meshSize; i++) { + mesh.push_back(Vec3f(meshReader.ReadFloat(), meshReader.ReadFloat(), meshReader.ReadFloat())); + } + meshes.push_back(mesh); + } + + return std::make_shared<SF64::TriangleData>(tris, meshes); +} diff --git a/src/factories/sf64/TriangleFactory.h b/src/factories/sf64/TriangleFactory.h new file mode 100644 index 0000000..1e3bf6d --- /dev/null +++ b/src/factories/sf64/TriangleFactory.h @@ -0,0 +1,43 @@ +#pragma once + +#include "../BaseFactory.h" +#include "types/Vec3D.h" + +namespace SF64 { + +class TriangleData : public IParsedData { +public: + std::vector<Vec3s> mTris; + std::vector<std::vector<Vec3f>> mMeshes; + + TriangleData(std::vector<Vec3s> tris, std::vector<std::vector<Vec3f>> meshes); +}; + +class TriangleHeaderExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class TriangleBinaryExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class TriangleCodeExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class TriangleFactory : 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, TriangleCodeExporter) + REGISTER(Header, TriangleHeaderExporter) + REGISTER(Binary, TriangleBinaryExporter) + }; + } + bool SupportModdedAssets() override { return false; } +}; +} |
