Browse Source

Rework camera UI to not be so monolithic

pull/105/head
Adam Johnson 6 years ago
parent
commit
1ca9456870
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 3
      korman/exporter/camera.py
  2. 17
      korman/properties/prop_camera.py
  3. 4
      korman/render.py
  4. 23
      korman/ui/modifiers/region.py
  5. 214
      korman/ui/ui_camera.py

3
korman/exporter/camera.py

@ -140,6 +140,7 @@ class CameraConverter:
return brain
def _export_fixed_camera(self, so, bo, props):
if props.anim_enabled:
self._exporter().animation.convert_object_animations(bo, so)
brain = self._mgr.find_create_object(plCameraBrain1_Fixed, so=so)
self._convert_brain(so, bo, props, brain)
@ -185,6 +186,8 @@ class CameraConverter:
else:
# The animation is a loop
path.flags |= plAnimPath.kWrap
if props.rail_pos == "farthest":
path.flags |= plAnimPath.kFarthest
path.length = end / bpy.context.scene.render.fps
rail.path = path
brain.rail = rail.key

17
korman/properties/prop_camera.py

@ -159,8 +159,8 @@ class PlasmaCameraProperties(bpy.types.PropertyGroup):
options=set())
circle_pos = EnumProperty(name="Position on Circle",
description="The point on the circle the camera moves to",
items=[("closest", "Closest Point", "The camera moves to point on the circle closest to the Point of Attention"),
("farthest", "Farthest Point", "The point farthest from the Point of Attention")],
items=[("closest", "Closest Point", "The camera moves to the point on the circle closest to the Point of Attention"),
("farthest", "Farthest Point", "The camera moves to the point on the circle farthest from the Point of Attention")],
options=set())
circle_velocity = FloatProperty(name="Velocity",
description="Velocity of the circle camera in degrees per second",
@ -174,16 +174,29 @@ class PlasmaCameraProperties(bpy.types.PropertyGroup):
min=0.0, default=8.5, options={"HIDDEN"})
# Animation
anim_enabled = BoolProperty(name="Animation Enabled",
description="Export the camera's animation",
default=True,
options=set())
start_on_push = BoolProperty(name="Start on Push",
description="Start playing the camera's animation when the camera is activated",
default=True,
options=set())
stop_on_pop = BoolProperty(name="Pause on Pop",
description="Pauses the camera's animation when the camera is no longer activated",
default=True,
options=set())
reset_on_pop = BoolProperty(name="Reset on Pop",
description="Reset the camera's animation to the beginning when the camera is no longer activated",
options=set())
# Rail
rail_pos = EnumProperty(name="Position on Rail",
description="The point on the rail the camera moves to",
items=[("closest", "Closest Point", "The camera moves to the point on the rail closest to the Point of Attention"),
("farthest", "Farthest Point", "The camera moves to the point on the rail farthest from the Point of Attention")],
options=set())
def get_circle_radius(self, bo):
"""Gets the circle camera radius for this camera when it is attached to the given Object"""
assert bo is not None

4
korman/render.py

@ -36,10 +36,6 @@ properties_material.MATERIAL_PT_transp.COMPAT_ENGINES.add("PLASMA_GAME")
properties_material.MATERIAL_PT_shadow.COMPAT_ENGINES.add("PLASMA_GAME")
del properties_material
from bl_ui import properties_data_camera
properties_data_camera.DATA_PT_context_camera.COMPAT_ENGINES.add("PLASMA_GAME")
del properties_data_camera
from bl_ui import properties_data_mesh
properties_data_mesh.DATA_PT_uv_texture.COMPAT_ENGINES.add("PLASMA_GAME")
properties_data_mesh.DATA_PT_vertex_colors.COMPAT_ENGINES.add("PLASMA_GAME")

23
korman/ui/modifiers/region.py

@ -14,14 +14,33 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy
from ..ui_camera import draw_camera_properties
from .. import ui_camera
def camera_rgn(modifier, layout, context):
layout.prop(modifier, "camera_type")
if modifier.camera_type == "manual":
layout.prop(modifier, "camera_object", icon="CAMERA_DATA")
else:
draw_camera_properties("follow", modifier.auto_camera, layout, context, True)
cam_type = modifier.camera_type[5:]
cam_props = modifier.auto_camera
def _draw_props(layout, cb):
for i in cb:
layout.separator()
i(layout, cam_type, cam_props)
def _draw_circle_cam_props(layout, cam_type, props):
# needs a sublayout that we can deactivate because the ui_camera
# version assumes we are most definitely a circle camera...
col = layout.column()
col.active = cam_type == "circle"
col.label("Circle Camera:")
ui_camera.draw_circle_camera_props(col, props)
_draw_props(layout, (ui_camera.draw_camera_mode_props,
ui_camera.draw_camera_poa_props,
ui_camera.draw_camera_pos_props,
ui_camera.draw_camera_manipulation_props,
_draw_circle_cam_props))
def footstep(modifier, layout, context):
layout.prop(modifier, "bounds")

214
korman/ui/ui_camera.py

@ -14,41 +14,10 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy
from .. import helpers
class CameraButtonsPanel:
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "data"
@classmethod
def poll(cls, context):
return (context.camera and context.scene.render.engine == "PLASMA_GAME")
class PlasmaCameraPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Plasma Camera"
def draw(self, context):
camera = context.camera.plasma_camera
layout = self.layout
layout.prop(camera, "camera_type")
layout.separator()
draw_camera_properties(camera.camera_type, camera.settings, layout, context)
class PlasmaCameraTransitionPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Plasma Transitions"
def draw(self, context):
pass
def draw_camera_properties(cam_type, props, layout, context, force_no_anim=False):
trans = props.transition
def _draw_alert_prop(layout, props, the_prop, cam="", min=None, max=None, **kwargs):
can_alert = not cam or cam == cam_type
def _draw_alert_prop(layout, props, the_prop, cam_type, alert_cam="", min=None, max=None, **kwargs):
can_alert = not alert_cam or alert_cam == cam_type
if can_alert:
value = getattr(props, the_prop)
if min is not None and value < min:
@ -59,24 +28,31 @@ def draw_camera_properties(cam_type, props, layout, context, force_no_anim=False
layout.alert = False
else:
layout.prop(props, the_prop, **kwargs)
def _draw_gated_prop(layout, props, gate_prop, actual_prop):
row = layout.row(align=True)
row.prop(props, gate_prop, text="")
row = row.row(align=True)
row.active = getattr(props, gate_prop)
row.prop(props, actual_prop)
def _is_camera_animated(cam_type, props, context, force_no_anim):
if force_no_anim or cam_type == "rail":
return False
# Check for valid animation data on either the object or the camera
# TODO: Should probably check for valid FCurve channels at some point???
for i in (props.id_data, context.object):
if i.animation_data is None:
continue
if i.animation_data.action is not None:
return True
return False
def draw_camera_manipulation_props(layout, cam_type, props):
# Camera Panning
split = layout.split()
col = split.column()
col.label("Limit Panning:")
col.prop(props, "x_pan_angle")
col.prop(props, "y_pan_angle")
# Camera Zoom
col = split.column()
col.label("Field of View:")
col.prop(props, "fov")
_draw_gated_prop(col, props, "limit_zoom", "zoom_min")
_draw_gated_prop(col, props, "limit_zoom", "zoom_max")
_draw_gated_prop(col, props, "limit_zoom", "zoom_rate")
def draw_camera_mode_props(layout, cam_type, props):
# Point of Attention
split = layout.split()
col = split.column()
@ -99,8 +75,10 @@ def draw_camera_properties(cam_type, props, layout, context, force_no_anim=False
col.prop(props, "fast_run")
col.prop(props, "ignore_subworld")
def draw_camera_poa_props(layout, cam_type, props):
trans = props.transition
# PoA Tracking
layout.separator()
split = layout.split()
col = split.column()
col.label("Default Tracking Transition:")
@ -115,17 +93,22 @@ def draw_camera_properties(cam_type, props, layout, context, force_no_anim=False
col.prop(props, "poa_offset", text="")
col.prop(props, "poa_worldspace")
def draw_camera_pos_props(layout, cam_type, props):
trans = props.transition
# Position Tracking (only for follow cams)
layout.separator()
split = layout.split()
col = split.column()
# Position Transitions
col.active = cam_type != "circle"
col.label("Default Position Transition:")
_draw_alert_prop(col, trans, "pos_acceleration", cam="rail", max=10.0, text="Acceleration")
_draw_alert_prop(col, trans, "pos_deceleration", cam="rail", max=10.0, text="Deceleration")
_draw_alert_prop(col, trans, "pos_velocity", cam="rail", max=10.0, text="Maximum Velocity")
_draw_alert_prop(col, trans, "pos_acceleration", cam_type,
alert_cam="rail", max=10.0, text="Acceleration")
_draw_alert_prop(col, trans, "pos_deceleration", cam_type,
alert_cam="rail", max=10.0, text="Deceleration")
_draw_alert_prop(col, trans, "pos_velocity", cam_type,
alert_cam="rail", max=10.0, text="Maximum Velocity")
col.prop(trans, "pos_cut")
# Position Offsets
@ -135,39 +118,116 @@ def draw_camera_properties(cam_type, props, layout, context, force_no_anim=False
col.prop(props, "pos_offset", text="")
col.prop(props, "pos_worldspace")
# Camera Panning
layout.separator()
split = layout.split()
col = split.column()
col.label("Limit Panning:")
col.prop(props, "x_pan_angle")
col.prop(props, "y_pan_angle")
# Camera Zoom
col = split.column()
col.label("Field of View:")
col.prop(props, "fov")
_draw_gated_prop(col, props, "limit_zoom", "zoom_min")
_draw_gated_prop(col, props, "limit_zoom", "zoom_max")
_draw_gated_prop(col, props, "limit_zoom", "zoom_rate")
def draw_circle_camera_props(layout, props):
# Circle Camera Stuff
layout.separator()
split = layout.split()
col = split.column()
col.active = cam_type == "circle"
col.label("Circle Camera:")
col.prop(props, "circle_center", text="")
col.prop(props, "circle_pos", text="")
col.prop(props, "circle_velocity")
row = col.row(align=True)
layout.prop(props, "circle_center")
layout.prop(props, "circle_pos")
layout.prop(props, "circle_velocity")
row = layout.row(align=True)
row.active = props.circle_center is None
row.prop(props, "circle_radius_ui")
# Animated Camera Stuff
class CameraButtonsPanel:
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "data"
@classmethod
def poll(cls, context):
return (context.camera and context.scene.render.engine == "PLASMA_GAME")
class PlasmaCameraTypePanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = ""
bl_options = {"HIDE_HEADER"}
def draw(self, context):
camera = context.camera.plasma_camera
self.layout.prop(camera, "camera_type")
class PlasmaCameraModePanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Camera Tracking"
def draw(self, context):
camera = context.camera.plasma_camera
draw_camera_mode_props(self.layout, camera.camera_type, camera.settings)
class PlasmaCameraAttentionPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Point of Attention Tracking"
def draw(self, context):
camera = context.camera.plasma_camera
draw_camera_poa_props(self.layout, camera.camera_type, camera.settings)
class PlasmaCameraPositionPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Position Tracking"
def draw(self, context):
camera = context.camera.plasma_camera
draw_camera_pos_props(self.layout, camera.camera_type, camera.settings)
class PlasmaCameraCirclePanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Circle Camera"
def draw(self, context):
camera = context.camera.plasma_camera
draw_circle_camera_props(self.layout, camera.settings)
@classmethod
def poll(cls, context):
return super().poll(context) and context.camera.plasma_camera.camera_type == "circle"
class PlasmaCameraAnimationPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Camera Animation"
bl_options = {"DEFAULT_CLOSED"}
def draw(self, context):
layout = self.layout
camera = context.camera.plasma_camera
props = camera.settings
split = layout.split()
col = split.column()
col.active = _is_camera_animated(cam_type, props, context, force_no_anim)
col.label("Animation:")
col.active = props.anim_enabled and any(helpers.fetch_fcurves(context.object))
col.prop(props, "start_on_push")
col.prop(props, "stop_on_pop")
col.prop(props, "reset_on_pop")
col = split.column()
col.active = camera.camera_type == "rail"
col.label("Rail:")
col.prop(props, "rail_pos", text="")
def draw_header(self, context):
self.layout.active = any(helpers.fetch_fcurves(context.object))
self.layout.prop(context.camera.plasma_camera.settings, "anim_enabled", text="")
class PlasmaCameraViewPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Camera Lens"
def draw(self, context):
camera = context.camera.plasma_camera
draw_camera_manipulation_props(self.layout, camera.camera_type, camera.settings)
class TransitionListUI(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_property, index=0, flt_flag=0):
if item.camera is None:
layout.label("[Default Transition]")
else:
layout.label(item.camera.name, icon="CAMERA_DATA")
layout.prop(item, "enabled", text="")
class PlasmaCameraTransitionPanel(CameraButtonsPanel, bpy.types.Panel):
bl_label = "Transitions"
def draw(self, context):
pass

Loading…
Cancel
Save