fix for misc py errors + some pep8 edits.
[blender.git] / release / scripts / startup / bl_ui / properties_game.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 import bpy
21 from bpy.types import Panel
22
23
24 class PhysicsButtonsPanel():
25     bl_space_type = 'PROPERTIES'
26     bl_region_type = 'WINDOW'
27     bl_context = "physics"
28
29
30 class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
31     bl_label = "Physics"
32     COMPAT_ENGINES = {'BLENDER_GAME'}
33
34     @classmethod
35     def poll(cls, context):
36         ob = context.active_object
37         rd = context.scene.render
38         return ob and ob.game and (rd.engine in cls.COMPAT_ENGINES)
39
40     def draw(self, context):
41         layout = self.layout
42
43         ob = context.active_object
44         game = ob.game
45         soft = ob.game.soft_body
46
47         layout.prop(game, "physics_type")
48         layout.separator()
49
50         #if game.physics_type == 'DYNAMIC':
51         if game.physics_type in {'DYNAMIC', 'RIGID_BODY'}:
52             split = layout.split()
53
54             col = split.column()
55             col.prop(game, "use_actor")
56             col.prop(game, "use_ghost")
57             col.prop(ob, "hide_render", text="Invisible")  # out of place but useful
58
59             col = split.column()
60             col.prop(game, "use_material_physics_fh")
61             col.prop(game, "use_rotate_from_normal")
62             col.prop(game, "use_sleep")
63
64             layout.separator()
65
66             split = layout.split()
67
68             col = split.column()
69             col.label(text="Attributes:")
70             col.prop(game, "mass")
71             col.prop(game, "radius")
72             col.prop(game, "form_factor")
73
74             col = split.column()
75             sub = col.column()
76             sub.prop(game, "use_anisotropic_friction")
77             subsub = sub.column()
78             subsub.active = game.use_anisotropic_friction
79             subsub.prop(game, "friction_coefficients", text="", slider=True)
80
81             split = layout.split()
82
83             col = split.column()
84             col.label(text="Velocity:")
85             sub = col.column(align=True)
86             sub.prop(game, "velocity_min", text="Minimum")
87             sub.prop(game, "velocity_max", text="Maximum")
88
89             col = split.column()
90             col.label(text="Damping:")
91             sub = col.column(align=True)
92             sub.prop(game, "damping", text="Translation", slider=True)
93             sub.prop(game, "rotation_damping", text="Rotation", slider=True)
94
95             layout.separator()
96
97             split = layout.split()
98
99             col = split.column()
100             col.label(text="Lock Translation:")
101             col.prop(game, "lock_location_x", text="X")
102             col.prop(game, "lock_location_y", text="Y")
103             col.prop(game, "lock_location_z", text="Z")
104
105             col = split.column()
106             col.label(text="Lock Rotation:")
107             col.prop(game, "lock_rotation_x", text="X")
108             col.prop(game, "lock_rotation_y", text="Y")
109             col.prop(game, "lock_rotation_z", text="Z")
110
111         elif game.physics_type == 'SOFT_BODY':
112             col = layout.column()
113             col.prop(game, "use_actor")
114             col.prop(game, "use_ghost")
115             col.prop(ob, "hide_render", text="Invisible")
116
117             layout.separator()
118
119             split = layout.split()
120
121             col = split.column()
122             col.label(text="Attributes:")
123             col.prop(game, "mass")
124             col.prop(soft, "weld_threshold")
125             col.prop(soft, "location_iterations")
126             col.prop(soft, "linear_stiffness", slider=True)
127             col.prop(soft, "dynamic_friction", slider=True)
128             col.prop(soft, "collision_margin", slider=True)
129             col.prop(soft, "use_bending_constraints", text="Bending Constraints")
130
131             col = split.column()
132             col.prop(soft, "use_shape_match")
133             sub = col.column()
134             sub.active = soft.use_shape_match
135             sub.prop(soft, "shape_threshold", slider=True)
136
137             col.separator()
138
139             col.label(text="Cluster Collision:")
140             col.prop(soft, "use_cluster_rigid_to_softbody")
141             col.prop(soft, "use_cluster_soft_to_softbody")
142             sub = col.column()
143             sub.active = (soft.use_cluster_rigid_to_softbody or soft.use_cluster_soft_to_softbody)
144             sub.prop(soft, "cluster_iterations", text="Iterations")
145
146         elif game.physics_type == 'STATIC':
147             col = layout.column()
148             col.prop(game, "use_actor")
149             col.prop(game, "use_ghost")
150             col.prop(ob, "hide_render", text="Invisible")
151
152             layout.separator()
153
154             split = layout.split()
155
156             col = split.column()
157             col.label(text="Attributes:")
158             col.prop(game, "radius")
159
160             col = split.column()
161             sub = col.column()
162             sub.prop(game, "use_anisotropic_friction")
163             subsub = sub.column()
164             subsub.active = game.use_anisotropic_friction
165             subsub.prop(game, "friction_coefficients", text="", slider=True)
166
167         elif game.physics_type in {'SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
168             layout.prop(ob, "hide_render", text="Invisible")
169
170
171 class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
172     bl_label = "Collision Bounds"
173     COMPAT_ENGINES = {'BLENDER_GAME'}
174
175     @classmethod
176     def poll(cls, context):
177         game = context.object.game
178         rd = context.scene.render
179         return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
180
181     def draw_header(self, context):
182         game = context.active_object.game
183
184         self.layout.prop(game, "use_collision_bounds", text="")
185
186     def draw(self, context):
187         layout = self.layout
188
189         game = context.active_object.game
190
191         layout.active = game.use_collision_bounds
192         layout.prop(game, "collision_bounds_type", text="Bounds")
193
194         row = layout.row()
195         row.prop(game, "collision_margin", text="Margin", slider=True)
196         row.prop(game, "use_collision_compound", text="Compound")
197
198
199 class RenderButtonsPanel():
200     bl_space_type = 'PROPERTIES'
201     bl_region_type = 'WINDOW'
202     bl_context = "render"
203
204     @classmethod
205     def poll(cls, context):
206         rd = context.scene.render
207         return (rd.engine in cls.COMPAT_ENGINES)
208
209
210 class RENDER_PT_game(RenderButtonsPanel, Panel):
211     bl_label = "Game"
212     COMPAT_ENGINES = {'BLENDER_GAME'}
213
214     def draw(self, context):
215         layout = self.layout
216
217         row = layout.row()
218         row.operator("view3d.game_start", text="Start")
219         row.label()
220
221
222 class RENDER_PT_game_player(RenderButtonsPanel, Panel):
223     bl_label = "Standalone Player"
224     COMPAT_ENGINES = {'BLENDER_GAME'}
225
226     def draw(self, context):
227         layout = self.layout
228
229         gs = context.scene.game_settings
230
231         layout.prop(gs, "show_fullscreen")
232
233         split = layout.split()
234
235         col = split.column()
236         col.label(text="Resolution:")
237         sub = col.column(align=True)
238         sub.prop(gs, "resolution_x", slider=False, text="X")
239         sub.prop(gs, "resolution_y", slider=False, text="Y")
240
241         col = split.column()
242         col.label(text="Quality:")
243         sub = col.column(align=True)
244         sub.prop(gs, "depth", text="Bit Depth", slider=False)
245         sub.prop(gs, "frequency", text="FPS", slider=False)
246
247         # framing:
248         col = layout.column()
249         col.label(text="Framing:")
250         col.row().prop(gs, "frame_type", expand=True)
251         if gs.frame_type == 'LETTERBOX':
252             col.prop(gs, "frame_color", text="")
253
254
255 class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
256     bl_label = "Stereo"
257     COMPAT_ENGINES = {'BLENDER_GAME'}
258
259     def draw(self, context):
260         layout = self.layout
261
262         gs = context.scene.game_settings
263         stereo_mode = gs.stereo
264
265         # stereo options:
266         layout.prop(gs, "stereo", expand=True)
267
268         # stereo:
269         if stereo_mode == 'STEREO':
270             layout.prop(gs, "stereo_mode")
271             layout.prop(gs, "stereo_eye_separation")
272
273         # dome:
274         elif stereo_mode == 'DOME':
275             layout.prop(gs, "dome_mode", text="Dome Type")
276
277             dome_type = gs.dome_mode
278
279             split = layout.split()
280
281             if dome_type == 'FISHEYE' or \
282                dome_type == 'TRUNCATED_REAR' or \
283                dome_type == 'TRUNCATED_FRONT':
284
285                 col = split.column()
286                 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
287                 col.prop(gs, "dome_angle", slider=True)
288
289                 col = split.column()
290                 col.prop(gs, "dome_tesselation", text="Tesselation")
291                 col.prop(gs, "dome_tilt")
292
293             elif dome_type == 'PANORAM_SPH':
294                 col = split.column()
295
296                 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
297                 col = split.column()
298                 col.prop(gs, "dome_tesselation", text="Tesselation")
299
300             else:  # cube map
301                 col = split.column()
302                 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
303
304                 col = split.column()
305
306             layout.prop(gs, "dome_text")
307
308
309 class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
310     bl_label = "Shading"
311     COMPAT_ENGINES = {'BLENDER_GAME'}
312
313     def draw(self, context):
314         layout = self.layout
315
316         gs = context.scene.game_settings
317
318         layout.prop(gs, "material_mode", expand=True)
319
320         if gs.material_mode == 'GLSL':
321             split = layout.split()
322
323             col = split.column()
324             col.prop(gs, "use_glsl_lights", text="Lights")
325             col.prop(gs, "use_glsl_shaders", text="Shaders")
326             col.prop(gs, "use_glsl_shadows", text="Shadows")
327             col.prop(gs, "use_glsl_color_management", text="Color Management")
328
329             col = split.column()
330             col.prop(gs, "use_glsl_ramps", text="Ramps")
331             col.prop(gs, "use_glsl_nodes", text="Nodes")
332             col.prop(gs, "use_glsl_extra_textures", text="Extra Textures")
333
334
335 class RENDER_PT_game_performance(RenderButtonsPanel, Panel):
336     bl_label = "Performance"
337     COMPAT_ENGINES = {'BLENDER_GAME'}
338
339     def draw(self, context):
340         layout = self.layout
341
342         gs = context.scene.game_settings
343         col = layout.column()
344         row = col.row()
345         row.prop(gs, "use_frame_rate")
346         row.prop(gs, "use_display_lists")
347
348         col.prop(gs, "restrict_animation_updates")
349
350
351 class RENDER_PT_game_display(RenderButtonsPanel, Panel):
352     bl_label = "Display"
353     COMPAT_ENGINES = {'BLENDER_GAME'}
354
355     def draw(self, context):
356         layout = self.layout
357
358         gs = context.scene.game_settings
359         flow = layout.column_flow()
360         flow.prop(gs, "show_debug_properties", text="Debug Properties")
361         flow.prop(gs, "show_framerate_profile", text="Framerate and Profile")
362         flow.prop(gs, "show_physics_visualization", text="Physics Visualization")
363         flow.prop(gs, "use_deprecation_warnings")
364         flow.prop(gs, "show_mouse", text="Mouse Cursor")
365
366
367 class WorldButtonsPanel():
368     bl_space_type = 'PROPERTIES'
369     bl_region_type = 'WINDOW'
370     bl_context = "world"
371
372
373 class WORLD_PT_game_context_world(WorldButtonsPanel, Panel):
374     bl_label = ""
375     bl_options = {'HIDE_HEADER'}
376     COMPAT_ENGINES = {'BLENDER_GAME'}
377
378     @classmethod
379     def poll(cls, context):
380         rd = context.scene.render
381         return (context.scene) and (rd.use_game_engine)
382
383     def draw(self, context):
384         layout = self.layout
385
386         scene = context.scene
387         world = context.world
388         space = context.space_data
389
390         split = layout.split(percentage=0.65)
391         if scene:
392             split.template_ID(scene, "world", new="world.new")
393         elif world:
394             split.template_ID(space, "pin_id")
395
396
397 class WORLD_PT_game_world(WorldButtonsPanel, Panel):
398     bl_label = "World"
399     COMPAT_ENGINES = {'BLENDER_GAME'}
400
401     @classmethod
402     def poll(cls, context):
403         scene = context.scene
404         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
405
406     def draw(self, context):
407         layout = self.layout
408
409         world = context.world
410
411         row = layout.row()
412         row.column().prop(world, "horizon_color")
413         row.column().prop(world, "ambient_color")
414
415
416 class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
417     bl_label = "Mist"
418     COMPAT_ENGINES = {'BLENDER_GAME'}
419
420     @classmethod
421     def poll(cls, context):
422         scene = context.scene
423         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
424
425     def draw_header(self, context):
426         world = context.world
427
428         self.layout.prop(world.mist_settings, "use_mist", text="")
429
430     def draw(self, context):
431         layout = self.layout
432
433         world = context.world
434
435         layout.active = world.mist_settings.use_mist
436
437         row = layout.row()
438         row.prop(world.mist_settings, "start")
439         row.prop(world.mist_settings, "depth")
440
441
442 class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
443     bl_label = "Physics"
444     COMPAT_ENGINES = {'BLENDER_GAME'}
445
446     @classmethod
447     def poll(cls, context):
448         scene = context.scene
449         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
450
451     def draw(self, context):
452         layout = self.layout
453
454         gs = context.scene.game_settings
455
456         layout.prop(gs, "physics_engine")
457         if gs.physics_engine != 'NONE':
458             layout.prop(gs, "physics_gravity", text="Gravity")
459
460             split = layout.split()
461
462             col = split.column()
463             col.label(text="Physics Steps:")
464             sub = col.column(align=True)
465             sub.prop(gs, "physics_step_max", text="Max")
466             sub.prop(gs, "physics_step_sub", text="Substeps")
467             col.prop(gs, "fps", text="FPS")
468
469             col = split.column()
470             col.label(text="Logic Steps:")
471             col.prop(gs, "logic_step_max", text="Max")
472
473             col = layout.column()
474             col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
475             sub = col.column()
476             sub.active = gs.use_occlusion_culling
477             sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
478
479         else:
480             split = layout.split()
481
482             col = split.column()
483             col.label(text="Physics Steps:")
484             col.prop(gs, "fps", text="FPS")
485
486             col = split.column()
487             col.label(text="Logic Steps:")
488             col.prop(gs, "logic_step_max", text="Max")
489
490 if __name__ == "__main__":  # only for live edit.
491     bpy.utils.register_module(__name__)