1
0
KF2-Dev-Scripts/GameFramework/Classes/GameThirdPersonCameraMode.uc

477 lines
18 KiB
Ucode
Raw Normal View History

2020-12-13 15:01:13 +00:00
/**
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
*/
class GameThirdPersonCameraMode extends Object
config(Camera)
native(Camera);
/**
* Contains all the information needed to define a camera
* mode.
*/
/** Ref to the camera object that owns this mode object. */
var transient GameThirdPersonCamera ThirdPersonCam;
/** FOV for camera to use */
var() const config float FOVAngle;
/** Blend Time to and from this view mode */
var() float BlendTime;
/**
* True if, while in this mode, the camera should be tied to the viewtarget rotation.
* This is typical for the normal walking-around camera, since the controls rotate the controller
* and the camera follows. This can be false if you want free control of the camera, independent
* of the viewtarget's orient -- we use this for vehicles. Note that if this is false,
*/
var() const protected bool bLockedToViewTarget;
/**
* True if, while in this mode, looking around should be directly mapped to stick position
* as opposed to relative to previous camera positions.
*/
var() const protected bool bDirectLook;
/**
* True if, while in this mode, the camera should interpolate towards a following position
* in relation to the target and it's motion. Ignored if bLockedToViewTarget is set to true.
*/
var() const protected bool bFollowTarget;
/*
* How fast the camera should track to follow behind the viewtarget. 0.f for no following.
* Only used if bLockedToViewTarget is FALSE
*/
var() const protected float FollowingInterpSpeed_Pitch;
var() const protected float FollowingInterpSpeed_Yaw;
var() const protected float FollowingInterpSpeed_Roll;
/** Actual following interp speed gets scaled from FollowingInterpSpeed to zero between velocities of this value and zero. */
var() const protected float FollowingCameraVelThreshold;
/** True means camera will attempt to smoothly interpolate to its new position. False will snap it to it's new position. */
var() bool bInterpLocation;
/** Controls interpolation speed of location for camera origin. Ignored if bInterpLocation is false. */
var() protected float OriginLocInterpSpeed;
/**
* This is a special case of origin location interpolation. If true, interpolaton will be done on each axis independently, with the specified speeds.
* Ignored if bInterpLocation is false.
*/
var() protected bool bUsePerAxisOriginLocInterp;
var() protected vector PerAxisOriginLocInterpSpeed;
/** True means camera will attempt to smoothly interpolate to its new rotation. False will snap it to it's new rotation. */
var() bool bInterpRotation;
/** Controls interpolation speed of rotation for the camera origin. Ignored if bInterpRotation is false. */
var() protected float OriginRotInterpSpeed;
/** Whether rotation interpolation happens at constant speed or not */
var() bool bRotInterpSpeedConstant;
/** Adjustment vector to apply to camera view offset when target is strafing to the left */
var() const protected vector StrafeLeftAdjustment;
/** Adjustment vector to apply to camera view offset when target is strafing to the right */
var() const protected vector StrafeRightAdjustment;
/** Velocity at (and above) which the full adjustment should be applied. */
var() const protected float StrafeOffsetScalingThreshold;
/** Interpolation speed for interpolating to a NONZERO strafe offsets. Higher is faster/tighter interpolation. */
var() const protected float StrafeOffsetInterpSpeedIn;
/** Interpolation speed for interpolating to a ZERO strafe offset. Higher is faster/tighter interpolation. */
var() const protected float StrafeOffsetInterpSpeedOut;
/** Strafe offset last tick, used for interpolation. */
var protected transient vector LastStrafeOffset;
/** Adjustment vector to apply to camera view offset when target is moving forward */
var() const protected vector RunFwdAdjustment;
/** Adjustment vector to apply to camera view offset when target is moving backward */
var() const protected vector RunBackAdjustment;
/** Velocity at (and above) which the full adjustment should be applied. */
var() const protected float RunOffsetScalingThreshold;
/** Interpolation speed for interpolating to a NONZERO offset. Higher is faster/tighter interpolation. */
var() const protected float RunOffsetInterpSpeedIn;
/** Interpolation speed for interpolating to a ZERO offset. Higher is faster/tighter interpolation. */
var() const protected float RunOffsetInterpSpeedOut;
/** Run offset last tick, used for interpolation. */
var protected transient vector LastRunOffset;
/**
* An offset from the location of the viewtarget, in the viewtarget's local space.
* Used to calculate the "worst case" camera location, which is where the camera should retreat to
* if tightly obstructed.
*/
var() protected vector WorstLocOffset;
/** True to turn do predictive camera avoidance, false otherwise */
var() const bool bDoPredictiveAvoidance;
/** TRUE to do a raytrace from camera base loc to worst loc, just to be sure it's cool. False to skip it */
var() const bool bValidateWorstLoc;
/** If TRUE, all camera collision is disabled */
var() bool bSkipCameraCollision;
/** Offset, in the camera target's local space, from the camera target to the camera's origin. */
var() const protected vector TargetRelativeCameraOriginOffset;
/** Supported viewport configurations. */
enum ECameraViewportTypes
{
CVT_16to9_Full,
CVT_16to9_VertSplit,
CVT_16to9_HorizSplit,
CVT_4to3_Full,
CVT_4to3_HorizSplit,
CVT_4to3_VertSplit,
};
struct native ViewOffsetData
{
/** View point offset for high player view pitch */
var() vector OffsetHigh;
/** View point offset for medium (horizon) player view pitch */
var() vector OffsetMid;
/** View point offset for low player view pitch */
var() vector OffsetLow;
};
/** contains offsets from camera target to camera loc */
var() const protected ViewOffsetData ViewOffset;
/** TRUE to smooth the interp between high/mid/low, false to blend linearly between high <-> mid <-> low */
var() const protected bool bSmoothViewOffsetPitchChanges;
/** viewoffset adjustment vectors for each possible viewport type, so the game looks close to the same in each */
var() const protected ViewOffsetData ViewOffset_ViewportAdjustments[ECameraViewportTypes.EnumCount];
/** whether delta or actual view offset should be applied to the camera location */
var() bool bApplyDeltaViewOffset;
/** Optional parameters for DOF adjustments. */
var(DepthOfField) const protected bool bAdjustDOF;
var(DepthOfField) const protected float DOF_FalloffExponent;
var(DepthOfField) const protected float DOF_BlurKernelSize;
var(DepthOfField) const protected float DOF_FocusInnerRadius;
var(DepthOfField) const protected float DOF_MaxNearBlurAmount;
var(DepthOfField) const protected float DOF_MaxFarBlurAmount;
var transient protected bool bDOFUpdated;
var protected transient float LastDOFRadius;
var protected transient float LastDOFDistance;
var(DepthOfField) protected const float DOFDistanceInterpSpeed;
var(DepthOfField) protected const vector DOFTraceExtent;
/** Maps out how the DOF inner radius changes over distance. */
var(DepthOfField) protected const float DOF_RadiusFalloff;
var(DepthOfField) protected const vector2d DOF_RadiusRange;
var(DepthOfField) protected const vector2d DOF_RadiusDistRange;
/** Whether camera anims and other post processing should change the FOV */
var bool bNoFOVPostProcess;
/** If TRUE ViewOffset will only be interpolated between camera mode transitions, and then be instantaneous */
var() bool bInterpViewOffsetOnlyForCamTransition;
/** Keep track of our ViewOffset Interpolation factor */
var float ViewOffsetInterp;
/** We optionally interpolate the results of AdjustViewOffset() to prevent pops when a cameramode changes its adjustment suddenly. */
var() protected float OffsetAdjustmentInterpSpeed;
/** Keep track of the current viewport type as computed by GetViewOffset() */
var protected transient ECameraViewportTypes CurrentViewportType;
cpptext
{
// GearThirdPersonCameraMode interface
/**
* Calculates and returns the ideal view offset for the specified camera mode.
* The offset is relative to the Camera's pos/rot and calculated by interpolating
* 2 ideal view points based on the player view pitch.
*
* @param ViewedPawn Camera target pawn
* @param DeltaTime Delta time since last frame.
* @param ViewRotation Rot of the camera
*/
virtual FVector GetViewOffset(class APawn* ViewedPawn, FLOAT DeltaTime, const FVector& ViewOrigin, const FRotator& ViewRotation);
FLOAT GetViewOffsetInterpSpeed(class APawn* ViewedPawn, FLOAT DeltaTime);
virtual FRotator GetViewOffsetRotBase( class APawn* ViewedPawn, const FTViewTarget& VT );
/** Returns View relative offsets */
virtual void GetBaseViewOffsets(class APawn* ViewedPawn, BYTE ViewportConfig, FLOAT DeltaTime, FVector& out_Low, FVector& out_Mid, FVector& out_High);
/** Returns true if mode should be using direct-look mode, false otherwise */
virtual UBOOL UseDirectLookMode(class APawn* CameraTarget);
/** Returns true if mode should lock camera to view target, false otherwise */
virtual UBOOL LockedToViewTarget(class APawn* CameraTarget);
/**
* Returns true if this mode should do target following. If true is returned, interp speeds are filled in.
* If false is returned, interp speeds are not altered.
*/
virtual UBOOL ShouldFollowTarget(class APawn* CameraTarget, FLOAT& PitchInterpSpeed, FLOAT& YawInterpSpeed, FLOAT& RollInterpSpeed);
/** Returns an offset, in pawn-local space, to be applied to the camera origin. */
virtual FVector GetTargetRelativeOriginOffset(class APawn* TargetPawn);
/**
* Returns location and rotation, in world space, of the camera's basis point. The camera will rotate
* around this point, offsets are applied from here, etc.
*/
virtual void GetCameraOrigin(class APawn* TargetPawn, FVector& OriginLoc, FRotator& OriginRot);
/**
* Interpolates from previous location/rotation toward desired location/rotation
*/
virtual void InterpolateCameraOrigin( class APawn* TargetPawn, FLOAT DeltaTime, FVector& out_ActualCameraOrigin, FVector const& IdealCameraOrigin, FRotator& out_ActualCameraOriginRot, FRotator const& IdealCameraOriginRot );
/** Returns time to interpolate location/rotation changes. */
virtual FLOAT GetBlendTime(class APawn* Pawn);
/** Returns time to interpolate FOV changes. */
virtual FLOAT GetFOVBlendTime(class APawn* Pawn);
/*
* Interpolates a camera's origin from the last location to a new ideal location
* @CameraTargetRot - Rotation of the camera target, used to create a reference frame for interpolation
* @LastLoc - Last location of the camera
* @IdealLoc - Ideal location for the camera this frame
* @DeltaTime - time step
* @return if bInterpLocation is false, returns IdealLoc, otherwise if bUsePerAxisOriginLocInterp is TRUE it interpolates relative to the target axis via PerAxisOriginLocInterpSpeed, else via constant OriginLocInterpSpeed
*/
virtual FVector InterpolateCameraOriginLoc(class APawn* TargetPawn, FRotator const& CameraTargetRot, FVector const& LastLoc, FVector const& IdealLoc, FLOAT DeltaTime);
virtual FRotator InterpolateCameraOriginRot(class APawn* TargetPawn, FRotator const& LastRot, FRotator const& IdealRot, FLOAT DeltaTime);
virtual FVector ApplyViewOffset( class APawn* ViewedPawn, const FVector& CameraOrigin, const FVector& ActualViewOffset, const FVector& DeltaViewOffset, const FTViewTarget& OutVT );
protected:
virtual FLOAT GetViewPitch(APawn* TargetPawn, FRotator const& ViewRotation) const;
public:
};
/** Called when this mode is initially created/new'd */
function Init();
/** Called when Camera mode becomes active */
function OnBecomeActive(Pawn TargetPawn, GameThirdPersonCameraMode PrevMode)
{
// Setup BlendTime for ViewOffsets
if( BlendTime > 0.f )
{
ViewOffsetInterp = 1 / BlendTime;
}
else
{
ViewOffsetInterp = 0;
}
}
/** Called when camera mode becomes inactive */
function OnBecomeInActive(Pawn TargetPawn, GameThirdPersonCameraMode NewMode);
/**
* Allows mode to make any final situational adjustments to the base view offset.
*/
event vector AdjustViewOffset( Pawn P, vector Offset )
{
// no adjustment by default
return Offset;
}
/** Returns FOV that this camera mode desires. */
function float GetDesiredFOV( Pawn ViewedPawn )
{
return FOVAngle;
}
/**
* Returns the "worst case" camera location for this camera mode.
* This is the position that the camera penetration avoidance is based off of,
* so it should be a guaranteed safe place to put the camera.
* @param TargetPawn Pawn being viewed.
* @param CurrentViewTarget current desired camera POV. Minus penetration checks.
*/
simulated event vector GetCameraWorstCaseLoc(Pawn TargetPawn, TViewTarget CurrentViewTarget)
{
return TargetPawn.Location + (WorstLocOffset >> TargetPawn.Rotation);
}
/**
* Camera mode has a chance to set a focus point, if it so chooses.
* Return true if setting one, false if not.
*/
simulated function bool SetFocusPoint(Pawn ViewedPawn)
{
// no focus point by default
return FALSE;
}
simulated function ProcessViewRotation( float DeltaTime, Actor ViewTarget, out Rotator out_ViewRotation, out Rotator out_DeltaRot );
simulated protected function vector GetDOFFocusLoc(Actor TraceOwner, vector StartTrace, vector EndTrace)
{
return DOFTrace(TraceOwner, StartTrace, EndTrace);
}
/** Modeled after CalcWeaponFire to avoid triggers. Consider moving to native code and using a single line check call? */
simulated protected function vector DOFTrace(Actor TraceOwner, vector StartTrace, vector EndTrace)
{
local vector HitLocation, HitNormal;
local Actor HitActor;
// Perform trace to retrieve hit info
HitActor = TraceOwner.Trace(HitLocation, HitNormal, EndTrace, StartTrace, TRUE, DOFTraceExtent,, TraceOwner.TRACEFLAG_Bullet);
// If we didn't hit anything, then set the HitLocation as being the EndTrace location
if( HitActor == None )
{
HitLocation = EndTrace;
}
// `log("DOF trace hit"@HitActor);
// check to see if we've hit a trigger.
// In this case, we want to add this actor to the list so we can give it damage, and then continue tracing through.
if( HitActor != None )
{
if ( !HitActor.bBlockActors &&
( HitActor.IsA('Trigger') || HitActor.IsA('TriggerVolume') ) )
{
// disable collision temporarily for the trigger so that we can catch anything inside the trigger
HitActor.bProjTarget = false;
// recurse another trace
// `log("... recursing!");
HitLocation = DOFTrace(TraceOwner, HitLocation, EndTrace);
// and reenable collision for the trigger
HitActor.bProjTarget = true;
}
}
return HitLocation;
}
/** Gives mode a chance to adjust/override postprocess as desired. */
simulated function UpdatePostProcess(const out TViewTarget VT, float DeltaTime)
{
local vector FocusLoc, StartTrace, EndTrace, CamDir;
local float FocusDist, SubjectDist, Pct;
bDOFUpdated = FALSE;
if (bAdjustDOF)
{
// nudge forward a little, in case camera gets itself in a wierd place.
CamDir = vector(VT.POV.Rotation);
StartTrace = VT.POV.Location + CamDir * 10;
EndTrace = StartTrace + CamDir * 50000;
FocusLoc = GetDOFFocusLoc(VT.Target, StartTrace, EndTrace);
SubjectDist = VSize(FocusLoc - StartTrace);
if (!ThirdPersonCam.bResetCameraInterpolation)
{
FocusDist = FInterpTo(LastDOFDistance, SubjectDist, DeltaTime, DOFDistanceInterpSpeed);
}
else
{
FocusDist = SubjectDist;
}
LastDOFDistance = FocusDist;
// find focus radius
// simpler method, with better-feeling results than actual optics math
Pct = GetRangePctByValue(DOF_RadiusDistRange, FocusDist);
LastDOFRadius = GetRangeValueByPct(DOF_RadiusRange, FClamp(Pct, 0.f, 1.f)**DOF_RadiusFalloff);
bDOFUpdated = TRUE;
}
}
simulated function ModifyPostProcessSettings(out PostProcessSettings PP)
{
if (bDOFUpdated)
{
PP.bEnableDOF = TRUE;
`if(`__TW_POSTPROCESS_)
PP.LegacySettings.DOF_FalloffExponent = DOF_FalloffExponent;
PP.LegacySettings.DOF_BlurKernelSize = DOF_BlurKernelSize;
PP.LegacySettings.DOF_MaxNearBlurAmount = DOF_MaxNearBlurAmount;
PP.LegacySettings.DOF_MaxFarBlurAmount = DOF_MaxFarBlurAmount;
PP.LegacySettings.DOF_FocusType = FOCUS_Distance;
PP.LegacySettings.DOF_FocusInnerRadius = DOF_FocusInnerRadius;
PP.LegacySettings.DOF_FocusDistance = LastDOFDistance;
PP.LegacySettings.DOF_FocusInnerRadius = LastDOFRadius;
`else
PP.DOF_FalloffExponent = DOF_FalloffExponent;
PP.DOF_BlurKernelSize = DOF_BlurKernelSize;
PP.DOF_MaxNearBlurAmount = DOF_MaxNearBlurAmount;
PP.DOF_MaxFarBlurAmount = DOF_MaxFarBlurAmount;
PP.DOF_FocusType = FOCUS_Distance;
PP.DOF_FocusInnerRadius = DOF_FocusInnerRadius;
PP.DOF_FocusDistance = LastDOFDistance;
PP.DOF_FocusInnerRadius = LastDOFRadius;
`endif
bDOFUpdated = FALSE;
}
}
native final function SetViewOffset(const out ViewOffsetData NewViewOffset);
defaultproperties
{
BlendTime=0.67
bLockedToViewTarget=TRUE
bDoPredictiveAvoidance=TRUE
bValidateWorstLoc=TRUE
bInterpLocation=TRUE
OriginLocInterpSpeed=8
StrafeLeftAdjustment=(X=0,Y=0,Z=0)
StrafeRightAdjustment=(X=0,Y=0,Z=0)
StrafeOffsetInterpSpeedIn=12.f
StrafeOffsetInterpSpeedOut=20.f
RunFwdAdjustment=(X=0,Y=0,Z=0)
RunBackAdjustment=(X=0,Y=0,Z=0)
RunOffsetInterpSpeedIn=6.f
RunOffsetInterpSpeedOut=12.f
WorstLocOffset=(X=-8,Y=1,Z=90)
bInterpViewOffsetOnlyForCamTransition=TRUE
/** all offsets are hand-crafted for this mode, so they should theoretically be all zeroes for all modes */
ViewOffset_ViewportAdjustments(CVT_16to9_Full)={(
OffsetHigh=(X=0,Y=0,Z=0),
OffsetLow=(X=0,Y=0,Z=0),
OffsetMid=(X=0,Y=0,Z=0),
)}
bAdjustDOF=FALSE
DOF_FalloffExponent=1.f
DOF_BlurKernelSize=3.f
// DOF_FocusInnerRadius=2500.f
DOF_MaxNearBlurAmount=0.6f
DOF_MaxFarBlurAmount=1.f
DOFDistanceInterpSpeed=10.f
DOFTraceExtent=(X=0.f,Y=0.f,Z=0.f)
DOF_RadiusFalloff=1.f
DOF_RadiusRange=(X=2500,Y=60000)
DOF_RadiusDistRange=(X=1000,Y=50000)
OffsetAdjustmentInterpSpeed=12.f
}