Merge branch 'master' into blender2.8
[blender.git] / release / scripts / startup / bl_ui / properties_game.py
index 5ff49a7d369b3d4b74a68dfe709b18f90aefdc3b..386ad2548926213ef7c5b459ff1a8067df027fdd 100644 (file)
 
 # <pep8 compliant>
 import bpy
-from bpy.types import Panel
+from bpy.types import Panel, Menu
 
 
-class PhysicsButtonsPanel():
+class PhysicsButtonsPanel:
     bl_space_type = 'PROPERTIES'
     bl_region_type = 'WINDOW'
     bl_context = "physics"
@@ -55,6 +55,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
             layout.prop(game, "step_height", slider=True)
             layout.prop(game, "jump_speed")
             layout.prop(game, "fall_speed")
+            layout.prop(game, "jump_max")
 
         elif physics_type in {'DYNAMIC', 'RIGID_BODY'}:
             split = layout.split()
@@ -89,10 +90,14 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
             split = layout.split()
 
             col = split.column()
-            col.label(text="Velocity:")
+            col.label(text="Linear velocity:")
             sub = col.column(align=True)
             sub.prop(game, "velocity_min", text="Minimum")
             sub.prop(game, "velocity_max", text="Maximum")
+            col.label(text="Angular velocity:")
+            sub = col.column(align=True)
+            sub.prop(game, "angular_velocity_min", text="Minimum")
+            sub.prop(game, "angular_velocity_max", text="Maximum")
 
             col = split.column()
             col.label(text="Damping:")
@@ -110,6 +115,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
             col.prop(game, "lock_location_y", text="Y")
             col.prop(game, "lock_location_z", text="Z")
 
+        if physics_type == 'RIGID_BODY':
             col = split.column()
             col.label(text="Lock Rotation:")
             col.prop(game, "lock_rotation_x", text="X")
@@ -156,6 +162,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
             col = layout.column()
             col.prop(game, "use_actor")
             col.prop(game, "use_ghost")
+            col.prop(game, "use_record_animation")
             col.prop(ob, "hide_render", text="Invisible")
 
             layout.separator()
@@ -178,7 +185,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
             col.prop(game, "use_actor", text="Detect Actors")
             col.prop(ob, "hide_render", text="Invisible")
 
-        elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
+        elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDER'}:
             layout.prop(ob, "hide_render", text="Invisible")
 
         elif physics_type == 'NAVMESH':
@@ -199,7 +206,8 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
     def poll(cls, context):
         game = context.object.game
         rd = context.scene.render
-        return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER'}) and (rd.engine in cls.COMPAT_ENGINES)
+        return (rd.engine in cls.COMPAT_ENGINES) \
+                and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'CHARACTER', 'SOFT_BODY'})
 
     def draw_header(self, context):
         game = context.active_object.game
@@ -210,13 +218,25 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
         layout = self.layout
 
         game = context.active_object.game
+        split = layout.split()
+        split.active = game.use_collision_bounds
 
-        layout.active = game.use_collision_bounds
-        layout.prop(game, "collision_bounds_type", text="Bounds")
+        col = split.column()
+        col.prop(game, "collision_bounds_type", text="Bounds")
 
-        row = layout.row()
+        row = col.row()
         row.prop(game, "collision_margin", text="Margin", slider=True)
-        row.prop(game, "use_collision_compound", text="Compound")
+
+        sub = row.row()
+        sub.active = game.physics_type not in {'SOFT_BODY', 'CHARACTER'}
+        sub.prop(game, "use_collision_compound", text="Compound")
+
+        layout.separator()
+        split = layout.split()
+        col = split.column()
+        col.prop(game, "collision_group")
+        col = split.column()
+        col.prop(game, "collision_mask")
 
 
 class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
@@ -227,7 +247,8 @@ class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
     def poll(cls, context):
         game = context.object.game
         rd = context.scene.render
-        return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
+        return (rd.engine in cls.COMPAT_ENGINES) \
+                and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'SOFT_BODY', 'CHARACTER', 'NO_COLLISION'})
 
     def draw_header(self, context):
         game = context.active_object.game
@@ -246,7 +267,7 @@ class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
         row.label()
 
 
-class RenderButtonsPanel():
+class RenderButtonsPanel:
     bl_space_type = 'PROPERTIES'
     bl_region_type = 'WINDOW'
     bl_context = "render"
@@ -281,7 +302,9 @@ class RENDER_PT_game_player(RenderButtonsPanel, Panel):
     COMPAT_ENGINES = {'BLENDER_GAME'}
 
     def draw(self, context):
+        import sys
         layout = self.layout
+        not_osx = sys.platform != "darwin"
 
         gs = context.scene.game_settings
 
@@ -292,14 +315,17 @@ class RENDER_PT_game_player(RenderButtonsPanel, Panel):
         row = layout.row()
         row.label(text="Resolution:")
         row = layout.row(align=True)
+        row.active = not_osx or not gs.show_fullscreen
         row.prop(gs, "resolution_x", slider=False, text="X")
         row.prop(gs, "resolution_y", slider=False, text="Y")
         row = layout.row()
         col = row.column()
         col.prop(gs, "show_fullscreen")
-        col = row.column()
-        col.prop(gs, "use_desktop")
-        col.active = gs.show_fullscreen
+
+        if not_osx:
+            col = row.column()
+            col.prop(gs, "use_desktop")
+            col.active = gs.show_fullscreen
 
         col = layout.column()
         col.label(text="Quality:")
@@ -378,7 +404,7 @@ class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
             col.prop(gs, "use_glsl_lights", text="Lights")
             col.prop(gs, "use_glsl_shaders", text="Shaders")
             col.prop(gs, "use_glsl_shadows", text="Shadows")
-            col.prop(gs, "use_glsl_color_management", text="Color Management")
+            col.prop(gs, "use_glsl_environment_lighting", text="Environment Lighting")
 
             col = split.column()
             col.prop(gs, "use_glsl_ramps", text="Ramps")
@@ -394,13 +420,21 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
         layout = self.layout
 
         gs = context.scene.game_settings
+        col = layout.column()
+        row = col.row()
+        col = row.column()
+        col.prop(gs, "use_frame_rate")
+        col.prop(gs, "use_restrict_animation_updates")
+        col.prop(gs, "use_material_caching")
+        col = row.column()
+        col.prop(gs, "use_display_lists")
+        col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
 
         row = layout.row()
-        row.prop(gs, "use_frame_rate")
-        row.prop(gs, "restrict_animation_updates")
+        row.prop(gs, "vsync")
 
         row = layout.row()
-        row.prop(gs, "use_display_lists")
+        row.prop(gs, "raster_storage")
 
         row = layout.row()
         row.label("Exit Key")
@@ -432,7 +466,7 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel):
             col.prop(gs, "frame_color", text="")
 
 
-class SceneButtonsPanel():
+class SceneButtonsPanel:
     bl_space_type = 'PROPERTIES'
     bl_region_type = 'WINDOW'
     bl_context = "scene"
@@ -477,7 +511,11 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
         col.label(text="Region:")
         row = col.row()
         row.prop(rd, "region_min_size")
-        row.prop(rd, "region_merge_size")
+        if rd.partitioning != 'LAYERS':
+            row.prop(rd, "region_merge_size")
+
+        col = layout.column()
+        col.prop(rd, "partitioning")
 
         col = layout.column()
         col.label(text="Polygonization:")
@@ -496,23 +534,27 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
         row.prop(rd, "sample_max_error")
 
 
-class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
-    bl_label = "Sound"
+class SCENE_PT_game_hysteresis(SceneButtonsPanel, Panel):
+    bl_label = "Level of Detail"
     COMPAT_ENGINES = {'BLENDER_GAME'}
 
-    def draw(self, context):
-        layout = self.layout
-
+    @classmethod
+    def poll(cls, context):
         scene = context.scene
+        return (scene and scene.render.engine in cls.COMPAT_ENGINES)
 
-        layout.prop(scene, "audio_distance_model")
+    def draw(self, context):
+        layout = self.layout
+        gs = context.scene.game_settings
 
-        col = layout.column(align=True)
-        col.prop(scene, "audio_doppler_speed", text="Speed")
-        col.prop(scene, "audio_doppler_factor")
+        row = layout.row()
+        row.prop(gs, "use_scene_hysteresis", text="Hysteresis")
+        row = layout.row()
+        row.active = gs.use_scene_hysteresis
+        row.prop(gs, "scene_hysteresis_percentage", text="")
 
 
-class WorldButtonsPanel():
+class WorldButtonsPanel:
     bl_space_type = 'PROPERTIES'
     bl_region_type = 'WINDOW'
     bl_context = "world"
@@ -526,7 +568,7 @@ class WORLD_PT_game_context_world(WorldButtonsPanel, Panel):
     @classmethod
     def poll(cls, context):
         rd = context.scene.render
-        return (context.scene) and (rd.use_game_engine)
+        return (context.scene) and (rd.engine in cls.COMPAT_ENGINES)
 
     def draw(self, context):
         layout = self.layout
@@ -558,9 +600,35 @@ class WORLD_PT_game_world(WorldButtonsPanel, Panel):
 
         row = layout.row()
         row.column().prop(world, "horizon_color")
+        row.column().prop(world, "zenith_color")
         row.column().prop(world, "ambient_color")
 
 
+class WORLD_PT_game_environment_lighting(WorldButtonsPanel, Panel):
+    bl_label = "Environment Lighting"
+    COMPAT_ENGINES = {'BLENDER_GAME'}
+
+    @classmethod
+    def poll(cls, context):
+        scene = context.scene
+        return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
+
+    def draw_header(self, context):
+        light = context.world.light_settings
+        self.layout.prop(light, "use_environment_light", text="")
+
+    def draw(self, context):
+        layout = self.layout
+
+        light = context.world.light_settings
+
+        layout.active = light.use_environment_light
+
+        split = layout.split()
+        split.prop(light, "environment_energy", text="Energy")
+        split.prop(light, "environment_color", text="")
+
+
 class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
     bl_label = "Mist"
     COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -605,7 +673,7 @@ class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
 
         gs = context.scene.game_settings
 
-        layout.prop(gs, "physics_engine")
+        layout.prop(gs, "physics_engine", text="Engine")
         if gs.physics_engine != 'NONE':
             layout.prop(gs, "physics_gravity", text="Gravity")
 
@@ -668,7 +736,7 @@ class WORLD_PT_game_physics_obstacles(WorldButtonsPanel, Panel):
             layout.prop(gs, "show_obstacle_simulation")
 
 
-class DataButtonsPanel():
+class DataButtonsPanel:
     bl_space_type = 'PROPERTIES'
     bl_region_type = 'WINDOW'
     bl_context = "data"
@@ -701,6 +769,8 @@ class DATA_PT_shadow_game(DataButtonsPanel, Panel):
 
         col = split.column()
         col.prop(lamp, "shadow_color", text="")
+        if lamp.type == 'SUN':
+            col.prop(lamp, "show_shadow_box")
 
         col = split.column()
         col.prop(lamp, "use_shadow_layer", text="This Layer Only")
@@ -726,5 +796,63 @@ class DATA_PT_shadow_game(DataButtonsPanel, Panel):
             row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
 
 
+class ObjectButtonsPanel:
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "object"
+
+
+class OBJECT_MT_lod_tools(Menu):
+    bl_label = "Level Of Detail Tools"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("object.lod_by_name", text="Set By Name")
+        layout.operator("object.lod_generate", text="Generate")
+        layout.operator("object.lod_clear_all", text="Clear All", icon='PANEL_CLOSE')
+
+
+class OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel):
+    bl_label = "Levels of Detail"
+    COMPAT_ENGINES = {'BLENDER_GAME'}
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene.render.engine in cls.COMPAT_ENGINES
+
+    def draw(self, context):
+        layout = self.layout
+        ob = context.object
+        gs = context.scene.game_settings
+
+        col = layout.column()
+
+        for i, level in enumerate(ob.lod_levels):
+            if i == 0:
+                continue
+            box = col.box()
+            row = box.row()
+            row.prop(level, "object", text="")
+            row.operator("object.lod_remove", text="", icon='PANEL_CLOSE').index = i
+
+            row = box.row()
+            row.prop(level, "distance")
+            row = row.row(align=True)
+            row.prop(level, "use_mesh", text="")
+            row.prop(level, "use_material", text="")
+
+            row = box.row()
+            row.active = gs.use_scene_hysteresis
+            row.prop(level, "use_object_hysteresis", text="Hysteresis Override")
+            row = box.row()
+            row.active = gs.use_scene_hysteresis and level.use_object_hysteresis
+            row.prop(level, "object_hysteresis_percentage", text="")
+
+        row = col.row(align=True)
+        row.operator("object.lod_add", text="Add", icon='ZOOMIN')
+        row.menu("OBJECT_MT_lod_tools", text="", icon='TRIA_DOWN')
+
+
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)