rna data path names which are more likely to break animations.
[blender-staging.git] / release / scripts / 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
22
23 class PhysicsButtonsPanel():
24     bl_space_type = 'PROPERTIES'
25     bl_region_type = 'WINDOW'
26     bl_context = "physics"
27
28
29 class PHYSICS_PT_game_physics(PhysicsButtonsPanel, bpy.types.Panel):
30     bl_label = "Physics"
31     COMPAT_ENGINES = {'BLENDER_GAME'}
32
33     @classmethod
34     def poll(cls, context):
35         ob = context.active_object
36         rd = context.scene.render
37         return ob and ob.game and (rd.engine in cls.COMPAT_ENGINES)
38
39     def draw(self, context):
40         layout = self.layout
41
42         ob = context.active_object
43         game = ob.game
44         soft = ob.game.soft_body
45
46         layout.prop(game, "physics_type")
47         layout.separator()
48
49         #if game.physics_type == 'DYNAMIC':
50         if game.physics_type in ('DYNAMIC', 'RIGID_BODY'):
51             split = layout.split()
52
53             col = split.column()
54             col.prop(game, "use_actor")
55             col.prop(game, "use_ghost")
56             col.prop(ob, "hide_render", text="Invisible") # out of place but useful
57
58             col = split.column()
59             col.prop(game, "use_material_physics")
60             col.prop(game, "use_rotate_from_normal")
61             col.prop(game, "use_sleep")
62
63             layout.separator()
64
65             split = layout.split()
66
67             col = split.column()
68             col.label(text="Attributes:")
69             col.prop(game, "mass")
70             col.prop(game, "radius")
71             col.prop(game, "form_factor")
72
73             col = split.column()
74             sub = col.column()
75             sub.active = (game.physics_type == 'RIGID_BODY')
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.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         elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'):
153             layout.prop(ob, "hide_render", text="Invisible")
154
155
156 class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, bpy.types.Panel):
157     bl_label = "Collision Bounds"
158     COMPAT_ENGINES = {'BLENDER_GAME'}
159
160     @classmethod
161     def poll(cls, context):
162         game = context.object.game
163         rd = context.scene.render
164         return (game.physics_type in ('DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC')) and (rd.engine in cls.COMPAT_ENGINES)
165
166     def draw_header(self, context):
167         game = context.active_object.game
168
169         self.layout.prop(game, "use_collision_bounds", text="")
170
171     def draw(self, context):
172         layout = self.layout
173
174         game = context.active_object.game
175
176         layout.active = game.use_collision_bounds
177         layout.prop(game, "collision_bounds_type", text="Bounds")
178
179         split = layout.split()
180
181         col = split.column()
182         col.prop(game, "collision_margin", text="Margin", slider=True)
183
184         col = split.column()
185         col.prop(game, "use_collision_compound", text="Compound")
186
187
188 class RenderButtonsPanel():
189     bl_space_type = 'PROPERTIES'
190     bl_region_type = 'WINDOW'
191     bl_context = "render"
192
193     @classmethod
194     def poll(cls, context):
195         rd = context.scene.render
196         return (rd.engine in cls.COMPAT_ENGINES)
197
198
199 class RENDER_PT_game(RenderButtonsPanel, bpy.types.Panel):
200     bl_label = "Game"
201     COMPAT_ENGINES = {'BLENDER_GAME'}
202
203     def draw(self, context):
204         layout = self.layout
205
206         row = layout.row()
207         row.operator("view3d.game_start", text="Start")
208         row.label()
209
210
211 class RENDER_PT_game_player(RenderButtonsPanel, bpy.types.Panel):
212     bl_label = "Standalone Player"
213     COMPAT_ENGINES = {'BLENDER_GAME'}
214
215     def draw(self, context):
216         layout = self.layout
217
218         gs = context.scene.game_settings
219
220         layout.prop(gs, "show_fullscreen")
221
222         split = layout.split()
223
224         col = split.column()
225         col.label(text="Resolution:")
226         sub = col.column(align=True)
227         sub.prop(gs, "resolution_x", slider=False, text="X")
228         sub.prop(gs, "resolution_y", slider=False, text="Y")
229
230         col = split.column()
231         col.label(text="Quality:")
232         sub = col.column(align=True)
233         sub.prop(gs, "depth", text="Bit Depth", slider=False)
234         sub.prop(gs, "frequency", text="FPS", slider=False)
235
236         # framing:
237         col = layout.column()
238         col.label(text="Framing:")
239         col.row().prop(gs, "frame_type", expand=True)
240         if gs.frame_type == 'LETTERBOX':
241             col.prop(gs, "frame_color", text="")
242
243
244 class RENDER_PT_game_stereo(RenderButtonsPanel, bpy.types.Panel):
245     bl_label = "Stereo"
246     COMPAT_ENGINES = {'BLENDER_GAME'}
247
248     def draw(self, context):
249         layout = self.layout
250
251         gs = context.scene.game_settings
252         stereo_mode = gs.stereo
253
254         # stereo options:
255         layout.prop(gs, "stereo", expand=True)
256
257         # stereo:
258         if stereo_mode == 'STEREO':
259             layout.prop(gs, "stereo_mode")
260             layout.prop(gs, "stereo_eye_separation")
261
262         # dome:
263         elif stereo_mode == 'DOME':
264             layout.prop(gs, "dome_mode", text="Dome Type")
265
266             dome_type = gs.dome_mode
267
268             split = layout.split()
269
270             if dome_type == 'FISHEYE' or \
271                dome_type == 'TRUNCATED_REAR' or \
272                dome_type == 'TRUNCATED_FRONT':
273
274                 col = split.column()
275                 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
276                 col.prop(gs, "dome_angle", slider=True)
277
278                 col = split.column()
279                 col.prop(gs, "dome_tesselation", text="Tesselation")
280                 col.prop(gs, "dome_tilt")
281
282             elif dome_type == 'PANORAM_SPH':
283                 col = split.column()
284
285                 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
286                 col = split.column()
287                 col.prop(gs, "dome_tesselation", text="Tesselation")
288
289             else: # cube map
290                 col = split.column()
291                 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
292
293                 col = split.column()
294
295             layout.prop(gs, "dome_text")
296
297
298 class RENDER_PT_game_shading(RenderButtonsPanel, bpy.types.Panel):
299     bl_label = "Shading"
300     COMPAT_ENGINES = {'BLENDER_GAME'}
301
302     def draw(self, context):
303         layout = self.layout
304
305         gs = context.scene.game_settings
306
307         layout.prop(gs, "material_mode", expand=True)
308
309         if gs.material_mode == 'GLSL':
310             split = layout.split()
311
312             col = split.column()
313             col.prop(gs, "use_glsl_lights", text="Lights")
314             col.prop(gs, "use_glsl_shaders", text="Shaders")
315             col.prop(gs, "use_glsl_shadows", text="Shadows")
316
317             col = split.column()
318             col.prop(gs, "use_glsl_ramps", text="Ramps")
319             col.prop(gs, "use_glsl_nodes", text="Nodes")
320             col.prop(gs, "use_glsl_extra_textures", text="Extra Textures")
321
322
323 class RENDER_PT_game_performance(RenderButtonsPanel, bpy.types.Panel):
324     bl_label = "Performance"
325     COMPAT_ENGINES = {'BLENDER_GAME'}
326
327     def draw(self, context):
328         layout = self.layout
329
330         gs = context.scene.game_settings
331
332         split = layout.split()
333
334         col = split.column()
335         col.label(text="Show:")
336         col.prop(gs, "show_debug_properties", text="Debug Properties")
337         col.prop(gs, "show_framerate_profile", text="Framerate and Profile")
338         col.prop(gs, "show_physics_visualization", text="Physics Visualization")
339         col.prop(gs, "use_deprecation_warnings")
340
341         col = split.column()
342
343         col.label(text="Render:")
344         col.prop(gs, "use_frame_rate")
345         col.prop(gs, "use_display_lists")
346
347
348 class RENDER_PT_game_sound(RenderButtonsPanel, bpy.types.Panel):
349     bl_label = "Sound"
350     COMPAT_ENGINES = {'BLENDER_GAME'}
351
352     def draw(self, context):
353         layout = self.layout
354
355         scene = context.scene
356
357         layout.prop(scene, "audio_distance_model")
358
359         layout.prop(scene, "audio_doppler_speed", text="Speed")
360         layout.prop(scene, "audio_doppler_factor")
361
362
363 class WorldButtonsPanel():
364     bl_space_type = 'PROPERTIES'
365     bl_region_type = 'WINDOW'
366     bl_context = "world"
367
368
369 class WORLD_PT_game_context_world(WorldButtonsPanel, bpy.types.Panel):
370     bl_label = ""
371     bl_show_header = False
372     COMPAT_ENGINES = {'BLENDER_GAME'}
373
374     @classmethod
375     def poll(cls, context):
376         rd = context.scene.render
377         return (context.scene) and (rd.use_game_engine)
378
379     def draw(self, context):
380         layout = self.layout
381
382         scene = context.scene
383         world = context.world
384         space = context.space_data
385
386         split = layout.split(percentage=0.65)
387         if scene:
388             split.template_ID(scene, "world", new="world.new")
389         elif world:
390             split.template_ID(space, "pin_id")
391
392
393 class WORLD_PT_game_world(WorldButtonsPanel, bpy.types.Panel):
394     bl_label = "World"
395     COMPAT_ENGINES = {'BLENDER_GAME'}
396
397     @classmethod
398     def poll(cls, context):
399         scene = context.scene
400         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
401
402     def draw(self, context):
403         layout = self.layout
404
405         world = context.world
406
407         split = layout.split()
408
409         col = split.column()
410         col.prop(world, "horizon_color")
411
412         col = split.column()
413         col.prop(world, "ambient_color")
414
415
416 class WORLD_PT_game_mist(WorldButtonsPanel, bpy.types.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, "use_mist", text="")
429
430     def draw(self, context):
431         layout = self.layout
432
433         world = context.world
434
435         layout.active = world.mist.use_mist
436         split = layout.split()
437
438         col = split.column()
439         col.prop(world.mist, "start")
440
441         col = split.column()
442         col.prop(world.mist, "depth")
443
444
445 class WORLD_PT_game_physics(WorldButtonsPanel, bpy.types.Panel):
446     bl_label = "Physics"
447     COMPAT_ENGINES = {'BLENDER_GAME'}
448
449     @classmethod
450     def poll(cls, context):
451         scene = context.scene
452         return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
453
454     def draw(self, context):
455         layout = self.layout
456
457         gs = context.scene.game_settings
458
459         layout.prop(gs, "physics_engine")
460         if gs.physics_engine != 'NONE':
461             layout.prop(gs, "physics_gravity", text="Gravity")
462
463             split = layout.split()
464
465             col = split.column()
466             col.label(text="Physics Steps:")
467             sub = col.column(align=True)
468             sub.prop(gs, "physics_step_max", text="Max")
469             sub.prop(gs, "physics_step_sub", text="Substeps")
470             col.prop(gs, "fps", text="FPS")
471
472             col = split.column()
473             col.label(text="Logic Steps:")
474             col.prop(gs, "logic_step_max", text="Max")
475
476             col = layout.column()
477             col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
478             sub = col.column()
479             sub.active = gs.use_occlusion_culling
480             sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
481
482         else:
483             split = layout.split()
484
485             col = split.column()
486             col.label(text="Physics Steps:")
487             col.prop(gs, "fps", text="FPS")
488
489             col = split.column()
490             col.label(text="Logic Steps:")
491             col.prop(gs, "logic_step_max", text="Max")
492
493
494 def register():
495     pass
496
497
498 def unregister():
499     pass
500
501 if __name__ == "__main__":
502     register()