forked from niacdoial/blemd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Matrix44.py
137 lines (107 loc) · 4.78 KB
/
Matrix44.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#! /usr/bin/python3
from mathutils import Matrix, Vector, Euler
from .Evp1 import *
def Mad(r, m, f):
for j in range(3):
for k in range(4):
r[j][k] += f * m[j][k]
return r
def LocalMatrix(jnt, i, use_scale):
f = jnt.frames[i]
scale_vector = Vector((f.sx, f.sy, f.sz))
sx = Matrix.Scale(scale_vector.x, 4, Vector((1, 0, 0)))
sy = Matrix.Scale(scale_vector.y, 4, Vector((0, 1, 0)))
sz = Matrix.Scale(scale_vector.z, 4, Vector((0, 0, 1)))
# TODO: I don't know which of these two return values are the right ones
# (if it's the first, then what is scale used for at all?)
# looks wrong in certain circumstances...
if use_scale:
return f.matrix @ sz @ sy @ sx # this looks a bit better with mario's bottle_in animation
else:
return f.matrix # this looks better with vf_064l.bdl (from zelda)
def FrameMatrix(f):
t = Matrix.Translation(Vector((f.t.x, f.t.y, f.t.z)))
r = Euler((f.rx, f.ry, f.rz), 'XYZ').to_matrix().to_4x4()
res = t@r
return res
def updateMatrix(frame, parentmatrix):
return parentmatrix@FrameMatrix(frame)
def updateMatrixTable(evp, drw, jnt, currPacket, multiMatrixTable, matrixTable, isMatrixWeighted, use_scale):
global dataholder
for n in range(len(currPacket.matrixTable)):
index = currPacket.matrixTable[n]
# if index is 0xffff, use the last packet's data.
if index != 0xffff: # 0xffff this means keep old entry
if drw.isWeighted[index]:
# --TODO: the EVP1 data should probably be used here,
# --figure out how this works (most files look ok
# --without this, but models/ji.bdl is for example
# --broken this way)
# --matrixTable[n] = def_;
# --the following _does_ the right thing...it looks
# --ok for all files, but i don't understand why :-P
# --(and this code is slow as hell, so TODO: fix this)
# --NO idea if this is right this way...
m = Matrix()
m.zero() # zero-ifiy m
mm = evp.weightedIndices[drw.data[index]] # -- get MultiMatrix
singleMultiMatrixEntry = MultiMatrix()
singleMultiMatrixEntry.weights = mm.weights.copy()
singleMultiMatrixEntry.indices = mm.indices.copy()
for r in range(len(mm.weights)):
# did before.
#singleMultiMatrixEntry.weights[r] = mm.weights[r]
#singleMultiMatrixEntry.indices[r] = mm.indices[r]
# corrected (r]+1) # -- (drw.data[mm.indices[r]+ 1] + 1) -- bone index
# -- messageBox (mm.indices as string)
# --if (mm.indices[r] != 0) then
# -- (
sm1 = evp.matrices[mm.indices[r]] # -- const Matrix44f
sm2 = LocalMatrix(jnt, mm.indices[r], use_scale)
sm3 = sm2@sm1
# )
# else
# -- sm3 = (LocalMatrix mm.indices[r] )
Mad(m, sm3, mm.weights[r])
while len(multiMatrixTable) <= n:
multiMatrixTable.append(None)
multiMatrixTable[n] = singleMultiMatrixEntry
m[3][3] = 1 # fixed
while len(matrixTable) <= n:
matrixTable.append(None)
matrixTable[n] = m
while len(isMatrixWeighted) <= n:
isMatrixWeighted.append(None)
isMatrixWeighted[n] = True
else:
while len(matrixTable) <= n:
matrixTable.append(None)
while len(isMatrixWeighted) <= n:
isMatrixWeighted.append(None)
matrixTable[n] = jnt.frames[drw.data[index]].matrix
isMatrixWeighted[n] = False
singleMultiMatrixEntry = MultiMatrix()
singleMultiMatrixEntry.weights = [1]
singleMultiMatrixEntry.indices = [drw.data[index]]
while len(multiMatrixTable) <= n:
multiMatrixTable.append(None)
multiMatrixTable[n] = singleMultiMatrixEntry
# -- end if drw.isWeighted[index] then
def rotation_part(mtx):
ret = mtx.copy()
for i in range(3):
ret[i][3] = 0
return ret
def is_near(mm1, mm2):
if len(mm1.indices) != len(mm2.indices) :
return False
mm2d = {}
for i in range(len(mm2.indices)):
mm2d[mm2.indices[i]] = mm2.weights[i]
for i in range(len(mm1.indices)):
ref = mm2d.get(mm1.indices[i], -1)
if ref == -1:
return False
if abs(mm1.weights[i] - ref) > 1E-3:
return False
return True