diff --git a/NinjaBone.py b/NinjaBone.py index c90da8d..4f423b9 100644 --- a/NinjaBone.py +++ b/NinjaBone.py @@ -23,15 +23,19 @@ """ +import math + class NinjaBone: # { - def __init__(self, flag): - self.flag = flag + def __init__(self): + self.name = ""; self.localMatrix = self.identity() self.worldMatrix = self.identity() + self.parent = None + self.children = [] return None - def indentity(self): + def identity(self): return [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], @@ -63,12 +67,27 @@ class NinjaBone: # { self.localMatrix = tmp return None + def setName(self, num): + self.save() + self.name = 'bone_%03d' % num + return None + def save(self): for i in range(4): for k in range(4): self.worldMatrix[i][k] = self.localMatrix[i][k] return None + def setParent(self, parent): + self.parent = parent + return None + + def add(self, child): + child.multiplyWorld(self.worldMatrix) + self.children.append(child) + child.setParent(self) + return None + def setScale(self, vec3): tmp = self.identity() tmp[0][0] = vec3[0] @@ -126,3 +145,19 @@ class NinjaBone: # { self.multiplyLocal(tmp) return None + def apply(self, vec3): + vec3.append(1) + res = [0,0,0,0] + for i in range(4): + t = 0.0 + for j in range(4): + t = t + (vec3[j] * self.worldMatrix[j][i]) + res[i] = t + x = res[0] / res[3]; + y = res[1] / res[3]; + z = res[2] / res[3]; + vec3[0] = x + vec3[1] = y + vec3[2] = z + vec3.pop() + return None diff --git a/NinjaModel.py b/NinjaModel.py index 08a0afa..d4a515d 100644 --- a/NinjaModel.py +++ b/NinjaModel.py @@ -42,6 +42,12 @@ class NinjaModel: # { # Bone List self.bones = [] + #Vertex List + self.mat_list = [] + self.index_lookup = [ None ] * 5000 + self.vertex_list = [] + self.face_list = [] + return None # } @@ -64,53 +70,42 @@ class NinjaModel: # { len = struct.unpack('I', bytes)[0] pos = self.file.tell() + len self.pof = self.file.tell() - self.readNjcm() + self.readNjcm(None) self.file.seek(pos, 0) elif (bytes == 'NMDM') : print('Found Ninja Direct Motion') + # } + print(self.vertex_list) return None # } - def readNjtl(self): # { - + def readNjtl(self): pof = self.file.tell() - bytes = self.file.read(8) n = struct.unpack('II', bytes) - str_ofs = [] self.file.seek(n[0] + pof, 0) - for i in range(0, n[1]): # { + for i in range(0, n[1]): bytes = self.file.read(12) m = struct.unpack('III', bytes) str_ofs.append(m[0] + pof) - # } - for ofs in str_ofs: # { - + for ofs in str_ofs: str = '' self.file.seek(ofs, 0) - while 1: # { - ch = self.file.read(1) if(ch == '\0'): break str += ch - #} - self.tex_list.append(str) - - # } - return None - # } - def readNjcm(self, parentBone): # { + def readNjcm(self, parentBone): bytes = self.file.read(52) b = struct.unpack('IIfffiiifffII', bytes) @@ -135,14 +130,85 @@ class NinjaModel: # { if ( (flags & 0x01) == 0): self.bone.setPosition(pos) - self.bone.save() - if(model_ofs) { + num = len(self.bones) + self.bone.setName(num) + self.bones.append(self.bone) + + print(self.bone.name) + + if parentBone: + parentBone.add(self.bone) + + if model_ofs: self.file.seek(model_ofs + self.pof, 0) - } - + self.readModel() + + if child_ofs: + self.file.seek(child_ofs + self.pof, 0) + self.readNjcm(self.bone) + + if sibling_ofs: + self.file.seek(sibling_ofs + self.pof, 0) + self.readNjcm(parentBone) return None - # } + def readModel(self): + + bytes = self.file.read(24) + m = struct.unpack('IIffff', bytes) + + vertex_ofs = m[0] + chunk_ofs = m[1] + center = (m[2], m[3], m[4]) + radius = m[5] + + if vertex_ofs: + self.file.seek(vertex_ofs + self.pof, 0) + self.readVertexList() + + if chunk_ofs: + self.file.seek(chunk_ofs + self.pof, 0) + self.readChunkList() + + return None + + def readVertexList(self): + + print("Reading vertex list") + + bytes = self.file.read(8) + c = struct.unpack('BBHHH', bytes) + chunk_head = c[0] + chunk_flag = c[1] + chunk_len = c[2] + vertex_ofs = c[3] + vertex_count = c[4] + + if chunk_head != 41: + print("ERROR!!! NEW VERTEX TYPE!!!!") + + print("Chunk Head: %d" % chunk_head) + print("Chunk Flag: %d" % chunk_flag) + print("Vertex Ofs: %d" % vertex_ofs) + print("Vertex Count: %d" % vertex_count) + + for i in range(vertex_count): + + bytes = self.file.read(24) + v = struct.unpack('ffffff', bytes) + pos = [ v[0], v[1], v[2] ] + norm = [ v[3], v[4], v[5] ] + self.bone.apply(pos) + self.index_lookup[vertex_ofs] = len(self.vertex_list) + self.vertex_list.append({ + 'pos' : pos, + 'norm' : norm + }) + + return None + + def readChunkList(self): + + return None -# }