477 lines
18 KiB
Ucode
477 lines
18 KiB
Ucode
/**
|
|
* 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
|
|
}
|
|
|
|
|
|
|
|
|
|
|