6 20100731: meshioと互換になるように改造
9 http://yumin3123.at.webry.info/200810/article_4.html
10 http://atupdate.web.fc2.com/vmd_format.htm
13 http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
32 if sys.version_info[0]>=3:
35 ###############################################################################
37 ###############################################################################
38 if sys.version_info[0]<3:
39 def truncate_zero(src):
43 assert(type(src)==bytes)
44 pos = src.find(b"\x00")
50 def truncate_zero(src):
54 assert(type(src)==bytes)
55 pos = src.find(b"\x00")
57 return src[:pos].decode('cp932')
59 return src.decode('cp932')
62 if sys.version_info[0]<3:
66 return src.encode('cp932')
70 raise "INVALID str: %s" % t
81 return src.decode('cp932')
83 raise "INVALID str: %s" % t
86 return src.encode('cp932')
89 def radian_to_degree(x):
90 return x/math.pi * 180.0
93 ###############################################################################
95 ###############################################################################
96 class Vector2(object):
98 def __init__(self, x=0, y=0):
103 return "<%f %f>" % (self.x, self.y)
105 def __getitem__(self, key):
114 return (self.x, self.y)
117 class Vector3(object):
118 __slots__=['x', 'y', 'z']
119 def __init__(self, x=0, y=0, z=0):
125 return "<%f %f %f>" % (self.x, self.y, self.z)
127 def __getitem__(self, key):
138 return (self.x, self.y, self.z)
141 return Vector3(l.x+r.x, l.y+r.y, l.z+r.z)
144 class Quaternion(object):
145 __slots__=['x', 'y', 'z', 'w']
146 def __init__(self, x=0, y=0, z=0, w=1):
153 return "<%f %f %f %f>" % (self.x, self.y, self.z, self.w)
155 def __mul__(self, rhs):
156 u=numpy.array([self.x, self.y, self.z], 'f')
157 v=numpy.array([rhs.x, rhs.y, rhs.z], 'f')
158 xyz=self.w*v+rhs.w*u+numpy.cross(u, v)
159 q=Quaternion(xyz[0], xyz[1], xyz[2], self.w*rhs.w-numpy.dot(u, v))
163 return self.x*rhs.x+self.y*rhs.y+self.z*rhs.z+self.w*rhs.w
177 [1-2*sqY-2*sqZ, 2*xy+2*wz, 2*xz-2*wy, 0],
179 [2*xy-2*wz, 1-2*sqX-2*sqZ, 2*yz+2*wx, 0],
181 [2*xz+2*wy, 2*yz-2*wx, 1-2*sqX-2*sqY, 0],
186 def getRHMatrix(self):
202 [1-2*sqY-2*sqZ, 2*xy+2*wz, 2*xz-2*wy, 0],
204 [2*xy-2*wz, 1-2*sqX-2*sqZ, 2*yz+2*wx, 0],
206 [2*xz+2*wy, 2*yz-2*wx, 1-2*sqX-2*sqY, 0],
211 def getRollPitchYaw(self):
214 roll = math.atan2(m[0, 1], m[1, 1])
215 pitch = math.asin(-m[2, 1])
216 yaw = math.atan2(m[2, 0], m[2, 2])
218 if math.fabs(math.cos(pitch)) < 1.0e-6:
219 roll += m[0, 1] > math.pi if 0.0 else -math.pi
220 yaw += m[2, 0] > math.pi if 0.0 else -math.pi
222 return roll, pitch, yaw
225 return self.x*self.x+self.y*self.y+self.z*self.z+self.w*self.w
227 def getNormalized(self):
228 f=1.0/self.getSqNorm()
229 q=Quaternion(self.x*f, self.y*f, self.z*f, self.w*f)
232 def getRightHanded(self):
234 return Quaternion(-self.x, -self.z, -self.y, self.w)
237 def createFromAxisAngle(axis, rad):
242 return Quaternion(axis[0]*s, axis[1]*s, axis[2]*s, c)
246 __slots__=['r', 'g', 'b', 'a']
247 def __init__(self, r=0, g=0, b=0, a=1):
253 def __getitem__(self, key):
268 ###############################################################################
270 ###############################################################################
272 size=os.path.getsize(path)
275 if l.load(path, f, size):
279 size=os.path.getsize(path)
282 if l.load(path, f, size):
289 size=os.path.getsize(path)
291 if l.load(path, f, size):
295 ###############################################################################
297 ###############################################################################
301 print("fail to load")
304 print(unicode(l).encode(ENCODING))
305 print(l.comment.encode(ENCODING))
306 print("<ボーン>".decode('utf-8').encode(ENCODING))
307 for bone in l.no_parent_bones:
308 print(bone.name.encode(ENCODING))
310 #for bone in l.bones:
311 # uni="%s:%s" % (bone.english_name, bone.name)
312 # print uni.encode(ENCODING)
313 #for skin in l.morph_list:
314 # uni="%s:%s" % (skin.english_name, skin.name)
315 # print uni.encode(ENCODING)
316 #for i, v in enumerate(l.vertices):
318 #for i, f in enumerate(l.indices):
320 for m in l.materials:
323 def debug_pmd_write(path, out):
326 print("fail to load")
330 print("fail to write")
336 print("fail to load")
338 print(unicode(l).encode(ENCODING))
340 #for m in l.motions[u'センター']:
341 # print m.frame, m.pos
342 for n, m in l.shapes.items():
343 print(unicode(n).encode(ENCODING), getEnglishSkinName(n))
348 print("fail to load")
351 print(unicode(bone).encode(ENCODING))
353 if __name__=="__main__":
355 print("usage: %s {pmd file}" % sys.argv[0])
356 print("usage: %s {vmd file}" % sys.argv[0])
357 print("usage: %s {vpd file}" % sys.argv[0])
358 print("usage: %s {pmd file} {export pmdfile}" % sys.argv[0])
362 if not os.path.exists(path):
363 print("no such file: %s" % path)
365 if path.lower().endswith('.pmd'):
369 debug_pmd_write(path, sys.argv[2])
370 elif path.lower().endswith('.vmd'):
372 elif path.lower().endswith('.vpd'):
375 print("unknown file type: %s" % path)