skn
This commit is contained in:
parent
1d36b5e5b4
commit
4f45346980
@ -25,6 +25,15 @@ def read_bytes(fp, size):
|
||||
return bytes(struct.unpack('<' + str(size) + 'B', fp.read(size)))
|
||||
|
||||
|
||||
def read_string_until_none(fp) -> str:
|
||||
s = ""
|
||||
c = read_byte(fp)
|
||||
while c != 0x00:
|
||||
s += chr(c)
|
||||
c = read_byte(fp)
|
||||
return s
|
||||
|
||||
|
||||
def decompress(compressed_bytes, original_size: int):
|
||||
i = 0
|
||||
j = 0
|
||||
|
253
skn.py
Normal file
253
skn.py
Normal file
@ -0,0 +1,253 @@
|
||||
from lib.fileutils import *
|
||||
|
||||
NAM_FlagHasHandles = (1 << 0)
|
||||
NAM_FlagCaseInsensitive = (1 << 1)
|
||||
|
||||
|
||||
class MAP_KeyContext:
|
||||
def __init__(self):
|
||||
self.context = 0
|
||||
self.ppLUT = 0
|
||||
self.reserve = 0
|
||||
self.pData = 0
|
||||
|
||||
@classmethod
|
||||
def parse(cls, b):
|
||||
r = cls()
|
||||
r.context = read_int(b)
|
||||
r.ppLUT = read_int(b)
|
||||
r.reserve = read_int(b)
|
||||
r.pData = read_int(b)
|
||||
return r
|
||||
|
||||
|
||||
class MAP_Mapper:
|
||||
def __init__(self):
|
||||
self.pMemgroup = 0
|
||||
self.MemBaseSize = 0
|
||||
self.MemBlocks = 0
|
||||
self.MemSize = 0
|
||||
self.MemFree = 0
|
||||
self.pMem = 0
|
||||
self.MaxMappings = 0
|
||||
self.TotalMappings = 0
|
||||
self.TotalKeys = 0
|
||||
self.pKeyContexts = 0
|
||||
|
||||
@classmethod
|
||||
def parse(cls, b):
|
||||
r = cls()
|
||||
r.pMemgroup = read_int(b)
|
||||
r.MemBaseSize = read_int(b)
|
||||
r.MemBlocks = read_int(b)
|
||||
r.MemSize = read_int(b)
|
||||
r.MemFree = read_int(b)
|
||||
r.pMem = read_int(b)
|
||||
r.MaxMappings = read_int(b)
|
||||
r.TotalMappings = read_int(b)
|
||||
r.TotalKeys = read_int(b)
|
||||
r.pKeyContexts = read_int(b)
|
||||
return r
|
||||
|
||||
class MAP_Mapping:
|
||||
def __init__(self):
|
||||
self.index = 0
|
||||
|
||||
@classmethod
|
||||
def parse(cls, b):
|
||||
r = cls()
|
||||
r.index = read_short(b)
|
||||
return r
|
||||
|
||||
|
||||
def read_int_and_print(n, b):
|
||||
a = read_int(b)
|
||||
print("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
def read_float_and_print(n, b):
|
||||
a = read_float(b)
|
||||
print("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
def read_byte_and_print(n, b):
|
||||
a = read_byte(b)
|
||||
print("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
def read_short_and_print(n, b):
|
||||
a = read_short(b)
|
||||
print("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
class MAP_MemGroup:
|
||||
def __init__(self):
|
||||
self.mem = 0
|
||||
self.memgroup = 0
|
||||
self.memlist = 0
|
||||
self.total_size = 0
|
||||
self.total_blocks = 0
|
||||
self.base = 0
|
||||
|
||||
|
||||
class MAP_Image:
|
||||
def __init__(self):
|
||||
self.size = 0
|
||||
self.memgroupoffset = 0
|
||||
|
||||
|
||||
|
||||
class ANM_Skin:
|
||||
def __init__(self):
|
||||
self.custom = 0
|
||||
self.file_version = 0
|
||||
self.image = 0
|
||||
self.memgroup = 0
|
||||
self.node_dictionary = 0
|
||||
self.tree_dictionary = 0
|
||||
self.default_obj_dictionnary = 0
|
||||
self.total_number_trees = 0
|
||||
self.total_number_objs = 0
|
||||
self.total_number_clusters = 0
|
||||
self.name = 0
|
||||
|
||||
@classmethod
|
||||
def parse(cls, b):
|
||||
print("MAP_Image")
|
||||
read_int_and_print("size", b)
|
||||
ret = b.tell()
|
||||
memgroupoffset = read_int_and_print("memgroupoffset", b)
|
||||
|
||||
b.seek(memgroupoffset)
|
||||
|
||||
print("MAP_MemGroup")
|
||||
print("\tMAP_Mem")
|
||||
read_int_and_print("\tNode", b)
|
||||
read_int_and_print("\tSize", b)
|
||||
read_int_and_print("\tFlags", b)
|
||||
|
||||
read_int_and_print("pMemGroup", b)
|
||||
read_int_and_print("MemList", b)
|
||||
read_int_and_print("TotalSize", b)
|
||||
read_int_and_print("TotalBlocks", b)
|
||||
base = read_int_and_print("pBase", b)
|
||||
|
||||
b.seek(base)
|
||||
print("=========")
|
||||
print("ANM_Skin")
|
||||
read_int_and_print("pCustom", b)
|
||||
read_int_and_print("FileVersion", b)
|
||||
read_int_and_print("pImage", b)
|
||||
read_int_and_print("pMemGroup", b)
|
||||
read_int_and_print("pNodeDictionary", b)
|
||||
tree = read_int_and_print("pTreeDictionary", b)
|
||||
defaultobj = read_int_and_print("pDefaultObjDictionary", b)
|
||||
read_int_and_print("TotalNumberOfTrees", b)
|
||||
read_int_and_print("TotalNumberOfObjs", b)
|
||||
read_int_and_print("TotalNumberOfClusters", b)
|
||||
print(read_string_until_none(b))
|
||||
print("=========")
|
||||
|
||||
print("ANM_Skin->pTreeDictionary NAM_Dictionary")
|
||||
b.seek(defaultobj)
|
||||
read_int_and_print("pMemGroup", b)
|
||||
namemapper = read_int_and_print("pNameMapper", b)
|
||||
flags = read_int_and_print("Flags", b)
|
||||
print("Flags: NAM_FlagHasHandles: %s, NAM_FlagCaseInsensitive: %s" % (flags & NAM_FlagHasHandles, flags & NAM_FlagCaseInsensitive))
|
||||
namehandle = read_short_and_print("NameHandle", b)
|
||||
|
||||
|
||||
print("MAP_Image->ANM_Skin->NAM_Dictionnary->MAP_Mapper")
|
||||
b.seek(namemapper)
|
||||
pMemGroup = read_int_and_print("pMemGroup", b)
|
||||
read_int_and_print("MemBaseSize", b)
|
||||
read_int_and_print("MemBlocks", b)
|
||||
read_int_and_print("MemSize", b)
|
||||
read_int_and_print("MemFree", b)
|
||||
mem = read_int_and_print("pMem", b)
|
||||
read_int_and_print("MaxMappings", b)
|
||||
totalmappings = read_int_and_print("TotalMappings", b)
|
||||
read_int_and_print("TotalKeys", b)
|
||||
pKeyContexts = read_int_and_print("pKeyContexts", b)
|
||||
|
||||
print("MAP_Image->ANM_Skin->NAM_Dictionnary->MAP_Mapper->MAP_KeyContext NAM_STRING_KEY")
|
||||
b.seek(pKeyContexts)
|
||||
print("\tMAP_Image->ANM_Skin->NAM_Dictionnary->MAP_Mapper->MAP_KeyContext NAM_STRING_KEY->MAP_BinSearchContext")
|
||||
read_int_and_print("\tSize", b)
|
||||
read_int_and_print("\tpCallback", b)
|
||||
read_int_and_print("\tIndex", b)
|
||||
read_int_and_print("\tTest", b)
|
||||
pLUTNAM_STRING_KEY = read_int_and_print("pLUT", b)
|
||||
read_int_and_print("Reserve", b)
|
||||
read_int_and_print("pData", b)
|
||||
|
||||
def showdictbyindex(i):
|
||||
assert(0 <= i < totalmappings)
|
||||
print("LUT NAM_STRING_KEY")
|
||||
b.seek(pLUTNAM_STRING_KEY)
|
||||
pind0_string = read_int_and_print("LUT NAM_STRING_KEY[0]", b)
|
||||
for _ in range(i):
|
||||
pind0_string = read_int_and_print("LUT NAM_STRING_KEY[0]", b)
|
||||
print("NAM_StringData")
|
||||
b.seek(pind0_string)
|
||||
print("BELOW IS CUSTOM vv")
|
||||
pptr = read_short_and_print("pPtr->ANM_Obj", b)
|
||||
pptr2 = read_short_and_print("pPtr2->ANM_Obj", b)
|
||||
val = read_int_and_print("Value", b)
|
||||
print(b.tell())
|
||||
print(read_string_until_none(b))
|
||||
|
||||
b.seek(val)
|
||||
read_int_and_print("ANM_Obj->Custom", b)
|
||||
read_int_and_print("ANM_Obj->Skin", b)
|
||||
read_int_and_print("ANM_Obj->ZeroCluster", b)
|
||||
total_vertices = read_int_and_print("ANM_Obj->TotalNumberOfVertices", b)
|
||||
num_clusters = read_int_and_print("ANM_Obj->NumberOfClusters", b)
|
||||
clusters = read_int_and_print("ANM_Obj->Clusters", b)
|
||||
|
||||
SEEN_VERTICES_INDEX = []
|
||||
|
||||
b.seek(clusters)
|
||||
for i in range(num_clusters):
|
||||
print("READING CLUSTER %s" % i)
|
||||
read_int_and_print("ANM_Cluster->Custom", b)
|
||||
read_int_and_print("ANM_Cluster->Obj", b)
|
||||
read_int_and_print("ANM_Cluster->Handle", b)
|
||||
print("ANM_Cluster->BoundingBox")
|
||||
print("ANM_BoundingBox->Box[0]")
|
||||
read_float_and_print("X", b)
|
||||
read_float_and_print("Y", b)
|
||||
read_float_and_print("Z", b)
|
||||
print("ANM_BoundingBox->Box[1]")
|
||||
read_float_and_print("X", b)
|
||||
read_float_and_print("Y", b)
|
||||
read_float_and_print("Z", b)
|
||||
numverts = read_int_and_print("ANM_Cluster->NumberOfVertices", b)
|
||||
|
||||
for _ in range(numverts):
|
||||
read_float_and_print("X", b)
|
||||
read_float_and_print("Y", b)
|
||||
read_float_and_print("Z", b)
|
||||
vindex = read_int_and_print("Index", b)
|
||||
# read_int_and_print("Weight", b)
|
||||
assert(vindex not in SEEN_VERTICES_INDEX)
|
||||
SEEN_VERTICES_INDEX.append(vindex)
|
||||
|
||||
read_int_and_print("Unk", b)
|
||||
read_int_and_print("Unk", b)
|
||||
print("%s vertices in this cluster (vs %s reported)" % (len(SEEN_VERTICES_INDEX), total_vertices))
|
||||
showdictbyindex(2)
|
||||
|
||||
|
||||
def main():
|
||||
with open("/home/tasty/Projects/gck-map-extract-objects/anm_skn/mc_l0.skn", "rb") as fp:
|
||||
# with open("/home/tasty/Projects/gck-map-extract-objects/anm_skn/dust.skn", "rb") as fp:
|
||||
ANM_Skin.parse(fp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user