Advertisement
Sim_Piko

rig_physics.py

Jan 31st, 2017
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.74 KB | None | 0 0
  1. import os
  2. import sys
  3. import json
  4.  
  5. import vs
  6. import sfmUtils
  7. from filesystem import *
  8. import filesystem.valve
  9.  
  10. import sfmphys.rigutils
  11. sfmphys.rigutils = reload(sfmphys.rigutils)
  12.  
  13. from sfmphys.rigutils import *
  14. from sfmphys.dagutils import *
  15.  
  16. def unicodeToStr(data):
  17. if isinstance(data, dict):
  18. return dict((unicodeToStr(key), unicodeToStr(value)) for (key, value) in data.iteritems())
  19. elif isinstance(data, list):
  20. return [unicodeToStr(element) for element in data]
  21. elif isinstance(data, unicode):
  22. return data.encode('utf-8')
  23. else:
  24. return data
  25. #end
  26.  
  27. def vectorToList(vec):
  28. return [vec.x, vec.y, vec.z]
  29. #end
  30. def listToVector(tup):
  31. return vs.Vector(tup[0], tup[1], tup[2])
  32. #end
  33. def quatToList(quat):
  34. return [quat.x, quat.y, quat.z, quat.w]
  35. #end
  36. def listToQuat(tup):
  37. return vs.Quaternion(tup[0], tup[1], tup[2], tup[3])
  38. #end
  39.  
  40. shot = sfm.GetCurrentShot()
  41. animSet = sfm.GetCurrentAnimationSet()
  42. model = animSet.gameModel
  43.  
  44. mdl_path = RelativePathToFullPath(model.GetModelName(), game())
  45. if mdl_path is None:
  46. phys_path = "<FILE NOT FOUND>"
  47. else:
  48. phys_path = os.path.splitext(mdl_path)[0] + ".physics.txt"
  49.  
  50. data = dict()
  51.  
  52. sys.stderr.write("rig_physics.py: looking for config file at: "+str(phys_path)+"\n")
  53.  
  54. if os.path.isfile(phys_path):
  55. #load data from the file
  56. sys.stderr.write("rig_physics.py: loading config\n")
  57. infile = open(phys_path, "r")
  58. data = unicodeToStr(json.load(infile))
  59. infile.close()
  60. else:
  61. #try to guess with rigidbodies
  62. sys.stderr.write("rig_physics.py: no config found, assuming rigidbody\n")
  63. hdr = vs.CStudioHdr(model.GetStudioHdr())
  64. parents = {}
  65.  
  66. data["rigidbodies"] = list()
  67. data["constraints"] = list()
  68.  
  69. nhitset = hdr.numhitboxsets()
  70. for ihitset in range(nhitset):
  71. nhitbox = hdr.iHitboxCount(ihitset)
  72. for ihitbox in range(nhitbox):
  73. box = hdr.pHitbox(ihitbox, ihitset)
  74. bone = hdr.pBone(box.bone)
  75. bonename = bone.pszName()
  76. boxsize = (box.bbmax - box.bbmin) / 2
  77. boxcenter = (box.bbmax + box.bbmin) / 2
  78.  
  79. body = {"target": bonename,
  80. "boxcenter": vectorToList(boxcenter),
  81. "boxsize": vectorToList(boxsize)}
  82. data["rigidbodies"].append(body)
  83.  
  84. tempBone = bone
  85. parents[bonename] = []
  86. while tempBone.parent != -1:
  87. parent = hdr.pBone(tempBone.parent)
  88. parents[bonename].append(parent.pszName())
  89. tempBone = parent
  90. #end
  91. #end
  92. #end
  93.  
  94. #create constraints
  95. for i in parents:
  96. par = parents[i]
  97. for j in par:
  98. if j in parents: #if j is an ancestor of i *and* has an associated rigidbody
  99. cons = {"constype": "cone",
  100. "bodya": j,
  101. "bodyb": i,
  102. "rotx": 90,
  103. "roty": 90,
  104. "twist": 35}
  105.  
  106. data["constraints"].append(cons)
  107. break #we can only have 1 parent per bone
  108. #end
  109. #end
  110. #end
  111.  
  112. #don't do this yet.
  113. #if the rig doesn't work, it'll save the faulty rig and that's a Bad Thing
  114. #outfile = open(phys_path, "w")
  115. #json.dump(data, outfile, indent=2)
  116. #outfile.close()
  117. #sys.stderr.write("rig_physics.py: saved rigidbody config to "+str(phys_path)+"\n")
  118. #end
  119.  
  120. #create the rig
  121. rig = sfm.BeginRig("rig_physics_" + animSet.GetName(), True)
  122. rootGroup = animSet.GetRootControlGroup()
  123.  
  124. rigidbodyGroup = rootGroup.CreateControlGroup("Rigidbodies")
  125. constraintGroup = rootGroup.CreateControlGroup("PhysConstraints")
  126. softbodyGroup = rootGroup.CreateControlGroup("Softbodies")
  127.  
  128. if "rigidbodies" in data:
  129. for body in data["rigidbodies"]:
  130. body["boxcenter"] = listToVector(body["boxcenter"])
  131. body["boxsize"] = listToVector(body["boxsize"])
  132. group = rigidbodyGroup.CreateControlGroup("Body ("+body["target"]+")")
  133. bodyrig = RigidbodyRig(data=body)
  134. bodyrig.writeToGroup(group)
  135. #end
  136. #end
  137. if "constraints" in data:
  138. for cons in data["constraints"]:
  139. group = constraintGroup.CreateControlGroup(cons["constype"] + "_constraint ("+cons["bodya"]+" -> "+cons["bodyb"]+")")
  140. consrig = ConstraintRig(data=cons)
  141. consrig.writeToGroup(group)
  142. #end
  143. #end
  144.  
  145. if "cloths" in data:
  146. for cloth in data["cloths"]:
  147. body = dict(cloth)
  148. body["nodelist"] = list()
  149. body["linklist"] = list()
  150. body["facelist"] = list()
  151.  
  152. boneformat = cloth["boneformat"]
  153. ranges = cloth["formatranges"]
  154. body["boneprefix"] = boneformat.format(*["" for r in ranges])
  155. counters = [r[0] for r in ranges]
  156.  
  157. while 1:
  158. name = boneformat.format(*counters)
  159. body["nodelist"].append( (name, 1) )
  160.  
  161. endLoop = True
  162. for n in range(len(counters)):
  163. counters[n]+=1
  164. if counters[n] <= ranges[n][1]:
  165. endLoop = False
  166. break
  167. #end
  168.  
  169. counters[n] = ranges[n][0]
  170. #end
  171.  
  172. #if we go through the for-loop without breaking then the range is completed
  173. if endLoop:
  174. break
  175. #end
  176.  
  177. width = cloth["width"]
  178. height = cloth["height"]
  179.  
  180. for row in range(height):
  181. for column in range(width):
  182. index = row*width+column
  183. #only create links along face edges
  184. #no shear/bend links, since those are handled more or less by bullet
  185. if row != 0:
  186. body["linklist"].append( (index, index-width) )
  187. if column != 0:
  188. body["linklist"].append( (index, index-1) )
  189.  
  190. if (row != 0) and (column != 0):
  191. body["facelist"].append( (index, index-1, index-width-1, index-width) )
  192. #end
  193. #end
  194.  
  195. if not "softbodies" in data:
  196. data["softbodies"] = list()
  197.  
  198. data["softbodies"].append(body)
  199. #end
  200. #end
  201.  
  202. if "softbodies" in data:
  203. for body in data["softbodies"]:
  204. group = softbodyGroup.CreateControlGroup("Softbody ("+body["boneprefix"]+")")
  205. softrig = SoftbodyRig(data=body)
  206. softrig.writeToGroup(group)
  207. #end
  208. #end
  209.  
  210. sfmUtils.SetControlGroupColor(rigidbodyGroup, vs.Color(128,255,128,255))
  211. sfmUtils.SetControlGroupColor(constraintGroup, vs.Color(128,200,200,255))
  212. sfmUtils.SetControlGroupColor(softbodyGroup, vs.Color(128,128,255,255))
  213.  
  214. sfm.EndRig()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement