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