svn merge -r39781:39792 https://svn.blender.org/svnroot/bf-blender/trunk/blender...
[blender-staging.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         row = layout.row()
344         row.prop(gs, "use_frame_rate")
345         row.prop(gs, "use_display_lists")
346         row.prop(gs, "restrict_animation_updates")
347
348
349 class RENDER_PT_game_display(RenderButtonsPanel, Panel):
350     bl_label = "Display"
351     COMPAT_ENGINES = {'BLENDER_GAME'}
352
353     def draw(self, context):
354         layout = self.layout
355
356         gs = context.scene.game_settings
357         flow = layout.column_flow()
358         flow.prop(gs, "show_debug_properties", text="Debug Properties")
359         flow.prop(gs, "show_framerate_profile", text="Framerate and Profile")
360         flow.prop(gs, "show_physics_visualization", text="Physics Visualization")
361         flow.prop(gs, "use_deprecation_warnings")
362         flow.prop(gs, "show_mouse", text="Mouse Cursor")
363
364
365 class WorldButtonsPanel():
366     bl_space_type = 'PROPERTIES'
367     bl_region_type = 'WINDOW'
368     bl_context = "world"
369
370
371 class WORLD_PT_game_context_world(WorldButtonsPanel, Panel):
372     bl_label = ""
373     bl_options = {'HIDE_HEADER'}
374     COMPAT_ENGINES = {'BLENDER_GAME'}
375
376     @classmethod
377     def poll(cls, context):
378         rd = context.scene.render
379         return (context.scene) and (rd.use_game_engine)
380
381     def draw(self, context):
382         layout = self.layout
383
384         scene = context.scene
385         world = context.world
386         space = context.space_data
387
388         split = layout.split(percentage=0.65)
389         if scene:
390             split.template_ID(scene, "world", new="world.new")
391         elif world:
392             split.template_ID(space, "pin_id")
393
394
395 class WORLD_PT_game_world(WorldButtonsPanel, Panel):
396     bl_label = "World"
397     COMPAT_ENGINES = {'BLENDER_GAME'}
398
399     @classmethod
400     def poll(cls, context):
401         scene = context.scene
402         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
403
404     def draw(self, context):
405         layout = self.layout
406
407         world = context.world
408
409         row = layout.row()
410         row.column().prop(world, "horizon_color")
411         row.column().prop(world, "ambient_color")
412
413
414 class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
415     bl_label = "Mist"
416     COMPAT_ENGINES = {'BLENDER_GAME'}
417
418     @classmethod
419     def poll(cls, context):
420         scene = context.scene
421         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
422
423     def draw_header(self, context):
424         world = context.world
425
426         self.layout.prop(world.mist_settings, "use_mist", text="")
427
428     def draw(self, context):
429         layout = self.layout
430
431         world = context.world
432
433         layout.active = world.mist_settings.use_mist
434
435         row = layout.row()
436         row.prop(world.mist_settings, "start")
437         row.prop(world.mist_settings, "depth")
438
439
440 class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
441     bl_label = "Physics"
442     COMPAT_ENGINES = {'BLENDER_GAME'}
443
444     @classmethod
445     def poll(cls, context):
446         scene = context.scene
447         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
448
449     def draw(self, context):
450         layout = self.layout
451
452         gs = context.scene.game_settings
453
454         layout.prop(gs, "physics_engine")
455         if gs.physics_engine != 'NONE':
456             layout.prop(gs, "physics_gravity", text="Gravity")
457
458             split = layout.split()
459
460             col = split.column()
461             col.label(text="Physics Steps:")
462             sub = col.column(align=True)
463             sub.prop(gs, "physics_step_max", text="Max")
464             sub.prop(gs, "physics_step_sub", text="Substeps")
465             col.prop(gs, "fps", text="FPS")
466
467             col = split.column()
468             col.label(text="Logic Steps:")
469             col.prop(gs, "logic_step_max", text="Max")
470
471             col = layout.column()
472             col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
473             sub = col.column()
474             sub.active = gs.use_occlusion_culling
475             sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
476
477         else:
478             split = layout.split()
479
480             col = split.column()
481             col.label(text="Physics Steps:")
482             col.prop(gs, "fps", text="FPS")
483
484             col = split.column()
485             col.label(text="Logic Steps:")
486             col.prop(gs, "logic_step_max", text="Max")
487
488 if __name__ == "__main__":  # only for live edit.
489     bpy.utils.register_module(__name__)