mirror of https://github.com/H-uru/korman.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
9.8 KiB
282 lines
9.8 KiB
# This file is part of Korman. |
|
# |
|
# Korman is free software: you can redistribute it and/or modify |
|
# it under the terms of the GNU General Public License as published by |
|
# the Free Software Foundation, either version 3 of the License, or |
|
# (at your option) any later version. |
|
# |
|
# Korman is distributed in the hope that it will be useful, |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
# GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License |
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
import bpy |
|
|
|
from .. import helpers |
|
from . import ui_list |
|
|
|
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: |
|
layout.alert = True |
|
if max is not None and value > max: |
|
layout.alert = True |
|
layout.prop(props, the_prop, **kwargs) |
|
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 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() |
|
col.label("Camera Mode:") |
|
col = col.column() |
|
col.alert = cam_type != "fixed" and props.poa_type == "none" |
|
col.prop(props, "poa_type", text="") |
|
col.alert = False |
|
row = col.row() |
|
row.active = props.poa_type == "object" |
|
row.prop(props, "poa_object", text="") |
|
col.separator() |
|
col.prop(props, "primary_camera") |
|
|
|
# Miscellaneous |
|
col = split.column() |
|
col.label("Tracking Settings:") |
|
col_follow = col.column() |
|
col_follow.active = cam_type == "follow" |
|
col_follow.prop(props, "maintain_los") |
|
col_follow.prop(props, "fall_vertical") |
|
col_follow.prop(props, "fast_run") |
|
col_target = col.column() |
|
col_target.active = props.poa_type != "none" |
|
col_target.prop(props, "ignore_subworld") |
|
|
|
def draw_camera_poa_props(layout, cam_type, props): |
|
trans = props.transition |
|
|
|
# PoA Tracking |
|
split = layout.split() |
|
col = split.column() |
|
col.label("Default Tracking Transition:") |
|
col.prop(trans, "poa_acceleration", text="Acceleration") |
|
col.prop(trans, "poa_deceleration", text="Deceleration") |
|
col.prop(trans, "poa_velocity", text="Maximum Velocity") |
|
col = col.column() |
|
col.active = cam_type in {"firstperson", "follow"} |
|
col.prop(trans, "poa_cut", text="Cut Animation") |
|
|
|
# PoA Offset |
|
col = split.column() |
|
col.label("Point of Attention Offset:") |
|
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) |
|
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_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 = col.column() |
|
col.active = cam_type in {"firstperson", "follow"} |
|
col.prop(trans, "pos_cut", text="Cut Animation") |
|
|
|
# Position Offsets |
|
col = split.column() |
|
col.active = cam_type in {"firstperson", "follow"} |
|
col.label("Position Offset:") |
|
col.prop(props, "pos_offset", text="") |
|
col.prop(props, "pos_worldspace") |
|
|
|
def draw_circle_camera_props(layout, props): |
|
# Circle Camera Stuff |
|
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") |
|
|
|
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.label("Animation:") |
|
anim_enabled = props.anim_enabled or context.object.plasma_modifiers.animation.enabled |
|
col.active = anim_enabled and context.object.plasma_object.has_animation_data |
|
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" |
|
invalid = camera.camera_type == "rail" and not context.object.plasma_object.has_transform_animation |
|
col.alert = invalid |
|
col.label("Rail:") |
|
col.prop(props, "rail_pos", text="") |
|
if invalid: |
|
col.label("Rail cameras must have a transformation animation!", icon="ERROR") |
|
|
|
def draw_header(self, context): |
|
self.layout.active = context.object.plasma_object.has_animation_data |
|
if not context.object.plasma_modifiers.animation.enabled: |
|
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): |
|
layout = self.layout |
|
camera = context.camera.plasma_camera |
|
|
|
ui_list.draw_list(layout, "TransitionListUI", "camera", camera, "transitions", |
|
"active_transition_index", rows=3, maxrows=4) |
|
|
|
try: |
|
item = camera.transitions[camera.active_transition_index] |
|
trans = item.transition |
|
except: |
|
pass |
|
else: |
|
layout.separator() |
|
box = layout.box() |
|
box.prop(item, "camera", text="Transition From") |
|
box.prop(item, "mode") |
|
|
|
box.separator() |
|
split = box.split() |
|
split.active = item.mode == "manual" |
|
|
|
col = split.column() |
|
col.label("Tracking Transition:") |
|
col.prop(trans, "poa_acceleration", text="Acceleration") |
|
col.prop(trans, "poa_deceleration", text="Deceleration") |
|
col.prop(trans, "poa_velocity", text="Maximum Velocity") |
|
col.prop(trans, "poa_cut", text="Cut Transition") |
|
|
|
col = split.column() |
|
col.label("Position Transition:") |
|
col.prop(trans, "pos_acceleration", text="Acceleration") |
|
col.prop(trans, "pos_deceleration", text="Deceleration") |
|
col.prop(trans, "pos_velocity", text="Maximum Velocity") |
|
col.prop(trans, "pos_cut", text="Cut Transition")
|
|
|