StarSkyPresenter/Projection.cs
2025-12-14 18:39:02 +01:00

105 lines
3.3 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
using System.Numerics;
using StarSkyPresenter;
using YamlDotNet.Serialization;
using Vector2 = Godot.Vector2;
public partial class Projection : Window
{
private double _sceneTime = 0;
private int _lastScene = 0;
private int _activeScene = 0;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
private double Fapply(double input, string fname)
{
switch (fname)
{
case "lin": return input;
case "sin": return Math.Sin(input);
case "cos": return 1.0 - Math.Cos(input);
case "sin2": return Math.Sin(input)*Math.Sin(input);
default: return 0;
}
}
private double FadeTime(bool fadeIn, bool fadeOut, double t)
{
switch ((fadeIn, fadeOut))
{
case (true, true): return Math.Sin(t)*Math.Sin(t);
case (true, false): return 1 - Math.Cos(t);
case (false, true): return Math.Sin(t);
case (false, false): return t;
}
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
// get MainScript instance
MainScript mainScript = (MainScript)this.GetTree().GetRoot().GetNode<MainScript>("Main");
if (mainScript.GetScenes().Count == 0) return;
// check for scene update and if so reset the scene time
if (mainScript.GetScene() != this._activeScene)
{
this._lastScene = this._activeScene;
this._activeScene = mainScript.GetScene();
this._sceneTime = 0;
}
else
{
this._sceneTime += delta;
}
// TODO: calculate scene weight
var transition = mainScript.GetScenes()[this._lastScene].transition;
string xFade = transition.x;
string yFade = transition.y;
double t = (Math.Clamp(this._sceneTime / transition.t, 0, 1)) * 3.14159265 / 2;
double weight = FadeTime(transition.fade_out, transition.fade_in, t);
Vector2 posWeight = new Vector2((float)Fapply(weight * 3.14159265 / 2, yFade), (float)Fapply(weight * 3.14159265 / 2, xFade));
//GD.Print("T: " + t + ", weight: " + weight + ", posWeight: " + posWeight);
// update background
var background = this.GetNode<TextureRect>("Background");
float scaleX = background.Texture.GetWidth() / (float)this.GetSize().X;
float scaleY = background.Texture.GetHeight() / (float)this.GetSize().Y;
background.Scale = Vector2.One / Math.Min(scaleX, scaleY);
// update all the stars
foreach (Star star in mainScript.GetStars())
{
var oldStar = mainScript.GetScenes()[this._lastScene].stars[star.Id];
var newStar = mainScript.GetScenes()[this._activeScene].stars[star.Id];
float baseScale = ((float)this.GetSize().X / star.Sprite.GetTexture().GetWidth()) / 100;
double activeRot = (1 - weight) * oldStar.Rot + weight * newStar.Rot;
Vector2 activePos = (Vector2.One - posWeight) * new Vector2(oldStar.X, oldStar.Y) + posWeight * new Vector2(newStar.X, newStar.Y);
float activeScale = ((1 - (float)weight) * oldStar.Scale + (float)weight * newStar.Scale) * baseScale;
//GD.Print("Scene: " + this._activeScene + ", Time: " + this._sceneTime + ", Weight: " + weight + ", ActiveRot: " + activeRot + ", ActivePos: " + activePos + ", ActiveScale: " + activeScale);
star.Sprite.Rotation += (float)(((2*3.14159265)*(activeRot / 365)) * delta);
star.Sprite.Position = activePos * this.GetSize();
star.Sprite.Scale = Vector2.One * activeScale;
}
}
}