quats
This commit is contained in:
parent
45a58a1eee
commit
1d3e6372e5
240
Mat4.py
240
Mat4.py
@ -26,113 +26,165 @@ import math
|
||||
|
||||
class Mat4:
|
||||
|
||||
#constructor
|
||||
def __init__(self):
|
||||
self.mtx = self.identity()
|
||||
#constructor
|
||||
def __init__(self):
|
||||
self.mtx = self.identity()
|
||||
|
||||
# return matrix
|
||||
def getMatrix(self):
|
||||
return self.mtx
|
||||
# return matrix
|
||||
def getMatrix(self):
|
||||
return self.mtx
|
||||
|
||||
# create identity
|
||||
def identity(self):
|
||||
return [
|
||||
[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 1]
|
||||
]
|
||||
# create identity
|
||||
def identity(self):
|
||||
return [
|
||||
[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 1]
|
||||
]
|
||||
|
||||
# mutliply by 4x4 matrix
|
||||
def multiply(self, factor):
|
||||
tmp = self.identity()
|
||||
# mutliply by 4x4 matrix
|
||||
def multiply(self, factor):
|
||||
tmp = self.identity()
|
||||
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
t = 0.0
|
||||
for k in range(4):
|
||||
t = t + (self.mtx[i][k] * factor[k][j])
|
||||
tmp[i][j] = t
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
t = 0.0
|
||||
for k in range(4):
|
||||
t = t + (self.mtx[i][k] * factor[k][j])
|
||||
tmp[i][j] = t
|
||||
|
||||
self.mtx = tmp
|
||||
self.mtx = tmp
|
||||
|
||||
# apply matrix to vec3
|
||||
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.mtx[j][i])
|
||||
res[i] = t
|
||||
x = res[0] / res[3];
|
||||
y = res[1] / res[3];
|
||||
z = res[2] / res[3];
|
||||
return [x, y, z]
|
||||
# apply matrix to vec3
|
||||
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.mtx[j][i])
|
||||
res[i] = t
|
||||
x = res[0] / res[3];
|
||||
y = res[1] / res[3];
|
||||
z = res[2] / res[3];
|
||||
return [x, y, z]
|
||||
|
||||
# scale by vec3
|
||||
def scale(self, vec3):
|
||||
tmp = self.identity()
|
||||
# x
|
||||
tmp[0][0] = vec3[0]
|
||||
# y
|
||||
tmp[1][1] = vec3[1]
|
||||
# z
|
||||
tmp[2][2] = vec3[2]
|
||||
self.multiply(tmp)
|
||||
# scale by vec3
|
||||
def scale(self, vec3):
|
||||
tmp = self.identity()
|
||||
# x
|
||||
tmp[0][0] = vec3[0]
|
||||
# y
|
||||
tmp[1][1] = vec3[1]
|
||||
# z
|
||||
tmp[2][2] = vec3[2]
|
||||
self.multiply(tmp)
|
||||
|
||||
# translate by vec3
|
||||
def translate(self, vec3):
|
||||
tmp = self.identity()
|
||||
# x
|
||||
tmp[3][0] = vec3[0]
|
||||
# y
|
||||
tmp[3][1] = vec3[1]
|
||||
# z
|
||||
tmp[3][2] = vec3[2]
|
||||
self.multiply(tmp)
|
||||
# translate by vec3
|
||||
def translate(self, vec3):
|
||||
tmp = self.identity()
|
||||
# x
|
||||
tmp[3][0] = vec3[0]
|
||||
# y
|
||||
tmp[3][1] = vec3[1]
|
||||
# z
|
||||
tmp[3][2] = vec3[2]
|
||||
self.multiply(tmp)
|
||||
|
||||
# rotate by vec3
|
||||
def rotate(self, vec3, zxy_order = False):
|
||||
# rotate by vec3
|
||||
def rotate(self, vec3):
|
||||
|
||||
if zxy_order:
|
||||
z = vec3[0]
|
||||
x = vec3[1]
|
||||
y = vec3[2]
|
||||
else:
|
||||
x = vec3[0]
|
||||
y = vec3[1]
|
||||
z = vec3[2]
|
||||
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.multiply(tmp)
|
||||
# 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.multiply(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.multiply(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.multiply(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.multiply(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.multiply(tmp)
|
||||
|
||||
def toQuat(self):
|
||||
|
||||
m11 = self.mtx[0][0]
|
||||
m21 = self.mtx[1][0]
|
||||
m31 = self.mtx[2][0]
|
||||
|
||||
m12 = self.mtx[0][1]
|
||||
m22 = self.mtx[1][1]
|
||||
m32 = self.mtx[2][1]
|
||||
|
||||
m13 = self.mtx[0][2]
|
||||
m23 = self.mtx[1][2]
|
||||
m33 = self.mtx[2][2]
|
||||
|
||||
trace = m11 + m22 + m33;
|
||||
|
||||
x = 0
|
||||
y = 0
|
||||
z = 0
|
||||
w = 1
|
||||
|
||||
if (trace > 0):
|
||||
|
||||
s = 0.5 / math.sqrt( trace + 1.0 )
|
||||
w = 0.25 / s
|
||||
x = ( m32 - m23 ) * s
|
||||
y = ( m13 - m31 ) * s
|
||||
z = ( m21 - m12 ) * s
|
||||
|
||||
elif ( m11 > m22 and m11 > m33 ):
|
||||
|
||||
s = 2.0 * math.sqrt( 1.0 + m11 - m22 - m33 )
|
||||
w = ( m32 - m23 ) / s
|
||||
x = 0.25 * s
|
||||
y = ( m12 + m21 ) / s
|
||||
z = ( m13 + m31 ) / s
|
||||
|
||||
elif (m22 > m33) :
|
||||
|
||||
s = 2.0 * math.sqrt( 1.0 + m22 - m11 - m33 )
|
||||
|
||||
w = ( m13 - m31 ) / s
|
||||
x = ( m12 + m21 ) / s
|
||||
y = 0.25 * s
|
||||
z = ( m23 + m32 ) / s
|
||||
|
||||
else:
|
||||
|
||||
s = 2.0 * math.sqrt( 1.0 + m33 - m11 - m22 )
|
||||
|
||||
w = ( m21 - m12 ) / s
|
||||
x = ( m13 + m31 ) / s
|
||||
y = ( m23 + m32 ) / s
|
||||
z = 0.25 * s
|
||||
|
||||
return [x, y, z, w]
|
||||
|
||||
#==============================================================
|
||||
"""
|
||||
|
34
NinjaBone.py
34
NinjaBone.py
@ -37,6 +37,9 @@ class NinjaBone: # {
|
||||
self.world = Mat4()
|
||||
self.parent = None
|
||||
self.children = []
|
||||
self.rotation = [ 0, 0, 0 ]
|
||||
self.position = [ 0, 0, 0 ]
|
||||
self.scale = [ 1, 1, 1]
|
||||
return None
|
||||
|
||||
def getIndex(self):
|
||||
@ -45,6 +48,15 @@ class NinjaBone: # {
|
||||
def getWorld(self):
|
||||
return self.world.mtx
|
||||
|
||||
def getScale(self):
|
||||
return self.scale
|
||||
|
||||
def getPosition(self):
|
||||
return self.position
|
||||
|
||||
def getRotation(self):
|
||||
return self.rotation
|
||||
|
||||
def setName(self, num):
|
||||
self.index = num
|
||||
self.name = 'bone_%03d' % num
|
||||
@ -62,16 +74,31 @@ class NinjaBone: # {
|
||||
return None
|
||||
|
||||
def setScale(self, vec3):
|
||||
self.scale = vec3
|
||||
self.local.scale(vec3)
|
||||
self.world.scale(vec3)
|
||||
return None
|
||||
|
||||
def setRotation(self, vec3, zxy_order):
|
||||
self.local.rotate(vec3, zxy_order)
|
||||
self.world.rotate(vec3, zxy_order)
|
||||
def setRotation(self, vec3, zxy_order = False):
|
||||
|
||||
if zxy_order:
|
||||
z = vec3[0]
|
||||
x = vec3[1]
|
||||
y = vec3[2]
|
||||
else:
|
||||
x = vec3[0]
|
||||
y = vec3[1]
|
||||
z = vec3[2]
|
||||
|
||||
rot = [ x, y, z ]
|
||||
self.rotation = rot
|
||||
|
||||
self.local.rotate(vec3)
|
||||
self.world.rotate(vec3)
|
||||
return None
|
||||
|
||||
def setPosition(self, vec3):
|
||||
self.position = vec3
|
||||
self.local.translate(vec3)
|
||||
self.world.translate(vec3)
|
||||
return None
|
||||
@ -80,7 +107,6 @@ class NinjaBone: # {
|
||||
return self.world.apply(vec3)
|
||||
|
||||
def createDmfEntry(self, file):
|
||||
|
||||
# 0x00 Name
|
||||
name = self.name
|
||||
while len(name) < 0x20:
|
||||
|
@ -433,6 +433,7 @@ class NinjaModel:
|
||||
'rot' : p[2] & 0x02,
|
||||
'scl' : p[2] & 0x04
|
||||
}
|
||||
|
||||
factor_count = p[3] & 0x03
|
||||
spline_interpolation = p[3] & 0x40
|
||||
user_function_interpolation = p[3] & 0x80
|
||||
@ -443,22 +444,12 @@ class NinjaModel:
|
||||
anim.setSkeleton(self.bones)
|
||||
self.anim_list.append(anim)
|
||||
|
||||
print("READING ANIMTION!!!!")
|
||||
print(motion_type)
|
||||
|
||||
print("FRAME COUNT: %d" % frame_count)
|
||||
print("Factor Count %d" % factor_count)
|
||||
print("Spline Function %d" % spline_interpolation)
|
||||
|
||||
# Read Motion Table
|
||||
anim_vals = []
|
||||
|
||||
print("Table Offset: 0x%08x" % table_ofs)
|
||||
self.file.seek(table_ofs, 0)
|
||||
for i in range(len(self.bones)):
|
||||
|
||||
print("Current Offset: 0x%08x" % self.file.tell())
|
||||
|
||||
entry = {
|
||||
'bone_index' : i,
|
||||
'pos_ofs' : 0,
|
||||
@ -496,13 +487,13 @@ class NinjaModel:
|
||||
bytes = self.file.read(4)
|
||||
p = struct.unpack('I', bytes)
|
||||
entry['scl_num'] = p[0]
|
||||
|
||||
anim_vals.append(entry)
|
||||
|
||||
c = 2 * 3.141592 / 0x10000;
|
||||
for entry in anim_vals:
|
||||
|
||||
|
||||
boneIndex = entry['bone_index']
|
||||
print("Bone Index: %d" % boneIndex)
|
||||
|
||||
self.file.seek(entry['pos_ofs'], 0)
|
||||
for i in range(entry['pos_num']):
|
||||
@ -514,8 +505,8 @@ class NinjaModel:
|
||||
|
||||
self.file.seek(entry['rot_ofs'], 0)
|
||||
for i in range(entry['rot_num']):
|
||||
bytes = self.file.read(16)
|
||||
p = struct.unpack('Ifff', bytes)
|
||||
bytes = self.file.read(8)
|
||||
p = struct.unpack('Hhhh', bytes)
|
||||
frame = p[0]
|
||||
vec3 = [ p[1]*c, p[2]*c, p[3]*c ]
|
||||
anim.appendKeyFrame(boneIndex, frame, vec3, 'rot')
|
||||
@ -527,7 +518,7 @@ class NinjaModel:
|
||||
frame = p[0]
|
||||
vec3 = [ p[1], p[2], p[3] ]
|
||||
anim.appendKeyFrame(boneIndex, frame, vec3, 'scl')
|
||||
|
||||
anim.save(boneIndex)
|
||||
return None
|
||||
|
||||
def export(self):
|
||||
|
@ -42,7 +42,7 @@ class NinjaMotion:
|
||||
return None
|
||||
|
||||
def setSkeleton(self, bones):
|
||||
self.seleton = bones
|
||||
self.skeleton = bones
|
||||
for i in range(len(bones)):
|
||||
self.keyFrames.append([])
|
||||
return None
|
||||
@ -67,5 +67,50 @@ class NinjaMotion:
|
||||
|
||||
keyFrames.append(keyFrame)
|
||||
return None
|
||||
|
||||
def save(self, boneIndex):
|
||||
|
||||
bone = self.skeleton[boneIndex]
|
||||
keyFrames = self.keyFrames[boneIndex]
|
||||
|
||||
if len(keyFrames) == 0:
|
||||
keyFrames.append({
|
||||
'frame' : 0
|
||||
})
|
||||
keyFrames.append({
|
||||
'frame' : self.frames - 1
|
||||
})
|
||||
|
||||
if 'scl' not in keyFrames[0].keys():
|
||||
keyFrames[0]['scl'] = bone.getScale()
|
||||
|
||||
if 'pos' not in keyFrames[0].keys():
|
||||
keyFrames[0]['pos'] = bone.getPosition()
|
||||
|
||||
if 'rot' not in keyFrames[0].keys():
|
||||
keyFrames[0]['rot'] = bone.getRotation()
|
||||
|
||||
lastIndex = len(keyFrames) - 1
|
||||
|
||||
if 'scl' not in keyFrames[lastIndex].keys():
|
||||
keyFrames[lastIndex]['scl'] = bone.getScale()
|
||||
|
||||
if 'pos' not in keyFrames[lastIndex].keys():
|
||||
keyFrames[lastIndex]['pos'] = bone.getPosition()
|
||||
|
||||
if 'rot' not in keyFrames[lastIndex].keys():
|
||||
keyFrames[lastIndex]['rot'] = bone.getRotation()
|
||||
|
||||
for keyFrame in keyFrames:
|
||||
|
||||
if 'rot' not in keyFrame.keys():
|
||||
continue
|
||||
|
||||
mat4 = Mat4()
|
||||
mat4.rotate(keyFrame['rot'])
|
||||
keyFrame['quat'] = mat4.toQuat()
|
||||
print(keyFrame['quat'])
|
||||
|
||||
|
||||
return None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user