Skip to content

Instantly share code, notes, and snippets.

@LemonHaze420
Created November 22, 2024 17:11
Show Gist options
  • Save LemonHaze420/292a893d6564dc771cc7431efeefbfec to your computer and use it in GitHub Desktop.
Save LemonHaze420/292a893d6564dc771cc7431efeefbfec to your computer and use it in GitHub Desktop.
USM Mesh Tools
// 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();
}
}
#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