summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetrie911 <69443847+petrie911@users.noreply.github.com>2024-03-16 15:37:37 -0500
committerGitHub <noreply@github.com>2024-03-16 14:37:37 -0600
commit3330d5bd39bd4e0da8c8530290aba59fda849c17 (patch)
treedbce6b7876b018f6b8cc5bd0faaad86666a42400
parent02f2c2f03c5fb386258e62c377a0fcd686b57690 (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.cpp3
-rw-r--r--src/Companion.cpp55
-rw-r--r--src/Companion.h1
-rw-r--r--src/factories/Vec3fFactory.cpp89
-rw-r--r--src/factories/Vec3fFactory.h41
-rw-r--r--src/factories/sf64/ColPolyFactory.cpp11
-rw-r--r--src/factories/sf64/SkeletonFactory.cpp62
-rw-r--r--src/factories/sf64/TriangleFactory.cpp158
-rw-r--r--src/factories/sf64/TriangleFactory.h8
-rw-r--r--src/types/Vec3D.cpp100
-rw-r--r--src/types/Vec3D.h9
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