bone format

This commit is contained in:
Benjamin Collins 2020-08-20 07:30:50 +09:00
parent 76c91020b1
commit f5dfc32779
3 changed files with 26 additions and 129 deletions

View File

@ -24,143 +24,56 @@
"""
import math
from Mat4 import Mat4
class NinjaBone: # {
def __init__(self):
self.name = "";
self.localMatrix = self.identity()
self.worldMatrix = self.identity()
self.index = -1
self.parentIndex = -1
self.local = Mat4()
self.world = Mat4()
self.parent = None
self.children = []
return None
def identity(self):
return [
[ 1, 0, 0, 0 ],
[ 0, 1, 0, 0 ],
[ 0, 0, 1, 0 ],
[ 0, 0, 0, 1 ]
]
def getIndex(self):
return self.index
def multiply(self, a, b):
tmp = self.identity()
for i in range(4):
for j in range(4):
t = 0.0
for k in range(4):
t = t + (b[i][k] * a[k][j])
tmp[i][j] = t
return tmp
def multiplyLocal(self, factor):
a = self.localMatrix
b = factor
tmp = self.multiply(a, b)
self.localMatrix = tmp
return None
def multiplyWorld(self, factor):
a = self.worldMatrix
b = factor
tmp = self.multiply(a, b)
self.worldMatrix = tmp
return None
def getWorld(self):
return self.world.mtx
def setName(self, num):
self.save()
self.id = num
self.index = num
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
self.parentIndex = parent.getIndex()
self.world.multiply(parent.getWorld())
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]
tmp[1][1] = vec3[1]
tmp[2][2] = vec3[2]
self.multiplyLocal(tmp)
self.local.scale(vec3)
self.world.scale(vec3)
return None
def setRotation(self, vec3, zxy_order):
if zxy_order:
z = vec3[0]
x = vec3[1]
y = vec3[2]
else:
x = vec3[0]
y = vec3[1]
z = vec3[2]
# rotate x-axis
tmp = self.identity()
c = math.cos(x)
s = math.sin(x)
tmp[1][1] = c;
tmp[1][2] = s;
tmp[2][1] = -s;
tmp[2][2] = c;
self.multiplyLocal(tmp)
# rotate y-axis
tmp = self.identity()
c = math.cos(y)
s = math.sin(y)
tmp[0][0] = c;
tmp[0][2] = -s;
tmp[2][0] = s;
tmp[2][2] = c;
self.multiplyLocal(tmp)
# rotate z-axis
tmp = self.identity()
c = math.cos(z)
s = math.sin(z)
tmp[0][0] = c;
tmp[0][1] = s;
tmp[1][0] = -s;
tmp[1][1] = c;
self.multiplyLocal(tmp)
self.local.rotate(vec3, zxy_order)
self.world.rotate(vec3, zxy_order)
return None
def setPosition(self, vec3):
tmp = self.identity()
tmp[0][0] = vec3[0]
tmp[1][1] = vec3[1]
tmp[2][2] = vec3[2]
self.multiplyLocal(tmp)
self.local.translate(vec3)
self.world.translate(vec3)
return None
def apply(self, vertex):
vec3 = [
vertex.pos['x'],
vertex.pos['y'],
vertex.pos['z'],
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]
vertex.setPosition(x, y, z)
return vertex
def apply(self, vec3):
return self.world.apply(vec3)

View File

@ -32,7 +32,6 @@ from NinjaMaterial import NinjaMaterial
from NinjaVertex import NinjaVertex
from NinjaFace import NinjaFace
from NinjaBone import NinjaBone
from matrix_44 import Mat4
class NinjaModel: # {
@ -88,7 +87,7 @@ class NinjaModel: # {
len = struct.unpack('I', bytes)[0]
pos = self.file.tell() + len
self.pof = self.file.tell()
self.readNjcm(None, None)
self.readNjcm(None)
self.file.seek(pos, 0)
elif (bytes == b'NMDM') :
print('Found Ninja Direct Motion')
@ -118,7 +117,7 @@ class NinjaModel: # {
name += ch.decode()
return None
def readNjcm(self, parentBone, ptx):
def readNjcm(self, parentBone):
bytes = self.file.read(52)
b = struct.unpack('IIfffiiifffII', bytes)
@ -144,25 +143,15 @@ class NinjaModel: # {
print("Flags: %d" % flags);
print(pos)
mtx = Mat4()
if ( (flags & 0x04) == 0):
mtx.scale(scl)
self.bone.setScale(scl)
if ( (flags & 0x02) == 0):
mtx.rotate(rot)
self.bone.setRotation(rot, flags & 0x20)
if ( (flags & 0x01) == 0):
mtx.translate(pos)
self.bone.setPosition(pos)
if ptx is not None:
mtx.multiply(ptx.getMatrix())
self.mtx = mtx
if parentBone:
parentBone.add(self.bone)
@ -173,11 +162,11 @@ class NinjaModel: # {
if child_ofs:
self.file.seek(child_ofs + self.pof, 0)
self.readNjcm(self.bone, mtx)
self.readNjcm(self.bone)
if sibling_ofs:
self.file.seek(sibling_ofs + self.pof, 0)
self.readNjcm(parentBone, ptx)
self.readNjcm(parentBone)
return None
@ -220,16 +209,12 @@ class NinjaModel: # {
v = struct.unpack('ffffff', bytes)
pos = [ v[0], v[1], v[2] ]
pos = self.mtx.apply(pos)
pos = self.bone.apply(pos)
vertex = NinjaVertex()
vertex.setPosition( pos[0], pos[1], pos[2] )
vertex.setNormal( v[3], v[4], v[5] )
vertex.setSkinWeight(0, self.bone.id, 1.0)
#print("vertex in: %s" % vertex)
#vertex = self.bone.apply(vertex)
#print("vertex out: %s" % vertex)
vertex.setSkinWeight(0, self.bone.index, 1.0)
while len(self.index_lookup) < vertex_ofs + 1:
self.index_lookup.append(None)
@ -249,7 +234,6 @@ class NinjaModel: # {
print("End Chunk Head: %d" % chunk_head)
print("End Chunk Flag: %d" % chunk_flag)
return None
def readChunkList(self):