commit 998f16dd6aef77607c0fc3118f889f5d30d2de60
parent b1cf594f1f6ee0b9b8e285958926196627112457
Author: Mikolaj Lenczewski <33129490+EnderRifter@users.noreply.github.com>
Date: Mon, 1 Jul 2019 21:33:43 +0100
Added initial orbit tracing until a proper solution can be found.
Diffstat:
7 files changed, 421 insertions(+), 270 deletions(-)
diff --git a/StarSim/StarSim/Program.cs b/StarSim/StarSim/Program.cs
@@ -68,201 +68,11 @@ namespace StarSim
bodyPositionUpdater = BodyUpdater.UpdateBodiesBruteForce;
#endif
bodyDrawer = new Drawer(window, ref bodies, ref bodyShapeMap);
- inputHandler = new InputHandler();
+ inputHandler = new InputHandler(ref bodyDrawer);
Rng = new Random();
}
/// <summary>
- /// Whether the simulation is paused at any given time.
- /// </summary>
- private static bool IsSimulationPaused { get; set; }
-
- /// <summary>
- /// Handles key presses.
- /// </summary>
- /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
- /// <param name="eventArgs">The <see cref="KeyEventArgs"/> associated with the key press.</param>
- private static void HandleKeyPressed(object sender, KeyEventArgs eventArgs)
- {
- string msg = "";
-
- switch (eventArgs.Code)
- {
- case Keyboard.Key.Space:
- // toggle the paused state
- IsSimulationPaused = !IsSimulationPaused;
- break;
-
- case Keyboard.Key.W:
- // rotate the view north
- bodyDrawer.Rotate(RotationDirection.North, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the x axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.A:
- // rotate the view west
- bodyDrawer.Rotate(RotationDirection.West, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} degrees clockwise in the y axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.S:
- // rotate the view south
- bodyDrawer.Rotate(RotationDirection.South, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} degrees clockwise in the x axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.D:
- // rotate the view east
- bodyDrawer.Rotate(RotationDirection.East, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the y axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.Q:
- // rotate the view anti-clockwise
- bodyDrawer.Rotate(RotationDirection.Anticlockwise, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the z axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.E:
- // rotate the view clockwise
- bodyDrawer.Rotate(RotationDirection.Clockwise, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the z axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- default:
- break;
- }
-
- if (!msg.Equals(""))
- {
- Console.WriteLine(msg);
- }
- }
-
- /// <summary>
- /// Handles key releases.
- /// </summary>
- /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
- /// <param name="eventArgs">The <see cref="KeyEventArgs"/> associated with the key press.</param>
- private static void HandleKeyReleased(object sender, KeyEventArgs eventArgs)
- {
- string msg = "";
-
- switch (eventArgs.Code)
- {
- case Keyboard.Key.Space:
- // toggle the paused state
- IsSimulationPaused = !IsSimulationPaused;
- break;
-
- case Keyboard.Key.W:
- // rotate the view north
- bodyDrawer.Rotate(RotationDirection.North, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} anticlockwise in the x axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.A:
- // rotate the view west
- bodyDrawer.Rotate(RotationDirection.West, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} clockwise in the y axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.S:
- // rotate the view south
- bodyDrawer.Rotate(RotationDirection.South, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} clockwise in the x axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.D:
- // rotate the view east
- bodyDrawer.Rotate(RotationDirection.East, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} anticlockwise in the y axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.Q:
- // rotate the view anti-clockwise
- bodyDrawer.Rotate(RotationDirection.Anticlockwise, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} anticlockwise in the z axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- case Keyboard.Key.E:
- // rotate the view clockwise
- bodyDrawer.Rotate(RotationDirection.Clockwise, Constants.EulerRotationStep);
- msg = $"Rotated by {Constants.EulerRotationStep} anticlockwise in the z axis. " +
- $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
- break;
-
- default:
- break;
- }
-
- if (!msg.Equals(""))
- {
- Console.WriteLine(msg);
- }
- }
-
- /// <summary>
- /// Handles motions of the mouse.
- /// </summary>
- /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
- /// <param name="eventArgs">The <see cref="MouseMoveEventArgs"/> associated with the key press.</param>
- private static void HandleMouseMoved(object sender, MouseMoveEventArgs eventArgs)
- {
- Console.WriteLine($"Mouse moved: {eventArgs.X} {eventArgs.Y}");
- }
-
- /// <summary>
- /// Handles key presses of the mouse.
- /// </summary>
- /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
- /// <param name="eventArgs">The <see cref="MouseButtonEventArgs"/> associated with the key press.</param>
- private static void HandleMousePressed(object sender, MouseButtonEventArgs eventArgs)
- {
- Console.WriteLine($"Mouse pressed: {eventArgs.X} {eventArgs.Y}, {eventArgs.Button}");
- }
-
- /// <summary>
- /// Handles key releases of the mouse.
- /// </summary>
- /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
- /// <param name="eventArgs">The <see cref="MouseButtonEventArgs"/> associated with the key press.</param>
- private static void HandleMouseReleased(object sender, MouseButtonEventArgs eventArgs)
- {
- Console.WriteLine($"Mouse released: {eventArgs.X} {eventArgs.Y}, {eventArgs.Button}");
- }
-
- /// <summary>
- /// Handles scrolling of the mouse wheel.
- /// </summary>
- /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
- /// <param name="eventArgs">The <see cref="MouseWheelScrollEventArgs"/> associated with the key press.</param>
- private static void HandleMouseScrolled(object sender, MouseWheelScrollEventArgs eventArgs)
- {
- if (eventArgs.Delta > 0)
- {
- bodyDrawer.Scale(1 + Constants.ZoomStep);
- }
- else if (eventArgs.Delta < 0)
- {
- bodyDrawer.Scale(1 - Constants.ZoomStep);
- }
-
- Console.WriteLine($"Current field of view (zoom level): {bodyDrawer.FOV} ({bodyDrawer.ZoomLevel})");
- }
-
- /// <summary>
/// Entry point for our application.
/// </summary>
/// <param name="args">Any command line arguments passed to the program.</param>
@@ -281,12 +91,12 @@ namespace StarSim
window.Closed += (sender, eventArgs) => ((RenderWindow)sender).Close();
// we apply event handlers to allow for interactivity inside the window
- window.KeyPressed += HandleKeyPressed;
- //window.KeyReleased += HandleKeyReleased;
- window.MouseButtonPressed += HandleMousePressed;
- window.MouseButtonReleased += HandleMouseReleased;
- //window.MouseMoved += HandleMouseMoved;
- window.MouseWheelScrolled += HandleMouseScrolled;
+ window.KeyPressed += inputHandler.HandleKeyPressed;
+ //window.KeyReleased += inputHandler.HandleKeyReleased;
+ window.MouseButtonPressed += inputHandler.HandleMousePressed;
+ window.MouseButtonReleased += inputHandler.HandleMouseReleased;
+ //window.MouseMoved += inputHandler.HandleMouseMoved;
+ window.MouseWheelScrolled += inputHandler.HandleMouseScrolled;
bodyDrawer.DrawBodies();
@@ -295,7 +105,7 @@ namespace StarSim
window.Clear();
window.DispatchEvents();
- if (!IsSimulationPaused)
+ if (!inputHandler.IsSimulationPaused)
{
bodyPositionUpdater(bodies, Constants.TimeStep);
}
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 = 3;
+ public const int BodyCount = 10;
/// <summary>
/// The mass of the central body, if it is included.
@@ -60,7 +60,7 @@ namespace StarSimLib
/// <summary>
/// The number of previous positions that will be stored by a body
/// </summary>
- public const int StoredPreviousPositionCount = 50;
+ public const int StoredPreviousPositionCount = 100;
/// <summary>
/// The time step for the simulation.
diff --git a/StarSim/StarSimLib/Data Structures/EulerAngles.cs b/StarSim/StarSimLib/Data Structures/EulerAngles.cs
@@ -0,0 +1,36 @@
+namespace StarSimLib.Data_Structures
+{
+ /// <summary>
+ /// Represents a set of 3 angles, that together describe a 3D rotation.
+ /// </summary>
+ public struct EulerAngles
+ {
+ /// <summary>
+ /// Angle of rotation in the x axis.
+ /// </summary>
+ public double X;
+
+ /// <summary>
+ /// Angle of rotation in the y axis.
+ /// </summary>
+ public double Y;
+
+ /// <summary>
+ /// Angle of rotation in the z axis.
+ /// </summary>
+ public double Z;
+
+ /// <summary>
+ /// Initialises a new instance of the <see cref="EulerAngles"/> struct.
+ /// </summary>
+ /// <param name="x">The angle of rotation in the x axis.</param>
+ /// <param name="y">The angle of rotation in the y axis.</param>
+ /// <param name="z">The angle of rotation in the z axis.</param>
+ public EulerAngles(double x, double y, double z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+ }
+}
+\ No newline at end of file
diff --git a/StarSim/StarSimLib/Graphics/Drawer.cs b/StarSim/StarSimLib/Graphics/Drawer.cs
@@ -71,6 +71,11 @@ namespace StarSimLib.Graphics
private const double NearDistance = 0;
/// <summary>
+ /// The vector by which all projected points are translated away from the camera and halfway into the view frustum.
+ /// </summary>
+ private static readonly Vector4d cameraTranslationVector = new Vector4d(0, 0, (FarDistance - NearDistance) / 2);
+
+ /// <summary>
/// The aspect ratio of the render target. Allows for normalisation of the <see cref="RenderTarget"/> space
/// into a normal plane ([-1, -1] = top left, [1, 1] = bottom right), instead of having to deal with a
/// variable render space.
@@ -110,9 +115,9 @@ namespace StarSimLib.Graphics
private Matrix4x4 projectionMatrix;
/// <summary>
- /// Angle of rotation in the x axis.
+ /// The 3D rotation.
/// </summary>
- private double xAngle = 0;
+ private EulerAngles rotation;
/// <summary>
/// The rotation matrix for the x axis.
@@ -120,21 +125,11 @@ namespace StarSimLib.Graphics
private Matrix4x4 xRotationMatrix;
/// <summary>
- /// Angle of rotation in the y axis.
- /// </summary>
- private double yAngle = 0;
-
- /// <summary>
/// The rotation matrix for the y axis.
/// </summary>
private Matrix4x4 yRotationMatrix;
/// <summary>
- /// Angle of rotation in the z axis.
- /// </summary>
- private double zAngle = 0;
-
- /// <summary>
/// The rotation matrix for the z axis.
/// </summary>
private Matrix4x4 zRotationMatrix;
@@ -157,6 +152,7 @@ namespace StarSimLib.Graphics
aspectRatio = renderTarget.Size.Y / (double)renderTarget.Size.X;
+ // projection and rotation matrices
projectionMatrix = new Matrix4x4(new[]
{
new [] { aspectRatio * InverseScaleFactor, 0, 0, 0 },
@@ -189,6 +185,7 @@ namespace StarSimLib.Graphics
new [] { 0d, 0, 0, 1 }
});
+ // set initial values for the rotation matrices
UpdateRotationMatrices();
managedBodies = bodies;
@@ -216,7 +213,7 @@ namespace StarSimLib.Graphics
/// </summary>
public double XAngle
{
- get { return xAngle; }
+ get { return rotation.X; }
}
/// <summary>
@@ -224,7 +221,7 @@ namespace StarSimLib.Graphics
/// </summary>
public double YAngle
{
- get { return yAngle; }
+ get { return rotation.Y; }
}
/// <summary>
@@ -232,7 +229,7 @@ namespace StarSimLib.Graphics
/// </summary>
public double ZAngle
{
- get { return zAngle; }
+ get { return rotation.Z; }
}
/// <summary>
@@ -244,10 +241,48 @@ namespace StarSimLib.Graphics
}
/// <summary>
+ /// Projects the given <see cref="Vector4d"/> point from world space into screen space.
+ /// </summary>
+ /// <param name="point">The point to project.</param>
+ /// <returns>The projected point.</returns>
+ private Vector4d ProjectPoint(Vector4d point)
+ {
+ // rotations should happen before the point is translated into camera space
+ Vector4d worldSpace = point;
+
+ // rotations of point in the x, y and z axes
+ worldSpace *= zRotationMatrix;
+ worldSpace *= yRotationMatrix;
+ worldSpace *= xRotationMatrix;
+
+ // points must be translated into the camera space, as the camera must be some distance away from the
+ // world space origin (0,0,0) or else rendering breaks. the point is translated into the middle of the
+ // camera space (the view frustum)
+ Vector4d cameraSpace = worldSpace + cameraTranslationVector;
+
+ // project the point position from camera space into screen space (without any special transformations)
+ Vector4d projectedPosition = cameraSpace * projectionMatrix;
+
+ if (!projectedPosition.W.Equals(0))
+ {
+ projectedPosition.X /= projectedPosition.W;
+ projectedPosition.Y /= projectedPosition.W;
+ projectedPosition.Z /= projectedPosition.W;
+ }
+
+ // any transformations can be applied now
+ Vector4d screenPosition = projectedPosition;
+
+ return screenPosition;
+ }
+
+ /// <summary>
/// Updates the rotation matrices for the view.
/// </summary>
private void UpdateRotationMatrices()
{
+ (double xAngle, double yAngle, double zAngle) = (rotation.X, rotation.Y, rotation.Z);
+
// update the rotation matrix values for the x axis
xRotationMatrix[1, 1] = Math.Cos(xAngle * DegToRad);
xRotationMatrix[1, 2] = -Math.Sin(xAngle * DegToRad);
@@ -279,31 +314,23 @@ namespace StarSimLib.Graphics
// which is used as the new position of the shape
CircleShape shape = managedBodyShapeMap[body];
- // rotations should happen before the body is translated into camera space
- Vector4d worldSpace = body.Position;
-
- // rotations of points in the x, y and z axes
- worldSpace *= zRotationMatrix;
- worldSpace *= yRotationMatrix;
- worldSpace *= xRotationMatrix;
-
- // bodies must be translated into the camera space, as the camera must be some distance away from the
- // world space origin (0,0,0) or else rendering breaks. the bodies are translated into the middle of
- // camera space.
- Vector4d cameraSpace = worldSpace + new Vector4d(0, 0, (FarDistance - NearDistance) / 2);
-
- // project the body position from camera space into screen space (without any special transformations)
- Vector4d projectedPosition = cameraSpace * projectionMatrix;
-
- if (!projectedPosition.W.Equals(0))
+ foreach (Vector4d previousPosition in body.PreviousPositions)
{
- projectedPosition.X /= projectedPosition.W;
- projectedPosition.Y /= projectedPosition.W;
- projectedPosition.Z /= projectedPosition.W;
+ // project previous position onto the screen
+ Vector4d pointScreenPosition = ProjectPoint(previousPosition);
+
+ CircleShape previousPositionShape = new CircleShape(0.5f)
+ {
+ Position = new Vector2f(
+ (float)(pointScreenPosition.X * renderTarget.Size.X / 2 + originOffset.X),
+ (float)(pointScreenPosition.Y * renderTarget.Size.Y / 2 + originOffset.Y)),
+ FillColor = Color.Cyan
+ };
+
+ previousPositionShape.Draw(renderTarget, RenderStates.Default);
}
- // any transformations can be applied now
- Vector4d screenPosition = projectedPosition;
+ Vector4d screenPosition = ProjectPoint(body.Position);
// final position
shape.Position = new Vector2f(
@@ -326,27 +353,27 @@ namespace StarSimLib.Graphics
switch (direction)
{
case RotationDirection.North:
- xAngle += angle % 360;
+ rotation.X += angle % 360;
break;
case RotationDirection.East:
- yAngle += angle % 360;
+ rotation.Y += angle % 360;
break;
case RotationDirection.South:
- xAngle -= angle % 360;
+ rotation.X -= angle % 360;
break;
case RotationDirection.West:
- yAngle -= angle % 360;
+ rotation.Y -= angle % 360;
break;
case RotationDirection.Clockwise:
- zAngle -= angle % 360;
+ rotation.Z -= angle % 360;
break;
case RotationDirection.Anticlockwise:
- zAngle += angle % 360;
+ rotation.Z += angle % 360;
break;
default:
@@ -355,9 +382,9 @@ namespace StarSimLib.Graphics
}
// once we hit 360 (or -360) degrees of rotation, we wrap back around to 0 degrees
- xAngle %= 360;
- yAngle %= 360;
- zAngle %= 360;
+ rotation.X %= 360;
+ rotation.Y %= 360;
+ rotation.Z %= 360;
UpdateRotationMatrices();
}
diff --git a/StarSim/StarSimLib/Physics/Body.cs b/StarSim/StarSimLib/Physics/Body.cs
@@ -16,6 +16,11 @@ namespace StarSimLib.Physics
"Body {0,2}.{1,-4}: Pos-{2}, Vel-{3} Mass-{4,3}";
/// <summary>
+ /// Backing field for the <see cref="PreviousPositions"/> property.
+ /// </summary>
+ private readonly Queue<Vector4d> previousPositions;
+
+ /// <summary>
/// The backing field for the <see cref="Force"/> property.
/// </summary>
private Vector4d force;
@@ -31,11 +36,6 @@ namespace StarSimLib.Physics
private Vector4d position;
/// <summary>
- /// Backing field for the <see cref="PreviousPositions"/> property.
- /// </summary>
- private Queue<Vector4d> previousPositions;
-
- /// <summary>
/// Backing field for the <see cref="Velocity"/> property.
/// </summary>
private Vector4d velocity;
@@ -69,6 +69,7 @@ namespace StarSimLib.Physics
this.mass = mass;
force = new Vector4d();
+ previousPositions = new Queue<Vector4d>(Constants.StoredPreviousPositionCount + 1);
}
/// <summary>
@@ -112,6 +113,21 @@ namespace StarSimLib.Physics
}
/// <summary>
+ /// Enqueues the current position on the <see cref="previousPositions"/> queue, to save it.
+ /// Will dequeue positions from the queue if the number of stored positions exceeds the
+ /// value in <see cref="Constants.StoredPreviousPositionCount"/>.
+ /// </summary>
+ private void EnqueuePosition()
+ {
+ previousPositions.Enqueue(position);
+
+ if (previousPositions.Count > Constants.StoredPreviousPositionCount)
+ {
+ previousPositions.Dequeue();
+ }
+ }
+
+ /// <summary>
/// Gets the force vector for the attraction between <see cref="Body"/> A and <see cref="Body"/> B.
/// </summary>
/// <param name="a">The first <see cref="Body"/> instance.</param>
@@ -194,6 +210,7 @@ namespace StarSimLib.Physics
public void Update(double deltaTime)
{
velocity += deltaTime * force / mass;
+ EnqueuePosition();
position += deltaTime * velocity;
}
@@ -205,6 +222,7 @@ namespace StarSimLib.Physics
public void Update(Vector4d forceVector, double deltaTime)
{
velocity += deltaTime * forceVector / mass;
+ EnqueuePosition();
position += deltaTime * velocity;
}
diff --git a/StarSim/StarSimLib/StarSimLib.xml b/StarSim/StarSimLib/StarSimLib.xml
@@ -106,6 +106,34 @@
<member name="M:StarSimLib.Contexts.SimulatorContext.OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
+ <member name="T:StarSimLib.Data_Structures.EulerAngles">
+ <summary>
+ Represents a set of 3 angles, that together describe a 3D rotation.
+ </summary>
+ </member>
+ <member name="F:StarSimLib.Data_Structures.EulerAngles.X">
+ <summary>
+ Angle of rotation in the x axis.
+ </summary>
+ </member>
+ <member name="F:StarSimLib.Data_Structures.EulerAngles.Y">
+ <summary>
+ Angle of rotation in the y axis.
+ </summary>
+ </member>
+ <member name="F:StarSimLib.Data_Structures.EulerAngles.Z">
+ <summary>
+ Angle of rotation in the z axis.
+ </summary>
+ </member>
+ <member name="M:StarSimLib.Data_Structures.EulerAngles.#ctor(System.Double,System.Double,System.Double)">
+ <summary>
+ Initialises a new instance of the <see cref="T:StarSimLib.Data_Structures.EulerAngles"/> struct.
+ </summary>
+ <param name="x">The angle of rotation in the x axis.</param>
+ <param name="y">The angle of rotation in the y axis.</param>
+ <param name="z">The angle of rotation in the z axis.</param>
+ </member>
<member name="T:StarSimLib.Data_Structures.Matrix4x4">
<summary>
A 4-by-4 matrix of <see cref="T:System.Double"/> values.
@@ -551,6 +579,11 @@
to the camera than this distance (i.e. behind the camera) are culled and not rendered.
</summary>
</member>
+ <member name="F:StarSimLib.Graphics.Drawer.cameraTranslationVector">
+ <summary>
+ The vector by which all projected points are translated away from the camera and halfway into the view frustum.
+ </summary>
+ </member>
<member name="F:StarSimLib.Graphics.Drawer.aspectRatio">
<summary>
The aspect ratio of the render target. Allows for normalisation of the <see cref="T:SFML.Graphics.RenderTarget"/> space
@@ -590,9 +623,9 @@
Projection matrix used for mapping from 3D to 2D.
</summary>
</member>
- <member name="F:StarSimLib.Graphics.Drawer.xAngle">
+ <member name="F:StarSimLib.Graphics.Drawer.rotation">
<summary>
- Angle of rotation in the x axis.
+ The 3D rotation.
</summary>
</member>
<member name="F:StarSimLib.Graphics.Drawer.xRotationMatrix">
@@ -600,21 +633,11 @@
The rotation matrix for the x axis.
</summary>
</member>
- <member name="F:StarSimLib.Graphics.Drawer.yAngle">
- <summary>
- Angle of rotation in the y axis.
- </summary>
- </member>
<member name="F:StarSimLib.Graphics.Drawer.yRotationMatrix">
<summary>
The rotation matrix for the y axis.
</summary>
</member>
- <member name="F:StarSimLib.Graphics.Drawer.zAngle">
- <summary>
- Angle of rotation in the z axis.
- </summary>
- </member>
<member name="F:StarSimLib.Graphics.Drawer.zRotationMatrix">
<summary>
The rotation matrix for the z axis.
@@ -663,6 +686,13 @@
Current zoom level of the drawer.
</summary>
</member>
+ <member name="M:StarSimLib.Graphics.Drawer.ProjectPoint(StarSimLib.Data_Structures.Vector4d)">
+ <summary>
+ Projects the given <see cref="T:StarSimLib.Data_Structures.Vector4d"/> point from world space into screen space.
+ </summary>
+ <param name="point">The point to project.</param>
+ <returns>The projected point.</returns>
+ </member>
<member name="M:StarSimLib.Graphics.Drawer.UpdateRotationMatrices">
<summary>
Updates the rotation matrices for the view.
@@ -697,6 +727,11 @@
Describes how the <see cref="T:StarSimLib.Physics.Body"/> instance should be formatted as a <see cref="T:System.String"/>.
</summary>
</member>
+ <member name="F:StarSimLib.Physics.Body.previousPositions">
+ <summary>
+ Backing field for the <see cref="P:StarSimLib.Physics.Body.PreviousPositions"/> property.
+ </summary>
+ </member>
<member name="F:StarSimLib.Physics.Body.force">
<summary>
The backing field for the <see cref="P:StarSimLib.Physics.Body.Force"/> property.
@@ -712,11 +747,6 @@
Backing field for the <see cref="P:StarSimLib.Physics.Body.Position"/> property.
</summary>
</member>
- <member name="F:StarSimLib.Physics.Body.previousPositions">
- <summary>
- Backing field for the <see cref="P:StarSimLib.Physics.Body.PreviousPositions"/> property.
- </summary>
- </member>
<member name="F:StarSimLib.Physics.Body.velocity">
<summary>
Backing field for the <see cref="P:StarSimLib.Physics.Body.Velocity"/> property.
@@ -767,6 +797,13 @@
The current velocity of the <see cref="T:StarSimLib.Physics.Body"/> in 3D space.
</summary>
</member>
+ <member name="M:StarSimLib.Physics.Body.EnqueuePosition">
+ <summary>
+ Enqueues the current position on the <see cref="F:StarSimLib.Physics.Body.previousPositions"/> queue, to save it.
+ Will dequeue positions from the queue if the number of stored positions exceeds the
+ value in <see cref="F:StarSimLib.Constants.StoredPreviousPositionCount"/>.
+ </summary>
+ </member>
<member name="M:StarSimLib.Physics.Body.GetForceBetween(StarSimLib.Physics.Body,StarSimLib.Physics.Body)">
<summary>
Gets the force vector for the attraction between <see cref="T:StarSimLib.Physics.Body"/> A and <see cref="T:StarSimLib.Physics.Body"/> B.
@@ -893,5 +930,70 @@
</summary>
<returns>A 3D position vector.</returns>
</member>
+ <member name="T:StarSimLib.UI.InputHandler">
+ <summary>
+ Provides user input handling functions.
+ </summary>
+ </member>
+ <member name="F:StarSimLib.UI.InputHandler.bodyDrawer">
+ <summary>
+ The renderer used to display the <see cref="T:StarSimLib.Physics.Body"/> instances on the screen.
+ </summary>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.#ctor(StarSimLib.Graphics.Drawer@)">
+ <summary>
+ Initialises a new instance of the <see cref="T:StarSimLib.UI.InputHandler"/> class.
+ </summary>
+ <param name="drawer">
+ A reference to the renderer used to display the <see cref="T:StarSimLib.Physics.Body"/> instances on the screen.
+ </param>
+ </member>
+ <member name="P:StarSimLib.UI.InputHandler.IsSimulationPaused">
+ <summary>
+ Whether the simulation is paused at any given time.
+ </summary>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.HandleKeyPressed(System.Object,SFML.Window.KeyEventArgs)">
+ <summary>
+ Handles key presses.
+ </summary>
+ <param name="sender">The <see cref="T:SFML.Window.Window"/> that sent the event.</param>
+ <param name="eventArgs">The <see cref="T:SFML.Window.KeyEventArgs"/> associated with the key press.</param>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.HandleKeyReleased(System.Object,SFML.Window.KeyEventArgs)">
+ <summary>
+ Handles key releases.
+ </summary>
+ <param name="sender">The <see cref="T:SFML.Window.Window"/> that sent the event.</param>
+ <param name="eventArgs">The <see cref="T:SFML.Window.KeyEventArgs"/> associated with the key release.</param>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.HandleMouseMoved(System.Object,SFML.Window.MouseMoveEventArgs)">
+ <summary>
+ Handles motions of the mouse.
+ </summary>
+ <param name="sender">The <see cref="T:SFML.Window.Window"/> that sent the event.</param>
+ <param name="eventArgs">The <see cref="T:SFML.Window.MouseMoveEventArgs"/> associated with the mouse movement.</param>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.HandleMousePressed(System.Object,SFML.Window.MouseButtonEventArgs)">
+ <summary>
+ Handles key presses of the mouse.
+ </summary>
+ <param name="sender">The <see cref="T:SFML.Window.Window"/> that sent the event.</param>
+ <param name="eventArgs">The <see cref="T:SFML.Window.MouseButtonEventArgs"/> associated with the mouse press.</param>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.HandleMouseReleased(System.Object,SFML.Window.MouseButtonEventArgs)">
+ <summary>
+ Handles key releases of the mouse.
+ </summary>
+ <param name="sender">The <see cref="T:SFML.Window.Window"/> that sent the event.</param>
+ <param name="eventArgs">The <see cref="T:SFML.Window.MouseButtonEventArgs"/> associated with the mouse release.</param>
+ </member>
+ <member name="M:StarSimLib.UI.InputHandler.HandleMouseScrolled(System.Object,SFML.Window.MouseWheelScrollEventArgs)">
+ <summary>
+ Handles scrolling of the mouse wheel.
+ </summary>
+ <param name="sender">The <see cref="T:SFML.Window.Window"/> that sent the event.</param>
+ <param name="eventArgs">The <see cref="T:SFML.Window.MouseWheelScrollEventArgs"/> associated with the mouse scroll.</param>
+ </member>
</members>
</doc>
diff --git a/StarSim/StarSimLib/UI/InputHandler.cs b/StarSim/StarSimLib/UI/InputHandler.cs
@@ -1,4 +1,9 @@
-namespace StarSimLib.UI
+using System;
+using SFML.Window;
+using StarSimLib.Graphics;
+using StarSimLib.Physics;
+
+namespace StarSimLib.UI
{
/// <summary>
/// Provides user input handling functions.
@@ -6,10 +11,162 @@
public class InputHandler
{
/// <summary>
+ /// The renderer used to display the <see cref="Body"/> instances on the screen.
+ /// </summary>
+ private readonly Drawer bodyDrawer;
+
+ /// <summary>
/// Initialises a new instance of the <see cref="InputHandler"/> class.
/// </summary>
- public InputHandler()
+ /// <param name="drawer">
+ /// A reference to the renderer used to display the <see cref="Body"/> instances on the screen.
+ /// </param>
+ public InputHandler(ref Drawer drawer)
+ {
+ bodyDrawer = drawer;
+ }
+
+ /// <summary>
+ /// Whether the simulation is paused at any given time.
+ /// </summary>
+ public bool IsSimulationPaused { get; set; }
+
+ /// <summary>
+ /// Handles key presses.
+ /// </summary>
+ /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
+ /// <param name="eventArgs">The <see cref="KeyEventArgs"/> associated with the key press.</param>
+ public void HandleKeyPressed(object sender, KeyEventArgs eventArgs)
+ {
+ string msg = "";
+
+ switch (eventArgs.Code)
+ {
+ case Keyboard.Key.Space:
+ // toggle the paused state
+ IsSimulationPaused = !IsSimulationPaused;
+ break;
+
+ case Keyboard.Key.W:
+ // rotate the view north
+ bodyDrawer.Rotate(RotationDirection.North, Constants.EulerRotationStep);
+ msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the x axis. " +
+ $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
+ break;
+
+ case Keyboard.Key.A:
+ // rotate the view west
+ bodyDrawer.Rotate(RotationDirection.West, Constants.EulerRotationStep);
+ msg = $"Rotated by {Constants.EulerRotationStep} degrees clockwise in the y axis. " +
+ $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
+ break;
+
+ case Keyboard.Key.S:
+ // rotate the view south
+ bodyDrawer.Rotate(RotationDirection.South, Constants.EulerRotationStep);
+ msg = $"Rotated by {Constants.EulerRotationStep} degrees clockwise in the x axis. " +
+ $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
+ break;
+
+ case Keyboard.Key.D:
+ // rotate the view east
+ bodyDrawer.Rotate(RotationDirection.East, Constants.EulerRotationStep);
+ msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the y axis. " +
+ $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
+ break;
+
+ case Keyboard.Key.Q:
+ // rotate the view anti-clockwise
+ bodyDrawer.Rotate(RotationDirection.Anticlockwise, Constants.EulerRotationStep);
+ msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the z axis. " +
+ $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
+ break;
+
+ case Keyboard.Key.E:
+ // rotate the view clockwise
+ bodyDrawer.Rotate(RotationDirection.Clockwise, Constants.EulerRotationStep);
+ msg = $"Rotated by {Constants.EulerRotationStep} degrees anticlockwise in the z axis. " +
+ $"View Rotation: ({bodyDrawer.XAngle},{bodyDrawer.YAngle},{bodyDrawer.ZAngle})";
+ break;
+
+ default:
+ break;
+ }
+
+ if (!msg.Equals(""))
+ {
+ Console.WriteLine(msg);
+ }
+ }
+
+ /// <summary>
+ /// Handles key releases.
+ /// </summary>
+ /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
+ /// <param name="eventArgs">The <see cref="KeyEventArgs"/> associated with the key release.</param>
+ public void HandleKeyReleased(object sender, KeyEventArgs eventArgs)
+ {
+ string msg = "";
+
+ switch (eventArgs.Code)
+ {
+ default:
+ break;
+ }
+
+ if (!msg.Equals(""))
+ {
+ Console.WriteLine(msg);
+ }
+ }
+
+ /// <summary>
+ /// Handles motions of the mouse.
+ /// </summary>
+ /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
+ /// <param name="eventArgs">The <see cref="MouseMoveEventArgs"/> associated with the mouse movement.</param>
+ public void HandleMouseMoved(object sender, MouseMoveEventArgs eventArgs)
+ {
+ Console.WriteLine($"Mouse moved: {eventArgs.X} {eventArgs.Y}");
+ }
+
+ /// <summary>
+ /// Handles key presses of the mouse.
+ /// </summary>
+ /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
+ /// <param name="eventArgs">The <see cref="MouseButtonEventArgs"/> associated with the mouse press.</param>
+ public void HandleMousePressed(object sender, MouseButtonEventArgs eventArgs)
+ {
+ Console.WriteLine($"Mouse pressed: {eventArgs.X} {eventArgs.Y}, {eventArgs.Button}");
+ }
+
+ /// <summary>
+ /// Handles key releases of the mouse.
+ /// </summary>
+ /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
+ /// <param name="eventArgs">The <see cref="MouseButtonEventArgs"/> associated with the mouse release.</param>
+ public void HandleMouseReleased(object sender, MouseButtonEventArgs eventArgs)
+ {
+ Console.WriteLine($"Mouse released: {eventArgs.X} {eventArgs.Y}, {eventArgs.Button}");
+ }
+
+ /// <summary>
+ /// Handles scrolling of the mouse wheel.
+ /// </summary>
+ /// <param name="sender">The <see cref="Window"/> that sent the event.</param>
+ /// <param name="eventArgs">The <see cref="MouseWheelScrollEventArgs"/> associated with the mouse scroll.</param>
+ public void HandleMouseScrolled(object sender, MouseWheelScrollEventArgs eventArgs)
{
+ if (eventArgs.Delta > 0)
+ {
+ bodyDrawer.Scale(1 + Constants.ZoomStep);
+ }
+ else if (eventArgs.Delta < 0)
+ {
+ bodyDrawer.Scale(1 - Constants.ZoomStep);
+ }
+
+ Console.WriteLine($"Current field of view (zoom level): {bodyDrawer.FOV} ({bodyDrawer.ZoomLevel})");
}
}
}
\ No newline at end of file