properties_physics_rigidbody.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8 compliant>
  19. from bpy.types import (
  20. Panel,
  21. )
  22. def rigid_body_warning(layout):
  23. row = layout.row(align=True)
  24. row.alignment = 'RIGHT'
  25. row.label(text="Object does not have a Rigid Body")
  26. class PHYSICS_PT_rigidbody_panel:
  27. bl_space_type = 'PROPERTIES'
  28. bl_region_type = 'WINDOW'
  29. bl_context = "physics"
  30. class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
  31. bl_label = "Rigid Body"
  32. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  33. @classmethod
  34. def poll(cls, context):
  35. obj = context.object
  36. return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
  37. def draw(self, context):
  38. layout = self.layout
  39. layout.use_property_split = True
  40. ob = context.object
  41. rbo = ob.rigid_body
  42. if rbo is None:
  43. rigid_body_warning(layout)
  44. return
  45. layout.prop(rbo, "type", text="Type")
  46. class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel):
  47. bl_label = "Settings"
  48. bl_parent_id = 'PHYSICS_PT_rigid_body'
  49. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  50. @classmethod
  51. def poll(cls, context):
  52. obj = context.object
  53. return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
  54. def draw(self, context):
  55. layout = self.layout
  56. layout.use_property_split = True
  57. ob = context.object
  58. rbo = ob.rigid_body
  59. if rbo is None:
  60. rigid_body_warning(layout)
  61. return
  62. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  63. col = flow.column()
  64. if rbo.type == 'ACTIVE':
  65. col.prop(rbo, "mass")
  66. col.prop(rbo, "enabled", text="Dynamic")
  67. col = flow.column()
  68. col.prop(rbo, "kinematic", text="Animated")
  69. class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
  70. bl_label = "Collisions"
  71. bl_parent_id = 'PHYSICS_PT_rigid_body'
  72. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  73. @classmethod
  74. def poll(cls, context):
  75. obj = context.object
  76. return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
  77. def draw(self, context):
  78. layout = self.layout
  79. ob = context.object
  80. rbo = ob.rigid_body
  81. layout.use_property_split = True
  82. layout.prop(rbo, "collision_shape", text="Shape")
  83. if rbo.collision_shape in {'MESH', 'CONVEX_HULL'}:
  84. layout.prop(rbo, "mesh_source", text="Source")
  85. if rbo.collision_shape == 'MESH' and rbo.mesh_source == 'DEFORM':
  86. layout.prop(rbo, "use_deform", text="Deforming")
  87. class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel):
  88. bl_label = "Surface Response"
  89. bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
  90. bl_options = {'DEFAULT_CLOSED'}
  91. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  92. @classmethod
  93. def poll(cls, context):
  94. obj = context.object
  95. return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
  96. def draw(self, context):
  97. layout = self.layout
  98. layout.use_property_split = True
  99. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  100. ob = context.object
  101. rbo = ob.rigid_body
  102. col = flow.column()
  103. col.prop(rbo, "friction")
  104. col = flow.column()
  105. col.prop(rbo, "restitution", text="Bounciness")
  106. class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, Panel):
  107. bl_label = "Sensitivity"
  108. bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
  109. bl_options = {'DEFAULT_CLOSED'}
  110. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  111. @classmethod
  112. def poll(cls, context):
  113. obj = context.object
  114. return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
  115. def draw(self, context):
  116. layout = self.layout
  117. layout.use_property_split = True
  118. ob = context.object
  119. rbo = ob.rigid_body
  120. if rbo.collision_shape in {'MESH', 'CONE'}:
  121. col = layout.column()
  122. col.prop(rbo, "collision_margin", text="Margin")
  123. else:
  124. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  125. col = flow.column()
  126. col.prop(rbo, "use_margin")
  127. col = flow.column()
  128. col.active = rbo.use_margin
  129. col.prop(rbo, "collision_margin", text="Margin")
  130. class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, Panel):
  131. bl_label = "Collections"
  132. bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
  133. bl_options = {'DEFAULT_CLOSED'}
  134. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  135. @classmethod
  136. def poll(cls, context):
  137. obj = context.object
  138. return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
  139. def draw(self, context):
  140. layout = self.layout
  141. ob = context.object
  142. rbo = ob.rigid_body
  143. layout.prop(rbo, "collision_collections", text="")
  144. class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
  145. bl_label = "Dynamics"
  146. bl_parent_id = 'PHYSICS_PT_rigid_body'
  147. bl_options = {'DEFAULT_CLOSED'}
  148. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  149. @classmethod
  150. def poll(cls, context):
  151. obj = context.object
  152. return (obj and obj.rigid_body and obj.rigid_body.type == 'ACTIVE'
  153. and (context.engine in cls.COMPAT_ENGINES))
  154. def draw(self, context):
  155. layout = self.layout
  156. layout.use_property_split = True
  157. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  158. ob = context.object
  159. rbo = ob.rigid_body
  160. # col = layout.column(align=True)
  161. # col.label(text="Activation:")
  162. # XXX: settings such as activate on collison/etc.
  163. col = flow.column()
  164. col.prop(rbo, "linear_damping", text="Damping Translation")
  165. col = flow.column()
  166. col.prop(rbo, "angular_damping", text="Rotation")
  167. class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Panel):
  168. bl_label = "Deactivation"
  169. bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics'
  170. bl_options = {'DEFAULT_CLOSED'}
  171. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  172. @classmethod
  173. def poll(cls, context):
  174. obj = context.object
  175. return (obj and obj.rigid_body
  176. and obj.rigid_body.type == 'ACTIVE'
  177. and (context.engine in cls.COMPAT_ENGINES))
  178. def draw_header(self, context):
  179. ob = context.object
  180. rbo = ob.rigid_body
  181. self.layout.prop(rbo, "use_deactivation", text="")
  182. def draw(self, context):
  183. layout = self.layout
  184. layout.use_property_split = True
  185. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  186. ob = context.object
  187. rbo = ob.rigid_body
  188. layout.active = rbo.use_deactivation
  189. col = flow.column()
  190. col.prop(rbo, "use_start_deactivated")
  191. col = flow.column()
  192. col.prop(rbo, "deactivate_linear_velocity", text="Velocity Linear")
  193. col.prop(rbo, "deactivate_angular_velocity", text="Angular")
  194. # TODO: other params such as time?
  195. classes = (
  196. PHYSICS_PT_rigid_body,
  197. PHYSICS_PT_rigid_body_settings,
  198. PHYSICS_PT_rigid_body_collisions,
  199. PHYSICS_PT_rigid_body_collisions_surface,
  200. PHYSICS_PT_rigid_body_collisions_sensitivity,
  201. PHYSICS_PT_rigid_body_collisions_collections,
  202. PHYSICS_PT_rigid_body_dynamics,
  203. PHYSICS_PT_rigid_body_dynamics_deactivation,
  204. )
  205. if __name__ == "__main__": # only for live edit.
  206. from bpy.utils import register_class
  207. for cls in classes:
  208. register_class(cls)