rj-action-library/Runtime/VirtualCameras/VirtualCamera3DManager.cs

128 lines
2.8 KiB
C#

using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class VirtualCamera3DManager:RJVirtualCamera3DManager
{
[Export]
public Camera3D camera;
[Export]
public bool refreshSlots = false;
public override void _Process( double delta )
{
LerpCameras( delta );
}
public float smoothStepDelta => 1f / CameraPrioritySmoothingStepFPS;
public float safeSmoothing => Mathf.Max( 0, CameraPrioritySmoothingCoefficient );
List<VirtualCamera3DSlot> _cameraSlots = new List<VirtualCamera3DSlot>();
public void SetActiveSlot( VirtualCamera3DSlot slot )
{
_cameraSlots.ForEach( c => c.priority = c == slot ? 1 : 0 );
}
void LerpCameras( double delta )
{
if ( refreshSlots || _cameraSlots == null || _cameraSlots.Count == 0 )
{
refreshSlots = false;
_cameraSlots = Nodes.GetDirectChildren<VirtualCamera3DSlot>( this );
//RJLog.Log( "GRABBED SLOTs" , _cameraSlots.Count );
}
var sumPriority = 0f;
_cameraSlots.ForEach(
c =>
{
c.Update( delta, this );
sumPriority += MathF.Max( 0, c.smoothedPriority );
}
);
if ( sumPriority == 0 )
{
return;
}
var position = new Vector3();
var up = new Vector3();
var forward = new Vector3();
_cameraSlots.ForEach(
c =>
{
var priority = MathF.Max( 0, c.smoothedPriority );
var rotation = c.camera.GetCameraRotation();
var vUp = rotation * Vector3.Up;
var vForward = rotation * Vector3.Forward;
position += priority * c.camera.GetCameraPosition();
up += priority * vUp;
forward += priority * vForward;
}
);
position /= sumPriority;
if ( forward.LengthSquared() == 0 )
{
forward = camera.Basis.Z;
}
else
{
forward = forward.Normalized();
}
if ( up.LengthSquared() == 0 )
{
up = camera.Basis.Y;
}
else
{
up = up.Normalized();
}
camera.GlobalPosition = position;
camera.LookAt( position - forward, up );
}
public override RJVirtualCamera3D GetCamera( int index )
{
return _cameraSlots[ index ].camera;
}
public override int GetCameraIndex( RJVirtualCamera3D camera3D )
{
return _cameraSlots.FindIndex( c => c.camera == camera3D );
}
public override float GetCameraPriority( int index )
{
return _cameraSlots[ index ].priority;
}
public override void SetCameraPriority( int index, float priority )
{
_cameraSlots[ index ].priority = priority;
}
}
}