Added game soft body settings, and cleaned up layout there slightly.
[blender.git] / release / ui / buttons_object_constraint.py
1
2 import bpy
3
4 class ConstraintButtonsPanel(bpy.types.Panel):
5         __space_type__ = "BUTTONS_WINDOW"
6         __region_type__ = "WINDOW"
7         __context__ = "constraint"
8
9         def draw_constraint(self, con):
10                 layout = self.layout
11                 
12                 box = layout.template_constraint(con)
13
14                 if box:
15                         # match enum type to our functions, avoids a lookup table.
16                         getattr(self, con.type)(box, con)
17         
18                         # show/key buttons here are most likely obsolete now, with
19                         # keyframing functionality being part of every button
20                         if con.type not in ('RIGID_BODY_JOINT', 'NULL'):
21                                 box.itemR(con, "influence")
22         
23         def space_template(self, layout, con, target=True, owner=True):
24                 if target or owner:
25                         row = layout.row()
26
27                         row.itemL(text="Convert:")
28
29                         if target:
30                                 row.itemR(con, "target_space", text="")
31
32                         if target and owner:
33                                 row.itemL(icon='ICON_ARROW_LEFTRIGHT')
34
35                         if owner:
36                                 row.itemR(con, "owner_space", text="")
37                         
38         def target_template(self, layout, con, subtargets=True):
39                 layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
40                 
41                 if con.target and subtargets:
42                         if con.target.type == "ARMATURE":
43                                 layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
44                                 
45                                 if con.type == 'COPY_LOCATION':
46                                         row = layout.row()
47                                         row.itemL(text="Head/Tail:")
48                                         row.itemR(con, "head_tail", text="")
49                         elif con.target.type in ('MESH', 'LATTICE'):
50                                 layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
51         
52         def CHILD_OF(self, layout, con):
53                 self.target_template(layout, con)
54
55                 split = layout.split()
56                 
57                 col = split.column()
58                 col.itemL(text="Location:")
59                 col.itemR(con, "locationx", text="X")
60                 col.itemR(con, "locationy", text="Y")
61                 col.itemR(con, "locationz", text="Z")
62                 
63                 col = split.column()
64                 col.itemL(text="Rotation:")
65                 col.itemR(con, "rotationx", text="X")
66                 col.itemR(con, "rotationy", text="Y")
67                 col.itemR(con, "rotationz", text="Z")
68                 
69                 col = split.column()
70                 col.itemL(text="Scale:")
71                 col.itemR(con, "sizex", text="X")
72                 col.itemR(con, "sizey", text="Y")
73                 col.itemR(con, "sizez", text="Z")
74                 
75                 row = layout.row()
76                 row.itemO("constraint.childof_set_inverse")
77                 row.itemO("constraint.childof_clear_inverse")
78                 
79         def TRACK_TO(self, layout, con):
80                 self.target_template(layout, con)
81                 
82                 row = layout.row()
83                 row.itemL(text="To:")
84                 row.itemR(con, "track", expand=True)
85                 
86                 row = layout.row()
87                 #row.itemR(con, "up", text="Up", expand=True) # XXX: up and expand don't play nice together
88                 row.itemR(con, "up", text="Up")
89                 row.itemR(con, "target_z")
90                 
91                 self.space_template(layout, con)
92                 
93         def IK(self, layout, con):
94                 self.target_template(layout, con)
95                 
96                 layout.itemR(con, "pole_target")
97         
98                 if con.pole_target and con.pole_target.type == 'ARMATURE':
99                         layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
100                 
101                 split = layout.split()
102         
103                 col = split.column()
104                 col.itemR(con, "iterations")
105                 col.itemR(con, "chain_length")
106                 sub = col.column()
107                 sub.active = con.pole_target
108                 sub.itemR(con, "pole_angle")
109                 col.itemL(text="Weight:")
110                 col.itemR(con, "weight", text="Position", slider=True)
111                 sub = col.column()
112                 sub.active = con.rotation
113                 sub.itemR(con, "orient_weight", text="Rotation", slider=True)
114                 
115                 col = split.column()
116                 col.itemR(con, "tail")
117                 col.itemR(con, "rotation")
118                 col.itemR(con, "targetless")
119                 col.itemR(con, "stretch")
120                 
121         def FOLLOW_PATH(self, layout, con):
122                 self.target_template(layout, con)
123                 
124                 row = layout.row()
125                 row.itemR(con, "curve_follow")
126                 row.itemR(con, "offset")
127                 
128                 row = layout.row()
129                 row.itemL(text="Forward:")
130                 row.itemR(con, "forward", expand=True)
131                 
132                 row = layout.row()
133                 row.itemR(con, "up", text="Up")
134                 row.itemL()
135                 
136         def LIMIT_ROTATION(self, layout, con):
137                 
138                 split = layout.split()
139                 
140                 col = split.column()
141                 col.itemR(con, "use_limit_x")
142                 sub = col.column()
143                 sub.active = con.use_limit_x
144                 sub.itemR(con, "minimum_x", text="Min")
145                 sub.itemR(con, "maximum_x", text="Max")
146                 
147                 col = split.column()
148                 col.itemR(con, "use_limit_y")
149                 sub = col.column()
150                 sub.active = con.use_limit_y
151                 sub.itemR(con, "minimum_y", text="Min")
152                 sub.itemR(con, "maximum_y", text="Max")
153                 
154                 col = split.column()
155                 col.itemR(con, "use_limit_z")
156                 sub = col.column()
157                 sub.active = con.use_limit_z
158                 sub.itemR(con, "minimum_z", text="Min")
159                 sub.itemR(con, "maximum_z", text="Max")
160                 
161                 row = layout.row()
162                 row.itemR(con, "limit_transform")
163                 row.itemL()
164                 
165                 row = layout.row()
166                 row.itemL(text="Convert:")
167                 row.itemR(con, "owner_space", text="")
168                 
169         def LIMIT_LOCATION(self, layout, con):
170                 split = layout.split()
171                 
172                 col = split.column()
173                 col.itemR(con, "use_minimum_x")
174                 sub = col.column()
175                 sub.active = con.use_minimum_x
176                 sub.itemR(con, "minimum_x", text="")
177                 col.itemR(con, "use_maximum_x")
178                 sub = col.column()
179                 sub.active = con.use_maximum_x
180                 sub.itemR(con, "maximum_x", text="")
181                 
182                 col = split.column()
183                 col.itemR(con, "use_minimum_y")
184                 sub = col.column()
185                 sub.active = con.use_minimum_y
186                 sub.itemR(con, "minimum_y", text="")
187                 col.itemR(con, "use_maximum_y")
188                 sub = col.column()
189                 sub.active = con.use_maximum_y
190                 sub.itemR(con, "maximum_y", text="")
191                 
192                 col = split.column()
193                 col.itemR(con, "use_minimum_z")
194                 sub = col.column()
195                 sub.active = con.use_minimum_z
196                 sub.itemR(con, "minimum_z", text="")
197                 col.itemR(con, "use_maximum_z")
198                 sub = col.column()
199                 sub.active = con.use_maximum_z
200                 sub.itemR(con, "maximum_z", text="")
201         
202                 row = layout.row()
203                 row.itemR(con, "limit_transform")
204                 row.itemL()
205                 
206                 row = layout.row()
207                 row.itemL(text="Convert:")
208                 row.itemR(con, "owner_space", text="")
209                 
210         def LIMIT_SCALE(self, layout, con):
211                 split = layout.split()
212
213                 col = split.column()
214                 col.itemR(con, "use_minimum_x")
215                 sub = col.column()
216                 sub.active = con.use_minimum_x
217                 sub.itemR(con, "minimum_x", text="")
218                 col.itemR(con, "use_maximum_x")
219                 sub = col.column()
220                 sub.active = con.use_maximum_x
221                 sub.itemR(con, "maximum_x", text="")
222                 
223                 col = split.column()
224                 col.itemR(con, "use_minimum_y")
225                 sub = col.column()
226                 sub.active = con.use_minimum_y
227                 sub.itemR(con, "minimum_y", text="")
228                 col.itemR(con, "use_maximum_y")
229                 sub = col.column()
230                 sub.active = con.use_maximum_y
231                 sub.itemR(con, "maximum_y", text="")
232                 
233                 col = split.column()
234                 col.itemR(con, "use_minimum_z")
235                 sub = col.column()
236                 sub.active = con.use_minimum_z
237                 sub.itemR(con, "minimum_z", text="")
238                 col.itemR(con, "use_maximum_z")
239                 sub = col.column()
240                 sub.active = con.use_maximum_z
241                 sub.itemR(con, "maximum_z", text="")
242                 
243                 row = layout.row()
244                 row.itemR(con, "limit_transform")
245                 row.itemL()
246                 
247                 row = layout.row()
248                 row.itemL(text="Convert:")
249                 row.itemR(con, "owner_space", text="")
250         
251         def COPY_ROTATION(self, layout, con):
252                 self.target_template(layout, con)
253                 
254                 split = layout.split()
255                 
256                 col = split.column()
257                 col.itemR(con, "rotate_like_x", text="X")
258                 sub = col.column()
259                 sub.active = con.rotate_like_x
260                 sub.itemR(con, "invert_x", text="Invert")
261                 
262                 col = split.column()
263                 col.itemR(con, "rotate_like_y", text="Y")
264                 sub = col.column()
265                 sub.active = con.rotate_like_y
266                 sub.itemR(con, "invert_y", text="Invert")
267                 
268                 col = split.column()
269                 col.itemR(con, "rotate_like_z", text="Z")
270                 sub = col.column()
271                 sub.active = con.rotate_like_z
272                 sub.itemR(con, "invert_z", text="Invert")
273
274                 layout.itemR(con, "offset")
275                 
276                 self.space_template(layout, con)
277                 
278         def COPY_LOCATION(self, layout, con):
279                 self.target_template(layout, con)
280                 
281                 split = layout.split()
282                 
283                 col = split.column()
284                 col.itemR(con, "locate_like_x", text="X")
285                 sub = col.column()
286                 sub.active = con.locate_like_x
287                 sub.itemR(con, "invert_x", text="Invert")
288                 
289                 col = split.column()
290                 col.itemR(con, "locate_like_y", text="Y")
291                 sub = col.column()
292                 sub.active = con.locate_like_y
293                 sub.itemR(con, "invert_y", text="Invert")
294                 
295                 col = split.column()
296                 col.itemR(con, "locate_like_z", text="Z")
297                 sub = col.column()
298                 sub.active = con.locate_like_z
299                 sub.itemR(con, "invert_z", text="Invert")
300
301                 layout.itemR(con, "offset")
302                         
303                 self.space_template(layout, con)
304                 
305         def COPY_SCALE(self, layout, con):
306                 self.target_template(layout, con)
307                 
308                 row = layout.row(align=True)
309                 row.itemR(con, "size_like_x", text="X")
310                 row.itemR(con, "size_like_y", text="Y")
311                 row.itemR(con, "size_like_z", text="Z")
312
313                 layout.itemR(con, "offset")
314                 
315                 self.space_template(layout, con)
316                 
317         #def SCRIPT(self, layout, con):
318         
319         def ACTION(self, layout, con):
320                 self.target_template(layout, con)
321                 
322                 layout.itemR(con, "action")
323                 layout.itemR(con, "transform_channel")
324
325                 split = layout.split()
326         
327                 col = split.column(align=True)
328                 col.itemR(con, "start_frame", text="Start")
329                 col.itemR(con, "end_frame", text="End")
330                 
331                 col = split.column(align=True)
332                 col.itemR(con, "minimum", text="Min")
333                 col.itemR(con, "maximum", text="Max")
334                 
335                 row = layout.row()
336                 row.itemL(text="Convert:")
337                 row.itemR(con, "owner_space", text="")
338         
339         def LOCKED_TRACK(self, layout, con):
340                 self.target_template(layout, con)
341                 
342                 row = layout.row()
343                 row.itemL(text="To:")
344                 row.itemR(con, "track", expand=True)
345                 
346                 row = layout.row()
347                 row.itemL(text="Lock:")
348                 row.itemR(con, "locked", expand=True)
349                 
350         def LIMIT_DISTANCE(self, layout, con):
351                 self.target_template(layout, con)
352                 
353                 col = layout.column(align=True);
354                 col.itemR(con, "distance")
355                 col.itemO("constraint.limitdistance_reset")
356                 
357                 row = layout.row()
358                 row.itemL(text="Clamp Region:")
359                 row.itemR(con, "limit_mode", text="")
360                 
361         def STRETCH_TO(self, layout, con):
362                 self.target_template(layout, con)
363                 
364                 row = layout.row()
365                 row.itemR(con, "original_length", text="Rest Length")
366                 row.itemO("constraint.stretchto_reset", text="Reset")
367                 
368                 col = layout.column()
369                 col.itemR(con, "bulge", text="Volume Variation")
370                 
371                 row = layout.row()
372                 row.itemL(text="Volume:")
373                 row.itemR(con, "volume", expand=True)
374                 row.itemL(text="Plane:")
375                 row.itemR(con, "keep_axis", expand=True)
376                 
377         def FLOOR(self, layout, con):
378                 self.target_template(layout, con)
379                 
380                 row = layout.row()
381                 row.itemR(con, "sticky")
382                 row.itemR(con, "use_rotation")
383                 
384                 layout.itemR(con, "offset")
385                 
386                 row = layout.row()
387                 row.itemL(text="Min/Max:")
388                 row.itemR(con, "floor_location", expand=True)
389                 
390         def RIGID_BODY_JOINT(self, layout, con):
391                 self.target_template(layout, con)
392                 
393                 layout.itemR(con, "pivot_type")
394                 layout.itemR(con, "child")
395                 
396                 row = layout.row()
397                 row.itemR(con, "disable_linked_collision", text="No Collision")
398                 row.itemR(con, "draw_pivot", text="Display Pivot")
399                 
400                 split = layout.split()
401                 
402                 col = split.column(align=True)
403                 col.itemL(text="Pivot:")
404                 col.itemR(con, "pivot_x", text="X")
405                 col.itemR(con, "pivot_y", text="Y")
406                 col.itemR(con, "pivot_z", text="Z")
407                 
408                 col = split.column(align=True)
409                 col.itemL(text="Axis:")
410                 col.itemR(con, "axis_x", text="X")
411                 col.itemR(con, "axis_y", text="Y")
412                 col.itemR(con, "axis_z", text="Z")
413                 
414                 #Missing: Limit arrays (not wrapped in RNA yet) 
415         
416         def CLAMP_TO(self, layout, con):
417                 self.target_template(layout, con)
418                 
419                 row = layout.row()
420                 row.itemL(text="Main Axis:")
421                 row.itemR(con, "main_axis", expand=True)
422                 
423                 row = layout.row()
424                 row.itemR(con, "cyclic")
425                 
426         def TRANSFORM(self, layout, con):
427                 self.target_template(layout, con)
428                 
429                 layout.itemR(con, "extrapolate_motion", text="Extrapolate")
430                 
431                 split = layout.split()
432                 
433                 col = split.column()
434                 col.itemL(text="Source:")
435                 col.row().itemR(con, "map_from", expand=True)
436                 
437                 sub = col.row(align=True)
438                 sub.itemL(text="X:")
439                 sub.itemR(con, "from_min_x", text="")
440                 sub.itemR(con, "from_max_x", text="")
441                 
442                 sub = col.row(align=True)
443                 sub.itemL(text="Y:")
444                 sub.itemR(con, "from_min_y", text="")
445                 sub.itemR(con, "from_max_y", text="")
446                 
447                 sub = col.row(align=True)
448                 sub.itemL(text="Z:")
449                 sub.itemR(con, "from_min_z", text="")
450                 sub.itemR(con, "from_max_z", text="")
451                 
452                 split = layout.split()
453                 
454                 col = split.column()
455                 col.itemL(text="Destination:")
456                 col.row().itemR(con, "map_to", expand=True)
457
458                 sub = col.row(align=True)
459                 sub.itemR(con, "map_to_x_from", text="")
460                 sub.itemR(con, "to_min_x", text="")
461                 sub.itemR(con, "to_max_x", text="")
462                 
463                 sub = col.row(align=True)
464                 sub.itemR(con, "map_to_y_from", text="")
465                 sub.itemR(con, "to_min_y", text="")
466                 sub.itemR(con, "to_max_y", text="")
467                 
468                 sub = col.row(align=True)
469                 sub.itemR(con, "map_to_z_from", text="")
470                 sub.itemR(con, "to_min_z", text="")
471                 sub.itemR(con, "to_max_z", text="")
472                 
473                 self.space_template(layout, con)
474                 
475         def SHRINKWRAP (self, layout, con):
476                 self.target_template(layout, con)
477                 
478                 layout.itemR(con, "distance")
479                 layout.itemR(con, "shrinkwrap_type")
480                 
481                 if con.shrinkwrap_type == "PROJECT":
482                         row = layout.row(align=True)
483                         row.itemR(con, "axis_x")
484                         row.itemR(con, "axis_y")
485                         row.itemR(con, "axis_z")
486                 
487 class OBJECT_PT_constraints(ConstraintButtonsPanel):
488         __label__ = "Constraints"
489         __context__ = "constraint"
490
491         def poll(self, context):
492                 return (context.object)
493                 
494         def draw(self, context):
495                 layout = self.layout
496                 ob = context.object
497
498                 row = layout.row()
499                 row.item_menu_enumO("object.constraint_add", "type")
500                 row.itemL();
501
502                 for con in ob.constraints:
503                         self.draw_constraint(con)
504
505 class BONE_PT_constraints(ConstraintButtonsPanel):
506         __label__ = "Constraints"
507         __context__ = "bone"
508
509         def poll(self, context):
510                 ob = context.object
511                 return (ob and ob.type == 'ARMATURE' and context.bone)
512                 
513         def draw(self, context):
514                 layout = self.layout
515                 
516                 ob = context.object
517                 pchan = ob.pose.pose_channels[context.bone.name]
518
519                 row = layout.row()
520                 row.item_menu_enumO("pose.constraint_add", "type")
521                 row.itemL();
522
523                 for con in pchan.constraints:
524                         self.draw_constraint(con)
525
526 bpy.types.register(OBJECT_PT_constraints)
527 bpy.types.register(BONE_PT_constraints)