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.
260 lines
15 KiB
260 lines
15 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 bpy.props import * |
|
import math |
|
|
|
from .. import idprops |
|
|
|
camera_types = [("circle", "Circle Camera", "The camera circles a fixed point"), |
|
("follow", "Follow Camera", "The camera follows an object"), |
|
("fixed", "Fixed Camera", "The camera is fixed in one location"), |
|
("rail", "Rail Camera", "The camera follows an object by moving along a line"), |
|
("firstperson", "First Person", "Simulates first person view and disappears avatar")] |
|
|
|
class PlasmaTransition(bpy.types.PropertyGroup): |
|
poa_acceleration = FloatProperty(name="PoA Acceleration", |
|
description="Rate the camera's Point of Attention tracking velocity increases in feet per second squared", |
|
min=-100.0, max=100.0, precision=0, default=60.0, |
|
unit="ACCELERATION", options=set()) |
|
poa_deceleration = FloatProperty(name="PoA Deceleration", |
|
description="Rate the camera's Point of Attention tracking velocity decreases in feet per second squared", |
|
min=-100.0, max=100.0, precision=0, default=60.0, |
|
unit="ACCELERATION", options=set()) |
|
poa_velocity = FloatProperty(name="PoA Velocity", |
|
description="Maximum velocity of the camera's Point of Attention tracking", |
|
min=-100.0, max=100.0, precision=0, default=60.0, |
|
unit="VELOCITY", options=set()) |
|
poa_cut = BoolProperty(name="Cut", |
|
description="The camera immediately begins tracking the Point of Attention", |
|
options=set()) |
|
|
|
pos_acceleration = FloatProperty(name="Position Acceleration", |
|
description="Rate the camera's positional velocity increases in feet per second squared", |
|
min=-100.0, max=100.0, precision=0, default=60.0, |
|
unit="ACCELERATION", options=set()) |
|
pos_deceleration = FloatProperty(name="Position Deceleration", |
|
description="Rate the camera's positional velocity decreases in feet per second squared", |
|
min=-100.0, max=100.0, precision=0, default=60.0, |
|
unit="ACCELERATION", options=set()) |
|
pos_velocity = FloatProperty(name="Position Max Velocity", |
|
description="Maximum positional velocity of the camera", |
|
min=-100.0, max=100.0, precision=0, default=60.0, |
|
unit="VELOCITY", options=set()) |
|
pos_cut = BoolProperty(name="Cut", |
|
description="The camera immediately moves to its new position", |
|
options=set()) |
|
|
|
|
|
class PlasmaManualTransition(bpy.types.PropertyGroup): |
|
camera = PointerProperty(name="Camera", |
|
description="The camera from which this transition is intended", |
|
type=bpy.types.Object, |
|
poll=idprops.poll_camera_objects, |
|
options=set()) |
|
transition = PointerProperty(type=PlasmaTransition, options=set()) |
|
mode = EnumProperty(name="Transition Mode", |
|
description="Type of transition that should occur between the two cameras", |
|
items=[("ignore", "Ignore Camera", "Ignore this camera and do not transition"), |
|
("auto", "Auto", "Auto transition as defined by the two cameras' properies"), |
|
("manual", "Manual", "Manually defined transition")], |
|
default="auto", |
|
options=set()) |
|
enabled = BoolProperty(name="Enabled", |
|
description="Export this transition", |
|
default=True, |
|
options=set()) |
|
|
|
|
|
class PlasmaCameraProperties(bpy.types.PropertyGroup): |
|
# Point of Attention |
|
poa_type = EnumProperty(name="Point of Attention", |
|
description="The point of attention that this camera tracks", |
|
items=[("avatar", "Track Local Player", "Camera tracks the player's avatar"), |
|
("object", "Track Object", "Camera tracks an object in the scene"), |
|
("none", "Don't Track", "Camera does not track anything")], |
|
options=set()) |
|
poa_object = PointerProperty(name="PoA Object", |
|
description="Object the camera should track as its Point of Attention", |
|
type=bpy.types.Object, |
|
options=set()) |
|
poa_offset = FloatVectorProperty(name="PoA Offset", |
|
description="Offset from the point of attention's origin to track", |
|
soft_min=-50.0, soft_max=50.0, |
|
size=3, default=(0.0, 0.0, 3.0), |
|
options=set()) |
|
poa_worldspace = BoolProperty(name="Worldspace Offset", |
|
description="Point of Attention Offset is in worldspace coordinates", |
|
options=set()) |
|
|
|
# Position Offset |
|
pos_offset = FloatVectorProperty(name="Position Offset", |
|
description="Offset the camera's position", |
|
soft_min=-50.0, soft_max=50.0, |
|
size=3, default=(0.0, 10.0, 3.0), |
|
options=set()) |
|
pos_worldspace = BoolProperty(name="Worldspace Offset", |
|
description="Position offset is in worldspace coordinates", |
|
options=set()) |
|
|
|
# Default Transition |
|
transition = PointerProperty(type=PlasmaTransition, options=set()) |
|
|
|
# Limit Panning |
|
x_pan_angle = FloatProperty(name="X Degrees", |
|
description="Maximum camera pan angle in the X direction", |
|
min=0.0, max=math.radians(180.0), precision=0, default=math.radians(90.0), |
|
subtype="ANGLE", options=set()) |
|
y_pan_angle = FloatProperty(name="Y Degrees", |
|
description="Maximum camera pan angle in the Y direction", |
|
min=0.0, max=math.radians(180.0), precision=0, default=math.radians(90.0), |
|
subtype="ANGLE", options=set()) |
|
pan_rate = FloatProperty(name="Pan Velocity", |
|
description="", |
|
min=0.0, precision=1, default=50.0, |
|
unit="VELOCITY", options=set()) |
|
|
|
# Zooming |
|
fov = FloatProperty(name="Default FOV", |
|
description="Horizontal Field of View angle", |
|
min=0.0, max=math.radians(180.0), precision=0, default=math.radians(70.0), |
|
subtype="ANGLE") |
|
limit_zoom = BoolProperty(name="Limit Zoom", |
|
description="The camera allows zooming per artist limitations", |
|
options=set()) |
|
zoom_max = FloatProperty(name="Max FOV", |
|
description="Maximum camera FOV when zooming", |
|
min=0.0, max=math.radians(180.0), precision=0, default=math.radians(120.0), |
|
subtype="ANGLE", options=set()) |
|
zoom_min = FloatProperty(name="Min FOV", |
|
description="Minimum camera FOV when zooming", |
|
min=0.0, max=math.radians(180.0), precision=0, default=math.radians(35.0), |
|
subtype="ANGLE", options=set()) |
|
zoom_rate = FloatProperty(name="Zoom Velocity", |
|
description="Velocity of the camera's zoom in degrees per second", |
|
min=0.0, max=180.0, precision=0, default=90.0, |
|
unit="VELOCITY", options=set()) |
|
|
|
# Miscellaneous Movement Props |
|
maintain_los = BoolProperty(name="Maintain LOS", |
|
description="The camera should move to maintain line-of-sight with the object it's tracking", |
|
default=True, |
|
options=set()) |
|
fall_vertical = BoolProperty(name="Fall Camera", |
|
description="The camera will orient itself vertically when the local player begins falling", |
|
options=set()) |
|
fast_run = BoolProperty(name="Faster When Falling", |
|
description="The camera's velocity will be increased when the local player is falling", |
|
options=set()) |
|
ignore_subworld = BoolProperty(name="Ignore Subworld Movement", |
|
description="The camera will not be parented to any subworlds", |
|
options=set()) |
|
|
|
# Core Type Properties |
|
primary_camera = BoolProperty(name="Primary Camera", |
|
description="The camera should be considered the Age's primary camera.", |
|
options=set()) |
|
|
|
# Cricle Camera |
|
def _get_circle_radius(self): |
|
# This is coming from the UI, so we need to get the active object from |
|
# Blender's context and pass that on to the actual getter. |
|
return self.get_circle_radius(bpy.context.object) |
|
def _set_circle_radius(self, value): |
|
# Don't really care about error checking... |
|
self.circle_radius_value = value |
|
|
|
circle_center = PointerProperty(name="Center", |
|
description="Center of the circle camera's orbit", |
|
type=bpy.types.Object, |
|
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 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", |
|
min=0.0, max=math.radians(360.0), precision=0, default=math.radians(36.0), |
|
subtype="ANGLE", options=set()) |
|
circle_radius_ui = FloatProperty(name="Radius", |
|
description="Radius at which the circle camera should orbit the Point of Attention", |
|
min=0.0, get=_get_circle_radius, set=_set_circle_radius, options=set()) |
|
circle_radius_value = FloatProperty(name="INTERNAL: Radius", |
|
description="Radius at which the circle camera should orbit the Point of Attention", |
|
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 |
|
if self.circle_center is not None: |
|
vec = bo.matrix_world.translation - self.circle_center.matrix_world.translation |
|
return vec.magnitude |
|
return self.circle_radius_value |
|
|
|
def harvest_actors(self): |
|
actors = set() |
|
if self.poa_type == "object": |
|
actors.add(self.poa_object.name) |
|
|
|
# Dang! We need to escape out to the object to figure out if this is a circle camera... |
|
data = self.id_data |
|
if isinstance(data, bpy.types.Camera) and data.plasma_camera.camera_type == "circle": |
|
if self.circle_center is not None: |
|
actors.add(self.circle_center.name) |
|
return actors |
|
|
|
|
|
class PlasmaCamera(bpy.types.PropertyGroup): |
|
camera_type = EnumProperty(name="Camera Type", |
|
description="", |
|
items=camera_types, |
|
options=set()) |
|
settings = PointerProperty(type=PlasmaCameraProperties, options=set()) |
|
transitions = CollectionProperty(type=PlasmaManualTransition, |
|
name="Transitions", |
|
description="", |
|
options=set()) |
|
active_transition_index = IntProperty(options={"HIDDEN"}) |
|
|
|
@property |
|
def allow_animations(self) -> bool: |
|
"""Check to see if animations are allowed on this camera""" |
|
return self.camera_type == "fixed"
|
|
|