//============================================================================= // KFSceneCaptureDebugCam //============================================================================= // Renders a debug scene window focusing on the FocusActor's location. // Activated through KFCheatManager - see "FocusOn" exec function. //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC //============================================================================= class KFSceneCaptureDebugCam extends SceneCapture2DActor native(Camera); const MAXDEBUGWINDOWS = 1; var Texture2D BlackTexture; /** Scene capture component that's attached when debug scene camera is active */ var SceneCapture2DComponent CaptureComponent; /** Actor that this camera is focused on */ var Actor FocusActor; /** Class of actor that this camera is focused on */ var class FocusClass; /** This variable is used if the current focus actor is a Pawn */ var Pawn FocusPawn; /** Owning player controller for this debug scene camera */ var KFPlayerController PCOwner; /** Pop up a debug scene view focusing on NPC who most recently failed a move */ var bool bWatchNPCPathFailures; /** Pop up a debug scene view when an actor with a specific name is spawned */ var bool bWatchActorSpawn; /** Actor name to watch for spawn if bWatchActorSpawn is true */ var name ActorNameToWatchOnSpawn; /** Pop up a debug scene view when the camera receives a touch event */ var bool bWatchTouch; /** Debug scene view orbits around focus actor when true */ var bool bOrbitFocus; /** Set the camera's base to the focus actor */ var bool bSetBaseToFocus; /** Prevents the focus actor's skeletal mesh from pausing animations when not in view */ var bool bNoAnimPause; /** When true, camera location/orientation has been placed in a fixed position/rotation by player */ var bool bOverrideFocus; /** Number of currently active debug windows (WIP, currently 1 max) */ var int ActiveDebugWindows; var bool bLockFocus; /** If bNoAnimPause is true, some of the focus actor's skeletal mesh properties are stored here to be reset later */ var bool bTickAnimNodesWhenNotRendered; var bool bUpdateSkelWhenNotRendered; var bool bIgnoreControllersWhenNotRendered; var float MinDistFactorForKinematicUpdate; var bool bPauseAnims; var string CurrentDebugSceneMessage; var bool bTextOnly; /** Material for debug scene window */ var MaterialInterface DebugViewMaterial; var MaterialInstanceConstant DebugViewMaterialInstance; var KFAIController FocusController; var KFPawn FocusKFPawn; var vector LastLocation; /********************************************************************************************* Native functions **********************************************************************************************/ /** Creates the TextureRenderTarget2D in which the debug scene is rendered */ native function TextureRenderTarget2D CreateDebugTexture(); /** Overridden to call the PostRender event if this camera is active and PC is the PCOwner */ simulated native function NativePostRenderFor(PlayerController PC, Canvas Canvas, vector CameraPosition, vector CameraDir); simulated native function GetDebugSceneViewPoint( out vector out_Location, out Rotator out_Rotation ); /********************************************************************************************* Initialization / Destruction **********************************************************************************************/ /** * public function bool InitDebugScene() * Called from KFPlayerController - initializes the debug scene to focus on ActorToWatch * @param NewOwner PlayerController who will own this debug cam * @param ActorToWatch Debug scene will be focused on this actor's location * @param DebugMessage Optional debug message which will be shown in debug text by PostRenderFor() */ function bool InitDebugScene( KFPlayerController NewOwner, actor ActorToWatch, optional string DebugMessage ) { local TextureRenderTarget2D TextureTarget; local vector SceneLocation; local rotator SceneRotation; PCOwner = NewOwner; CurrentDebugSceneMessage = DebugMessage; if( FocusActor == ActorToWatch ) { return false; } FocusActor = ActorToWatch; FocusPawn = Pawn( FocusActor ); FocusKFPawn = KFPawn( FocusActor ); FocusController = KFAIController( FocusKFPawn.Controller ); if( FocusPawn != none && !bTextOnly ) { RestoreFocusPawnMeshProperties(); FocusPawn = None; } TextureTarget = CreateDebugTexture(); //SetLocation( ActorToWatch.Location ); SetRotation( ActorToWatch.Rotation ); if( bSetBaseToFocus ) { //SetBase( ActorToWatch ); } CaptureComponent.SetEnabled( true ); CaptureComponent.SetCaptureParameters( TextureTarget ); GetDebugSceneViewPoint( SceneLocation, SceneRotation ); CaptureComponent.SetView( SceneLocation, SceneRotation ); // Create the material instance for the debug scene view if( DebugViewMaterialInstance == none ) { DebugViewMaterialInstance = new(self) class'MaterialInstanceConstant'; } DebugViewMaterialInstance.SetParent( DebugViewMaterial ); DebugViewMaterialInstance.SetTextureParameterValue( 'RenderToTextureMap', TextureTarget); AttachComponent( CaptureComponent ); ActiveDebugWindows++; // Special handling if actor to watch is a pawn if( Pawn( ActorToWatch ) != none && !bTextOnly ) { FocusPawn = Pawn( ActorToWatch ); if( FocusPawn.Mesh != none ) { // Make the pawn animate if not visible, if desired if( bNoAnimPause ) { CacheAndUpdateFocusPawnMeshProperties(); } } } return true; } /** * public function DestroyDebugScene() * Clean up the debug scene and capture component, and restore any properties changed on the focus actor's skeletal mesh */ event DestroyDebugScene() { CurrentDebugSceneMessage = ""; ActiveDebugWindows--; if( FocusPawn != none ) { RestoreFocusPawnMeshProperties(); FocusPawn = none; } FocusActor = none; DebugViewMaterialInstance.SetParent( none ); DebugViewMaterialInstance = none; FocusClass = none; PCOwner = none; DetachComponent( CaptureComponent ); CaptureComponent = none; Destroy(); } /********************************************************************************************* Behavior changing functions accessed through cheat manager **********************************************************************************************/ /** Turn the orbiting camera movement on or off */ function ToggleDebugSceneOrbit() { bOrbitFocus = !bOrbitFocus; } /** Called from cheat manager when player wants to set the debug view to a fixed position/rotation matching the pawn's current values */ function MoveToMyPawnLocation() { local vector CameraLoc; local rotator CameraRot; bOverrideFocus = true; // Turn movement/orbiting off SetBase( None ); bOrbitFocus = false; PCOwner.GetPlayerViewPoint( CameraLoc, CameraRot ); SetLocation( CameraLoc ); SetRotation( CameraRot ); CaptureComponent.SetView( CameraLoc, CameraRot ); } /** * public function ToggleLockFocus() * Toggles whether debug scene focus is locked to its current view */ function ToggleLockFocus() { bLockFocus = !bLockFocus; } /** * public function SetDebugSceneViewMode() * Called from cheat manager - lets player change debug scene viewmode * @param NewViewMode New scene capture view mode to use (SceneCapView_Lit,SceneCapView_Wire,etc.) */ function SetDebugSceneViewMode( ESceneCaptureViewMode NewViewMode ) { CaptureComponent.ViewMode = NewViewMode; DetachComponent( CaptureComponent ); AttachComponent( CaptureComponent ); } /** * public function PauseDebugSceneUpdate() * Called from cheat manager, toggles pausing of debug scene window updates */ function PauseDebugSceneUpdate() { CaptureComponent.bEnabled = !CaptureComponent.bEnabled; } /********************************************************************************************* FocusPawn handling - if FocusActor is a pawn **********************************************************************************************/ /** * public function CacheAndUpdateFocusPawnMeshProperties() * Store some of the focus pawn's mesh property values and get the mesh to animate if it's not * considered visible */ function CacheAndUpdateFocusPawnMeshProperties() { // Store the mesh properties that will might be changing bTickAnimNodesWhenNotRendered = FocusPawn.Mesh.bTickAnimNodesWhenNotRendered; bUpdateSkelWhenNotRendered = FocusPawn.Mesh.bUpdateSkelWhenNotRendered; bIgnoreControllersWhenNotRendered = FocusPawn.Mesh.bIgnoreControllersWhenNotRendered; MinDistFactorForKinematicUpdate = FocusPawn.Mesh.MinDistFactorForKinematicUpdate; bPauseAnims = FocusPawn.Mesh.bPauseAnims; // Update the mesh properties to prevent the focus target mesh from pausing its animations FocusPawn.Mesh.bTickAnimNodesWhenNotRendered = true; FocusPawn.Mesh.bUpdateSkelWhenNotRendered = true; FocusPawn.Mesh.bIgnoreControllersWhenNotRendered = false; FocusPawn.Mesh.MinDistFactorForKinematicUpdate = 0; FocusPawn.Mesh.bPauseAnims = false; } /** * public function RestoreFocusPawnMeshProperties() * Reset any properties changed for the focus actor's skeletal mesh */ function RestoreFocusPawnMeshProperties() { FocusPawn.Mesh.bTickAnimNodesWhenNotRendered = bTickAnimNodesWhenNotRendered; FocusPawn.Mesh.bUpdateSkelWhenNotRendered = bUpdateSkelWhenNotRendered; FocusPawn.Mesh.bIgnoreControllersWhenNotRendered = bIgnoreControllersWhenNotRendered; FocusPawn.Mesh.MinDistFactorForKinematicUpdate = MinDistFactorForKinematicUpdate; FocusPawn.Mesh.bPauseAnims = bPauseAnims; } /********************************************************************************************* Rendering **********************************************************************************************/ /** * public function GetDebugSceneViewPoint() * Used to get the orbit locations for the debug scene camera * @param out_Location Location of current orbiting view point * @param out_Rotation Rotation of current orbiting view point */ // function GetDebugSceneViewPoint( out vector out_Location, out Rotator out_Rotation ) // { // if( FocusActor != none ) // { // if( bOrbitFocus ) // { // out_Rotation = FocusActor.Rotation; // out_Rotation.Pitch -= 3000; // out_Rotation.Yaw = ( WorldInfo.TimeSeconds * 65536 ) / 10; // out_Location = ( FocusActor.Location + vect(0,0,72) ) - 120 * vector( out_Rotation ); // } // else // { // out_Rotation = FocusActor.Rotation; // //out_Rotation.Pitch -= 3000; // // out_Rotation.Yaw = ( WorldInfo.TimeSeconds * 65536 ) / 10; // out_Location = ( FocusActor.Location + vect(0,0,72) ) - 120 * vector( out_Rotation ); // } // return; // } // } /** * public simulated event PostRenderFor() * Event called by NativePostRenderFor - Draws debug text related to current FocusActor * @param PC PlayerController we're rendering for * @param Canvas HUD Canvas to use * @param CameraPosition * @param CameraDir */ simulated event PostRenderFor( PlayerController PC, Canvas Canvas, vector CameraPosition, vector CameraDir ) { local float H, W; local vector SceneLocation; local rotator SceneRotation; return; if( ( FocusActor == none && !bOverrideFocus ) ) { if( PCOwner != none && PCOwner.CheatManager != none ) { KFCheatManager( PCOwner.CheatManager ).DestroyDebugScene(); } else { DestroyDebugScene(); } return; } if( !bTextOnly && bOrbitFocus ) { if( CaptureComponent.bEnabled ) { // Don't think detach/attach is necessary here, will double check DetachComponent( CaptureComponent ); GetDebugSceneViewPoint( SceneLocation, SceneRotation ); CaptureComponent.SetView( SceneLocation, SceneRotation ); AttachComponent( CaptureComponent ); } } else if( !bOrbitFocus ) { GetDebugSceneViewPoint( SceneLocation, SceneRotation ); if( SceneLocation != LastLocation ) { DetachComponent( CaptureComponent ); //GetDebugSceneViewPoint( SceneLocation, SceneRotation ); CaptureComponent.SetView( SceneLocation, SceneRotation ); AttachComponent( CaptureComponent ); LastLocation = SceneLocation; } } // if( PC != none && PC.myHUD != none ) // { // if( FocusKFPawn != none && FocusController != none ) // { // FocusController.KFDrawDebug( KFHUDBase(PC.myHUD), 'Default' ); // } // } if( !bTextOnly ) { // Draw the debug scene material //Canvas.SetPos( 4, 200 ); Canvas.SetPos( Canvas.ClipX * 0.65f, Canvas.ClipY * 0.075 ); H = 256 * ( Canvas.ClipY/768.0 ); W = 256 * ( Canvas.ClipY/768.0 ); Canvas.DrawTile( BlackTexture, H, W, 0, 0, 32, 32 ); Canvas.DrawColor = MakeColor( 255, 255, 255, 255 ); Canvas.SetPos( Canvas.ClipX * 0.65f, Canvas.ClipY * 0.075 ); Canvas.DrawMaterialTile( DebugViewMaterialInstance, H, W, 0.0, 0.0, 1.0, 1.0 ); } } DefaultProperties { bAlwaysRelevant=true bOrbitFocus=true bNoAnimPause=true bSetBaseToFocus=true bNoDelete=false bPostRenderIfNotVisible=true bCollideActors=false bCollideWorld=false bBlockActors=false BlackTexture=Texture2D'EngineResources.Black' Begin Object Name=SceneCapture2DComponent0 ClearColor=(R=0,G=0,B=0,A=255) Viewmode=SceneCapView_Unlit MaxUpdateDist=0.0 //bSkipRenderingDepthPrepass=false bUpdateMatrices=false bEnableFog=false NearPlane=10 FarPlane=-1 //1024 End Object CaptureComponent=SceneCapture2DComponent0 DebugViewMaterial=MaterialInterface'ENG_EngineResources_MAT.Debugging.DebugRenderTargetMaterial' }