[QUESTION] ZMD File parse

This forum is for Graphics and 3D objects discussions.

Moderators: osRose dev team, ospRose dev team, osiRose dev team, Moderators

Forum rules
Client Editing is a delicate subject. osRose and osiRose will not support or use any Client Editing tool or results as a standard. So you are free to experiment, test, and develop there on Client Editing, but at your own risk

Re: [QUESTION] ZMD File parse

Postby lmame on Tue Nov 04, 2008 6:51 pm

Btw, the code I posted two posts above is not the same as the one I sent you in PM, did you try it?
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

Re: [QUESTION] ZMD File parse

Postby cssvb94 on Tue Nov 04, 2008 7:01 pm

lmame wrote:Btw, the code I posted two posts above is not the same as the one I sent you in PM, did you try it?

Yes, and the modified script is based on your code.
aka Spark (ZMSViewer, Blender ZMS plug-in, RoseOnline ZMS/ZMD/ZMO to SMD and vice versa converter)
User avatar
cssvb94
Pomic
Pomic
 
Posts: 109
Joined: Thu May 01, 2008 7:22 am
Location: GMT +1

Re: [QUESTION] ZMD File parse

Postby lmame on Tue Nov 04, 2008 7:03 pm

cssvb94 wrote:
lmame wrote:Btw, the code I posted two posts above is not the same as the one I sent you in PM, did you try it?

Yes, and the modified script is based on your code.


Ok, so you stripped the "i==0" case on purpose?

Edit:
There is an error in my code:
zbone.co = v_result

should replace:
zbone.v_abs = v_result
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

Re: [QUESTION] ZMD File parse

Postby lmame on Tue Nov 04, 2008 8:19 pm

Ok there is something weird...
I coded formulas in another program to test values since it's pretty much unlikely that LCalf and RCalf are not parallell since vectors are nearly the same, same for quaternions...
In my program, they seem parallel, coordinates are nearly the same (at the 4th decimal) but clearly not in Blender... Perhaps there is a problem with quaternion manipulations or something so I'll try to use the quaternion formula to input a rotation matrix rather than using quaternions...
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

Re: [QUESTION] ZMD File parse

Postby cssvb94 on Tue Nov 04, 2008 8:59 pm

I'll modify the script to use Blender's quaternions to check.

UPDATE:
Yes, you are right about the quats in euclid and Blender - not good at all for some reason;
When I switched from euclid to Blender.Mathutils the result of Quat*Quat was float !!?? WTF ...

It's better to implement our quat/matrix/vector lib or just the required functions.
I copied and modified some previous version of the script, sorry for missing "i==0".
aka Spark (ZMSViewer, Blender ZMS plug-in, RoseOnline ZMS/ZMD/ZMO to SMD and vice versa converter)
User avatar
cssvb94
Pomic
Pomic
 
Posts: 109
Joined: Thu May 01, 2008 7:22 am
Location: GMT +1

Re: [QUESTION] ZMD File parse

Postby lmame on Tue Nov 04, 2008 9:40 pm

No problem for the i==0 :) it's for rotation test anyway so well...

So is it working better with mathutils from blender?
Problem is that values are very little sometimes, I'm having issues with my program because of this...

Problem also is that I found two formulas for transforming a quaternion to a rotation matrix:
(this one seems to be the one used by Euclid).
q54.gif
q54.gif (3.49 KiB) Viewed 18763 times


and another one that simply switches the "+" and "-" for every cell (only the diagonal with square numbers (²) remain the same).
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

Re: [QUESTION] ZMD File parse

Postby lmame on Wed Nov 05, 2008 1:14 am

Ok I feel like a mad scientist :lol: genetically changing a poor alligator ^_^

Ok here is my "progress" (alligator and man), as you can see, the arms are (generally) in the right direction now, don't know if it's that useful or not :)
Anyway, I checked the formulas from euclid and it seems it's in fact ok.
Though there are two possible way to calculate a quaternion so I used the second and the second gives those two screenshots, without extra rotation.
test1.jpg

test2.jpg


So all calculations are done "manually" and as you can see, it's pretty much the same :(
If you use the first version to calculate the quaternion, you find the very same results as with euclid.

Anyway, here is the code:
  1.  
  2. #!BPY
  3. """
  4. Name: 'RoseOnline ZMD binary File Format (.zmd)...'
  5. Blender: 248
  6. Group: 'Import'
  7. Tooltip: 'Import RoseOnline binary ZMD file format (.zmd)'
  8. """
  9.  
  10. __author__= ['cssvb94']
  11. __url__ = ("forum.dev-osrose.com", "www.blender.org", "pyeuclid.googlecode.com")
  12. __version__= '0.0.5'
  13. __bpydoc__= '''\
  14.  
  15. 0.0.5:
  16. lmame:
  17. -> added the i==0 from 0.0.3
  18. -> quaternion is calculated 'manually', same for mats multiplication and rot matrix (if needed),
  19. -> two formula for quaternion exist,
  20.  
  21.  
  22. 0.0.4:
  23. cssvb94
  24. -> Cleanup,
  25. -> Empty objects instead of cubes,
  26.  
  27.  
  28. 0.0.3:
  29. lmame:
  30. -> test of a new way, works not perfectly...
  31.  
  32. 0.0.2:
  33. lmame:
  34. -> added a "load file stuff",
  35. -> Just changed a stuff in the read vector (format was z,y,x instead of x,y,z),
  36.  
  37. 0.0.1
  38. -> cssvb94 initial release,
  39. '''
  40. import struct
  41. from struct import *
  42. import Blender
  43. from Blender.Mesh.Primitives import *
  44. from Blender import Scene, Object
  45. from euclid import *
  46. import math
  47.  
  48. class zmdObject:
  49.  
  50.   def __init__(self):
  51.     self.binaryFormat = "<7ci"
  52.  
  53.     self.format = ''
  54.     self.boneCount = 0
  55.  
  56.  
  57.   def load(self, file):
  58.     tmpData = file.read(struct.calcsize(self.binaryFormat))
  59.     data = struct.unpack(self.binaryFormat, tmpData)
  60.  
  61.     self.format = ''.join(data[0:7])
  62.  
  63.     self.boneCount = data[7] # DWORD = 4 bytes
  64.  
  65.     return self
  66.  
  67.   def __repr__(self):
  68.     return "Format:\t%s\tBones:\t%d" % (self.format, self.boneCount)
  69.  
  70. class zmdBoneObject:
  71.  
  72.   def __init__(self, ID):
  73.     self.binaryFormat = "<7f"
  74.  
  75.     self.parentID = -1
  76.  
  77.     #self.co = Vector3(0.0, 0.0, 0.0)
  78.  
  79.     #~ w, x, y, z
  80.     #~ self.quaternion = Quaternion(1.0, 0.0, 0.0, 0.0)
  81.     self.quaternion = Quaternion()
  82.     #LMA: Quaternion "manual".
  83.     self.MatQ = Matrix3()
  84.  
  85.     self.ID = ID
  86.  
  87.     self.name = ''
  88.     self.parentName = 'NONE'
  89.  
  90.   def readName(self, file):
  91.     #~ Reads byte by byte until \0x00, i.e cstr
  92.     bname = ''
  93.     while True:
  94.       tmpData = file.read(1)
  95.       if tmpData[0] == chr(0): break
  96.       bname = bname + tmpData
  97.     return bname
  98.  
  99.   def readParentID(self, file):
  100.     tmpData = file.read(struct.calcsize('i'))
  101.     return struct.unpack('i', tmpData)[0]
  102.  
  103.   def load(self, file):
  104.     self.parentID = self.readParentID(file)
  105.     self.name = self.readName(file)
  106.  
  107.     tmpData = file.read(struct.calcsize(self.binaryFormat))
  108.     data = struct.unpack(self.binaryFormat, tmpData)
  109.  
  110.     self.co = Vector3(data[0]/ 100.0, data[2]/ 100.0, data[1]/ 100.0)
  111.    
  112.     #some tests:
  113.     #xyzw (values), then rotation test for first bone (see #ROTATION_TEST later)
  114.     #4563
  115.     # 4653 looks ok but not perfect (arms inverted) with +-pi/2 on z
  116.     #6543
  117.     #6453 looks right but not perfect even with +- pi on z axis
  118.     #5643
  119.     #5463 looks right but not perfect even with pi/2 on y axis
  120.     '''
  121.    self.quaternion.x=data[4]
  122.    self.quaternion.y=data[6]
  123.    self.quaternion.z=data[5]
  124.    self.quaternion.w=data[3]
  125.    '''
  126.     self.quaternion.x=data[4]
  127.     self.quaternion.y=data[6]
  128.     self.quaternion.z=data[5]
  129.     self.quaternion.w=data[3]
  130.    
  131.     #LMA: Quaternion, manual...
  132.     '''
  133.    #First version
  134.    self.MatQ.a=1-2*self.quaternion.y*self.quaternion.y-2*self.quaternion.z*self.quaternion.z
  135.    self.MatQ.e=2*(self.quaternion.x*self.quaternion.y+self.quaternion.w*self.quaternion.z)
  136.    self.MatQ.i=2*(self.quaternion.x*self.quaternion.z-self.quaternion.w*self.quaternion.y)
  137.        
  138.    self.MatQ.b=2*(self.quaternion.x*self.quaternion.y-self.quaternion.w*self.quaternion.z)
  139.    self.MatQ.f=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.z*self.quaternion.z
  140.    self.MatQ.j=2*(self.quaternion.y*self.quaternion.z+self.quaternion.w*self.quaternion.x)
  141.        
  142.    self.MatQ.c=2*(self.quaternion.x*self.quaternion.z+self.quaternion.w*self.quaternion.y)
  143.    self.MatQ.g=2*(self.quaternion.y*self.quaternion.z-self.quaternion.w*self.quaternion.x)
  144.    self.MatQ.k=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.y*self.quaternion.y    
  145.    '''
  146.     #second version
  147.     self.MatQ.a=1-2*self.quaternion.y*self.quaternion.y-2*self.quaternion.z*self.quaternion.z
  148.     self.MatQ.e=2*(self.quaternion.x*self.quaternion.y-self.quaternion.w*self.quaternion.z)
  149.     self.MatQ.i=2*(self.quaternion.x*self.quaternion.z+self.quaternion.w*self.quaternion.y)
  150.        
  151.     self.MatQ.b=2*(self.quaternion.x*self.quaternion.y+self.quaternion.w*self.quaternion.z)
  152.     self.MatQ.f=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.z*self.quaternion.z
  153.     self.MatQ.j=2*(self.quaternion.y*self.quaternion.z-self.quaternion.w*self.quaternion.x)
  154.        
  155.     self.MatQ.c=2*(self.quaternion.x*self.quaternion.z-self.quaternion.w*self.quaternion.y)
  156.     self.MatQ.g=2*(self.quaternion.y*self.quaternion.z+self.quaternion.w*self.quaternion.x)
  157.     self.MatQ.k=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.y*self.quaternion.y    
  158.     '''
  159.    print self.name
  160.    print "%.10f,%.10f,%.10f,%.10f" % (self.quaternion.w,self.quaternion.x,self.quaternion.y,self.quaternion.z)
  161.    print self.MatQ
  162.    '''
  163.     return self
  164.    
  165.  
  166.   def __str__(self):
  167.     return 'Bone %d name: "%s" \tparendBoneID: %d\tparentName: "%s"\n' % (self.ID, self.name, self.parentID, self.parentName) + \
  168.   'Coord:\t\t Vector(%.4f, %.4f, %.4f)\n' % tuple(self.co)  + \
  169.   'Rotation:\t Quaternion(%.4f, %.4f, %.4f, %.4f)\n' % (self.quaternion.w, self.quaternion.x, self.quaternion.y, self.quaternion.z)
  170.  
  171. #Loading file procedure.
  172. binaryDummyFormat = "<i"
  173.  
  174. #That was for tests.
  175. filename = 'D:/ZMD/ALLIGATOR_BONE.ZMD'
  176. #filename = 'D:/ZMD/YOUNGMAN_BONE.ZMD'
  177.  
  178. # Open a binary file
  179. file=open(filename,"rb")
  180.  
  181. zmd = zmdObject()
  182. zmd.load(file)
  183. print zmd
  184.  
  185. # Empty dictionary
  186. bones = {}
  187.  
  188. #LMA: Rotation matrixes.
  189. lmaAngle=math.pi/2
  190. RotX=Matrix3()
  191. RotY=Matrix3()
  192. RotZ=Matrix3()
  193. RotX.a=1
  194. RotX.b=0
  195. RotX.c=0
  196. RotX.e=0
  197. RotX.f=math.cos(lmaAngle)
  198. RotX.g=math.sin(lmaAngle)
  199. RotX.i=0
  200. RotX.j=-math.sin(lmaAngle)
  201. RotX.k=math.cos(lmaAngle)
  202.  
  203. RotY.a=math.cos(lmaAngle)
  204. RotY.b=0
  205. RotY.c=-math.sin(lmaAngle)
  206. RotY.e=0
  207. RotY.f=1
  208. RotY.g=0
  209. RotY.i=math.sin(lmaAngle)
  210. RotY.j=0
  211. RotY.k=math.cos(lmaAngle)
  212.  
  213. RotZ.a=math.cos(lmaAngle)
  214. RotZ.b=math.sin(lmaAngle)
  215. RotZ.c=0
  216. RotZ.e=-math.sin(lmaAngle)
  217. RotZ.f=math.cos(lmaAngle)
  218. RotZ.g=0
  219. RotZ.i=0
  220. RotZ.j=0
  221. RotZ.k=1
  222.  
  223. # Read and transform each bone position
  224. #LMA: Other test begin.
  225. print "\n\n\nReading time..."
  226. for i in range(zmd.boneCount):
  227.   zbone = zmdBoneObject(i)
  228.   # Read bone
  229.   zbone.load(file)
  230.   v_result = zbone.co
  231.  
  232.   print "Org %s=%.10f,%.10f,%.10f" % (zbone.name,zbone.co.x,zbone.co.y,zbone.co.z)
  233.   '''
  234.  print "%.10f,%.10f,%.10f,%.10f" % (zbone.quaternion.w,zbone.quaternion.x,zbone.quaternion.y,zbone.quaternion.z)  
  235.  #print zbone.MatQ
  236.  print "%.4f,%.4f,%.4f" % (v_result.x,v_result.y,v_result.z)
  237.  print "%.4f,%.4f,%.4f,%.4f" % (zbone.quaternion.w,zbone.quaternion.x,zbone.quaternion.y,zbone.quaternion.z)
  238.  '''
  239.    
  240.     #ROTATION_TEST (see above)  
  241.   if i==0:
  242.     print "i==0"
  243.     '''
  244.    #v_result=zbone.quaternion*v_result     
  245.    qrot = Quaternion.new_rotate_axis(-1*math.pi/2, Vector3(0, 0, 1))
  246.    zbone.quaternion=qrot*zbone.quaternion
  247.    #v_result=zbone.quaternion*v_result
  248.    v_result=qrot*v_result
  249.    zbone.co = v_result
  250.    '''
  251.     #v_result=zbone.quaternion*v_result     
  252.    
  253.     #LMA: manual version
  254.     '''
  255.    qrot = RotZ
  256.    zbone.MatQ=zbone.MatQ*qrot
  257.    #v_result=zbone.quaternion*v_result
  258.    temp_result=Vector3(0,0,0)
  259.    temp_result.x=qrot.a*v_result.x+qrot.b*v_result.y+qrot.c*v_result.z
  260.    temp_result.y=qrot.e*v_result.x+qrot.f*v_result.y+qrot.g*v_result.z
  261.    temp_result.z=qrot.i*v_result.x+qrot.j*v_result.y+qrot.k*v_result.z     
  262.    v_result=temp_result
  263.    zbone.co = v_result     
  264.    '''
  265.  
  266.    
  267.   if i>0:
  268.     zbone.parentName = bones[zbone.parentID].name
  269.     v_parent = bones[zbone.parentID].co
  270.     '''
  271.    q_parent = bones[zbone.parentID].quaternion
  272.    v_result=(q_parent * v_result) + v_parent
  273.    zbone.quaternion = zbone.quaternion * q_parent
  274.    print zbone.name
  275.    print "%10f,%.10f,%.10f" % (v_result.x,v_result.y,v_result.z)
  276.    '''
  277.    
  278.    
  279.     '''test LMA'''
  280.     temp_result=Vector3(0,0,0)
  281.     q_parent=bones[zbone.parentID].MatQ
  282.     print "Parent MatQ %s" % (zbone.parentName)
  283.     print q_parent
  284.     temp_result.x=q_parent.a*v_result.x+q_parent.b*v_result.y+q_parent.c*v_result.z
  285.     temp_result.y=q_parent.e*v_result.x+q_parent.f*v_result.y+q_parent.g*v_result.z
  286.     temp_result.z=q_parent.i*v_result.x+q_parent.j*v_result.y+q_parent.k*v_result.z
  287.     v_result=temp_result
  288.     print "before + v_parent, %s=%.10f,%.10f,%.10f" % (zbone.name,v_result.x,v_result.y,v_result.z)    
  289.     v_result=v_result+v_parent
  290.     print "after + v_parent= %.10f,%.10f,%.10f" % (v_result.x,v_result.y,v_result.z)    
  291.     zbone.MatQ = zbone.MatQ * q_parent
  292.     '''END test'''
  293.    
  294.     zbone.co = v_result
  295.  
  296.     #print zbone.parentName
  297.     #print q_parent
  298.     #print q_parent.get_matrix()
  299.  
  300.     #~  print zbone.co
  301.   #zbone.co = v_result
  302.  
  303.   #print zbone.name
  304.   #print v_result
  305.   #print zbone.quaternion  
  306.   #print "%.4f,%.4f,%.4f" % (v_result.x,v_result.y,v_result.z)
  307.   #print "%.4f,%.4f,%.4f,%.4f" % (zbone.quaternion.w,zbone.quaternion.x,zbone.quaternion.y,zbone.quaternion.z)    
  308.  
  309.   bones[i] = zbone
  310. #LMA: Other test end.
  311.  
  312. # Close the file
  313. file.close()
  314. print "\n\n\nCube time..."
  315. # Put some cubes instead bones
  316. sc = Blender.Scene.GetCurrent()
  317.  
  318. #~ Read bone dictionary and create dummy cubes instead of bones for a test purpose
  319. if True:
  320.  
  321.   for i, bone in enumerate(bones.values()):
  322.     #~ Create dummy object
  323.     obj = Object.New("Empty", bone.name)
  324.     obj.drawMode=obj.drawMode|8
  325.     obj.emptyShape = 5 # Cube shape = 5
  326.     obj.size = (0.0125, 0.0125, 0.0125)
  327.  
  328.      #~ Put/link the object with the scene
  329.     sc.objects.link(obj)
  330.  
  331.     #~ All generated objects will appear already selected - much easier to zoom into them - use "." from NUM PAD to zoom on selected !
  332.     obj.sel = True
  333.     #~ Set the position
  334.     obj.LocX = bone.co[0]
  335.     obj.LocY = bone.co[1]
  336.     obj.LocZ = bone.co[2]
  337.  
  338.     #~ Print some info
  339.     #print bone
  340.     #~ Next part creates parent <-> child connection, not necessary, but visual feedback =)
  341.     if i > 0:
  342.       parent_obj = Blender.Object.Get(bone.parentName)
  343.       parent_obj.makeParent([obj])
  344.  
  345. # Refresh the views
  346. Blender.Window.RedrawAll()
  347.  
  348. # Clean up used memory
  349. #del sc, zmd, bones, file, zbone, parent_obj, bone, i
  350.  
  351.  
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

Re: [QUESTION] ZMD File parse

Postby lmame on Thu Nov 06, 2008 2:19 pm

Ok I think we're getting somewhere ^_^

  1.  
  2. #!BPY
  3. """
  4. Name: 'RoseOnline ZMD binary File Format (.zmd)...'
  5. Blender: 248
  6. Group: 'Import'
  7. Tooltip: 'Import RoseOnline binary ZMD file format (.zmd)'
  8. """
  9.  
  10. __author__= ['cssvb94']
  11. __url__ = ("forum.dev-osrose.com", "www.blender.org", "pyeuclid.googlecode.com")
  12. __version__= '0.0.6'
  13. __bpydoc__= '''\
  14.  
  15. 0.0.6:
  16. lmame:
  17. -> math attack time ^_^, seems to getting better now,
  18.  
  19. 0.0.5:
  20. lmame:
  21. -> added the i==0 from 0.0.3
  22. -> quaternion is calculated 'manually', same for mats multiplication and rot matrix (if needed),
  23. -> two formula for quaternion exist,
  24.  
  25.  
  26. 0.0.4:
  27. cssvb94
  28. -> Cleanup,
  29. -> Empty objects instead of cubes,
  30.  
  31.  
  32. 0.0.3:
  33. lmame:
  34. -> test of a new way, works not perfectly...
  35.  
  36. 0.0.2:
  37. lmame:
  38. -> added a "load file stuff",
  39. -> Just changed a stuff in the read vector (format was z,y,x instead of x,y,z),
  40.  
  41. 0.0.1
  42. -> cssvb94 initial release,
  43. '''
  44. import struct
  45. from struct import *
  46. import Blender
  47. from Blender.Mesh.Primitives import *
  48. from Blender import Scene, Object
  49. from euclid import *
  50. import math
  51.  
  52. class zmdObject:
  53.  
  54.   def __init__(self):
  55.     self.binaryFormat = "<7ci"
  56.  
  57.     self.format = ''
  58.     self.boneCount = 0
  59.  
  60.  
  61.   def load(self, file):
  62.     tmpData = file.read(struct.calcsize(self.binaryFormat))
  63.     data = struct.unpack(self.binaryFormat, tmpData)
  64.  
  65.     self.format = ''.join(data[0:7])
  66.  
  67.     self.boneCount = data[7] # DWORD = 4 bytes
  68.  
  69.     return self
  70.  
  71.   def __repr__(self):
  72.     return "Format:\t%s\tBones:\t%d" % (self.format, self.boneCount)
  73.  
  74. class zmdBoneObject:
  75.  
  76.   def __init__(self, ID):
  77.     self.binaryFormat = "<7f"
  78.  
  79.     self.parentID = -1
  80.  
  81.     #self.co = Vector3(0.0, 0.0, 0.0)
  82.  
  83.     #~ w, x, y, z
  84.     #~ self.quaternion = Quaternion(1.0, 0.0, 0.0, 0.0)
  85.     self.quaternion = Quaternion()
  86.     #LMA: Quaternion "manual".
  87.     self.MatQ = Matrix3()
  88.  
  89.     self.ID = ID
  90.  
  91.     self.name = ''
  92.     self.parentName = 'NONE'
  93.  
  94.   def readName(self, file):
  95.     #~ Reads byte by byte until \0x00, i.e cstr
  96.     bname = ''
  97.     while True:
  98.       tmpData = file.read(1)
  99.       if tmpData[0] == chr(0): break
  100.       bname = bname + tmpData
  101.     return bname
  102.  
  103.   def readParentID(self, file):
  104.     tmpData = file.read(struct.calcsize('i'))
  105.     return struct.unpack('i', tmpData)[0]
  106.  
  107.   def load(self, file):
  108.     self.parentID = self.readParentID(file)
  109.     self.name = self.readName(file)
  110.  
  111.     tmpData = file.read(struct.calcsize(self.binaryFormat))
  112.     data = struct.unpack(self.binaryFormat, tmpData)
  113.  
  114.     self.co = Vector3(data[0]/ 100.0, data[2]/ 100.0, data[1]/ 100.0)
  115.    
  116.     #some tests:
  117.     #xyzw (values), then rotation test for first bone (see #ROTATION_TEST later)
  118.     #4563
  119.     # 4653 looks ok but not perfect (arms inverted) with +-pi/2 on z
  120.     #6543
  121.     #6453 looks right but not perfect even with +- pi on z axis
  122.     #5643
  123.     #5463 looks right but not perfect even with pi/2 on y axis
  124.     '''
  125.    self.quaternion.x=data[4]
  126.    self.quaternion.y=data[6]
  127.    self.quaternion.z=data[5]
  128.    self.quaternion.w=data[3]
  129.    '''
  130.     self.quaternion.x=data[4]
  131.     self.quaternion.y=data[6]
  132.     self.quaternion.z=data[5]
  133.     self.quaternion.w=data[3]
  134.    
  135.     #LMA: Quaternion, manual...
  136.    
  137.     #First version
  138.     '''
  139.    self.MatQ.a=1-2*self.quaternion.y*self.quaternion.y-2*self.quaternion.z*self.quaternion.z
  140.    self.MatQ.e=2*(self.quaternion.x*self.quaternion.y+self.quaternion.w*self.quaternion.z)
  141.    self.MatQ.i=2*(self.quaternion.x*self.quaternion.z-self.quaternion.w*self.quaternion.y)
  142.        
  143.    self.MatQ.b=2*(self.quaternion.x*self.quaternion.y-self.quaternion.w*self.quaternion.z)
  144.    self.MatQ.f=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.z*self.quaternion.z
  145.    self.MatQ.j=2*(self.quaternion.y*self.quaternion.z+self.quaternion.w*self.quaternion.x)
  146.        
  147.    self.MatQ.c=2*(self.quaternion.x*self.quaternion.z+self.quaternion.w*self.quaternion.y)
  148.    self.MatQ.g=2*(self.quaternion.y*self.quaternion.z-self.quaternion.w*self.quaternion.x)
  149.    self.MatQ.k=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.y*self.quaternion.y    
  150.    '''
  151.    
  152.     #second version
  153.     self.MatQ.a=1-2*self.quaternion.y*self.quaternion.y-2*self.quaternion.z*self.quaternion.z
  154.     self.MatQ.e=2*(self.quaternion.x*self.quaternion.y-self.quaternion.w*self.quaternion.z)
  155.     self.MatQ.i=2*(self.quaternion.x*self.quaternion.z+self.quaternion.w*self.quaternion.y)
  156.        
  157.     self.MatQ.b=2*(self.quaternion.x*self.quaternion.y+self.quaternion.w*self.quaternion.z)
  158.     self.MatQ.f=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.z*self.quaternion.z
  159.     self.MatQ.j=2*(self.quaternion.y*self.quaternion.z-self.quaternion.w*self.quaternion.x)
  160.        
  161.     self.MatQ.c=2*(self.quaternion.x*self.quaternion.z-self.quaternion.w*self.quaternion.y)
  162.     self.MatQ.g=2*(self.quaternion.y*self.quaternion.z+self.quaternion.w*self.quaternion.x)
  163.     self.MatQ.k=1-2*self.quaternion.x*self.quaternion.x-2*self.quaternion.y*self.quaternion.y    
  164.    
  165.    
  166.     print "Quaternion %s" % self.name
  167.     print "%.10f,%.10f,%.10f,%.10f" % (self.quaternion.w,self.quaternion.x,self.quaternion.y,self.quaternion.z)
  168.     print self.MatQ
  169.    
  170.     return self
  171.    
  172.  
  173.   def __str__(self):
  174.     return 'Bone %d name: "%s" \tparendBoneID: %d\tparentName: "%s"\n' % (self.ID, self.name, self.parentID, self.parentName) + \
  175.   'Coord:\t\t Vector(%.4f, %.4f, %.4f)\n' % tuple(self.co)  + \
  176.   'Rotation:\t Quaternion(%.4f, %.4f, %.4f, %.4f)\n' % (self.quaternion.w, self.quaternion.x, self.quaternion.y, self.quaternion.z)
  177.  
  178. #Loading file procedure.
  179. binaryDummyFormat = "<i"
  180.  
  181. #That was for tests.
  182. filename = 'D:/ZMD/ALLIGATOR_BONE.ZMD'
  183. #filename = 'D:/ZMD/YOUNGMAN_BONE.ZMD'
  184.  
  185. # Open a binary file
  186. file=open(filename,"rb")
  187.  
  188. zmd = zmdObject()
  189. zmd.load(file)
  190. print zmd
  191.  
  192. # Empty dictionary
  193. bones = {}
  194.  
  195. #LMA: Rotation matrixes.
  196. lmaAngle=math.pi/2
  197. RotX=Matrix3()
  198. RotY=Matrix3()
  199. RotZ=Matrix3()
  200. RotX.a=1
  201. RotX.b=0
  202. RotX.c=0
  203. RotX.e=0
  204. RotX.f=math.cos(lmaAngle)
  205. RotX.g=math.sin(lmaAngle)
  206. RotX.i=0
  207. RotX.j=-math.sin(lmaAngle)
  208. RotX.k=math.cos(lmaAngle)
  209.  
  210. RotY.a=math.cos(lmaAngle)
  211. RotY.b=0
  212. RotY.c=-math.sin(lmaAngle)
  213. RotY.e=0
  214. RotY.f=1
  215. RotY.g=0
  216. RotY.i=math.sin(lmaAngle)
  217. RotY.j=0
  218. RotY.k=math.cos(lmaAngle)
  219.  
  220. RotZ.a=math.cos(lmaAngle)
  221. RotZ.b=math.sin(lmaAngle)
  222. RotZ.c=0
  223. RotZ.e=-math.sin(lmaAngle)
  224. RotZ.f=math.cos(lmaAngle)
  225. RotZ.g=0
  226. RotZ.i=0
  227. RotZ.j=0
  228. RotZ.k=1
  229.  
  230. # Read and transform each bone position
  231. #LMA: Other test begin.
  232. print "\n\n\nReading time..."
  233. for i in range(zmd.boneCount):
  234.   zbone = zmdBoneObject(i)
  235.   # Read bone
  236.   zbone.load(file)
  237.   v_result = zbone.co
  238.  
  239.   print "Org %s=%.10f,%.10f,%.10f" % (zbone.name,zbone.co.x,zbone.co.y,zbone.co.z)
  240.   '''
  241.  print "%.10f,%.10f,%.10f,%.10f" % (zbone.quaternion.w,zbone.quaternion.x,zbone.quaternion.y,zbone.quaternion.z)  
  242.  #print zbone.MatQ
  243.  print "%.4f,%.4f,%.4f" % (v_result.x,v_result.y,v_result.z)
  244.  print "%.4f,%.4f,%.4f,%.4f" % (zbone.quaternion.w,zbone.quaternion.x,zbone.quaternion.y,zbone.quaternion.z)
  245.  '''
  246.    
  247.     #ROTATION_TEST (see above)  
  248.   if i==0:
  249.     print "i==0"
  250.     '''
  251.    #v_result=zbone.quaternion*v_result     
  252.    qrot = Quaternion.new_rotate_axis(-1*math.pi/2, Vector3(0, 0, 1))
  253.    zbone.quaternion=qrot*zbone.quaternion
  254.    #v_result=zbone.quaternion*v_result
  255.    v_result=qrot*v_result
  256.    zbone.co = v_result
  257.    '''
  258.     #v_result=zbone.quaternion*v_result     
  259.    
  260.     #LMA: manual version
  261.     '''
  262.    qrot = RotZ
  263.    zbone.MatQ=zbone.MatQ*qrot
  264.    #v_result=zbone.quaternion*v_result
  265.    temp_result=Vector3(0,0,0)
  266.    temp_result.x=qrot.a*v_result.x+qrot.b*v_result.y+qrot.c*v_result.z
  267.    temp_result.y=qrot.e*v_result.x+qrot.f*v_result.y+qrot.g*v_result.z
  268.    temp_result.z=qrot.i*v_result.x+qrot.j*v_result.y+qrot.k*v_result.z     
  269.    v_result=temp_result
  270.    zbone.co = v_result     
  271.    '''
  272.  
  273.    
  274.   if i>0:
  275.     zbone.parentName = bones[zbone.parentID].name
  276.     v_parent = bones[zbone.parentID].co
  277.     '''
  278.    q_parent = bones[zbone.parentID].quaternion
  279.    v_result=(q_parent * v_result) + v_parent
  280.    zbone.quaternion = zbone.quaternion * q_parent
  281.    print zbone.name
  282.    print "%10f,%.10f,%.10f" % (v_result.x,v_result.y,v_result.z)
  283.    '''
  284.    
  285.    
  286.     '''test LMA'''
  287.     temp_result=Vector3(0,0,0)
  288.     q_parent=bones[zbone.parentID].MatQ
  289.     print "Parent MatQ %s" % (zbone.parentName)
  290.     print q_parent
  291.     temp_result.x=q_parent.a*v_result.x+q_parent.b*v_result.y+q_parent.c*v_result.z
  292.     temp_result.y=q_parent.e*v_result.x+q_parent.f*v_result.y+q_parent.g*v_result.z
  293.     temp_result.z=q_parent.i*v_result.x+q_parent.j*v_result.y+q_parent.k*v_result.z
  294.    
  295.     v_result=temp_result
  296.     print "before + v_parent, %s=%.10f,%.10f,%.10f" % (zbone.name,v_result.x,v_result.y,v_result.z)    
  297.     v_result=v_result+v_parent
  298.     print "after + v_parent= %.10f,%.10f,%.10f" % (v_result.x,v_result.y,v_result.z)    
  299.     #zbone.MatQ = zbone.MatQ * q_parent
  300.     zbone.MatQ = q_parent*zbone.MatQ
  301.     '''END test'''
  302.    
  303.     zbone.co = v_result
  304.  
  305.     #print zbone.parentName
  306.     #print q_parent
  307.     #print q_parent.get_matrix()
  308.  
  309.     #~  print zbone.co
  310.   #zbone.co = v_result
  311.  
  312.   #print zbone.name
  313.   #print v_result
  314.   #print zbone.quaternion  
  315.   #print "%.4f,%.4f,%.4f" % (v_result.x,v_result.y,v_result.z)
  316.   #print "%.4f,%.4f,%.4f,%.4f" % (zbone.quaternion.w,zbone.quaternion.x,zbone.quaternion.y,zbone.quaternion.z)    
  317.  
  318.   bones[i] = zbone
  319. #LMA: Other test end.
  320.  
  321. # Close the file
  322. file.close()
  323. print "\n\n\nCube time..."
  324. # Put some cubes instead bones
  325. sc = Blender.Scene.GetCurrent()
  326.  
  327. #~ Read bone dictionary and create dummy cubes instead of bones for a test purpose
  328. if True:
  329.  
  330.   for i, bone in enumerate(bones.values()):
  331.     #~ Create dummy object
  332.     obj = Object.New("Empty", bone.name)
  333.     obj.drawMode=obj.drawMode|8
  334.     obj.emptyShape = 5 # Cube shape = 5
  335.     obj.size = (0.0125, 0.0125, 0.0125)
  336.  
  337.      #~ Put/link the object with the scene
  338.     sc.objects.link(obj)
  339.  
  340.     #~ All generated objects will appear already selected - much easier to zoom into them - use "." from NUM PAD to zoom on selected !
  341.     obj.sel = True
  342.     #~ Set the position
  343.     obj.LocX = bone.co[0]
  344.     obj.LocY = bone.co[1]
  345.     obj.LocZ = bone.co[2]
  346.  
  347.     #~ Print some info
  348.     #print bone
  349.     #~ Next part creates parent <-> child connection, not necessary, but visual feedback =)
  350.     if i > 0:
  351.       parent_obj = Blender.Object.Get(bone.parentName)
  352.       parent_obj.makeParent([obj])
  353.  
  354. # Refresh the views
  355. Blender.Window.RedrawAll()
  356.  
  357. # Clean up used memory
  358. #del sc, zmd, bones, file, zbone, parent_obj, bone, i
  359.  
Attachments
test5.jpg
test4.jpg
test3.jpg
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

Re: [QUESTION] ZMD File parse

Postby cssvb94 on Thu Nov 06, 2008 3:32 pm

Oh sweet =)
ATM I can not check it - still at work :( , but as far I can see it's getting better and better.
+1 @ Imame
aka Spark (ZMSViewer, Blender ZMS plug-in, RoseOnline ZMS/ZMD/ZMO to SMD and vice versa converter)
User avatar
cssvb94
Pomic
Pomic
 
Posts: 109
Joined: Thu May 01, 2008 7:22 am
Location: GMT +1

Re: [QUESTION] ZMD File parse

Postby lmame on Sat Nov 08, 2008 10:07 pm

I think it's ok actually, last step is to compare all points absolute coordinates and see, but visually it seems ok now.
The world is full of love and peace ^_^
Image
User avatar
lmame
Admin
Admin
 
Posts: 8997
Joined: Mon Aug 06, 2007 4:42 pm
Location: July City

PreviousNext

Return to 3D discussions

Who is online

Users browsing this forum: No registered users and 3 guests