bone format
This commit is contained in:
parent
76c91020b1
commit
f5dfc32779
127
NinjaBone.py
127
NinjaBone.py
@ -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)
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user