refactor anm
This commit is contained in:
parent
05f665e6ab
commit
7bbad9bb6e
267
anm.py
267
anm.py
@ -1,267 +1,16 @@
|
||||
from lib.fileutils import *
|
||||
import logging
|
||||
import sys
|
||||
from lib.skn_anm import *
|
||||
|
||||
|
||||
class MConsoleHandler(logging.StreamHandler):
|
||||
special_code = '[!n]'
|
||||
|
||||
def emit(self, record) -> None:
|
||||
record.msg = str(record.msg)
|
||||
if self.special_code in record.msg:
|
||||
record.msg = record.msg.replace(self.special_code, '')
|
||||
self.terminator = ''
|
||||
else:
|
||||
self.terminator = '\n'
|
||||
return super().emit(record)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
cs = MConsoleHandler(sys.stdout)
|
||||
fmt = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
|
||||
fmt = logging.Formatter("%(message)s")
|
||||
cs.setFormatter(fmt)
|
||||
logger.addHandler(cs)
|
||||
|
||||
NAM_FlagHasHandles = (1 << 0)
|
||||
NAM_FlagCaseInsensitive = (1 << 1)
|
||||
ANM_NODE_FLAG_POS_ANIMATED = (1 << 0)
|
||||
ANM_NODE_FLAG_ROT_ANIMATED = (1 << 1)
|
||||
ANM_NODE_FLAG_ROL_ANIMATED = (1 << 2)
|
||||
ANM_NODE_FLAG_SCL_ANIMATED = (1 << 3)
|
||||
ANM_NODE_FLAG_AFF_ANIMATED = (1 << 4)
|
||||
ANM_NODE_FLAG_USR_ANIMATED = (1 << 5)
|
||||
ANM_NODE_FLAG_ANIMATED = ((1 << 6) - 1)
|
||||
|
||||
|
||||
def printdebug(msg):
|
||||
logger.debug(msg)
|
||||
|
||||
|
||||
def printinfo(msg):
|
||||
logger.info(msg, )
|
||||
|
||||
|
||||
def tb(i):
|
||||
return 1 if i > 0 else 0
|
||||
|
||||
|
||||
def read_int_and_print(n, b):
|
||||
a = read_int(b)
|
||||
printdebug("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
def read_float_and_print(n, b):
|
||||
a = read_float(b)
|
||||
printdebug("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
def read_byte_and_print(n, b):
|
||||
a = read_byte(b)
|
||||
printdebug("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
def read_short_and_print(n, b):
|
||||
a = read_short(b)
|
||||
printdebug("%s=%s" % (n, a))
|
||||
return a
|
||||
|
||||
|
||||
class ANM_Anim:
|
||||
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):
|
||||
printinfo("Decoding %s" % b.name)
|
||||
|
||||
printdebug("MAP_Image")
|
||||
read_int_and_print("size", b)
|
||||
memgroupoffset = read_int_and_print("memgroupoffset", b)
|
||||
|
||||
b.seek(memgroupoffset)
|
||||
|
||||
printdebug("MAP_MemGroup")
|
||||
printdebug("\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)
|
||||
printdebug("=========")
|
||||
printdebug("ANM_Anim")
|
||||
read_int_and_print("pCustom", b)
|
||||
read_int_and_print("FileVersion", b)
|
||||
read_int_and_print("pImage", b)
|
||||
read_int_and_print("pMemGroup", b)
|
||||
starttime = read_int_and_print("StartTime", b)
|
||||
endtime = read_int_and_print("EndTime", b)
|
||||
ticksperframe = read_int_and_print("TicksPerFrame", b)
|
||||
framerate = read_int_and_print("FrameRate", b)
|
||||
tree = read_int_and_print("pTreeDictionary", b)
|
||||
defaultobj = read_int_and_print("pDefaultObjDictionary", b)
|
||||
numnodes = read_int_and_print("NumberOfNodes", b)
|
||||
printdebug("ANM_AnimExtra")
|
||||
read_int_and_print("ANM_AnimExtra->Stamp", b)
|
||||
read_int_and_print("ANM_AnimExtra->Flags", b)
|
||||
read_int_and_print("ANM_AnimExtra->Time1", b)
|
||||
read_int_and_print("ANM_AnimExtra->Stamp1", b)
|
||||
read_int_and_print("ANM_AnimExtra->Time2", b)
|
||||
read_int_and_print("ANM_AnimExtra->Stamp2", b)
|
||||
read_float_and_print("ANM_AnimExtra->Factor", b)
|
||||
read_int_and_print("ANM_AnimExtra->OtherAnim", b)
|
||||
name = read_string_until_none(b)
|
||||
printdebug(name)
|
||||
|
||||
printinfo("[%s] StartTime:%s EndTime:%s TicksPerFrame:%s FrameRate:%s NumNodes:%s" % (name, starttime, endtime, ticksperframe , framerate, numnodes))
|
||||
|
||||
printdebug("=========")
|
||||
|
||||
printdebug("ANM_Anim->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)
|
||||
printdebug("Flags: NAM_FlagHasHandles: %s, NAM_FlagCaseInsensitive: %s" % (flags & NAM_FlagHasHandles, flags & NAM_FlagCaseInsensitive))
|
||||
namehandle = read_short_and_print("NameHandle", b)
|
||||
|
||||
|
||||
printdebug("MAP_Image->ANM_Anim->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)
|
||||
|
||||
printdebug("MAP_Image->ANM_Anim->NAM_Dictionnary->MAP_Mapper->MAP_KeyContext NAM_STRING_KEY")
|
||||
b.seek(pKeyContexts)
|
||||
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)
|
||||
printdebug("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)
|
||||
printdebug("NAM_StringData")
|
||||
b.seek(pind0_string)
|
||||
read_int_and_print("pPtr->ANM_Obj", b)
|
||||
val = read_int_and_print("Value", b)
|
||||
printdebug(b.tell())
|
||||
nodename = read_string_until_none(b)
|
||||
printdebug(nodename)
|
||||
|
||||
b.seek(val)
|
||||
|
||||
read_int_and_print("ANM_Node->Custom", b)
|
||||
read_short_and_print("ANM_Node->Type", b)
|
||||
read_short_and_print("ANM_Node->XformType", b)
|
||||
nodeflags = read_int_and_print("ANM_Node->Flags", b)
|
||||
read_int_and_print("ANM_Node->pAnim", b)
|
||||
read_int_and_print("ANM_Node->pParent", b)
|
||||
read_int_and_print("ANM_Node->pTarget", b)
|
||||
read_int_and_print("ANM_Node->pUserCall", b)
|
||||
read_int_and_print("ANM_Node->pUserContext", b)
|
||||
stamp = read_int_and_print("ANM_Node->Stamp", b)
|
||||
printdebug("ANM_Node->Mat")
|
||||
read_int_and_print("GEO_Mat->Class", b)
|
||||
for _i in range(4):
|
||||
for _j in range(4):
|
||||
read_float_and_print("GEO_Mat->E", b)
|
||||
|
||||
printdebug("ANM_Node->Transform")
|
||||
transformtime = read_int_and_print("ANM_Transform->Time", b)
|
||||
printdebug("ANM_Transform->Affine")
|
||||
read_float_and_print("GEO_Affine->Trans[x]", b)
|
||||
read_float_and_print("GEO_Affine->Trans[y]", b)
|
||||
read_float_and_print("GEO_Affine->Trans[z]", b)
|
||||
read_float_and_print("GEO_Affine->Quat[x]", b)
|
||||
read_float_and_print("GEO_Affine->Quat[y]", b)
|
||||
read_float_and_print("GEO_Affine->Quat[z]", b)
|
||||
read_float_and_print("GEO_Affine->Quat[w]", b)
|
||||
read_float_and_print("GEO_Affine->Scale[x]", b)
|
||||
read_float_and_print("GEO_Affine->Scale[y]", b)
|
||||
read_float_and_print("GEO_Affine->Scale[z]", b)
|
||||
read_int_and_print("GEO_Affine->Class", b)
|
||||
|
||||
posKeys = read_int_and_print("ANM_Node->pPosKeys", b)
|
||||
rotKeys = read_int_and_print("ANM_Node->pRotKeys", b)
|
||||
sclKeys = read_int_and_print("ANM_Node->pSclKeys", b)
|
||||
|
||||
printinfo("\t[%s] Animated:%s[!n]" % (nodename, bool(nodeflags & ANM_NODE_FLAG_ANIMATED)))
|
||||
if nodeflags & ANM_NODE_FLAG_POS_ANIMATED:
|
||||
printinfo(" PosAnimated:True[!n]")
|
||||
if nodeflags & ANM_NODE_FLAG_ROT_ANIMATED:
|
||||
printinfo(" RotAnimated:True[!n]")
|
||||
if nodeflags & ANM_NODE_FLAG_ROL_ANIMATED:
|
||||
printinfo(" RolAnimated:True[!n]")
|
||||
if nodeflags & ANM_NODE_FLAG_SCL_ANIMATED:
|
||||
printinfo(" SclAnimated:True[!n]")
|
||||
if nodeflags & ANM_NODE_FLAG_AFF_ANIMATED:
|
||||
printinfo(" AffAnimated:True[!n]")
|
||||
if nodeflags & ANM_NODE_FLAG_USR_ANIMATED:
|
||||
printinfo(" UsrAnimated:True[!n]")
|
||||
printinfo("")
|
||||
|
||||
"""
|
||||
printinfo("\t[%s] Anim:%s Pos:%s Rot:%s Rol:%s Scl:%s Aff:%s Usr:%s" % (
|
||||
nodename, tb(nodeflags & ANM_NODE_FLAG_ANIMATED), tb(nodeflags & ANM_NODE_FLAG_POS_ANIMATED), tb(nodeflags & ANM_NODE_FLAG_ROT_ANIMATED),
|
||||
tb(nodeflags & ANM_NODE_FLAG_ROL_ANIMATED), tb(nodeflags & ANM_NODE_FLAG_SCL_ANIMATED), tb(nodeflags & ANM_NODE_FLAG_AFF_ANIMATED),
|
||||
tb(nodeflags & ANM_NODE_FLAG_USR_ANIMATED)))
|
||||
"""
|
||||
|
||||
if nodeflags & ANM_NODE_FLAG_POS_ANIMATED:
|
||||
b.seek(posKeys)
|
||||
read_byte_and_print("\t\tType", b)
|
||||
read_byte_and_print("\t\tORTBefore", b)
|
||||
read_byte_and_print("\t\tORTAfter", b)
|
||||
read_byte_and_print("\t\tFlags", b)
|
||||
read_int_and_print("\t\tpInterpolate", b)
|
||||
read_int_and_print("\t\tNumberOfKeys", b)
|
||||
read_int_and_print("\t\tpKeys", b)
|
||||
|
||||
for p in range(totalmappings):
|
||||
showdictbyindex(p)
|
||||
def read_skn(filepath) -> AnmAnim:
|
||||
with open(filepath, "rb") as fp:
|
||||
r = AnmFile.parse(fp, AnmAnim)
|
||||
return r
|
||||
|
||||
|
||||
def main():
|
||||
#with open("/home/tasty/Projects/gck-map-extract-objects/anm_skn/sm_book.anm", "rb") as fp:
|
||||
# with open("/home/tasty/Projects/gck-map-extract-objects/anm_skn/vp_hit.anm", "rb") as fp:
|
||||
with open("/home/tasty/Projects/gck-map-extract-objects/anm_skn/Mc_salute.anm", "rb") as fp:
|
||||
ANM_Anim.parse(fp)
|
||||
anm = read_skn("/home/tasty/Projects/gck-map-extract-objects/anm_skn/Mc_salute.anm")
|
||||
pprint(anm)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
284
lib/skn_anm.py
284
lib/skn_anm.py
@ -1,6 +1,12 @@
|
||||
from lib.fileutils import *
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Union
|
||||
import math
|
||||
import prettyprinter
|
||||
from prettyprinter import pprint
|
||||
|
||||
|
||||
prettyprinter.install_extras()
|
||||
|
||||
|
||||
NAM_FlagHasHandles = (1 << 0)
|
||||
@ -15,10 +21,29 @@ ANM_NODE_FLAG_ANIMATED = ((1 << 6) - 1)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Vec3Indexed:
|
||||
class Vec3:
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
|
||||
def distance(self, other: 'Vec3') -> float:
|
||||
return math.sqrt(math.pow(self.x - other.x, 2) + math.pow(self.y - other.y, 2) + math.pow(self.z - other.z, 2))
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
x = read_float_and_print("Vec3->x", b)
|
||||
y = read_float_and_print("Vec3->y", b)
|
||||
z = read_float_and_print("Vec3->z", b)
|
||||
if offset:
|
||||
b.seek(old)
|
||||
return cls(x=x, y=y, z=z)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Vec3Indexed(Vec3):
|
||||
index: int
|
||||
|
||||
@classmethod
|
||||
@ -36,27 +61,26 @@ class Vec3Indexed:
|
||||
|
||||
|
||||
@dataclass
|
||||
class Vec3:
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
class Vec4(Vec3):
|
||||
w: float
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
x = read_float_and_print("Vec3->x", b)
|
||||
y = read_float_and_print("Vec3->y", b)
|
||||
z = read_float_and_print("Vec3->z", b)
|
||||
x = read_float_and_print("Vec4->x", b)
|
||||
y = read_float_and_print("Vec4->y", b)
|
||||
z = read_float_and_print("Vec4->z", b)
|
||||
w = read_float_and_print("Vec4->w", b)
|
||||
if offset:
|
||||
b.seek(old)
|
||||
return cls(x=x, y=y, z=z)
|
||||
return cls(x=x, y=y, z=z, w=w)
|
||||
|
||||
|
||||
@dataclass
|
||||
class AnmObj:
|
||||
custom: int
|
||||
custom: int = field(repr=False)
|
||||
skin: int = field(repr=False)
|
||||
zero_cluster: int
|
||||
total_number_vertices: int
|
||||
@ -93,8 +117,8 @@ class AnmObj:
|
||||
@dataclass
|
||||
class AnmCluster:
|
||||
custom: int = field(repr=False)
|
||||
obj: Union[AnmObj, None]
|
||||
handle: int
|
||||
obj: Union[AnmObj, None] = field(repr=False)
|
||||
handle: int = field(repr=False)
|
||||
bounding_box: List[Vec3] = field(repr=False) # size 2
|
||||
num_vertices: int
|
||||
vertices: List[Vec3Indexed] = field(repr=False)
|
||||
@ -187,7 +211,233 @@ class NamDictionnary:
|
||||
read_int_and_print("Test", b)
|
||||
read_int_and_print("Test", b)
|
||||
bone_name = read_string_until_none_and_print("BoneName", b)
|
||||
r[str(i)] = {"RefCnt": refcnt, "Handle": handle, "BoneName": bone_name}
|
||||
r[str(i)] = {"BoneName": bone_name}
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
@dataclass
|
||||
class GeoMat4x4:
|
||||
m: List[float]
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
|
||||
m = []
|
||||
for _ in range(4):
|
||||
for _j in range(4):
|
||||
m.append(read_float(b))
|
||||
|
||||
r = cls(m=m)
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
@dataclass
|
||||
class GeoMat:
|
||||
mat_class: int
|
||||
s: GeoMat4x4
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
|
||||
mat_class = read_int(b)
|
||||
s = GeoMat4x4.create(b)
|
||||
|
||||
r = cls(mat_class=mat_class, s=s)
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
@dataclass
|
||||
class GeoAffine:
|
||||
transform: Vec3
|
||||
quat: Vec4
|
||||
scale: Vec3
|
||||
affine_class: int
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
|
||||
trans = Vec3.create(b)
|
||||
quat = Vec4.create(b)
|
||||
scale = Vec3.create(b)
|
||||
affine_class = read_int(b)
|
||||
|
||||
r = cls(transform=trans, quat=quat, scale=scale, affine_class=affine_class)
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
@dataclass
|
||||
class AnmTransform:
|
||||
time: int
|
||||
affine: GeoAffine
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
|
||||
time = read_int(b)
|
||||
affine = GeoAffine.create(b)
|
||||
|
||||
r = cls(time=time, affine=affine)
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
@dataclass
|
||||
class AnmNode:
|
||||
custom: int
|
||||
node_type: int
|
||||
x_form_type: int
|
||||
flags: int
|
||||
p_anim: int
|
||||
p_parent: int
|
||||
p_target: int
|
||||
p_usercall: int
|
||||
p_usercontext: int
|
||||
stamp: int
|
||||
geo_mat: GeoMat
|
||||
transform: AnmTransform
|
||||
pos_keys: int
|
||||
rot_keys: int
|
||||
scl_keys: int
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
|
||||
custom = read_int_and_print("ANM_Node->Custom", b)
|
||||
node_type = read_short_and_print("ANM_Node->Type", b)
|
||||
x_form_type = read_short_and_print("ANM_Node->XformType", b)
|
||||
flags = read_int_and_print("ANM_Node->Flags", b)
|
||||
p_anim = read_int_and_print("ANM_Node->pAnim", b)
|
||||
p_parent = read_int_and_print("ANM_Node->pParent", b)
|
||||
p_target = read_int_and_print("ANM_Node->pTarget", b)
|
||||
p_usercall = read_int_and_print("ANM_Node->pUserCall", b)
|
||||
p_usercontext = read_int_and_print("ANM_Node->pUserContext", b)
|
||||
stamp = read_int_and_print("ANM_Node->Stamp", b)
|
||||
geo_mat = GeoMat.create(b)
|
||||
transform = AnmTransform.create(b)
|
||||
pos_keys = read_int_and_print("ANM_Node->pPosKeys", b)
|
||||
rot_keys = read_int_and_print("ANM_Node->pRotKeys", b)
|
||||
scl_keys = read_int_and_print("ANM_Node->pSclKeys", b)
|
||||
|
||||
"""
|
||||
if nodeflags & ANM_NODE_FLAG_POS_ANIMATED:
|
||||
b.seek(posKeys)
|
||||
read_byte_and_print("\t\tType", b)
|
||||
read_byte_and_print("\t\tORTBefore", b)
|
||||
read_byte_and_print("\t\tORTAfter", b)
|
||||
read_byte_and_print("\t\tFlags", b)
|
||||
read_int_and_print("\t\tpInterpolate", b)
|
||||
read_int_and_print("\t\tNumberOfKeys", b)
|
||||
read_int_and_print("\t\tpKeys", b)
|
||||
"""
|
||||
|
||||
r = cls(custom=custom, node_type=node_type, x_form_type=x_form_type, flags=flags, p_anim=p_anim,
|
||||
p_parent=p_parent, p_target=p_target, p_usercall=p_usercall, p_usercontext=p_usercontext,
|
||||
stamp=stamp, geo_mat=geo_mat, transform=transform, pos_keys=pos_keys, rot_keys=rot_keys,
|
||||
scl_keys=scl_keys)
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
@dataclass
|
||||
class AnmAnim:
|
||||
custom: int
|
||||
fileversion: int
|
||||
image: int
|
||||
memgroup: int
|
||||
start_time: int
|
||||
end_time: int
|
||||
ticks_per_frame: int
|
||||
framerate: int
|
||||
tree_dictionnary: dict
|
||||
default_obj_dictionnary: dict
|
||||
num_nodes: int
|
||||
|
||||
extra_stamp: int
|
||||
extra_flags: int
|
||||
|
||||
extra_time1: int
|
||||
extra_stamp1: int
|
||||
|
||||
extra_time2: int
|
||||
extra_stamp2: int
|
||||
|
||||
extra_factor: float
|
||||
extra_other_anim: int
|
||||
name: str
|
||||
|
||||
@classmethod
|
||||
def create(cls, b, offset=None):
|
||||
old = b.tell()
|
||||
if offset:
|
||||
b.seek(offset)
|
||||
|
||||
custom = read_int_and_print("ANM_Anim->Custom", b)
|
||||
version = read_int_and_print("ANM_Anim->FileVersion", b)
|
||||
image = read_int_and_print("ANM_Anim->pImage", b)
|
||||
memgroup = read_int_and_print("ANM_Anim->pMemGroup", b)
|
||||
|
||||
start_time = read_int_and_print("ANM_Anim->StartTime", b)
|
||||
end_time = read_int_and_print("ANM_Anim->EndTime", b)
|
||||
ticks_per_frame = read_int_and_print("TicksPerFrame", b)
|
||||
framerate = read_int_and_print("FrameRate", b)
|
||||
treedict = read_int_and_print("pTreeDictionary", b)
|
||||
defaultobjdict = read_int_and_print("pDefaultObjDictionary", b)
|
||||
num_nodes = read_int_and_print("NumberOfNodes", b)
|
||||
stamp = read_int_and_print("ANM_AnimExtra->Stamp", b)
|
||||
flags = read_int_and_print("ANM_AnimExtra->Flags", b)
|
||||
time1 = read_int_and_print("ANM_AnimExtra->Time1", b)
|
||||
stamp1 = read_int_and_print("ANM_AnimExtra->Stamp1", b)
|
||||
time2 = read_int_and_print("ANM_AnimExtra->Time2", b)
|
||||
stamp2 = read_int_and_print("ANM_AnimExtra->Stamp2", b)
|
||||
factor = read_float_and_print("ANM_AnimExtra->Factor", b)
|
||||
otheranim = read_int_and_print("ANM_AnimExtra->OtherAnim", b)
|
||||
name = read_string_until_none(b)
|
||||
|
||||
treedict = NamDictionnary.create(b, AnmNode, depth=2, offset=treedict)
|
||||
defaultobjdict = NamDictionnary.create(b, AnmNode, offset=defaultobjdict)
|
||||
|
||||
r = cls(custom=custom, fileversion=version, image=image, memgroup=memgroup, start_time=start_time,
|
||||
end_time=end_time, ticks_per_frame=ticks_per_frame, framerate=framerate, tree_dictionnary=treedict,
|
||||
default_obj_dictionnary=defaultobjdict, num_nodes=num_nodes, extra_stamp=stamp, extra_flags=flags,
|
||||
extra_time1=time1, extra_stamp1=stamp1, extra_time2=time2, extra_stamp2=stamp2, extra_factor=factor,
|
||||
extra_other_anim=otheranim, name=name)
|
||||
|
||||
if offset:
|
||||
b.seek(old)
|
||||
@ -201,9 +451,9 @@ class AnmSkin:
|
||||
file_version: int
|
||||
image: int
|
||||
memgroup: int
|
||||
node_dictionnary: List[List]
|
||||
tree_dictionnary: List[List[AnmObj]]
|
||||
default_obj_dictionnary: List[AnmObj]
|
||||
node_dictionnary: dict
|
||||
tree_dictionnary: dict
|
||||
default_obj_dictionnary: dict
|
||||
total_number_trees: int
|
||||
total_number_objs: int
|
||||
total_number_clusters: int
|
||||
@ -239,7 +489,7 @@ class AnmSkin:
|
||||
treedict = NamDictionnary.create(b, AnmObj, depth=2, offset=tree)
|
||||
defaultobjdict = NamDictionnary.create(b, AnmObj, offset=defaultobj)
|
||||
|
||||
AnmSkin.link(nodedict, defaultobjdict)
|
||||
# AnmSkin.link(nodedict, defaultobjdict)
|
||||
r = cls(custom=custom, file_version=version, image=image, memgroup=memgroup, node_dictionnary=nodedict, tree_dictionnary=treedict, default_obj_dictionnary=defaultobjdict, total_number_trees=num_trees, total_number_objs=num_objs, total_number_clusters=num_clusters, name=name)
|
||||
|
||||
if offset:
|
||||
|
21
skn.py
21
skn.py
@ -1,18 +1,27 @@
|
||||
from lib.skn_anm import *
|
||||
|
||||
|
||||
def read_skn(filepath):
|
||||
def read_skn(filepath) -> AnmSkin:
|
||||
with open(filepath, "rb") as fp:
|
||||
r = AnmFile.parse(fp, AnmSkin)
|
||||
print(r)
|
||||
return r
|
||||
|
||||
|
||||
def main():
|
||||
f = ["/home/tasty/Projects/gck-map-extract-objects/anm_skn/mc_l0.skn",
|
||||
"/home/tasty/Projects/gck-map-extract-objects/anm_skn/rp_l0.skn",
|
||||
"/home/tasty/Projects/gck-map-extract-objects/anm_skn/kb_l0.skn"]
|
||||
f = ["/home/tasty/Projects/gck-map-extract-objects/anm_skn/rp_l0.skn"]
|
||||
my_vertex = Vec3(-0.927200, 0.099500, 3.108000)
|
||||
mini_dist_v = Vec3(0, 0, 0)
|
||||
for p in f:
|
||||
read_skn(p)
|
||||
skn = read_skn(p)
|
||||
pprint(skn.default_obj_dictionnary)
|
||||
pprint(skn.node_dictionnary)
|
||||
for obj_name, obj in skn.default_obj_dictionnary.items():
|
||||
for cluster in obj.clusters:
|
||||
for vertex in cluster.vertices:
|
||||
if vertex.distance(my_vertex) < mini_dist_v.distance(my_vertex):
|
||||
mini_dist_v = vertex
|
||||
|
||||
print("%s: dist=%s" % (mini_dist_v, mini_dist_v.distance(my_vertex)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user