StarSim

StarSim.git
git clone git://git.lenczewski.org/StarSim.git
Log | Files | Refs | README | LICENSE

commit 68208af8386737a3d42621ca364c43a96065066b
parent 6227fbd28b52018f2fcdbc2998e9c2848640a8e9
Author: Mikolaj Lenczewski <33129490+EnderRifter@users.noreply.github.com>
Date:   Mon,  8 Jul 2019 15:35:27 +0100

Added a fps counter and pretty orbit tracers

Diffstat:
MStarSim/StarSim/Program.cs | 38+++++++++++++++++++++++++++++++++++++-
MStarSim/StarSimLib/Constants.cs | 4++--
MStarSim/StarSimLib/Data Structures/OrbitTracer.cs | 10+---------
MStarSim/StarSimLib/Graphics/Drawer.cs | 23+++++++++++------------
4 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/StarSim/StarSim/Program.cs b/StarSim/StarSim/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Timers; using SFML.Graphics; using SFML.Window; using StarSimLib; @@ -16,6 +17,11 @@ namespace StarSim internal class Program { /// <summary> + /// The interval between timer refreshes, in milliseconds. + /// </summary> + private const double TimerRefreshIntervalMs = 500; + + /// <summary> /// Holds all the <see cref="Body"/> instances that should be simulated. /// </summary> private static readonly Body[] bodies; @@ -42,17 +48,32 @@ namespace StarSim private static readonly InputHandler inputHandler; /// <summary> + /// Timer that manages FPS counter and other miscellaneous counters. + /// </summary> + private static readonly Timer miscTimer; + + /// <summary> /// The SFML.NET window to which everything is rendered. /// </summary> private static readonly RenderWindow window; /// <summary> + /// The current amount of frames per second. + /// </summary> + private static double fps; + + /// <summary> + /// Counts the frames elapsed since the last timer pulse, so that the FPS can be tracked. + /// </summary> + private static uint framesElapsed; + + /// <summary> /// Initialises a new instance of the <see cref="Program"/> class, /// </summary> static Program() { // we construct a new window instance, but immediately hide it so that we can configure the rest of the app - window = new RenderWindow(VideoMode.DesktopMode, "N-Body Simulator", Styles.Default, new ContextSettings()); + window = new RenderWindow(VideoMode.DesktopMode, "N-Body Simulator: FPS ", Styles.Default, new ContextSettings()); window.SetVisible(false); bodies = BodyGenerator.GenerateBodies(Constants.BodyCount, true); @@ -66,6 +87,16 @@ namespace StarSim bodyDrawer = new Drawer(window, ref bodies, ref bodyShapeMap); inputHandler = new InputHandler(ref bodies, ref bodyDrawer); + + // constructs a new timer and attaches a timer event handler that updates the fps and window title every interval + miscTimer = new Timer(TimerRefreshIntervalMs) { AutoReset = true, Enabled = true }; + miscTimer.Elapsed += (sender, args) => + { + fps = framesElapsed / (TimerRefreshIntervalMs / 1000); + + framesElapsed = 0; + window.SetTitle($"N-Body Simulator: FPS {fps}"); + }; } /// <summary> @@ -80,6 +111,7 @@ namespace StarSim // we reveal the window so that the user may interact with our program window.SetVisible(true); + miscTimer.Start(); // we configure the window and its close handler, so that we may close the window once we are done with it window.SetFramerateLimit(Constants.FrameRate); @@ -108,8 +140,12 @@ namespace StarSim bodyDrawer.DrawBodies(); window.Display(); + + // increment the fps counter + framesElapsed++; } + miscTimer.Stop(); Console.WriteLine("Goodbye, World!"); Console.WriteLine("Press 'enter' to quit..."); Console.ReadLine(); diff --git a/StarSim/StarSimLib/Constants.cs b/StarSim/StarSimLib/Constants.cs @@ -10,7 +10,7 @@ namespace StarSimLib /// <summary> /// The amount of bodies that are rendered by default. /// </summary> - public const int BodyCount = 100; + public const int BodyCount = 10; /// <summary> /// The mass of the central body, if it is included. @@ -66,7 +66,7 @@ namespace StarSimLib /// <summary> /// The number of previous positions that will be stored by a body /// </summary> - public const int StoredPreviousPositionCount = 30; + public const int StoredPreviousPositionCount = 100; /// <summary> /// The time step for the simulation. diff --git a/StarSim/StarSimLib/Data Structures/OrbitTracer.cs b/StarSim/StarSimLib/Data Structures/OrbitTracer.cs @@ -12,7 +12,7 @@ namespace StarSimLib.Data_Structures /// Sample rate for the previous position. Used to improve performance and get a longer orbit tracer tail /// for less computation. The previous position will be saved once every 20 sampling opportunities. /// </summary> - private const int PositionSampleRate = 20; + private const int PositionSampleRate = 10; /// <summary> /// Backing field for the <see cref="PreviousPositions"/> property. @@ -61,14 +61,6 @@ namespace StarSimLib.Data_Structures // position using linear interpolation to give a smooth shrinking motion if (++positionSampleCounter < PositionSampleRate) { - /* - double interpolationPercentage = positionSampleCounter / (float)PositionSampleRate; - - previousPositions[0].X = (1 - interpolationPercentage) * previousPositions[0].X + interpolationPercentage * previousPositions[1].X; - previousPositions[0].Y = (1 - interpolationPercentage) * previousPositions[0].Y + interpolationPercentage * previousPositions[1].Y; - previousPositions[0].Z = (1 - interpolationPercentage) * previousPositions[0].Z + interpolationPercentage * previousPositions[1].Z; - */ - return; } diff --git a/StarSim/StarSimLib/Graphics/Drawer.cs b/StarSim/StarSimLib/Graphics/Drawer.cs @@ -265,17 +265,16 @@ namespace StarSimLib.Graphics /// <param name="b">One of the starting values between which to interpolate.</param> /// <param name="dt">The percentage by which to interpolate, capped between 0 and 1.</param> /// <returns>The interpolated value.</returns> - private Vector4 LinearInterpolate(Vector4 a, Vector4 b, double dt) + private static Vector4 LinearInterpolate(Vector4 a, Vector4 b, double dt) { - // the maximum distance between the two points - double distance = (b - a).Abs(); - - // caps the percentage first between 1 and -Infinity, and then between 1 and 0 + // caps the percentage first between 1 and -Infinity, and then between 1 and 0, and reverses it such + // that 0 is 100% a and 0% b, and that 1 is 0% a and 100% b. + dt = 1 - dt; dt = dt > 1 ? 1 : dt; dt = dt < 0 ? 0 : dt; /* formula: C = A + dt(B - A) / distance */ - Vector4 c = a + dt * (b - a) / distance; + Vector4 c = a + dt * (b - a) / 1; return c; } @@ -369,9 +368,9 @@ namespace StarSimLib.Graphics Vector4[] orbitTracerPositions = body.OrbitTracer.PreviousPositions.ToArray(); // we cache the colours used for the orbit tracers, and pack them into a 4D vector - Color tailColour = Color.Cyan, black = Color.Black; - Vector4 cyanVector = new Vector4(tailColour.A, tailColour.R, tailColour.G, tailColour.B); - Vector4 blackVector = new Vector4(black.A, black.R, black.G, black.B); + Color tracerColour = Color.Cyan, black = Color.Transparent; + Vector4 tracerVector = new Vector4(tracerColour.R, tracerColour.G, tracerColour.B, tracerColour.A); + Vector4 blackVector = new Vector4(black.R, black.G, black.B, black.A); for (uint i = 0; i < orbitTracerPositions.Length; i++) { @@ -387,14 +386,14 @@ namespace StarSimLib.Graphics // use linear interpolation to make the tail colour transition look smooth Vector4 interpolatedColourVector = - LinearInterpolate(cyanVector, blackVector, (double)i / orbitTracerPositions.Length); + LinearInterpolate(tracerVector, blackVector, i / (double)orbitTracerPositions.Length); // unpack the colour from a vector into a colour Color interpolatedColour = new Color( + (byte)interpolatedColourVector.X, (byte)interpolatedColourVector.Y, (byte)interpolatedColourVector.Z, - (byte)interpolatedColourVector.W, - (byte)interpolatedColourVector.X + (byte)interpolatedColourVector.W ); // append the new vertex to the orbit tracer array