diff --git a/X2WOTCCommunityHighlander/Src/XComGame/Classes/X2Camera_Photobooth.uc b/X2WOTCCommunityHighlander/Src/XComGame/Classes/X2Camera_Photobooth.uc new file mode 100644 index 000000000..8b9640375 --- /dev/null +++ b/X2WOTCCommunityHighlander/Src/XComGame/Classes/X2Camera_Photobooth.uc @@ -0,0 +1,258 @@ +//--------------------------------------------------------------------------------------- +// FILE: X2Camera_Photobooth.uc +// AUTHOR: Scott Boeckmann -- 11/15/2016 +// PURPOSE: Camera that looks at a location but pivots around a second location. +// +//--------------------------------------------------------------------------------------- +// Copyright (c) 2016 Firaxis Games, Inc. All rights reserved. +//--------------------------------------------------------------------------------------- + +class X2Camera_Photobooth extends X2Camera; + +var vector m_vRotationPoint; +var vector m_vTargetRotationPoint; + +var Rotator m_rRotationAroundPoint; +var Rotator m_rTargetRotationAroundPoint; + +var float m_fDistanceFromPoint; +var float m_fTargetDistanceFromPoint; + +var float m_fFOV; +var float m_fRotationSpeed; +var float m_fZoomSpeed; +var float m_fPanSpeed; + +var float m_fMinCameraDistance; +var float m_fMaxCameraDistance; +var float m_fSpringArmDistance; + +var bool m_bUsePresetCamera; + +var Box CameraBounds; +var float MinZ; + +function InitCamera(CameraActor inCamActor, vector inRotationPoint) +{ + local vector CameraToRotation, BoundsOrigin, BoundsExtent; + local float HalfMaxCameraDist; + + m_vRotationPoint = inRotationPoint; + m_vTargetRotationPoint = m_vRotationPoint; + + CameraToRotation = m_vRotationPoint - inCamActor.Location; + m_rRotationAroundPoint = Rotator(CameraToRotation); + m_rTargetRotationAroundPoint = m_rRotationAroundPoint; + + m_fDistanceFromPoint = vsize(CameraToRotation); + m_fTargetDistanceFromPoint = m_fDistanceFromPoint; + m_fSpringArmDistance = m_fTargetDistanceFromPoint; + + // Setup bounds. + MinZ = `XWORLD.GetFloorZForPosition(inRotationPoint) + 10.0; // Add slight offset to avoid seeing under roofs and other misc wonkiness. + HalfMaxCameraDist = m_fMaxCameraDistance / 2; + BoundsExtent.X = HalfMaxCameraDist; + BoundsExtent.Y = HalfMaxCameraDist; + BoundsExtent.Z = HalfMaxCameraDist; + BoundsOrigin = inRotationPoint; + BoundsOrigin.Z = MinZ + m_fMinCameraDistance + HalfMaxCameraDist; + CameraBounds.Min = BoundsOrigin - BoundsExtent; + CameraBounds.Max = BoundsOrigin + BoundsExtent; + CameraBounds.IsValid = 1; +} + +function UpdateCamera(float DeltaTime) +{ + super.UpdateCamera(DeltaTime); + + ClampToBounds(); + + InterpolateRotationPoint(DeltaTime); + InterpolateRotation(DeltaTime); + InterpolateDistance(DeltaTime); +} + +function MoveToFinal() +{ + m_rRotationAroundPoint = m_rTargetRotationAroundPoint; + m_fDistanceFromPoint = m_fTargetDistanceFromPoint; + m_vRotationPoint = m_vTargetRotationPoint; +} + +function InterpolateRotation(float DeltaTime) +{ + m_rRotationAroundPoint += (m_rTargetRotationAroundPoint - m_rRotationAroundPoint) * DeltaTime * m_fRotationSpeed; +} + +function InterpolateDistance(float DeltaTime) +{ + m_fDistanceFromPoint += ((m_fSpringArmDistance < m_fTargetDistanceFromPoint ? m_fSpringArmDistance : m_fTargetDistanceFromPoint) - m_fDistanceFromPoint) * DeltaTime * m_fZoomSpeed; +} + +function InterpolateRotationPoint(float DeltaTime) +{ + m_vRotationPoint += (m_vTargetRotationPoint - m_vRotationPoint) * DeltaTime * m_fPanSpeed; +} + +function Rotator GetCameraRotation() +{ + return m_rRotationAroundPoint; +} + +function Rotator GetCameraTargetRotation() +{ + return m_rTargetRotationAroundPoint; +} + +function Vector GetCameraOffset() +{ + return m_vTargetRotationPoint; +} + +function TPOV GetCameraLocationAndOrientation() +{ + local TPOV OutPOV; + + OutPOV.Location = m_vRotationPoint - vector(m_rRotationAroundPoint) * m_fDistanceFromPoint; + OutPOV.Rotation = m_rRotationAroundPoint; + OutPOV.FOV = m_fFOV; + + return OutPOV; +} + +function YawCamera(float Degrees) +{ + m_rTargetRotationAroundPoint.Yaw += Degrees * DegToUnrRot; +} + +function PitchCamera(float Degrees) +{ + m_rTargetRotationAroundPoint.Pitch += Degrees * DegToUnrRot; +} + +function ZoomCamera(float Amount) +{ + m_fTargetDistanceFromPoint += Amount; + m_fTargetDistanceFromPoint = Clamp(m_fTargetDistanceFromPoint, m_fMinCameraDistance, m_fMaxCameraDistance); +} + +function SetFOV(float FOV) +{ + m_fFOV = FOV; +} + +function MoveFocusPoint(float X, float Y, float Z) +{ + m_vTargetRotationPoint.X += X; + m_vTargetRotationPoint.Y += Y; + m_vTargetRotationPoint.Z += Z; +} + +function MoveFocusPointOnRotationAxes(float X, float Y, float Z) +{ + local Vector VecX, VecY, VecZ; + + GetAxes(m_rTargetRotationAroundPoint, VecX, VecY, VecZ); + + m_vTargetRotationPoint += X * VecX; + m_vTargetRotationPoint += Y * VecY; + m_vTargetRotationPoint += Z * VecZ; +} + +function AddRotation(float Pitch, float Yaw, float Roll) +{ + local Rotator RotationAmount; + + RotationAmount.Pitch = Pitch * DegToUnrRot; + RotationAmount.Yaw = Yaw * DegToUnrRot; + RotationAmount.Roll = Roll * DegToUnrRot; + + m_rTargetRotationAroundPoint += RotationAmount; +} + +function AddCameraRotation(Rotator newRot) +{ + m_rTargetRotationAroundPoint += newRot; +} + +function float GetZoomPercentage() +{ + local float percentage; + percentage = (m_fTargetDistanceFromPoint - m_fMinCameraDistance) / (m_fMaxCameraDistance - m_fMinCameraDistance); + if (percentage < 0.2f) + percentage = 0.2f; + + return percentage; +} + +function SetFocusPoint(vector newRotationPoint) +{ + m_vTargetRotationPoint = newRotationPoint; +} + +function SetCameraRotation(Rotator newRotation) +{ + m_rTargetRotationAroundPoint = newRotation; +} + +function SetViewDistance(float newViewDistance) +{ + m_fTargetDistanceFromPoint = newViewDistance; +} + +function float GetCameraDistance() +{ + return m_fTargetDistanceFromPoint; +} + +function ClampToBounds() +{ + local vector Direction, OneOverDirection, HitLoc, NewLoc; + local Plane BoundingPlane; + + if (!IsPointInBox(m_vTargetRotationPoint, CameraBounds)) + { + // Fix up m_vTargetRotationPoint. + // May want to revisit this as not all tactical locations have the formations axis-aligned. In that case we can + // transform m_vRotationPoint and m_vTargetRotationPoint to CameraBounds space and then transform the HitLoc back to world. + Direction = m_vRotationPoint - m_vTargetRotationPoint; + OneOverDirection.X = Direction.X == 0.0f ? Direction.X : 1.0f / Direction.X; + OneOverDirection.Y = Direction.Y == 0.0f ? Direction.Y : 1.0f / Direction.Y; + OneOverDirection.Z = Direction.Z == 0.0f ? Direction.Z : 1.0f / Direction.Z; + if (LineBoxIntersection(CameraBounds, m_vTargetRotationPoint, m_vRotationPoint, Direction, OneOverDirection, HitLoc)) + { + m_vTargetRotationPoint = HitLoc; + } + } + + // Check logical camera position. + NewLoc = m_vTargetRotationPoint - vector(m_rTargetRotationAroundPoint) * m_fTargetDistanceFromPoint; + if (NewLoc.Z < MinZ) + { + // Fix up virtual camera position via m_fSpringArmDistance. + BoundingPlane.X = 0.0; + BoundingPlane.Y = 0.0; + BoundingPlane.Z = 1.0; + BoundingPlane.W = MinZ; + + RayPlaneIntersection(m_vTargetRotationPoint, NewLoc - m_vTargetRotationPoint, BoundingPlane, HitLoc); + + m_fSpringArmDistance = VSize(m_vTargetRotationPoint - HitLoc); + } + else + { + m_fSpringArmDistance = m_fTargetDistanceFromPoint; + } +} + +defaultproperties +{ + Priority= eCameraPriority_Cinematic + m_fFOV = 90 + m_fRotationSpeed=4 + m_fZoomSpeed=4 + m_fPanSpeed=8 + + m_fMinCameraDistance = 40 + m_fMaxCameraDistance = 700 +} \ No newline at end of file diff --git a/X2WOTCCommunityHighlander/Src/XComGame/Classes/XComCamState_HQ_Photobooth.uc b/X2WOTCCommunityHighlander/Src/XComGame/Classes/XComCamState_HQ_Photobooth.uc new file mode 100644 index 000000000..affc835ca --- /dev/null +++ b/X2WOTCCommunityHighlander/Src/XComGame/Classes/XComCamState_HQ_Photobooth.uc @@ -0,0 +1,226 @@ +//----------------------------------------------------------- +// Base class for headquarters camera state classes +//----------------------------------------------------------- +class XComCamState_HQ_Photobooth extends XComCamState_HQ; + +var vector m_vRotationPoint; +var vector m_vTargetRotationPoint; + +/************ Camera Distance Variables **************/ + +var float m_fInitialCameraDistance; +var float m_fTargetCameraDistance; + +var float m_fMinCameraDistance; +var float m_fMaxCameraDistance; + +/************ Camera Rotation Variables **************/ + +var Rotator m_rInitialCameraRotation; +var Rotator m_rTargetCameraRotation; + +var float m_fRotationSpeed; +var float m_fZoomSpeed; +var float m_fPanSpeed; + +var CameraActor CamActor; + + +var bool m_bUsePresetCamera; + +var Box CameraBounds; +var bool bBoundsInitialized; + +function Init( PlayerController ForPlayer, CameraActor inCameraActor, PointInSpace inFocusPoint ) +{ + local vector CameraToRotation; + + CamActor = inCameraActor; + + m_vRotationPoint = inFocusPoint.Location; + m_vTargetRotationPoint = m_vRotationPoint; + + CameraToRotation = m_vRotationPoint - inCameraActor.Location; + m_rInitialCameraRotation = Rotator(CameraToRotation); + m_rTargetCameraRotation = m_rInitialCameraRotation; + + m_fInitialCameraDistance = vsize(CameraToRotation); + m_fTargetCameraDistance = m_fInitialCameraDistance; + + bBoundsInitialized = false; + + InitCameraState( ForPlayer ); +} + +function GetView(float DeltaTime, out vector out_Focus, out rotator out_Rotation, out float out_ViewDistance, out float out_FOV, out PostProcessSettings out_PPSettings, out float out_PPOverrideAlpha) +{ + UpdateBounds(); + ClampToBounds(); + + out_ViewDistance = InterpViewDistance(DeltaTime); + out_Rotation = InterpViewRotation(DeltaTime); + out_Focus = InterpViewFocusPoint(DeltaTime); + + + if(CamActor != none) + { + out_FOV = CamActor.FOVAngle; + out_PPSettings = CamActor.CamOverridePostProcess; + out_PPOverrideAlpha = CamActor.CamOverridePostProcessAlpha; + } + + PCOwner.SetRotation( out_Rotation ); +} + +protected function float InterpViewDistance( float DeltaTime ) +{ + m_fInitialCameraDistance += (m_fTargetCameraDistance - m_fInitialCameraDistance) * DeltaTime * m_fZoomSpeed; + + return m_fInitialCameraDistance; +} + +protected function rotator InterpViewRotation(float DeltaTime) +{ + m_rInitialCameraRotation += (m_rTargetCameraRotation - m_rInitialCameraRotation) * DeltaTime * m_fRotationSpeed; + + return m_rInitialCameraRotation; +} + +protected function vector InterpViewFocusPoint(float DeltaTime) +{ + m_vRotationPoint += (m_vTargetRotationPoint - m_vRotationPoint) * DeltaTime * m_fPanSpeed; + + return m_vRotationPoint; +} + +function MoveToFinal() +{ + m_rInitialCameraRotation = m_rTargetCameraRotation; + m_fInitialCameraDistance = m_fTargetCameraDistance; + m_vRotationPoint = m_vTargetRotationPoint; +} + +function GetFinalCameraViewPoint(out vector outViewLocation, out rotator outViewRotation) +{ + outViewRotation = m_rTargetCameraRotation; + outViewLocation = m_vRotationPoint - vector(m_rTargetCameraRotation) * m_fTargetCameraDistance; +} + +function MoveFocusPoint(float X, float Y, float Z) +{ + m_vTargetRotationPoint.X += X; + m_vTargetRotationPoint.Y += Y; + m_vTargetRotationPoint.Z += Z; +} + +function SetFocusPoint(vector FocusPoint) +{ + m_vTargetRotationPoint = FocusPoint; +} + +function MoveFocusPointOnRotationAxes(float X, float Y, float Z) +{ + local Vector VecX, VecY, VecZ; + + GetAxes(m_rTargetCameraRotation, VecX, VecY, VecZ); + + m_vTargetRotationPoint += X * VecX; + m_vTargetRotationPoint += Y * VecY; + m_vTargetRotationPoint += Z * VecZ; +} + +function AddRotation(float Pitch, float Yaw, float Roll) +{ + local Rotator RotationAmount; + + RotationAmount.Pitch = Pitch * DegToUnrRot; + RotationAmount.Yaw = Yaw * DegToUnrRot; + RotationAmount.Roll = Roll * DegToUnrRot; + + m_rTargetCameraRotation += RotationAmount; +} + +function SetCameraRotation(Rotator Rotation) +{ + m_rTargetCameraRotation = Rotation; +} + +function AddZoom(float inDistanceOffset) +{ + m_fTargetCameraDistance += inDistanceOffset; + m_fTargetCameraDistance = Clamp(m_fTargetCameraDistance, m_fMinCameraDistance, m_fMaxCameraDistance); +} + +function float GetZoomPercentage() +{ + local float percentage; + percentage = (m_fTargetCameraDistance - m_fMinCameraDistance) / (m_fMaxCameraDistance - m_fMinCameraDistance); + if (percentage < 0.2f) + percentage = 0.2f; + + return percentage; +} + +function SetViewDistance(float inViewDistance) +{ + m_fTargetCameraDistance = inViewDistance; +} + +function SetUseCameraPreset(bool bUse) +{ + m_bUsePresetCamera = bUse; +} + +function UpdateBounds() +{ + local LightInclusionVolume LIV; + local BoxSphereBounds BoxSphere; + + if (!bBoundsInitialized) + { + foreach WorldInfo.AllActors(class'LightInclusionVolume', LIV) + { + if (LIV.Tag == Name("PhotoboothLIV")) + { + if (LIV.BrushComponent != none) + { + BoxSphere = LIV.BrushComponent.Bounds; + CameraBounds.Min = BoxSphere.Origin - BoxSphere.BoxExtent; + CameraBounds.Max = BoxSphere.Origin + BoxSphere.BoxExtent; + CameraBounds.IsValid = 1; + bBoundsInitialized = true; + break; + } + } + } + } +} + +function ClampToBounds() +{ + local vector Direction, OneOverDirection, HitLoc; + + if (bBoundsInitialized && !IsPointInBox(m_vTargetRotationPoint, CameraBounds)) + { + // Fix up m_vTargetRotationPoint. + Direction = m_vRotationPoint - m_vTargetRotationPoint; + OneOverDirection.X = Direction.X == 0.0f ? Direction.X : 1.0f / Direction.X; + OneOverDirection.Y = Direction.Y == 0.0f ? Direction.Y : 1.0f / Direction.Y; + OneOverDirection.Z = Direction.Z == 0.0f ? Direction.Z : 1.0f / Direction.Z; + if (LineBoxIntersection(CameraBounds, m_vTargetRotationPoint, m_vRotationPoint, Direction, OneOverDirection, HitLoc)) + { + m_vTargetRotationPoint = HitLoc; + } + } +} + +DefaultProperties +{ + m_bUsePresetCamera = true; + m_fRotationSpeed = 4.0f + m_fZoomSpeed = 4.0f + m_fPanSpeed = 8.0f + + m_fMinCameraDistance = 40 + m_fMaxCameraDistance = 500 +}