d3ed8c05fdd0889bb656ddf9ea1645cc6140f1a6
[blender.git] / release / scripts / startup / bl_ui / properties_physics_rigidbody_constraint.py
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
19 # <pep8 compliant>
20
21 import bpy
22 from bpy.types import (
23     Panel,
24 )
25
26
27 class PHYSICS_PT_rigidbody_constraint_panel:
28     bl_space_type = 'PROPERTIES'
29     bl_region_type = 'WINDOW'
30     bl_context = "physics"
31
32
33 class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel):
34     bl_label = "Rigid Body Constraint"
35     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
36
37     @classmethod
38     def poll(cls, context):
39         ob = context.object
40         return (ob and ob.rigid_body_constraint and context.engine in cls.COMPAT_ENGINES)
41
42     def draw(self, context):
43         layout = self.layout
44         layout.use_property_split = True
45
46         ob = context.object
47         rbc = ob.rigid_body_constraint
48
49         layout.prop(rbc, "type")
50
51
52 class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_panel, Panel):
53     bl_label = "Settings"
54     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
55     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
56
57     @classmethod
58     def poll(cls, context):
59         ob = context.object
60         return (ob and ob.rigid_body_constraint and context.engine in cls.COMPAT_ENGINES)
61
62     def draw(self, context):
63         layout = self.layout
64         layout.use_property_split = True
65         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
66
67         ob = context.object
68         rbc = ob.rigid_body_constraint
69
70         col = flow.column()
71         col.prop(rbc, "enabled")
72         col.prop(rbc, "disable_collisions")
73
74         if rbc.type != 'MOTOR':
75             col = flow.column()
76             col.prop(rbc, "use_breaking")
77
78             sub = col.column()
79             sub.active = rbc.use_breaking
80             sub.prop(rbc, "breaking_threshold", text="Threshold")
81
82
83 class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_panel, Panel):
84     bl_label = "Objects"
85     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
86     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
87
88     @classmethod
89     def poll(cls, context):
90         ob = context.object
91         return (ob and ob.rigid_body_constraint and context.engine in cls.COMPAT_ENGINES)
92
93     def draw(self, context):
94         layout = self.layout
95         layout.use_property_split = True
96
97         ob = context.object
98         rbc = ob.rigid_body_constraint
99
100         layout.prop(rbc, "object1", text="First")
101         layout.prop(rbc, "object2", text="Second")
102
103
104 class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_constraint_panel, Panel):
105     bl_label = "Override Iterations"
106     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
107     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
108
109     @classmethod
110     def poll(cls, context):
111         ob = context.object
112         return (ob and ob.rigid_body_constraint and context.engine in cls.COMPAT_ENGINES)
113
114     def draw_header(self, context):
115         ob = context.object
116         rbc = ob.rigid_body_constraint
117         self.layout.row().prop(rbc, "use_override_solver_iterations", text="")
118
119     def draw(self, context):
120         layout = self.layout
121         layout.use_property_split = True
122
123         ob = context.object
124         rbc = ob.rigid_body_constraint
125
126         layout.active = rbc.use_override_solver_iterations
127         layout.prop(rbc, "solver_iterations", text="Iterations")
128
129
130 class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_panel, Panel):
131     bl_label = "Limits"
132     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
133     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
134
135     @classmethod
136     def poll(cls, context):
137         ob = context.object
138         rbc = ob.rigid_body_constraint
139
140         return (ob and rbc and (rbc.type in {'GENERIC', 'GENERIC_SPRING', 'HINGE', 'SLIDER', 'PISTON'})
141                 and context.engine in cls.COMPAT_ENGINES)
142
143     def draw(self, context):
144         return  # do nothing.
145
146
147 class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel):
148     bl_label = "Linear"
149     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits'
150     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
151
152     @classmethod
153     def poll(cls, context):
154         ob = context.object
155         rbc = ob.rigid_body_constraint
156
157         return (ob and rbc
158                 and (rbc.type in {'GENERIC', 'GENERIC_SPRING', 'SLIDER', 'PISTON'})
159                 and context.engine in cls.COMPAT_ENGINES)
160
161     def draw(self, context):
162         layout = self.layout
163         layout.use_property_split = True
164         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
165
166         ob = context.object
167         rbc = ob.rigid_body_constraint
168
169         if rbc.type in {'PISTON', 'SLIDER'}:
170             col = flow.column()
171             col.prop(rbc, "use_limit_lin_x")
172
173             sub = col.column(align=True)
174             sub.active = rbc.use_limit_lin_x
175             sub.prop(rbc, "limit_lin_x_lower", text="X Lower")
176             sub.prop(rbc, "limit_lin_x_upper", text="Upper")
177
178         elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}:
179             col = flow.column()
180             col.prop(rbc, "use_limit_lin_x")
181
182             sub = col.column(align=True)
183             sub.active = rbc.use_limit_lin_x
184             sub.prop(rbc, "limit_lin_x_lower", text="X Lower")
185             sub.prop(rbc, "limit_lin_x_upper", text="Upper")
186
187             col = flow.column()
188             col.prop(rbc, "use_limit_lin_y")
189
190             sub = col.column(align=True)
191             sub.active = rbc.use_limit_lin_y
192             sub.prop(rbc, "limit_lin_y_lower", text="Y Lower")
193             sub.prop(rbc, "limit_lin_y_upper", text="Upper")
194
195             col = flow.column()
196             col.prop(rbc, "use_limit_lin_z")
197
198             sub = col.column(align=True)
199             sub.active = rbc.use_limit_lin_z
200             sub.prop(rbc, "limit_lin_z_lower", text="Z Lower")
201             sub.prop(rbc, "limit_lin_z_upper", text="Upper")
202
203
204 class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel):
205     bl_label = "Angular"
206     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits'
207     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
208
209     @classmethod
210     def poll(cls, context):
211         ob = context.object
212         rbc = ob.rigid_body_constraint
213
214         return (ob and rbc
215                 and (rbc.type in {'GENERIC', 'GENERIC_SPRING', 'HINGE', 'PISTON'})
216                 and context.engine in cls.COMPAT_ENGINES)
217
218     def draw(self, context):
219         layout = self.layout
220         layout.use_property_split = True
221         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
222
223         ob = context.object
224         rbc = ob.rigid_body_constraint
225
226         if rbc.type == 'HINGE':
227             col = flow.column()
228             col.prop(rbc, "use_limit_ang_z")
229
230             sub = col.column(align=True)
231             sub.active = rbc.use_limit_ang_z
232             sub.prop(rbc, "limit_ang_z_lower", text="Z Lower")
233             sub.prop(rbc, "limit_ang_z_upper", text="Upper")
234
235         elif rbc.type == 'PISTON':
236             col = flow.column()
237             col.prop(rbc, "use_limit_ang_x")
238
239             sub = col.column(align=True)
240             sub.active = rbc.use_limit_ang_x
241             sub.prop(rbc, "limit_ang_x_lower", text="X Lower")
242             sub.prop(rbc, "limit_ang_x_upper", text="Upper")
243
244         elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}:
245             col = flow.column()
246             col.prop(rbc, "use_limit_ang_x")
247
248             sub = col.column(align=True)
249             sub.active = rbc.use_limit_ang_x
250             sub.prop(rbc, "limit_ang_x_lower", text="X Lower")
251             sub.prop(rbc, "limit_ang_x_upper", text="Upper")
252
253             col = flow.column()
254             col.prop(rbc, "use_limit_ang_y")
255
256             sub = col.column(align=True)
257             sub.active = rbc.use_limit_ang_y
258             sub.prop(rbc, "limit_ang_y_lower", text="Y Lower")
259             sub.prop(rbc, "limit_ang_y_upper", text="Upper")
260
261             col = flow.column()
262             col.prop(rbc, "use_limit_ang_z")
263
264             sub = col.column(align=True)
265             sub.active = rbc.use_limit_ang_z
266             sub.prop(rbc, "limit_ang_z_lower", text="Z Lower")
267             sub.prop(rbc, "limit_ang_z_upper", text="Upper")
268
269
270 class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_panel, Panel):
271     bl_label = "Motor"
272     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
273     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
274
275     @classmethod
276     def poll(cls, context):
277         ob = context.object
278         rbc = ob.rigid_body_constraint
279
280         return (ob and rbc and rbc.type == 'MOTOR'
281                 and context.engine in cls.COMPAT_ENGINES)
282
283     def draw(self, context):
284         return  # do nothing.
285
286
287 class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel):
288     bl_label = "Angular"
289     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor'
290     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
291
292     @classmethod
293     def poll(cls, context):
294         ob = context.object
295         rbc = ob.rigid_body_constraint
296
297         return (ob and rbc and rbc.type == 'MOTOR'
298                 and context.engine in cls.COMPAT_ENGINES)
299
300     def draw_header(self, context):
301         ob = context.object
302         rbc = ob.rigid_body_constraint
303
304         self.layout.row().prop(rbc, "use_motor_ang", text="")
305
306     def draw(self, context):
307         layout = self.layout
308         layout.use_property_split = True
309         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
310
311         ob = context.object
312         rbc = ob.rigid_body_constraint
313
314         flow.active = rbc.use_motor_ang
315
316         col = flow.column(align=True)
317         col.prop(rbc, "motor_ang_target_velocity", text="Target Velocity")
318
319         col = flow.column(align=True)
320         col.prop(rbc, "motor_ang_max_impulse", text="Max Impulse")
321
322
323 class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel):
324     bl_label = "Linear"
325     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor'
326     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
327
328     @classmethod
329     def poll(cls, context):
330         ob = context.object
331         rbc = ob.rigid_body_constraint
332
333         return (ob and rbc and rbc.type == 'MOTOR'
334                 and context.engine in cls.COMPAT_ENGINES)
335
336     def draw_header(self, context):
337         ob = context.object
338         rbc = ob.rigid_body_constraint
339
340         self.layout.row().prop(rbc, "use_motor_lin", text="")
341
342     def draw(self, context):
343         layout = self.layout
344         layout.use_property_split = True
345         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
346
347         ob = context.object
348         rbc = ob.rigid_body_constraint
349
350         flow.active = rbc.use_motor_lin
351
352         col = flow.column(align=True)
353         col.prop(rbc, "motor_lin_target_velocity", text="Target Velocity")
354
355         col = flow.column(align=True)
356         col.prop(rbc, "motor_lin_max_impulse", text="Max Impulse")
357
358
359 class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_panel, Panel):
360     bl_label = "Springs"
361     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
362     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
363
364     @classmethod
365     def poll(cls, context):
366         ob = context.object
367         rbc = ob.rigid_body_constraint
368
369         return (ob and ob.rigid_body_constraint
370                 and rbc.type in {'GENERIC_SPRING'}
371                 and context.engine in cls.COMPAT_ENGINES)
372
373     def draw(self, context):
374         layout = self.layout
375         layout.use_property_split = True
376
377         ob = context.object
378         rbc = ob.rigid_body_constraint
379
380         layout.prop(rbc, "spring_type", text="Type")
381
382
383 class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel):
384     bl_label = "Angular"
385     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs'
386     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
387
388     @classmethod
389     def poll(cls, context):
390         ob = context.object
391         rbc = ob.rigid_body_constraint
392
393         return (ob and ob.rigid_body_constraint
394                 and rbc.type in {'GENERIC_SPRING'}
395                 and context.engine in cls.COMPAT_ENGINES)
396
397     def draw(self, context):
398         layout = self.layout
399         layout.use_property_split = True
400
401         ob = context.object
402         rbc = ob.rigid_body_constraint
403
404         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
405
406         col = flow.column()
407         col.prop(rbc, "use_spring_ang_x", text="X Angle")
408
409         sub = col.column(align=True)
410         sub.active = rbc.use_spring_ang_x
411         sub.prop(rbc, "spring_stiffness_ang_x", text="X Stiffness")
412         sub.prop(rbc, "spring_damping_ang_x", text="Damping")
413
414         col = flow.column()
415         col.prop(rbc, "use_spring_ang_y", text="Y Angle")
416
417         sub = col.column(align=True)
418         sub.active = rbc.use_spring_ang_y
419         sub.prop(rbc, "spring_stiffness_ang_y", text="Y Stiffness")
420         sub.prop(rbc, "spring_damping_ang_y", text="Damping")
421
422         col = flow.column()
423         col.prop(rbc, "use_spring_ang_z", text="Z Angle")
424
425         sub = col.column(align=True)
426         sub.active = rbc.use_spring_ang_z
427         sub.prop(rbc, "spring_stiffness_ang_z", text="Z Stiffness")
428         sub.prop(rbc, "spring_damping_ang_z", text="Damping")
429
430
431 class PHYSICS_PT_rigid_body_constraint_springs_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel):
432     bl_label = "Linear"
433     bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs'
434     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
435
436     @classmethod
437     def poll(cls, context):
438         ob = context.object
439         rbc = ob.rigid_body_constraint
440
441         return (ob and ob.rigid_body_constraint
442                 and rbc.type in {'GENERIC_SPRING'}
443                 and context.engine in cls.COMPAT_ENGINES)
444
445     def draw(self, context):
446         layout = self.layout
447         layout.use_property_split = True
448
449         ob = context.object
450         rbc = ob.rigid_body_constraint
451
452         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
453
454         col = flow.column()
455         col.prop(rbc, "use_spring_x", text="X Axis")
456
457         sub = col.column(align=True)
458         sub.active = rbc.use_spring_x
459         sub.prop(rbc, "spring_stiffness_x", text="X Stiffness")
460         sub.prop(rbc, "spring_damping_x", text="Damping")
461
462         col = flow.column()
463         col.prop(rbc, "use_spring_y", text="Y Axis")
464
465         sub = col.column(align=True)
466         sub.active = rbc.use_spring_y
467         sub.prop(rbc, "spring_stiffness_y", text="Stiffness")
468         sub.prop(rbc, "spring_damping_y", text="Damping")
469
470         col = flow.column()
471         col.prop(rbc, "use_spring_z", text="Z Axis")
472
473         sub = col.column(align=True)
474         sub.active = rbc.use_spring_z
475         sub.prop(rbc, "spring_stiffness_z", text="Stiffness")
476         sub.prop(rbc, "spring_damping_z", text="Damping")
477
478
479 classes = (
480     PHYSICS_PT_rigid_body_constraint,
481     PHYSICS_PT_rigid_body_constraint_settings,
482     PHYSICS_PT_rigid_body_constraint_limits,
483     PHYSICS_PT_rigid_body_constraint_limits_angular,
484     PHYSICS_PT_rigid_body_constraint_limits_linear,
485     PHYSICS_PT_rigid_body_constraint_motor,
486     PHYSICS_PT_rigid_body_constraint_motor_angular,
487     PHYSICS_PT_rigid_body_constraint_motor_linear,
488     PHYSICS_PT_rigid_body_constraint_objects,
489     PHYSICS_PT_rigid_body_constraint_override_iterations,
490     PHYSICS_PT_rigid_body_constraint_springs,
491     PHYSICS_PT_rigid_body_constraint_springs_angular,
492     PHYSICS_PT_rigid_body_constraint_springs_linear,
493 )
494
495
496 if __name__ == "__main__":  # only for live edit.
497     from bpy.utils import register_class
498     for cls in classes:
499         register_class(cls)