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 == 'CHARACTER':
53 layout.prop(game, "use_actor")
54 layout.prop(ob, "hide_render", text="Invisible") # out of place but useful
55 layout.prop(game, "step_height", slider=True)
56 layout.prop(game, "jump_speed")
57 layout.prop(game, "fall_speed")
59 elif physics_type in {'DYNAMIC', 'RIGID_BODY'}:
60 split = layout.split()
63 col.prop(game, "use_actor")
64 col.prop(game, "use_ghost")
65 col.prop(ob, "hide_render", text="Invisible") # out of place but useful
68 col.prop(game, "use_material_physics_fh")
69 col.prop(game, "use_rotate_from_normal")
70 col.prop(game, "use_sleep")
74 split = layout.split()
77 col.label(text="Attributes:")
78 col.prop(game, "mass")
79 col.prop(game, "radius")
80 col.prop(game, "form_factor")
84 sub.prop(game, "use_anisotropic_friction")
86 subsub.active = game.use_anisotropic_friction
87 subsub.prop(game, "friction_coefficients", text="", slider=True)
89 split = layout.split()
92 col.label(text="Velocity:")
93 sub = col.column(align=True)
94 sub.prop(game, "velocity_min", text="Minimum")
95 sub.prop(game, "velocity_max", text="Maximum")
98 col.label(text="Damping:")
99 sub = col.column(align=True)
100 sub.prop(game, "damping", text="Translation", slider=True)
101 sub.prop(game, "rotation_damping", text="Rotation", slider=True)
105 split = layout.split()
108 col.label(text="Lock Translation:")
109 col.prop(game, "lock_location_x", text="X")
110 col.prop(game, "lock_location_y", text="Y")
111 col.prop(game, "lock_location_z", text="Z")
114 col.label(text="Lock Rotation:")
115 col.prop(game, "lock_rotation_x", text="X")
116 col.prop(game, "lock_rotation_y", text="Y")
117 col.prop(game, "lock_rotation_z", text="Z")
119 elif physics_type == 'SOFT_BODY':
120 col = layout.column()
121 col.prop(game, "use_actor")
122 col.prop(game, "use_ghost")
123 col.prop(ob, "hide_render", text="Invisible")
127 split = layout.split()
130 col.label(text="Attributes:")
131 col.prop(game, "mass")
132 # disabled in the code
133 # col.prop(soft, "weld_threshold")
134 col.prop(soft, "location_iterations")
135 col.prop(soft, "linear_stiffness", slider=True)
136 col.prop(soft, "dynamic_friction", slider=True)
137 col.prop(soft, "collision_margin", slider=True)
138 col.prop(soft, "use_bending_constraints", text="Bending Constraints")
141 col.prop(soft, "use_shape_match")
143 sub.active = soft.use_shape_match
144 sub.prop(soft, "shape_threshold", slider=True)
148 col.label(text="Cluster Collision:")
149 col.prop(soft, "use_cluster_rigid_to_softbody")
150 col.prop(soft, "use_cluster_soft_to_softbody")
152 sub.active = (soft.use_cluster_rigid_to_softbody or soft.use_cluster_soft_to_softbody)
153 sub.prop(soft, "cluster_iterations", text="Iterations")
155 elif physics_type == 'STATIC':
156 col = layout.column()
157 col.prop(game, "use_actor")
158 col.prop(game, "use_ghost")
159 col.prop(ob, "hide_render", text="Invisible")
163 split = layout.split()
166 col.label(text="Attributes:")
167 col.prop(game, "radius")
171 sub.prop(game, "use_anisotropic_friction")
172 subsub = sub.column()
173 subsub.active = game.use_anisotropic_friction
174 subsub.prop(game, "friction_coefficients", text="", slider=True)
176 elif physics_type == 'SENSOR':
177 col = layout.column()
178 col.prop(game, "use_actor", text="Detect Actors")
179 col.prop(ob, "hide_render", text="Invisible")
181 elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
182 layout.prop(ob, "hide_render", text="Invisible")
184 elif physics_type == 'NAVMESH':
185 layout.operator("mesh.navmesh_face_copy")
186 layout.operator("mesh.navmesh_face_add")
190 layout.operator("mesh.navmesh_reset")
191 layout.operator("mesh.navmesh_clear")
193 if physics_type not in {'NO_COLLISION', 'OCCLUDE'}:
195 split = layout.split()
198 col.prop(game, "collision_group")
200 col.prop(game, "collision_mask")
203 class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
204 bl_label = "Collision Bounds"
205 COMPAT_ENGINES = {'BLENDER_GAME'}
208 def poll(cls, context):
209 game = context.object.game
210 rd = context.scene.render
211 return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER'}) and (rd.engine in cls.COMPAT_ENGINES)
213 def draw_header(self, context):
214 game = context.active_object.game
216 self.layout.prop(game, "use_collision_bounds", text="")
218 def draw(self, context):
221 game = context.active_object.game
223 layout.active = game.use_collision_bounds
224 layout.prop(game, "collision_bounds_type", text="Bounds")
227 row.prop(game, "collision_margin", text="Margin", slider=True)
228 row.prop(game, "use_collision_compound", text="Compound")
231 class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
232 bl_label = "Create Obstacle"
233 COMPAT_ENGINES = {'BLENDER_GAME'}
236 def poll(cls, context):
237 game = context.object.game
238 rd = context.scene.render
239 return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
241 def draw_header(self, context):
242 game = context.active_object.game
244 self.layout.prop(game, "use_obstacle_create", text="")
246 def draw(self, context):
249 game = context.active_object.game
251 layout.active = game.use_obstacle_create
254 row.prop(game, "obstacle_radius", text="Radius")
258 class RenderButtonsPanel():
259 bl_space_type = 'PROPERTIES'
260 bl_region_type = 'WINDOW'
261 bl_context = "render"
264 def poll(cls, context):
265 rd = context.scene.render
266 return (rd.engine in cls.COMPAT_ENGINES)
269 class RENDER_PT_embedded(RenderButtonsPanel, Panel):
270 bl_label = "Embedded Player"
271 COMPAT_ENGINES = {'BLENDER_GAME'}
273 def draw(self, context):
276 rd = context.scene.render
279 row.operator("view3d.game_start", text="Start")
282 row.label(text="Resolution:")
283 row = layout.row(align=True)
284 row.prop(rd, "resolution_x", slider=False, text="X")
285 row.prop(rd, "resolution_y", slider=False, text="Y")
288 class RENDER_PT_game_player(RenderButtonsPanel, Panel):
289 bl_label = "Standalone Player"
290 COMPAT_ENGINES = {'BLENDER_GAME'}
292 def draw(self, context):
295 gs = context.scene.game_settings
298 row.operator("wm.blenderplayer_start", text="Start")
302 row.label(text="Resolution:")
303 row = layout.row(align=True)
304 row.prop(gs, "resolution_x", slider=False, text="X")
305 row.prop(gs, "resolution_y", slider=False, text="Y")
308 col.prop(gs, "show_fullscreen")
310 col.prop(gs, "use_desktop")
311 col.active = gs.show_fullscreen
313 col = layout.column()
314 col.label(text="Quality:")
315 col.prop(gs, "samples")
316 col = layout.column(align=True)
317 col.prop(gs, "depth", text="Bit Depth", slider=False)
318 col.prop(gs, "frequency", text="Refresh Rate", slider=False)
321 class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
323 COMPAT_ENGINES = {'BLENDER_GAME'}
325 def draw(self, context):
328 gs = context.scene.game_settings
329 stereo_mode = gs.stereo
332 layout.prop(gs, "stereo", expand=True)
335 if stereo_mode == 'STEREO':
336 layout.prop(gs, "stereo_mode")
337 layout.prop(gs, "stereo_eye_separation")
340 elif stereo_mode == 'DOME':
341 layout.prop(gs, "dome_mode", text="Dome Type")
343 dome_type = gs.dome_mode
345 split = layout.split()
347 if dome_type in {'FISHEYE', 'TRUNCATED_REAR', 'TRUNCATED_FRONT'}:
349 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
350 col.prop(gs, "dome_angle", slider=True)
353 col.prop(gs, "dome_tessellation", text="Tessellation")
354 col.prop(gs, "dome_tilt")
356 elif dome_type == 'PANORAM_SPH':
358 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
361 col.prop(gs, "dome_tessellation", text="Tessellation")
365 col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
369 layout.prop(gs, "dome_text")
372 class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
374 COMPAT_ENGINES = {'BLENDER_GAME'}
376 def draw(self, context):
379 gs = context.scene.game_settings
381 layout.prop(gs, "material_mode", expand=True)
383 if gs.material_mode == 'GLSL':
384 split = layout.split()
387 col.prop(gs, "use_glsl_lights", text="Lights")
388 col.prop(gs, "use_glsl_shaders", text="Shaders")
389 col.prop(gs, "use_glsl_shadows", text="Shadows")
390 col.prop(gs, "use_glsl_color_management", text="Color Management")
393 col.prop(gs, "use_glsl_ramps", text="Ramps")
394 col.prop(gs, "use_glsl_nodes", text="Nodes")
395 col.prop(gs, "use_glsl_extra_textures", text="Extra Textures")
398 class RENDER_PT_game_system(RenderButtonsPanel, Panel):
400 COMPAT_ENGINES = {'BLENDER_GAME'}
402 def draw(self, context):
405 gs = context.scene.game_settings
406 col = layout.column()
409 col.prop(gs, "use_frame_rate")
410 col.prop(gs, "use_restrict_animation_updates")
411 col.prop(gs, "use_material_caching")
413 col.prop(gs, "use_display_lists")
414 col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
417 row.prop(gs, "raster_storage")
420 row.label("Exit Key")
421 row.prop(gs, "exit_key", text="", event=True)
424 class RENDER_PT_game_display(RenderButtonsPanel, Panel):
426 COMPAT_ENGINES = {'BLENDER_GAME'}
428 def draw(self, context):
431 gs = context.scene.game_settings
433 layout.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False)
435 flow = layout.column_flow()
436 flow.prop(gs, "show_debug_properties", text="Debug Properties")
437 flow.prop(gs, "show_framerate_profile", text="Framerate and Profile")
438 flow.prop(gs, "show_physics_visualization", text="Physics Visualization")
439 flow.prop(gs, "use_deprecation_warnings")
440 flow.prop(gs, "show_mouse", text="Mouse Cursor")
442 col = layout.column()
443 col.label(text="Framing:")
444 col.row().prop(gs, "frame_type", expand=True)
445 if gs.frame_type == 'LETTERBOX':
446 col.prop(gs, "frame_color", text="")
449 class SceneButtonsPanel():
450 bl_space_type = 'PROPERTIES'
451 bl_region_type = 'WINDOW'
455 class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
456 bl_label = "Navigation mesh"
457 bl_options = {'DEFAULT_CLOSED'}
458 COMPAT_ENGINES = {'BLENDER_GAME'}
461 def poll(cls, context):
462 scene = context.scene
463 return (scene and scene.render.engine in cls.COMPAT_ENGINES)
465 def draw(self, context):
468 rd = context.scene.game_settings.recast_data
470 layout.operator("mesh.navmesh_make", text="Build navigation mesh")
472 col = layout.column()
473 col.label(text="Rasterization:")
475 row.prop(rd, "cell_size")
476 row.prop(rd, "cell_height")
478 col = layout.column()
479 col.label(text="Agent:")
483 col.prop(rd, "agent_height", text="Height")
484 col.prop(rd, "agent_radius", text="Radius")
487 col.prop(rd, "slope_max")
488 col.prop(rd, "climb_max")
490 col = layout.column()
491 col.label(text="Region:")
493 row.prop(rd, "region_min_size")
494 row.prop(rd, "region_merge_size")
496 col = layout.column()
497 col.label(text="Polygonization:")
501 col.prop(rd, "edge_max_len")
502 col.prop(rd, "edge_max_error")
504 split.prop(rd, "verts_per_poly")
506 col = layout.column()
507 col.label(text="Detail Mesh:")
509 row.prop(rd, "sample_dist")
510 row.prop(rd, "sample_max_error")
513 class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
515 COMPAT_ENGINES = {'BLENDER_GAME'}
517 def draw(self, context):
520 scene = context.scene
522 layout.prop(scene, "audio_distance_model")
524 col = layout.column(align=True)
525 col.prop(scene, "audio_doppler_speed", text="Speed")
526 col.prop(scene, "audio_doppler_factor")
529 class WorldButtonsPanel():
530 bl_space_type = 'PROPERTIES'
531 bl_region_type = 'WINDOW'
535 class WORLD_PT_game_context_world(WorldButtonsPanel, Panel):
537 bl_options = {'HIDE_HEADER'}
538 COMPAT_ENGINES = {'BLENDER_GAME'}
541 def poll(cls, context):
542 rd = context.scene.render
543 return (context.scene) and (rd.use_game_engine)
545 def draw(self, context):
548 scene = context.scene
549 world = context.world
550 space = context.space_data
552 split = layout.split(percentage=0.65)
554 split.template_ID(scene, "world", new="world.new")
556 split.template_ID(space, "pin_id")
559 class WORLD_PT_game_world(WorldButtonsPanel, Panel):
561 COMPAT_ENGINES = {'BLENDER_GAME'}
564 def poll(cls, context):
565 scene = context.scene
566 return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
568 def draw(self, context):
571 world = context.world
574 row.column().prop(world, "horizon_color")
575 row.column().prop(world, "ambient_color")
578 class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
580 COMPAT_ENGINES = {'BLENDER_GAME'}
583 def poll(cls, context):
584 scene = context.scene
585 return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
587 def draw_header(self, context):
588 world = context.world
590 self.layout.prop(world.mist_settings, "use_mist", text="")
592 def draw(self, context):
595 world = context.world
597 layout.active = world.mist_settings.use_mist
599 layout.prop(world.mist_settings, "falloff")
601 row = layout.row(align=True)
602 row.prop(world.mist_settings, "start")
603 row.prop(world.mist_settings, "depth")
605 layout.prop(world.mist_settings, "intensity", text="Minimum Intensity")
608 class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
610 COMPAT_ENGINES = {'BLENDER_GAME'}
613 def poll(cls, context):
614 scene = context.scene
615 return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
617 def draw(self, context):
620 gs = context.scene.game_settings
622 layout.prop(gs, "physics_engine")
623 if gs.physics_engine != 'NONE':
624 col = layout.column()
625 col.prop(gs, "physics_gravity", text="Gravity")
626 col.prop(gs, "occlusion_culling_resolution", text="Culling Resolution")
628 split = layout.split()
631 col.label(text="Physics Steps:")
632 sub = col.column(align=True)
633 sub.prop(gs, "physics_step_max", text="Max")
634 sub.prop(gs, "physics_step_sub", text="Substeps")
635 col.prop(gs, "fps", text="FPS")
638 col.label(text="Logic Steps:")
639 col.prop(gs, "logic_step_max", text="Max")
641 col = layout.column()
642 col.label(text="Physics Deactivation:")
643 sub = col.row(align=True)
644 sub.prop(gs, "deactivation_linear_threshold", text="Linear Threshold")
645 sub.prop(gs, "deactivation_angular_threshold", text="Angular Threshold")
647 sub.prop(gs, "deactivation_time", text="Time")
650 split = layout.split()
653 col.label(text="Physics Steps:")
654 col.prop(gs, "fps", text="FPS")
657 col.label(text="Logic Steps:")
658 col.prop(gs, "logic_step_max", text="Max")
661 class WORLD_PT_game_physics_obstacles(WorldButtonsPanel, Panel):
662 bl_label = "Obstacle simulation"
663 COMPAT_ENGINES = {'BLENDER_GAME'}
666 def poll(cls, context):
667 scene = context.scene
668 return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
670 def draw(self, context):
673 gs = context.scene.game_settings
675 layout.prop(gs, "obstacle_simulation", text="Type")
676 if gs.obstacle_simulation != 'NONE':
677 layout.prop(gs, "level_height")
678 layout.prop(gs, "show_obstacle_simulation")
681 class DataButtonsPanel():
682 bl_space_type = 'PROPERTIES'
683 bl_region_type = 'WINDOW'
687 class DATA_PT_shadow_game(DataButtonsPanel, Panel):
689 COMPAT_ENGINES = {'BLENDER_GAME'}
692 def poll(cls, context):
693 COMPAT_LIGHTS = {'SPOT', 'SUN'}
695 engine = context.scene.render.engine
696 return (lamp and lamp.type in COMPAT_LIGHTS) and (engine in cls.COMPAT_ENGINES)
698 def draw_header(self, context):
701 self.layout.prop(lamp, "use_shadow", text="")
703 def draw(self, context):
708 layout.active = lamp.use_shadow
710 split = layout.split()
713 col.prop(lamp, "shadow_color", text="")
716 col.prop(lamp, "use_shadow_layer", text="This Layer Only")
717 col.prop(lamp, "use_only_shadow")
719 col = layout.column()
720 col.label("Buffer Type:")
721 col.prop(lamp, "ge_shadow_buffer_type", text="", toggle=True)
722 col.label("Quality:")
723 col = layout.column(align=True)
724 col.prop(lamp, "shadow_buffer_size", text="Size")
725 col.prop(lamp, "shadow_buffer_bias", text="Bias")
726 col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
729 row.label("Clipping:")
730 row = layout.row(align=True)
731 row.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
732 row.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
734 if lamp.type == 'SUN':
736 row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
739 if __name__ == "__main__": # only for live edit.
740 bpy.utils.register_module(__name__)