1
# ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17
# ##### END GPL LICENSE BLOCK #####
21
from bpy.types import Panel
24
class PhysicsButtonsPanel():
25
bl_space_type = 'PROPERTIES'
26
bl_region_type = 'WINDOW'
27
bl_context = "physics"
30
class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
32
COMPAT_ENGINES = {'BLENDER_GAME'}
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)
40
def draw(self, context):
43
ob = context.active_object
45
soft = ob.game.soft_body
47
layout.prop(game, "physics_type")
50
physics_type = game.physics_type
52
if physics_type in {'DYNAMIC', 'RIGID_BODY'}:
53
split = layout.split()
56
col.prop(game, "use_actor")
57
col.prop(game, "use_ghost")
58
col.prop(ob, "hide_render", text="Invisible") # out of place but useful
61
col.prop(game, "use_material_physics_fh")
62
col.prop(game, "use_rotate_from_normal")
63
col.prop(game, "use_sleep")
67
split = layout.split()
70
col.label(text="Attributes:")
71
col.prop(game, "mass")
72
col.prop(game, "radius")
73
col.prop(game, "form_factor")
77
sub.prop(game, "use_anisotropic_friction")
79
subsub.active = game.use_anisotropic_friction
80
subsub.prop(game, "friction_coefficients", text="", slider=True)
82
split = layout.split()
85
col.label(text="Velocity:")
86
sub = col.column(align=True)
87
sub.prop(game, "velocity_min", text="Minimum")
88
sub.prop(game, "velocity_max", text="Maximum")
91
col.label(text="Damping:")
92
sub = col.column(align=True)
93
sub.prop(game, "damping", text="Translation", slider=True)
94
sub.prop(game, "rotation_damping", text="Rotation", slider=True)
98
split = layout.split()
101
col.label(text="Lock Translation:")
102
col.prop(game, "lock_location_x", text="X")
103
col.prop(game, "lock_location_y", text="Y")
104
col.prop(game, "lock_location_z", text="Z")
107
col.label(text="Lock Rotation:")
108
col.prop(game, "lock_rotation_x", text="X")
109
col.prop(game, "lock_rotation_y", text="Y")
110
col.prop(game, "lock_rotation_z", text="Z")
112
elif physics_type == 'SOFT_BODY':
113
col = layout.column()
114
col.prop(game, "use_actor")
115
col.prop(game, "use_ghost")
116
col.prop(ob, "hide_render", text="Invisible")
120
split = layout.split()
123
col.label(text="Attributes:")
124
col.prop(game, "mass")
125
# disabled in the code
126
# col.prop(soft, "weld_threshold")
127
col.prop(soft, "location_iterations")
128
col.prop(soft, "linear_stiffness", slider=True)
129
col.prop(soft, "dynamic_friction", slider=True)
130
col.prop(soft, "collision_margin", slider=True)
131
col.prop(soft, "use_bending_constraints", text="Bending Constraints")
134
col.prop(soft, "use_shape_match")
136
sub.active = soft.use_shape_match
137
sub.prop(soft, "shape_threshold", slider=True)
141
col.label(text="Cluster Collision:")
142
col.prop(soft, "use_cluster_rigid_to_softbody")
143
col.prop(soft, "use_cluster_soft_to_softbody")
145
sub.active = (soft.use_cluster_rigid_to_softbody or soft.use_cluster_soft_to_softbody)
146
sub.prop(soft, "cluster_iterations", text="Iterations")
148
elif physics_type == 'STATIC':
149
col = layout.column()
150
col.prop(game, "use_actor")
151
col.prop(game, "use_ghost")
152
col.prop(ob, "hide_render", text="Invisible")
156
split = layout.split()
159
col.label(text="Attributes:")
160
col.prop(game, "radius")
164
sub.prop(game, "use_anisotropic_friction")
165
subsub = sub.column()
166
subsub.active = game.use_anisotropic_friction
167
subsub.prop(game, "friction_coefficients", text="", slider=True)
169
elif physics_type == 'SENSOR':
170
col = layout.column()
171
col.prop(game, "use_actor", text="Detect Actors")
172
col.prop(ob, "hide_render", text="Invisible")
174
elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
175
layout.prop(ob, "hide_render", text="Invisible")
177
elif physics_type == 'NAVMESH':
178
layout.operator("mesh.navmesh_face_copy")
179
layout.operator("mesh.navmesh_face_add")
183
layout.operator("mesh.navmesh_reset")
184
layout.operator("mesh.navmesh_clear")
187
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
188
bl_label = "Collision Bounds"
189
COMPAT_ENGINES = {'BLENDER_GAME'}
192
def poll(cls, context):
193
game = context.object.game
194
rd = context.scene.render
195
return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
197
def draw_header(self, context):
198
game = context.active_object.game
200
self.layout.prop(game, "use_collision_bounds", text="")
202
def draw(self, context):
205
game = context.active_object.game
207
layout.active = game.use_collision_bounds
208
layout.prop(game, "collision_bounds_type", text="Bounds")
211
row.prop(game, "collision_margin", text="Margin", slider=True)
212
row.prop(game, "use_collision_compound", text="Compound")
215
class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
216
bl_label = "Create Obstacle"
217
COMPAT_ENGINES = {'BLENDER_GAME'}
220
def poll(cls, context):
221
game = context.object.game
222
rd = context.scene.render
223
return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
225
def draw_header(self, context):
226
game = context.active_object.game
228
self.layout.prop(game, "use_obstacle_create", text="")
230
def draw(self, context):
233
game = context.active_object.game
235
layout.active = game.use_obstacle_create
238
row.prop(game, "obstacle_radius", text="Radius")
242
class RenderButtonsPanel():
243
bl_space_type = 'PROPERTIES'
244
bl_region_type = 'WINDOW'
245
bl_context = "render"
248
def poll(cls, context):
249
rd = context.scene.render
250
return (rd.engine in cls.COMPAT_ENGINES)
253
class RENDER_PT_embedded(RenderButtonsPanel, Panel):
254
bl_label = "Embedded Player"
255
COMPAT_ENGINES = {'BLENDER_GAME'}
257
def draw(self, context):
260
rd = context.scene.render
263
row.operator("view3d.game_start", text="Start")
266
row.label(text="Resolution:")
267
row = layout.row(align=True)
268
row.prop(rd, "resolution_x", slider=False, text="X")
269
row.prop(rd, "resolution_y", slider=False, text="Y")
272
class RENDER_PT_game_player(RenderButtonsPanel, Panel):
273
bl_label = "Standalone Player"
274
COMPAT_ENGINES = {'BLENDER_GAME'}
276
def draw(self, context):
279
gs = context.scene.game_settings
282
row.operator("wm.blenderplayer_start", text="Start")
286
row.label(text="Resolution:")
287
row = layout.row(align=True)
288
row.prop(gs, "resolution_x", slider=False, text="X")
289
row.prop(gs, "resolution_y", slider=False, text="Y")
292
col.prop(gs, "show_fullscreen")
294
col.prop(gs, "use_desktop")
295
col.active = gs.show_fullscreen
297
col = layout.column()
298
col.label(text="Quality:")
299
col.prop(gs, "samples")
300
col = layout.column(align=True)
301
col.prop(gs, "depth", text="Bit Depth", slider=False)
302
col.prop(gs, "frequency", text="Refresh Rate", slider=False)
305
class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
307
COMPAT_ENGINES = {'BLENDER_GAME'}
309
def draw(self, context):
312
gs = context.scene.game_settings
313
stereo_mode = gs.stereo
316
layout.prop(gs, "stereo", expand=True)
319
if stereo_mode == 'STEREO':
320
layout.prop(gs, "stereo_mode")
321
layout.prop(gs, "stereo_eye_separation")
324
elif stereo_mode == 'DOME':
325
layout.prop(gs, "dome_mode", text="Dome Type")
327
dome_type = gs.dome_mode
329
split = layout.split()
331
if dome_type in {'FISHEYE', 'TRUNCATED_REAR', 'TRUNCATED_FRONT'}:
334
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
335
col.prop(gs, "dome_angle", slider=True)
338
col.prop(gs, "dome_tessellation", text="Tessellation")
339
col.prop(gs, "dome_tilt")
341
elif dome_type == 'PANORAM_SPH':
344
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
346
col.prop(gs, "dome_tessellation", text="Tessellation")
351
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
355
layout.prop(gs, "dome_text")
358
class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
360
COMPAT_ENGINES = {'BLENDER_GAME'}
362
def draw(self, context):
365
gs = context.scene.game_settings
367
layout.prop(gs, "material_mode", expand=True)
369
if gs.material_mode == 'GLSL':
370
split = layout.split()
373
col.prop(gs, "use_glsl_lights", text="Lights")
374
col.prop(gs, "use_glsl_shaders", text="Shaders")
375
col.prop(gs, "use_glsl_shadows", text="Shadows")
376
col.prop(gs, "use_glsl_color_management", text="Color Management")
379
col.prop(gs, "use_glsl_ramps", text="Ramps")
380
col.prop(gs, "use_glsl_nodes", text="Nodes")
381
col.prop(gs, "use_glsl_extra_textures", text="Extra Textures")
384
class RENDER_PT_game_system(RenderButtonsPanel, Panel):
386
COMPAT_ENGINES = {'BLENDER_GAME'}
388
def draw(self, context):
391
gs = context.scene.game_settings
393
row.prop(gs, "use_frame_rate")
394
row.prop(gs, "restrict_animation_updates")
397
row.prop(gs, "use_display_lists")
400
row.label("Exit Key")
401
row.prop(gs, "exit_key", text="", event=True)
404
class RENDER_PT_game_display(RenderButtonsPanel, Panel):
406
COMPAT_ENGINES = {'BLENDER_GAME'}
408
def draw(self, context):
412
row.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False)
414
gs = context.scene.game_settings
415
flow = layout.column_flow()
416
flow.prop(gs, "show_debug_properties", text="Debug Properties")
417
flow.prop(gs, "show_framerate_profile", text="Framerate and Profile")
418
flow.prop(gs, "show_physics_visualization", text="Physics Visualization")
419
flow.prop(gs, "use_deprecation_warnings")
420
flow.prop(gs, "show_mouse", text="Mouse Cursor")
422
col = layout.column()
423
col.label(text="Framing:")
424
col.row().prop(gs, "frame_type", expand=True)
425
if gs.frame_type == 'LETTERBOX':
426
col.prop(gs, "frame_color", text="")
429
class SceneButtonsPanel():
430
bl_space_type = 'PROPERTIES'
431
bl_region_type = 'WINDOW'
435
class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
436
bl_label = "Navigation mesh"
437
bl_options = {'DEFAULT_CLOSED'}
438
COMPAT_ENGINES = {'BLENDER_GAME'}
441
def poll(cls, context):
442
scene = context.scene
443
return (scene and scene.render.engine in cls.COMPAT_ENGINES)
445
def draw(self, context):
448
rd = context.scene.game_settings.recast_data
450
layout.operator("mesh.navmesh_make", text='Build navigation mesh')
452
col = layout.column()
453
col.label(text="Rasterization:")
455
row.prop(rd, "cell_size")
456
row.prop(rd, "cell_height")
458
col = layout.column()
459
col.label(text="Agent:")
463
col.prop(rd, "agent_height", text="Height")
464
col.prop(rd, "agent_radius", text="Radius")
467
col.prop(rd, "slope_max")
468
col.prop(rd, "climb_max")
470
col = layout.column()
471
col.label(text="Region:")
473
row.prop(rd, "region_min_size")
474
row.prop(rd, "region_merge_size")
476
col = layout.column()
477
col.label(text="Polygonization:")
481
col.prop(rd, "edge_max_len")
482
col.prop(rd, "edge_max_error")
484
split.prop(rd, "verts_per_poly")
486
col = layout.column()
487
col.label(text="Detail Mesh:")
489
row.prop(rd, "sample_dist")
490
row.prop(rd, "sample_max_error")
493
class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
495
COMPAT_ENGINES = {'BLENDER_GAME'}
497
def draw(self, context):
500
scene = context.scene
502
layout.prop(scene, "audio_distance_model")
504
col = layout.column(align=True)
505
col.prop(scene, "audio_doppler_speed", text="Speed")
506
col.prop(scene, "audio_doppler_factor")
509
class WorldButtonsPanel():
510
bl_space_type = 'PROPERTIES'
511
bl_region_type = 'WINDOW'
515
class WORLD_PT_game_context_world(WorldButtonsPanel, Panel):
517
bl_options = {'HIDE_HEADER'}
518
COMPAT_ENGINES = {'BLENDER_GAME'}
521
def poll(cls, context):
522
rd = context.scene.render
523
return (context.scene) and (rd.use_game_engine)
525
def draw(self, context):
528
scene = context.scene
529
world = context.world
530
space = context.space_data
532
split = layout.split(percentage=0.65)
534
split.template_ID(scene, "world", new="world.new")
536
split.template_ID(space, "pin_id")
539
class WORLD_PT_game_world(WorldButtonsPanel, Panel):
541
COMPAT_ENGINES = {'BLENDER_GAME'}
544
def poll(cls, context):
545
scene = context.scene
546
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
548
def draw(self, context):
551
world = context.world
554
row.column().prop(world, "horizon_color")
555
row.column().prop(world, "ambient_color")
558
class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
560
COMPAT_ENGINES = {'BLENDER_GAME'}
563
def poll(cls, context):
564
scene = context.scene
565
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
567
def draw_header(self, context):
568
world = context.world
570
self.layout.prop(world.mist_settings, "use_mist", text="")
572
def draw(self, context):
575
world = context.world
577
layout.active = world.mist_settings.use_mist
579
row.prop(world.mist_settings, "falloff")
581
row = layout.row(align=True)
582
row.prop(world.mist_settings, "start")
583
row.prop(world.mist_settings, "depth")
585
row.prop(world.mist_settings, "intensity", text="Minimum Intensity")
588
class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
590
COMPAT_ENGINES = {'BLENDER_GAME'}
593
def poll(cls, context):
594
scene = context.scene
595
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
597
def draw(self, context):
600
gs = context.scene.game_settings
602
layout.prop(gs, "physics_engine")
603
if gs.physics_engine != 'NONE':
604
layout.prop(gs, "physics_gravity", text="Gravity")
606
split = layout.split()
609
col.label(text="Physics Steps:")
610
sub = col.column(align=True)
611
sub.prop(gs, "physics_step_max", text="Max")
612
sub.prop(gs, "physics_step_sub", text="Substeps")
613
col.prop(gs, "fps", text="FPS")
616
col.label(text="Logic Steps:")
617
col.prop(gs, "logic_step_max", text="Max")
619
col = layout.column()
620
col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
622
sub.active = gs.use_occlusion_culling
623
sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
626
split = layout.split()
629
col.label(text="Physics Steps:")
630
col.prop(gs, "fps", text="FPS")
633
col.label(text="Logic Steps:")
634
col.prop(gs, "logic_step_max", text="Max")
637
class WORLD_PT_game_physics_obstacles(WorldButtonsPanel, Panel):
638
bl_label = "Obstacle simulation"
639
COMPAT_ENGINES = {'BLENDER_GAME'}
642
def poll(cls, context):
643
scene = context.scene
644
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
646
def draw(self, context):
649
gs = context.scene.game_settings
651
layout.prop(gs, "obstacle_simulation", text="Type")
652
if gs.obstacle_simulation != 'NONE':
653
layout.prop(gs, "level_height")
654
layout.prop(gs, "show_obstacle_simulation")
656
if __name__ == "__main__": # only for live edit.
657
bpy.utils.register_module(__name__)