Created
November 22, 2024 17:11
-
-
Save LemonHaze420/292a893d6564dc771cc7431efeefbfec to your computer and use it in GitHub Desktop.
USM Mesh Tools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Dylan E - 2024 | |
#include <iostream> | |
#include <ostream> | |
#include <fstream> | |
#include <string> | |
#include <vector> | |
struct header_t { | |
int fourcc; | |
int version; | |
int num_entries; | |
int dir_base; | |
int base_offset; | |
int reserved[3]; | |
}; | |
struct dir_entry_t { | |
char unk_val1; | |
char unk_val2; | |
char unk_val3; | |
char type; | |
int data_offset; | |
int object_name_tbl_offset; | |
}; | |
int main(int argc, char ** argp) | |
{ | |
if (!argp[1]) | |
return -1; | |
std::ifstream ifs(argp[1], std::ios::binary); | |
if (ifs.good()) | |
{ | |
std::vector<dir_entry_t> dirs; | |
header_t hdr; | |
ifs.read(reinterpret_cast<char*>(&hdr), sizeof(header_t)); | |
if (hdr.fourcc != 0x204d4350) // "PCM " | |
return -1; | |
printf("Version: %d\n", hdr.version); | |
if (hdr.num_entries) | |
{ | |
for (int i = 0; i < hdr.num_entries; ++i) { | |
dir_entry_t dir; | |
ifs.read(reinterpret_cast<char*>(&dir), sizeof(dir_entry_t)); | |
size_t last_pos = ifs.tellg(); | |
ifs.seekg(dir.object_name_tbl_offset); | |
int hash = 0, hash2, hash3; | |
ifs.read(reinterpret_cast<char*>(&hash), 4); | |
std::string name; | |
while (ifs.peek() != 0x00) | |
name.push_back(ifs.get()); | |
printf("Name: %s\t | Hash: 0x%X\n", name.c_str(), hash); | |
switch (dir.type) { | |
case 1: | |
printf("Type: Material\n"); | |
break; | |
case 2: | |
printf("Type: Mesh\n"); | |
break; | |
case 3: | |
printf("Type: Morph Target\n"); | |
break; | |
} | |
if (dir.data_offset) { | |
int offset = 0, offset2; | |
std::string name2, name3; | |
ifs.seekg(dir.data_offset); | |
ifs.read(reinterpret_cast<char*>(&offset), 4); | |
ifs.read(reinterpret_cast<char*>(&offset2), 4); | |
// read offset | |
if (offset) { | |
ifs.seekg(offset); | |
ifs.read(reinterpret_cast<char*>(&hash2), 4); | |
while (ifs.peek() != 0x00) | |
name2.push_back(ifs.get()); | |
if (hash2 != hash) | |
printf("Name: %s\t | Hash: 0x%X\n", name2.c_str(), hash2); | |
} | |
// read offs 2 | |
if (offset2) { | |
ifs.seekg(offset2); | |
ifs.read(reinterpret_cast<char*>(&hash3), 4); | |
while (ifs.peek() != 0x00) | |
name3.push_back(ifs.get()); | |
if (hash3 != hash) | |
printf("Flag: %s\n", name3.c_str()); | |
} | |
} | |
if (dir.type == 2) { | |
printf("data offs = %d\n", dir.data_offset); | |
} | |
ifs.seekg(last_pos); | |
dirs.push_back(dir); | |
printf("========================\n"); | |
} | |
printf("Finished parsing %d entries at 0x%llX\n", hdr.num_entries, (long long)ifs.tellg()); | |
} | |
ifs.close(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma endian little | |
import std.io; | |
import type.base; | |
struct Vector2 { | |
float x,y; | |
}; | |
struct Vector3 { | |
float x,y,z; | |
}; | |
enum eType : u8 { | |
Material = 1, | |
Mesh = 2, | |
Morph = 3 | |
}; | |
struct hash_string { | |
s32 hash_string; | |
s32 hash_flags; | |
}; | |
struct vertex_data | |
{ | |
/*float float0; | |
float float4; | |
float float8; | |
float floatC; | |
float x; | |
float y; | |
float z; | |
float float1C;*/ | |
float v[16]; | |
}; | |
struct section_data { | |
s32 ptr; | |
s32 material_offs; | |
s32 unk_num; | |
s32 indices_offs2; | |
float pos[6]; | |
s32 unk_val; | |
s32 NIndices; | |
s32 indices_offs; | |
s32 indices_dx_offs; | |
s32 m_numVertices; | |
s32 vertices_offs,vert_offs2; | |
s32 unk_ptr; | |
s32 stride; | |
s32 unk_offs; | |
s32 unk_val2; | |
s32 mesh_type_offs; | |
s32 unk_vals[2]; | |
s16 m_indices[NIndices] @ indices_offs; | |
s16 m_indices2[unk_num] @ indices_offs2; | |
vertex_data verts[m_numVertices] @ vertices_offs; | |
}; | |
struct section { | |
s32 unk; | |
s32 offs; | |
section_data data @ offs; | |
}; | |
struct section_flag_data { | |
s32 offs; | |
s32 unk[2]; | |
}; | |
struct mesh_extra_data { | |
float val[57]; | |
}; | |
struct final_mesh_data { | |
Vector2 v[8]; | |
}; | |
struct mesh { | |
hash_string parent_hash; | |
s32 NSections; | |
s32 sections_ptr; | |
s32 NBones; | |
s32 bones_ptr; | |
s32 NLODs; | |
s32 lods_ptr; | |
Vector3 pos[2]; | |
s32 unk1; | |
s32 unk2; | |
section sections[NSections] @ sections_ptr; | |
section_flag_data section_flags_offs[NSections] @ sections[NSections-1].offs + 96; | |
mesh_extra_data extra_data[NSections] @ sections[NSections-1].offs + 96 + (NSections * 3*4); | |
final_mesh_data extra_data2 @ sections[NSections-1].offs + 96 + (NSections * 3*4) + NSections * (57*4); | |
}; | |
struct material { | |
hash_string hstring; | |
s32 flags; | |
s32 offset; | |
s32 int; | |
s32 another_ptr; | |
s32 object_offs_name; | |
s32 int3; | |
s32 flag_offs_name; | |
Vector2 pos[3]; | |
s32 unk_flags[5]; | |
float unkf[2]; | |
s32 unki[2]; | |
}; | |
struct morph { | |
hash_string hstring; | |
}; | |
struct dir_entry { | |
char unk_val1; | |
char unk_val2; | |
char unk_val3; | |
eType type; | |
s32 data_offset; | |
s32 object_name_tbl_offset; | |
if (type == eType::Mesh) | |
mesh @ data_offset; | |
else if (type == eType::Material) | |
material @ data_offset; | |
else if (type == eType::Morph) | |
morph @ data_offset; | |
}; | |
struct header { | |
char fourcc[4]; | |
s32 version; | |
s32 num_entries; | |
s32 dir_base; | |
s32 base_offset; | |
s32 reserved[3]; | |
dir_entry entries[num_entries]; | |
}; | |
header header @ 0; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment