*More single column stuff.
[blender.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 narrowui = 180
23
24 class PhysicsButtonsPanel(bpy.types.Panel):
25     bl_space_type = 'PROPERTIES'
26     bl_region_type = 'WINDOW'
27     bl_context = "physics"
28
29     def poll(self, context):
30         ob = context.active_object
31         rd = context.scene.render_data
32         return ob and ob.game and (rd.engine == 'BLENDER_GAME')
33
34
35 class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
36     bl_label = "Physics"
37
38     def draw(self, context):
39         layout = self.layout
40
41         ob = context.active_object
42         game = ob.game
43         soft = ob.game.soft_body
44         col2 = context.region.width > narrowui
45
46         if col2:
47             layout.itemR(game, "physics_type")
48         else:
49             layout.itemR(game, "physics_type", text="")
50         layout.itemS()
51
52         #if game.physics_type == 'DYNAMIC':
53         if game.physics_type in ('DYNAMIC', 'RIGID_BODY'):
54             split = layout.split()
55
56             col = split.column()
57             col.itemR(game, "actor")
58             col.itemR(game, "ghost")
59             col.itemR(ob, "restrict_render", text="Invisible") # out of place but useful
60
61             if col2:
62                 col = split.column()
63             col.itemR(game, "material_physics")
64             col.itemR(game, "rotate_from_normal")
65             col.itemR(game, "no_sleeping")
66
67             layout.itemS()
68
69             split = layout.split()
70
71             col = split.column()
72             col.itemL(text="Attributes:")
73             col.itemR(game, "mass")
74             col.itemR(game, "radius")
75             col.itemR(game, "form_factor")
76
77             if col2:
78                 col = split.column()
79             sub = col.column()
80             sub.active = (game.physics_type == 'RIGID_BODY')
81             sub.itemR(game, "anisotropic_friction")
82             subsub = sub.column()
83             subsub.active = game.anisotropic_friction
84             subsub.itemR(game, "friction_coefficients", text="", slider=True)
85
86             split = layout.split()
87
88             col = split.column()
89             col.itemL(text="Velocity:")
90             sub = col.column(align=True)
91             sub.itemR(game, "minimum_velocity", text="Minimum")
92             sub.itemR(game, "maximum_velocity", text="Maximum")
93
94             if col2:
95                 col = split.column()
96             col.itemL(text="Damping:")
97             sub = col.column(align=True)
98             sub.itemR(game, "damping", text="Translation", slider=True)
99             sub.itemR(game, "rotation_damping", text="Rotation", slider=True)
100
101             layout.itemS()
102
103             split = layout.split()
104
105             col = split.column()
106             col.itemL(text="Lock Translation:")
107             col.itemR(game, "lock_x_axis", text="X")
108             col.itemR(game, "lock_y_axis", text="Y")
109             col.itemR(game, "lock_z_axis", text="Z")
110
111             col = split.column()
112             col.itemL(text="Lock Rotation:")
113             col.itemR(game, "lock_x_rot_axis", text="X")
114             col.itemR(game, "lock_y_rot_axis", text="Y")
115             col.itemR(game, "lock_z_rot_axis", text="Z")
116
117         elif game.physics_type == 'SOFT_BODY':
118             col = layout.column()
119             col.itemR(game, "actor")
120             col.itemR(game, "ghost")
121             col.itemR(ob, "restrict_render", text="Invisible")
122
123             layout.itemS()
124
125             split = layout.split()
126
127             col = split.column()
128             col.itemL(text="Attributes:")
129             col.itemR(game, "mass")
130             col.itemR(soft, "welding")
131             col.itemR(soft, "position_iterations")
132             col.itemR(soft, "linstiff", slider=True)
133             col.itemR(soft, "dynamic_friction", slider=True)
134             col.itemR(soft, "margin", slider=True)
135             col.itemR(soft, "bending_const", text="Bending Constraints")
136
137             if col2:
138                 col = split.column()
139             col.itemR(soft, "shape_match")
140             sub = col.column()
141             sub.active = soft.shape_match
142             sub.itemR(soft, "threshold", slider=True)
143
144             col.itemS()
145
146             col.itemL(text="Cluster Collision:")
147             col.itemR(soft, "cluster_rigid_to_softbody")
148             col.itemR(soft, "cluster_soft_to_softbody")
149             sub = col.column()
150             sub.active = (soft.cluster_rigid_to_softbody or soft.cluster_soft_to_softbody)
151             sub.itemR(soft, "cluster_iterations", text="Iterations")
152
153         elif game.physics_type == 'STATIC':
154             col = layout.column()
155             col.itemR(game, "actor")
156             col.itemR(game, "ghost")
157             col.itemR(ob, "restrict_render", text="Invisible")
158
159         elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'):
160             layout.itemR(ob, "restrict_render", text="Invisible")
161
162
163 class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel):
164     bl_label = "Collision Bounds"
165
166     def poll(self, context):
167         game = context.object.game
168         rd = context.scene.render_data
169         return (game.physics_type in ('DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC')) and (rd.engine == 'BLENDER_GAME')
170
171     def draw_header(self, context):
172         game = context.active_object.game
173
174         self.layout.itemR(game, "use_collision_bounds", text="")
175
176     def draw(self, context):
177         layout = self.layout
178
179         game = context.active_object.game
180         col2 = context.region.width > narrowui
181
182         layout.active = game.use_collision_bounds
183         if col2:
184             layout.itemR(game, "collision_bounds", text="Bounds")
185         else:
186             layout.itemR(game, "collision_bounds", text="")
187
188         split = layout.split()
189         
190         col = split.column()
191         col.itemR(game, "collision_margin", text="Margin", slider=True)
192         
193         if col2:
194             col = split.column()
195         col.itemR(game, "collision_compound", text="Compound")
196         
197
198 bpy.types.register(PHYSICS_PT_game_physics)
199 bpy.types.register(PHYSICS_PT_game_collision_bounds)
200
201
202 class RenderButtonsPanel(bpy.types.Panel):
203     bl_space_type = 'PROPERTIES'
204     bl_region_type = 'WINDOW'
205     bl_context = "render"
206
207     def poll(self, context):
208         rd = context.scene.render_data
209         return (rd.engine == 'BLENDER_GAME')
210
211
212 class RENDER_PT_game(RenderButtonsPanel):
213     bl_label = "Game"
214
215     def draw(self, context):
216         layout = self.layout
217
218         row = layout.row()
219         row.itemO("view3d.game_start", text="Start")
220         row.itemL()
221
222
223 class RENDER_PT_game_player(RenderButtonsPanel):
224     bl_label = "Standalone Player"
225
226     def draw(self, context):
227         layout = self.layout
228
229         gs = context.scene.game_data
230         col2 = context.region.width > narrowui
231
232         layout.itemR(gs, "fullscreen")
233
234         split = layout.split()
235
236         col = split.column()
237         col.itemL(text="Resolution:")
238         sub = col.column(align=True)
239         sub.itemR(gs, "resolution_x", slider=False, text="X")
240         sub.itemR(gs, "resolution_y", slider=False, text="Y")
241
242         if col2:
243             col = split.column()
244         col.itemL(text="Quality:")
245         sub = col.column(align=True)
246         sub.itemR(gs, "depth", text="Bit Depth", slider=False)
247         sub.itemR(gs, "frequency", text="FPS", slider=False)
248
249         # framing:
250         col = layout.column()
251         col.itemL(text="Framing:")
252         if col2:
253             col.row().itemR(gs, "framing_type", expand=True)
254         else:
255             col.itemR(gs, "framing_type", text="")
256         if gs.framing_type == 'LETTERBOX':
257             col.itemR(gs, "framing_color", text="")
258
259
260 class RENDER_PT_game_stereo(RenderButtonsPanel):
261     bl_label = "Stereo"
262
263     def draw(self, context):
264         layout = self.layout
265
266         gs = context.scene.game_data
267         stereo_mode = gs.stereo
268         col2 = context.region.width > narrowui
269
270         # stereo options:
271         layout.itemR(gs, "stereo", expand=True)
272
273         # stereo:
274         if stereo_mode == 'STEREO':
275             layout.itemR(gs, "stereo_mode")
276             layout.itemL(text="To do: Focal Length")
277             layout.itemL(text="To do: Eye Separation")
278
279         # dome:
280         elif stereo_mode == 'DOME':
281             if col2:
282                 layout.itemR(gs, "dome_mode", text="Dome Type")
283             else:
284                 layout.itemR(gs, "dome_mode", text="")
285
286             dome_type = gs.dome_mode
287
288             split = layout.split()
289
290             if dome_type == 'FISHEYE' or \
291                dome_type == 'TRUNCATED_REAR' or \
292                dome_type == 'TRUNCATED_FRONT':
293
294                 col = split.column()
295                 col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
296                 col.itemR(gs, "dome_angle", slider=True)
297
298                 if col2:
299                     col = split.column()
300                 col.itemR(gs, "dome_tesselation", text="Tesselation")
301                 col.itemR(gs, "dome_tilt")
302
303             elif dome_type == 'PANORAM_SPH':
304                 col = split.column()
305                 
306                 col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
307                 if col2:
308                     col = split.column()
309                 col.itemR(gs, "dome_tesselation", text="Tesselation")
310
311             else: # cube map
312                 col = split.column()
313                 col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
314                 if col2:
315                     col = split.column()
316
317             layout.itemR(gs, "dome_text")
318
319
320 class RENDER_PT_game_shading(RenderButtonsPanel):
321     bl_label = "Shading"
322
323     def draw(self, context):
324         layout = self.layout
325
326         gs = context.scene.game_data
327         col2 = context.region.width > narrowui
328         
329         if col2:
330             layout.itemR(gs, "material_mode", expand=True)
331         else:
332             layout.itemR(gs, "material_mode", text="")
333
334         if gs.material_mode == 'GLSL':
335             split = layout.split()
336
337             col = split.column()
338             col.itemR(gs, "glsl_lights", text="Lights")
339             col.itemR(gs, "glsl_shaders", text="Shaders")
340             col.itemR(gs, "glsl_shadows", text="Shadows")
341
342             col = split.column()
343             col.itemR(gs, "glsl_ramps", text="Ramps")
344             col.itemR(gs, "glsl_nodes", text="Nodes")
345             col.itemR(gs, "glsl_extra_textures", text="Extra Textures")
346
347
348 class RENDER_PT_game_performance(RenderButtonsPanel):
349     bl_label = "Performance"
350
351     def draw(self, context):
352         layout = self.layout
353
354         gs = context.scene.game_data
355         col2 = context.region.width > narrowui
356         
357         split = layout.split()
358
359         col = split.column()
360         col.itemL(text="Show:")
361         col.itemR(gs, "show_debug_properties", text="Debug Properties")
362         col.itemR(gs, "show_framerate_profile", text="Framerate and Profile")
363         col.itemR(gs, "show_physics_visualization", text="Physics Visualization")
364         col.itemR(gs, "deprecation_warnings")
365
366         if col2:
367             col = split.column()
368         col.itemL(text="Render:")
369         col.itemR(gs, "all_frames")
370         col.itemR(gs, "display_lists")
371
372
373 class RENDER_PT_game_sound(RenderButtonsPanel):
374     bl_label = "Sound"
375
376     def draw(self, context):
377         layout = self.layout
378
379         scene = context.scene
380         col2 = context.region.width > narrowui
381
382         if col2:
383             layout.itemR(scene, "distance_model")
384         else:
385             layout.itemR(scene, "distance_model", text="")
386         layout.itemR(scene, "speed_of_sound", text="Speed")
387         layout.itemR(scene, "doppler_factor")
388
389 bpy.types.register(RENDER_PT_game)
390 bpy.types.register(RENDER_PT_game_player)
391 bpy.types.register(RENDER_PT_game_stereo)
392 bpy.types.register(RENDER_PT_game_shading)
393 bpy.types.register(RENDER_PT_game_performance)
394 bpy.types.register(RENDER_PT_game_sound)
395
396
397 class WorldButtonsPanel(bpy.types.Panel):
398     bl_space_type = 'PROPERTIES'
399     bl_region_type = 'WINDOW'
400     bl_context = "world"
401
402     def poll(self, context):
403         rd = context.scene.render_data
404         return (rd.engine == 'BLENDER_GAME')
405
406
407 class WORLD_PT_game_context_world(WorldButtonsPanel):
408     bl_label = ""
409     bl_show_header = False
410
411     def poll(self, context):
412         rd = context.scene.render_data
413         return (context.scene) and (rd.use_game_engine)
414
415     def draw(self, context):
416         layout = self.layout
417
418         scene = context.scene
419         world = context.world
420         space = context.space_data
421         col2 = context.region.width > narrowui
422
423         if col2:
424             split = layout.split(percentage=0.65)
425             if scene:
426                 split.template_ID(scene, "world", new="world.new")
427             elif world:
428                 split.template_ID(space, "pin_id")
429         else:   
430             if scene:
431                 layout.template_ID(scene, "world", new="world.new")
432             elif world:
433                 layout.template_ID(space, "pin_id")
434
435 class WORLD_PT_game_world(WorldButtonsPanel):
436     bl_label = "World"
437
438     def draw(self, context):
439         layout = self.layout
440
441         world = context.world
442         col2 = context.region.width > narrowui
443
444         split = layout.split()
445         
446         col = split.column()
447         col.itemR(world, "horizon_color")
448         
449         if col2:
450             col = split.column()
451         col.itemR(world, "ambient_color")
452
453 class WORLD_PT_game_mist(WorldButtonsPanel):
454     bl_label = "Mist"
455     
456     def draw_header(self, context):
457         world = context.world
458         
459         self.layout.itemR(world.mist, "enabled", text="")
460     
461     def draw(self, context):
462         layout = self.layout
463
464         world = context.world
465         col2 = context.region.width > narrowui
466         
467         layout.active = world.mist.enabled
468         split = layout.split()
469         
470         col = split.column()
471         col.itemR(world.mist, "start")
472         
473         if col2:
474             col = split.column()
475         col.itemR(world.mist, "depth")
476
477 class WORLD_PT_game_physics(WorldButtonsPanel):
478     bl_label = "Physics"
479
480     def draw(self, context):
481         layout = self.layout
482
483         gs = context.scene.game_data
484         col2 = context.region.width > narrowui
485
486         layout.itemR(gs, "physics_engine")
487         if gs.physics_engine != 'NONE':
488             layout.itemR(gs, "physics_gravity", text="Gravity")
489
490             split = layout.split()
491
492             col = split.column()
493             col.itemL(text="Physics Steps:")
494             sub = col.column(align=True)
495             sub.itemR(gs, "physics_step_max", text="Max")
496             sub.itemR(gs, "physics_step_sub", text="Substeps")
497             col.itemR(gs, "fps", text="FPS")
498
499             if col2:
500                 col = split.column()
501             col.itemL(text="Logic Steps:")
502             col.itemR(gs, "logic_step_max", text="Max")
503
504             col = layout.column()
505             col.itemR(gs, "use_occlusion_culling", text="Occlusion Culling")
506             sub = col.column()
507             sub.active = gs.use_occlusion_culling
508             sub.itemR(gs, "occlusion_culling_resolution", text="Resolution")
509
510         else:
511             split = layout.split()
512
513             col = split.column()
514             col.itemL(text="Physics Steps:")
515             col.itemR(gs, "fps", text="FPS")
516
517             col = split.column()
518             col.itemL(text="Logic Steps:")
519             col.itemR(gs, "logic_step_max", text="Max")
520
521 bpy.types.register(WORLD_PT_game_context_world)
522 bpy.types.register(WORLD_PT_game_world)
523 bpy.types.register(WORLD_PT_game_mist)
524 bpy.types.register(WORLD_PT_game_physics)