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; [Export] public bool active = false; public override void _Process( double delta ) { if ( ! active ) { return; } LerpCameras( delta ); } public float smoothStepDelta => 1f / CameraPrioritySmoothingStepFPS; public float safeSmoothing => Mathf.Max( 0, CameraPrioritySmoothingCoefficient ); List _cameraSlots = new List(); 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( 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(); var fov = 0f; _cameraSlots.ForEach( c => { var priority = MathF.Max( 0, c.smoothedPriority ); var rotation = c.camera.GetCameraRotation(); if ( ! rotation.IsFinite() || rotation.Length() == 0 ) { rotation = new Quaternion(); rotation.X = 0; rotation.Y = 0; rotation.Z = 0; rotation.W = 1; rotation = rotation.Normalized(); //RJLog.Log( "Rotation was weird" ); } else { //RJLog.Log( "Rotation is fine" ); } //RJLog.Log( rotation.X, rotation.Y, rotation.Z, rotation.W ); var vUp = rotation * Vector3.Up; var vForward = rotation * Vector3.Forward; position += priority * c.camera.GetCameraPosition(); up += priority * vUp; forward += priority * vForward; fov += priority * c.camera.GetCameraFOV(); } ); position /= sumPriority; fov /= 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 ); camera.Fov = fov; } 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; } } }